linux-basic(11)认识和学习bash
生活随笔
收集整理的這篇文章主要介紹了
linux-basic(11)认识和学习bash
小編覺得挺不錯的,現在分享給大家,幫大家做個參考.
【11.1】認識bash這個shell
1)介紹:其實殼程序的功能只是提供用戶操作系統(tǒng)的一個接口,因此這個殼程序需要可以呼叫其他軟件才好。命令,包括 man, chmod, chown, vi, fdisk, mkfs 等等命令,這些命令都是獨立的應用程序, 但是我們可以透過殼程序 (就是命令列模式) 來操作這些應用程序,讓這些應用程序呼叫核心來運行所需的工作哩!?也就是說,只要能夠操作應用程序的接口都能夠稱為shell,即殼程序。
【11.1.3】
1)那么目前我們的 Linux (以 CentOS 5.x 為例) 有多少我們可以使用的 shells 呢? 你可以檢查一下 /etc/shells 這個文件,至少就有底下這幾個可以用的 shells:
(1)
補充:bash == Bourne Again SHell, 這個shell是 Bourne Shell的增強版本,基于GNU的架構下發(fā)展出來的。
2)為什么我們系統(tǒng)上合法的 shell 要寫入 /etc/shells 這個文件啊? 這是因為系統(tǒng)某些服務在運行過程中,會去檢查使用者能夠使用的 shells ,而這些 shell 的查詢就是藉由 /etc/shells 這個文件啰!
3)我這個用戶什么時候可以取得 shell 來工作呢?還有, 我這個使用者默認會取得哪一個 shell 啊?
看個荔枝:? 當我登陸的時候,系統(tǒng)就會給我一個 shell 讓我來工作了。 而這個登陸取得的 shell 就記錄在 /etc/passwd 這個文件內!這個文件的內容是啥?
(2)
【11.1.4】bash shell的功能
1)bash 優(yōu)點如下:
命令記憶功能;
命令與文件補全功能;
命令別名設置功能;
作用控制,前后臺控制;
程序腳本;
通配符;
【11.1.5】bash shell的內置命令:type
【荔枝】type命令:怎么知道這個命令是來自于外部命令(指的是其他非 bash 所提供的命令) 或是內建在 bash 當中的呢。
(3)
(4)
總結:type 主要在找出執(zhí)行文件而不是一般文件名!所以,這個 type 也可以用來作為類似 which 命令的用途啦;
【11.2】shell的變量功能
【11.2.1】什么是變量?
變量的可變性與方便性;
影響bash環(huán)境操作的變量;
腳本程序設計的幫手;
【11.2.2】變量的顯示與設置:echo, unset?
1)變量顯示 echo
(5)
【荔枝】變量設置與顯示
(6)
(7)
(8)
補充:什么是『子程序』呢?就是說,在我目前這個 shell 的情況下,去激活另一個新的 shell ,新的那個 shell 就是子程序啦!在一般的狀態(tài)下,父程序的自定義變量是無法在子程序內使用的。但是透過 export 將變量變成環(huán)境變量后,就能夠在子程序底下應用了!
(9)
補充:其實上面的命令可以說是作了兩次動作,亦即是:
? 1. 先進行反單引號內的動作『uname -r』并得到核心版本為 2.6.18-128.el5
? 2. 將上述的結果帶入原命令,故得命令為:『cd /lib/modules/2.6.18-128.el5/kernel/』
【荔枝】在變量的配置當中,單引號與雙引號的用途有何不同?
答:單引號與雙引號的最大不同在于雙引號仍然可以保有變量的內容,但單引號內僅能是一般字符 ,而不會有特殊符號。
(10)
【荔枝】反單引號 `(~破浪號的兄弟)代表何種意義?
在一串命令中,在 ` 之內的命令將會被先運行,而其運行出來的結果將做為外部的輸入信息!例如 uname -r 會顯示出目前的核心版本,而我們的核心版本在 /lib/modules 里面,因此,你可以先運行 uname -r 找出核心版本,然后再以『 cd 目錄』到該目錄下,當然也可以運行如同上面范例六的運行內容啰。
(11)
【注意】老實說,使用『 version=$(uname -r) 』來取代『 version=`uname -r` 』比較好,因為反單引號大家老是容易打錯或看錯! 所以現在鳥哥都習慣使用 $( 命令 ) 來介紹這個功能!
【11.2.3】環(huán)境變量的功能
1)目前我的 shell 環(huán)境中, 有多少默認的環(huán)境變量啊?我們可以利用兩個命令來查閱,分別是 env 與 export 呢!
【荔枝】用 env 觀察環(huán)境變量與常見環(huán)境變量說明
(12)
環(huán)境變量分析如下:
home:用戶的主文件夾;
shell:目前這個環(huán)境使用的是哪個shell程序;
histsize:記錄多少條歷史命令;
mail:當我們使用 mail 這個命令在收信時,系統(tǒng)會去讀取的郵件信箱文件 (mailbox)。
path:就是執(zhí)行文件搜尋的路徑啦~目錄與目錄中間以冒號(:)分隔, 由于文件的搜尋是依序由 PATH 的變量內的目錄來查詢,所以,目錄的順序也是重要的喔。
lang:語系數據;一般來說,我們中文編碼通常是 zh_TW.Big5 或者是 zh_TW.UTF-8,這兩個編碼偏偏不容易被解譯出來,所以,有的時候,可能需要修訂一下語系數據。?
RANDOM:隨機數變量;目前大多數的 distributions 都會有隨機數生成器,那就是 /dev/random 這個文件。 我們可以透過這個隨機數文件相關的變量 ($RANDOM) 來隨機取得隨機數值喔。
在 BASH 的環(huán)境下,這個 RANDOM 變量的內容,介于 0~32767 之間,所以,你只要 echo $RANDOM 時,系統(tǒng)就會主動的隨機取出一個介于 0~32767 的數值。萬一我想要使用 0~9 之間的數值呢?呵呵~利用 declare 宣告數值類型, 然后這樣做就可以了:
【荔枝】RANDOM隨機數生成器
(13)
2)用set 查看所有變量(含有環(huán)境變量與自定義變量)
2.1)bash 可不只有環(huán)境變量喔,還有一些與 bash 操作接口有關的變量,以及用戶自己定義的變量存在的。
2.2)set 除了環(huán)境變量之外, 還會將其他在 bash 內的變量通通顯示出來哩!
[root@server-2 ~]# set BASH=/bin/bash BASHOPTS=checkwinsize:cmdhist:expand_aliases:extquote:force_fignore:hostcomplete:interactive_comments:login_shell:progcomp:promptvars:sourcepath BASH_ALIASES=() BASH_ARGC=() BASH_ARGV=() BASH_CMDS=() BASH_LINENO=() BASH_SOURCE=() BASH_VERSINFO=([0]="4" [1]="1" [2]="2" [3]="1" [4]="release" [5]="i386-redhat-linux-gnu") BASH_VERSION='4.1.2(1)-release' COLORS=/etc/DIR_COLORS COLUMNS=102 DIRSTACK=() EUID=0 GROUPS=() G_BROKEN_FILENAMES=1 HISTCONTROL=ignoredups HISTFILE=/root/.bash_history HISTFILESIZE=1000 HISTSIZE=1000 HOME=/root HOSTNAME=server-2 HOSTTYPE=i386 ID=0 IFS=$' \t\n' JAVA_HOME=/usr/local/software/java/jdk1.8.0_162 JRE_HOME=/usr/local/software/java/jdk1.8.0_162/jre KAFKA_HOME=/usr/local/software/kafka/kafka_2.12-1.1.0 LANG=zh_CN.UTF-8 LESSOPEN='|/usr/bin/lesspipe.sh %s' LINES=29 LOGNAME=root LS_COLORS='rs=0:di=01;34:ln=01;36:mh=00:pi=40;33:so=01;35:do=01;35:bd=40;33;01:cd=40;33;01:or=40;31;01:mi=01;05;37;41:su=37;41:sg=30;43:ca=30;41:tw=30;42:ow=34;42:st=37;44:ex=01;32:*.tar=01;31:*.tgz=01;31:*.arj=01;31:*.taz=01;31:*.lzh=01;31:*.lzma=01;31:*.tlz=01;31:*.txz=01;31:*.zip=01;31:*.z=01;31:*.Z=01;31:*.dz=01;31:*.gz=01;31:*.lz=01;31:*.xz=01;31:*.bz2=01;31:*.tbz=01;31:*.tbz2=01;31:*.bz=01;31:*.tz=01;31:*.deb=01;31:*.rpm=01;31:*.jar=01;31:*.rar=01;31:*.ace=01;31:*.zoo=01;31:*.cpio=01;31:*.7z=01;31:*.rz=01;31:*.jpg=01;35:*.jpeg=01;35:*.gif=01;35:*.bmp=01;35:*.pbm=01;35:*.pgm=01;35:*.ppm=01;35:*.tga=01;35:*.xbm=01;35:*.xpm=01;35:*.tif=01;35:*.tiff=01;35:*.png=01;35:*.svg=01;35:*.svgz=01;35:*.mng=01;35:*.pcx=01;35:*.mov=01;35:*.mpg=01;35:*.mpeg=01;35:*.m2v=01;35:*.mkv=01;35:*.ogm=01;35:*.mp4=01;35:*.m4v=01;35:*.mp4v=01;35:*.vob=01;35:*.qt=01;35:*.nuv=01;35:*.wmv=01;35:*.asf=01;35:*.rm=01;35:*.rmvb=01;35:*.flc=01;35:*.avi=01;35:*.fli=01;35:*.flv=01;35:*.gl=01;35:*.dl=01;35:*.xcf=01;35:*.xwd=01;35:*.yuv=01;35:*.cgm=01;35:*.emf=01;35:*.axv=01;35:*.anx=01;35:*.ogv=01;35:*.ogx=01;35:*.aac=01;36:*.au=01;36:*.flac=01;36:*.mid=01;36:*.midi=01;36:*.mka=01;36:*.mp3=01;36:*.mpc=01;36:*.ogg=01;36:*.ra=01;36:*.wav=01;36:*.axa=01;36:*.oga=01;36:*.spx=01;36:*.xspf=01;36:' MACHTYPE=i386-redhat-linux-gnu MAIL=/var/spool/mail/root MAILCHECK=60 OPTERR=1 OPTIND=1 OSTYPE=linux-gnu PATH=/usr/local/sbin:/usr/local/bin:/sbin:/bin:/usr/sbin:/usr/bin:/usr/local/nginx/sbin:/usr/local/git/bin:/usr/local/software/java/jdk1.8.0_162/bin:/usr/local/software/java/jdk1.8.0_162/jre/bin:/usr/local/software/zookeeper/zookeeper-3.4.11/bin:/usr/local/software/kafka/kafka_2.12-1.1.0/bin:/sbin:/root/bin PIPESTATUS=([0]="0") PPID=1285 PROMPT_COMMAND='printf "\033]0;%s@%s:%s\007" "${USER}" "${HOSTNAME%%.*}" "${PWD/#$HOME/~}"' PS1='[\u@\h \W]\$ ' PS2='> ' PS4='+ ' PWD=/root SELINUX_LEVEL_REQUESTED= SELINUX_ROLE_REQUESTED= SELINUX_USE_CURRENT_RANGE= SHELL=/bin/bash SHELLOPTS=braceexpand:emacs:hashall:histexpand:history:interactive-comments:monitor SHLVL=1 SSH_CLIENT='192.168.186.1 50886 22' SSH_CONNECTION='192.168.186.1 50886 192.168.186.103 22' SSH_TTY=/dev/pts/0 TERM=xterm UID=0 USER=root ZOOKEEPER_HOME=/usr/local/software/zookeeper/zookeeper-3.4.11 _=clear colors=/etc/DIR_COLORS【荔枝】幾個重要的變量如下:
環(huán)境變量1)PS1:(提示字符的配置): 是 PS1 (數字的 1 不是英文字母),這個東西就是我們的『命令提示字符』喔! 當我們每次按下 [Enter] 按鍵去運行某個命令后,最后要再次出現提示字符時, 就會主動去讀取這個變量值了。
你可以用 man bash (注3)去查詢一下 PS1 的相關說明,以理解底下的一些符號意義。
? ● \d :可顯示出『星期 月 日』的日期格式,如:"Mon Feb 2"
? ● \H :完整的主機名。舉例來說,鳥哥的練習機為『www.vbird.tsai』
? ● \h :僅取主機名在第一個小數點之前的名字,如鳥哥主機則為『www』后面省略
? ● \t :顯示時間,為 24 小時格式的『HH:MM:SS』
? ● \T :顯示時間,為 12 小時格式的『HH:MM:SS』
? ● \A :顯示時間,為 24 小時格式的『HH:MM』
? ● \@ :顯示時間,為 12 小時格式的『am/pm』樣式
? ● \u :目前使用者的賬號名稱,如『root』;
? ● \v :BASH 的版本信息,如鳥哥的測試主板本為 3.2.25(1),僅取『3.2』顯示
? ● \w :完整的工作目錄名稱,由根目錄寫起的目錄名稱。但家目錄會以 ~ 取代;
? ● \W :利用 basename 函數取得工作目錄名稱,所以僅會列出最后一個目錄名。
? ● \# :下達的第幾個命令。
? ● \$ :提示字符,如果是 root 時,提示字符為 # ,否則就是 $ 啰~
環(huán)境變量2)$:(關于本 shell 的 PID): 錢字號本身也是個變量喔!這個咚咚代表的是『目前這個 Shell 的線程代號』,亦即是所謂的 PID (Process ID)。
環(huán)境變量3)問號?: 表示上一個執(zhí)行命令的回傳值;
(14)
3)export:自定義變量轉換為環(huán)境變量
3.1)介紹: 這兩者的差異在于 該變量是否被子進程所繼續(xù)引用;
3.2)這個程序概念與變量有啥關系啊?? 因為子程序僅會繼承父程序的環(huán)境變量, 子程序不會繼承父程序的自定義變量啦!所以你在原本 bash 的自定義變量在進入了子程序后就會消失不見, 一直到你離開子程序并回到原本的父程序后,這個變量才會又出現!
3.3)export 變量名稱, 把自定義變量轉換為環(huán)境變量
3.4)如果僅下達 export 而沒有接變量時,那么此時將會把所有的『環(huán)境變量』秀出來喔!例如:
[root@server-2 ~]# export declare -x G_BROKEN_FILENAMES="1" declare -x HISTCONTROL="ignoredups" declare -x HISTSIZE="1000" declare -x HOME="/root" declare -x HOSTNAME="server-2" declare -x JAVA_HOME="/usr/local/software/java/jdk1.8.0_162" declare -x JRE_HOME="/usr/local/software/java/jdk1.8.0_162/jre" declare -x KAFKA_HOME="/usr/local/software/kafka/kafka_2.12-1.1.0" declare -x LANG="zh_CN.UTF-8" declare -x LESSOPEN="|/usr/bin/lesspipe.sh %s" declare -x LOGNAME="root" declare -x LS_COLORS="rs=0:di=01;34:ln=01;36:mh=00:pi=40;33:so=01;35:do=01;35:bd=40;33;01:cd=40;33;01:or=40;31;01:mi=01;05;37;41:su=37;41:sg=30;43:ca=30;41:tw=30;42:ow=34;42:st=37;44:ex=01;32:*.tar=01;31:*.tgz=01;31:*.arj=01;31:*.taz=01;31:*.lzh=01;31:*.lzma=01;31:*.tlz=01;31:*.txz=01;31:*.zip=01;31:*.z=01;31:*.Z=01;31:*.dz=01;31:*.gz=01;31:*.lz=01;31:*.xz=01;31:*.bz2=01;31:*.tbz=01;31:*.tbz2=01;31:*.bz=01;31:*.tz=01;31:*.deb=01;31:*.rpm=01;31:*.jar=01;31:*.rar=01;31:*.ace=01;31:*.zoo=01;31:*.cpio=01;31:*.7z=01;31:*.rz=01;31:*.jpg=01;35:*.jpeg=01;35:*.gif=01;35:*.bmp=01;35:*.pbm=01;35:*.pgm=01;35:*.ppm=01;35:*.tga=01;35:*.xbm=01;35:*.xpm=01;35:*.tif=01;35:*.tiff=01;35:*.png=01;35:*.svg=01;35:*.svgz=01;35:*.mng=01;35:*.pcx=01;35:*.mov=01;35:*.mpg=01;35:*.mpeg=01;35:*.m2v=01;35:*.mkv=01;35:*.ogm=01;35:*.mp4=01;35:*.m4v=01;35:*.mp4v=01;35:*.vob=01;35:*.qt=01;35:*.nuv=01;35:*.wmv=01;35:*.asf=01;35:*.rm=01;35:*.rmvb=01;35:*.flc=01;35:*.avi=01;35:*.fli=01;35:*.flv=01;35:*.gl=01;35:*.dl=01;35:*.xcf=01;35:*.xwd=01;35:*.yuv=01;35:*.cgm=01;35:*.emf=01;35:*.axv=01;35:*.anx=01;35:*.ogv=01;35:*.ogx=01;35:*.aac=01;36:*.au=01;36:*.flac=01;36:*.mid=01;36:*.midi=01;36:*.mka=01;36:*.mp3=01;36:*.mpc=01;36:*.ogg=01;36:*.ra=01;36:*.wav=01;36:*.axa=01;36:*.oga=01;36:*.spx=01;36:*.xspf=01;36:" declare -x MAIL="/var/spool/mail/root" declare -x OLDPWD declare -x PATH="/usr/local/sbin:/usr/local/bin:/sbin:/bin:/usr/sbin:/usr/bin:/usr/local/nginx/sbin:/usr/local/git/bin:/usr/local/software/java/jdk1.8.0_162/bin:/usr/local/software/java/jdk1.8.0_162/jre/bin:/usr/local/software/zookeeper/zookeeper-3.4.11/bin:/usr/local/software/kafka/kafka_2.12-1.1.0/bin:/sbin:/root/bin" declare -x PWD="/root" declare -x SELINUX_LEVEL_REQUESTED="" declare -x SELINUX_ROLE_REQUESTED="" declare -x SELINUX_USE_CURRENT_RANGE="" declare -x SHELL="/bin/bash" declare -x SHLVL="1" declare -x SSH_CLIENT="192.168.186.1 50886 22" declare -x SSH_CONNECTION="192.168.186.1 50886 192.168.186.103 22" declare -x SSH_TTY="/dev/pts/0" declare -x TERM="xterm" declare -x USER="root" declare -x ZOOKEEPER_HOME="/usr/local/software/zookeeper/zookeeper-3.4.11"【11.2.4】影響顯示結果的語系變量 locale
1)查看 locale 變量
(15)
補充1: 事實上,如果其他的語系變量都未配置, 且你有配置 LANG 或者是 LC_ALL 時,則其他的語系變量就會被這兩個變量所取代! 這也是為什么我們在 Linux 當中,通常說明僅配置 LANG 這個變量而已,因為他是最主要的配置變量!
補充2:那么你應該要覺得奇怪的是,為什么在 Linux 主機的終端機接口 (tty1 ~ tty6) 的環(huán)境下,如果配置『 LANG=zh_TW.big5 』這個配置值生效后,使用 man 或者其他信息輸出時, 都會有一堆亂碼,尤其是使用 ls -l 這個參數時?
因為在 Linux 主機的終端機接口環(huán)境下是無法顯示像中文這么復雜的編碼文字, 所以就會產生亂碼了。也就是如此,我們才會必須要在 tty1 ~ tty6 的環(huán)境下, 加裝一些中文化接口的軟件,才能夠看到中文啊!
3)整體系統(tǒng)默認的語系定義在 /etc/sysconfig/i18n
(16 )
【11.2.5】變量的有效范圍
1)環(huán)境變量 == 全局變量; 自定義變量 == 局部變量;
【11.2.6】變量鍵盤讀取、數組與宣告: read, array, declare
1)read:讀取鍵盤輸入;
(17)
【荔枝】
(18)
(19)
2)declare/typeset:等同于typeset,聲明變量類型;
(20)
【荔枝】
(21)
2.1)由于在默認的情況底下, bash 對于變量有幾個基本的定義:
? ● 變量類型默認為『字符串』,所以若不指定變量類型,則 1+2 為一個『字符串』而不是『計算式』。 所以上述第一個運行的結果才會出現那個情況的;
? ● bash 環(huán)境中的數值運算,默認最多僅能到達整數形態(tài),所以 1/3 結果是 0;
【其他荔枝】
(22)
3)數組類型
(23)
【11.2.7】與文件系統(tǒng)及程序的限制關系:ulimit
1)ulimit作用: bash 是可以『限制用戶的某些系統(tǒng)資源』的,包括可以開啟的文件數量, 可以使用的 CPU 時間,可以使用的內存總量等等。如何配置?用 ulimit 吧!
(24)
【荔枝】ulimit
(25)
(26)
補充:想要復原 ulimit 的配置最簡單的方法就是注銷再登陸,否則就是得要重新以 ulimit 配置才行!
【11.2.8】變量內容的刪除,替代與替換
1)變量內容的刪除
1.1)從頭到右刪除
(27)
【注意】更正提示:第2個注釋改為“從頭到右刪除匹配 /*bin: 的最長字符串”;
補充:# 與 ## 就分別代表:
? ● # :符合取代文字的『最短的』那一個;
? ● ##:符合取代文字的『最長的』那一個
1.2)從尾到左刪除
(28)
【注意】更正提示:第2個注釋改為“從頭到右刪除匹配 :*bin: 的最長字符串”;
2)變量替換
(29)
3)變量的刪除,替換總結如下:
(30)
4)變量測試:判斷某個變量是否存在?
(31)
補充:在大括號內有沒有冒號『 : 』的差別是很大的!加上冒號后,被測試的變量未被配置或者是已被配置為空字符串時, 都能夠用后面的內容 (本例中是使用 root 為內容) 來替換與配置!
(32)
4.1)其他測試方法,如下:?
底下的例子當中,那個 var 與 str 為變量,我們想要針對 str 是否有配置來決定 var 的值喔! 一般來說, str: 代表『str 沒配置或為空的字符串時』;至于 str 則僅為『沒有該變量』。
(33)
4.2)根據上表給出荔枝如下:
(34)
5)關于減號 (-) 其實上面我們談過了!這里的測試只是要讓你更加了解,這個減號的測試并不會影響到舊變量的內容。 如果你想要將舊變量內容也一起替換掉的話,那么就使用等號 (=) 吧!
(35)
6)如果舊變量不存在時,整個測試就告知我『有錯誤』,此時就能夠使用問號『 ? 』的幫忙啦!
(36)
【11.3】命令別名與歷史命令
【11.3.1】命令別名設置:alias, unalias
(37)
注意1:alias 的定義規(guī)則與變量定義規(guī)則幾乎相同。
【荔枝】如何知道別名列表
(38)
【11.3.2】歷史命令:history
(39)
1)history命令介紹
(40)
【荔枝如下】
(41)
2)在正常的情況下,歷史命令的讀取與記錄是這樣的:
? ● 當我們以 bash 登陸 Linux 主機之后,系統(tǒng)會主動的由家目錄的 ~/.bash_history 讀取以前曾經下過的命令,那么 ~/.bash_history 會記錄幾筆數據呢?這就與你 bash 的 HISTFILESIZE 這個變量配置值有關了!
? ● 假設我這次登陸主機后,共下達過 100 次命令,『等我注銷時, 系統(tǒng)就會將 101~1100 這總共 1000 筆歷史命令升級到 ~/.bash_history 當中。』 也就是說,歷史命令在我注銷時,會將最近的 HISTFILESIZE 筆記錄到我的紀錄文件當中啦!
? ● 當然,也可以用 history -w 強制立刻寫入的!那為何用『升級』兩個字呢? 因為 ~/.bash_history 記錄的筆數永遠都是 HISTFILESIZE 那么多,舊的信息會被主動的拿掉! 僅保留最新的!
3)history的其他作用
(42)
(43)
【11.4】bash shell 的操作環(huán)境
【11.4.1】路徑與命令查找順序
1)命令運行的順序可以這樣看:
? 1. 以相對/絕對路徑運行命令,例如『 /bin/ls 』或『 ./ls 』;
? 2. 由 alias 找到該命令來運行;
? 3. 由 bash 內建的 (builtin) 命令來運行;
? 4. 透過 $PATH 這個變量的順序搜尋到的第一個命令來運行。
(上面的順序貌似不正確的,應該 先通過 alias查找,再通過 相對或絕對路徑查找)
【荔枝1】你可以下達 /bin/ls 及單純的 ls 看看,會發(fā)現使用 ls 有顏色但是 /bin/ls 則沒有顏色。 因為 /bin/ls 是直接取用該命令來下達,而 ls 會因為『 alias ls='ls --color=tty' 』這個命令別名而先使用!
(44)
【荔枝】如果想要了解命令搜尋的順序,其實透過 type -a ls 也可以查詢的到啦!上述的順序最好先了解喔!
(45)
【11.4.2】bash的登錄與歡迎信息: /etc/issue, /etc/motd
1)還記得在終端機接口 (tty1 ~ tty6) 登陸的時候,會有幾行提示的字符串嗎?那就是進站畫面啊! 那個字符串寫在哪里啊?呵呵!在 /etc/issue 里面。
(46)
(47)
注意:更改上述注釋為登錄界面,而不是歡迎信息;
2)可以 man issue 配合 man mingetty 得到底下的結果:
(48)
(49)
【11.4.3】bash的環(huán)境配置文件
1)你是否會覺得奇怪,怎么我們什么動作都沒有進行,但是一進入 bash 就取得一堆有用的變量了? 這是因為系統(tǒng)有一些環(huán)境配置文件的存在,讓 bash 在啟動時直接讀取這些配置文件,以規(guī)劃好 bash 的操作環(huán)境啦!
2)如果想保留用戶我自己的命令別名,自定義變量,就需要把這些設置信息寫入到配置文件, 如下:
2.1)login 與 non-login shell:
2.2)/etc/profile (login shell 才會讀)
2.2.1)這個文件配置的變量主要有:
? ● PATH:會依據 UID 決定 PATH 變量要不要含有 sbin 的系統(tǒng)命令目錄;
? ● MAIL:依據賬號配置好使用者的 mailbox 到 /var/spool/mail/賬號名;
? ● USER:根據用戶的賬號配置此一變量內容;
? ● HOSTNAME:依據主機的 hostname 命令決定此一變量內容;
? ● HISTSIZE:歷史命令記錄筆數。CentOS 5.x 配置為 1000 ;
2.2.2)/etc/profile 可不止會做這些事而已,他還會去呼叫外部的配置數據喔!在 CentOS 5.x 默認的情況下, 底下這些數據會依序的被呼叫進來:
/etc/inputrc:不建議修改;
/etc/profile.d/*.sh: 只要在 /etc/profile.d/ 這個目錄內且擴展名為 .sh ,另外,使用者能夠具有 r 的權限, 那么該文件就會被 /etc/profile調用。在 CentOS 5.x 中,這個目錄/etc/profile 底下的文件規(guī)范了 bash 操作接口的顏色、 語系、ll 與 ls 命令的命令別名、vi 的命令別名、which 的命令別名等等。如果你需要幫所有使用者配置一些共享的命令別名時, 可以在這個目錄底下自行創(chuàng)建擴展名為 .sh 的文件,并將所需要的數據寫入即可喔!
(50)
/etc/sysconfig/i18n: 這個文件是由 /etc/profile.d/lang.sh 調用的!這也是我們決定 bash 默認使用何種語系的重要配置文件! 文件里最重要的就是 LANG 這個變量的配置啦!
[root@localhost ~]# cat /etc/sysconfig/i18n
LANG="zh_CN.UTF-8"
總結:反正你只要記得,bash 的 login shell 情況下所讀取的整體環(huán)境配置文件其實只有 /etc/profile;
2.3)~/.bash_profile (login shell 才會讀): bash 在讀完了整體環(huán)境配置的 /etc/profile 并藉此調用其他配置文件后,接下來則是會讀取使用者的個人配置文件。 在 login shell 的 bash 環(huán)境中,所讀取的個人偏好配置文件其實主要有三個,依序分別是:
? 1. ~/.bash_profile
? 2. ~/.bash_login
? 3. ~/.profile
2.3.1)注意:其實 bash 的 login shell 配置只會讀取上面三個文件的其中一個, 而讀取的順序則是依照上面的順序。也就是說,如果 ~/.bash_profile 存在,那么其他兩個文件不論有無存在,都不會被讀取。 如果 ~/.bash_profile 不存在才會去讀取 ~/.bash_login,而前兩者都不存在才會讀取 ~/.profile 的意思。 會有這么多的文件,其實是因應其他 shell 轉換過來的使用者的習慣而已。
【荔枝】~/.bash_profile 的文件內容
(51)
2.3.2)bash 配置文件的讀入方式比較有趣,主要是透過一個命令『 source 』來讀取的!也就是說 ~/.bash_profile 其實會再調用 ~/.bashrc 的配置內容喔!
2.4)最后,我們來看看整個 login shell 的讀取流程:
(52)
2.4.1)source命令:讀入環(huán)境配置文件的命令。修改參數配置,如/etc/profile 文件后,通常情況下,需要重啟后才生效;而輸入 source /etc/profile 可以將修改內容立即生效;
(53)
2.5)~/.bashrc (non-login shell 會讀):
(54)
2.5.1)CentOS 5.x 還會主動調用 /etc/bashrc 這個文件喔!為什么需要調用 /etc/bashrc 呢? 因為 /etc/bashrc 幫我們的 bash 定義出底下的數據:
? ● 依據不同的 UID 規(guī)范出 umask 的值;
? ● 依據不同的 UID 規(guī)范出提示字符 (就是 PS1 變量);
? ● 調用 /etc/profile.d/*.sh 的配置
【注意】你要注意的是,這個 /etc/bashrc 是 CentOS 特有的 (其實是 Red Hat 系統(tǒng)特有的),其他不同的 distributions 可能會放置在不同的檔名就是了。由于這個 ~/.bashrc 會呼叫 /etc/bashrc 及 /etc/profile.d/*.sh , 所以,萬一你沒有 ~/.bashrc (可能自己不小心將他刪除了),那么你會發(fā)現你的 bash 提示字符可能會變成這個樣子:
-bash-3.2$??
【11.4.4】終端機的環(huán)境設置: stty, set
1)那么如何查閱目前的一些按鍵內容呢?可以利用 stty (setting tty 終端機的意思) 呢! stty 也可以幫助配置終端機的輸入按鍵代表意義喔!
(55)
(56)
[root@localhost ~]# stty -a speed 38400 baud; rows 45; columns 102; line = 0; intr = ^C; quit = ^\; erase = ^?; kill = ^U; eof = ^D; eol = <undef>; eol2 = <undef>; swtch = <undef>; start = ^Q; stop = ^S; susp = ^Z; rprnt = ^R; werase = ^W; lnext = ^V; flush = ^O; min = 1; time = 0; -parenb -parodd cs8 -hupcl -cstopb cread -clocal -crtscts -cdtrdsr -ignbrk -brkint -ignpar -parmrk -inpck -istrip -inlcr -igncr icrnl ixon -ixoff -iuclc -ixany -imaxbel -iutf8 opost -olcuc -ocrnl onlcr -onocr -onlret -ofill -ofdel nl0 cr0 tab0 bs0 vt0 ff0 isig icanon iexten echo echoe echok -echonl -noflsh -xcase -tostop -echoprt echoctl echoke分析1)如果出現 ^ 表示 [Ctrl] 那個按鍵的意思。舉例來說, intr = ^C 表示利用 [ctrl] + c 來達成的。
分析2)幾個重要的代表意義是:
? ● eof? ?: End of file 的意思,代表『結束輸入』。
? ● erase : 向后刪除字符,
? ● intr? : 送出一個 interrupt (中斷) 的訊號給目前正在 run 的程序;
? ● kill? : 刪除在目前命令列上的所有文字;
? ● quit? : 送出一個 quit 的訊號給目前正在 run 的程序;
? ● start : 在某個程序停止后,重新啟動他的 output
? ● stop? : 停止目前屏幕的輸出;
? ● susp? : 送出一個 terminal stop 的訊號給正在 run 的程序。
【荔枝】如果你想要用 [ctrl]+h 來進行字符的刪除,那么可以下達: stty erase ^h
2)set的設置功能:我們之前提到一些變量時,可以利用 set 來顯示,除此之外,其實 set 還可以幫我們配置整個命令輸出/輸入的環(huán)境。 例如記錄歷史命令、顯示錯誤內容等等。
(57)
(58)
(59)
(60)
【補充】/etc/inputrc 文件中存儲了其他按鍵設置功能:
[root@localhost ~]# cat /etc/inputrc # do not bell on tab-completion #set bell-style noneset meta-flag on set input-meta on set convert-meta off set output-meta on# Completed names which are symbolic links to # directories have a slash appended. set mark-symlinked-directories on$if mode=emacs# for linux console and RH/Debian xterm "\e[1~": beginning-of-line "\e[4~": end-of-line # commented out keymappings for pgup/pgdown to reach begin/end of history #"\e[5~": beginning-of-history #"\e[6~": end-of-history "\e[5~": history-search-backward "\e[6~": history-search-forward "\e[3~": delete-char "\e[2~": quoted-insert "\e[5C": forward-word "\e[5D": backward-word "\e[1;5C": forward-word "\e[1;5D": backward-word# for rxvt "\e[8~": end-of-line "\eOc": forward-word "\eOd": backward-word# for non RH/Debian xterm, can't hurt for RH/DEbian xterm "\eOH": beginning-of-line "\eOF": end-of-line# for freebsd console "\e[H": beginning-of-line "\e[F": end-of-line $endif【總結】bash 默認的組合鍵匯總如下:
(61)
【11.4.5】通配符與特殊符號
1)常用通配符如下:
(62)
2)通配符荔枝
2.1)利用通配符配合 ls 查找文件看看:荔枝如下:
(63)
(64)
(65)
(66)
2.2)bash 環(huán)境中的特殊符號有哪些呢?
(67)
【注意】以上為 bash 環(huán)境中常見的特殊符號匯整!理論上,你的文件名盡量不要使用到上述的字符啦。
【11.5】數據流重定向
【11.5.1】什么是數據流重定向?
1)數據流重導向就是將某個命令運行后應該要出現在屏幕上的數據, 給他傳輸到其他的地方,例如文件或者是裝置 (例如打印機之類的)!
2)數據流重導向可以將 standard output (簡稱 stdout) 與 standard error output (簡稱 stderr) 分別傳送到其他的文件或裝置去,而分別傳送所用的特殊字符則如下所示:
? 1. 標準輸入 (stdin) :代碼為 0 ,使用 < 或 << ;
? 2. 標準輸出 (stdout):代碼為 1 ,使用 > 或 >> ;
? 3. 標準錯誤輸出(stderr):代碼為 2 ,使用 2> 或 2>> ;
(68)
【補充】
補充1)符號 > 表示覆蓋文件內容; 符號 >> 表示追加內容到文件;
補充2)rootfile文件的創(chuàng)建方式是:
? 1. 該文件 (本例中是 ~/rootfile) 若不存在,系統(tǒng)會自動的將他創(chuàng)建起來,但是
? 2. 當這個文件存在的時候,那么系統(tǒng)就會先將這個文件內容清空,然后再將數據寫入!
? 3. 也就是若以 > 輸出到一個已存在的文件中,那個文件就會被覆蓋掉啰!
3)上面談到的是 standard output 的正確數據,那如果是 standard error output 的錯誤數據呢?那就透過 2> 及 2>> 啰!同樣是覆蓋 (2>) 與累加 (2>>) 的特性!詳情如下:
? ● 1> :以覆蓋的方法將『正確的數據』輸出到指定的文件或裝置上;
? ● 1>>:以累加的方法將『正確的數據』輸出到指定的文件或裝置上;
? ● 2> :以覆蓋的方法將『錯誤的數據』輸出到指定的文件或裝置上;
? ● 2>>:以累加的方法將『錯誤的數據』輸出到指定的文件或裝置上;
【荔枝】將 stdout 與 stderr 分存到不同的文件去
(69)
4)/dev/null 垃圾桶黑洞設備與特殊寫法: 如果我知道錯誤信息會發(fā)生,所以要將錯誤信息忽略掉而不顯示或儲存呢? 這個時候黑洞裝置 /dev/null 就很重要了!這個 /dev/null 可以吃掉任何導向這個裝置的信息喔!
【荔枝】 /dev/null 黑洞設備
(70)
【荔枝】將正確與錯誤數據通通寫入同一個文件去呢?
(71)
5)標準輸入: < 與 <<
< 表示 將原本需要由鍵盤輸入的數據,改由文件內容來取代;
【荔枝】通過 cat 命令操作來了解一下什么叫做『鍵盤輸入』吧
(72)
【荔枝】用某個文件的內容來取代鍵盤的敲擊呢: 用 stdin 取代鍵盤的輸入以創(chuàng)建新文件的簡單流程
(73)
【荔枝】 << 代表的是結束的輸入字符的意思! 舉例來講:我要用 cat 直接將輸入的信息輸出到 catfile 中, 且當由鍵盤輸入 eof 時,該次輸入就結束。
(74)
6)總結:為何要使用命令輸出重導向呢?我們來說一說吧!
? ● 屏幕輸出的信息很重要,而且我們需要將他存下來的時候;
? ● 背景運行中的程序,不希望他干擾屏幕正常的輸出結果時;
? ● 一些系統(tǒng)的例行命令 (例如寫在 /etc/crontab 中的文件) 的運行結果,希望他可以存下來時;
? ● 一些運行命令的可能已知錯誤信息時,想以『 2> /dev/null 』將他丟掉時;
? ● 錯誤信息與正確信息需要分別輸出時。
【11.5.2】命令執(zhí)行的判斷依據: 分號; , 雙and符號&&,雙豎線 ||;
1)背景:在某些情況下,很多命令我想要一次輸入去運行,而不想要分次運行時,該如何是好?基本上你有兩個選擇, 一個是透過第十三章要介紹的 shell script 撰寫腳本去運行,一種則是透過底下的介紹來一次輸入多重命令喔。
2)cmd ; cmd (不考慮命令相關性的連續(xù)命令下達)
【荔枝】例如在關機的時候我希望可以先運行兩次 sync 同步化寫入磁盤后才 shutdown 計算機,那么可以怎么作呢?
(75)
3)$? (命令回傳值) 與 && 或 ||
3.1)復習:若前一個命令運行的結果為正確,在 Linux 底下會回傳一個 $? = 0 的值;怎么透過這個回傳值來判斷后續(xù)的命令是否要運行呢?這就得要藉由『 && 』及『 || 』的幫忙了! 注意喔,兩個 & 之間是沒有空格的!
(76)
【荔枝】ls 查閱目錄 /tmp/abc 是否存在,若存在則用 touch 創(chuàng)建 /tmp/abc/hehe:
(77)
【荔枝】測試 /tmp/abc 是否存在,若不存在則予以創(chuàng)建,若存在就不作任何事情:
(78)
(79)
(80)
結果分析如下:
? ● (1)若 /tmp/abc 不存在故回傳 $?≠0,則 (2)因為 || 遇到非為 0 的 $? 故開始 mkdir /tmp/abc,由于 mkdir /tmp/abc 會成功進行,所以回傳 $?=0 (3)因為 && 遇到 $?=0 故會運行 touch /tmp/abc/hehe,最終 hehe 就被創(chuàng)建了;
? ● (2)若 /tmp/abc 存在故回傳 $?=0,則 (2)因為 || 遇到 0 的 $? 不會進行,此時 $?=0 繼續(xù)向后傳,故 (3)因為 && 遇到 $?=0 就開始創(chuàng)建 /tmp/abc/hehe 了!最終 /tmp/abc/hehe 被創(chuàng)建起來。
【荔枝】以 ls 測試 /tmp/vbirding 是否存在,若存在則顯示 "exist" ,若不存在,則顯示 "not exist"!
(81)
【11.6】管道命令
1)管線命令主要有兩個比較需要注意的地方:
? ● 管線命令僅會處理 standard output,對于 standard error output 會予以忽略;
? ● 管線命令必須要能夠接受來自前一個命令的數據成為 standard input 繼續(xù)處理才行。
【11.6.1】選取命令: cut, grep
1)cut命令(篩選列):cut 不就是『切』嗎?沒錯啦!這個命令可以將一段信息的某一段給他『切』出來。
(82)
【荔枝】
(83)
(84)
(85)
(86)
【cut命令總計】cut 主要的用途在于將『同一行里面的數據進行分解!』最常使用在分析一些數據或文字數據的時候! 這是因為有時候我們會以某些字符當作分割的參數,然后來將數據加以切割,以取得我們所需要的數據。
2)grep命令(篩選行):剛剛的 cut 是將一行信息當中,取出某部分我們想要的,而 grep 則是分析一行信息, 若當中有我們所需要的信息,就將該行拿出來;
【荔枝】
(87)
(88)
(89)
(90)
(91)
3)排序命令:sort, wc, uniq
3.1)sort命令:
注意:排序的字符與語系的編碼有關,因此, 如果您需要排序時,建議使用 LANG=C 來讓語系統(tǒng)一,數據排序比較好一些。
(92)
(93)
【荔枝】
(94)
(95)
(96)
3.2)uniq 命令:如果我排序完成了,想要將重復的數據僅列出一個顯示;
(97)
(98)
(99)
補充: 這個命令用來將『重復的行刪除掉只顯示一個』,舉個例子來說, 你要知道這個月份登陸你主機的用戶有誰,而不在乎他的登陸次數,那么就使用上面的范例, (1)先將所有的數據列出;(2)再將人名獨立出來;(3)經過排序;(4)只顯示一個! 由于這個命令是在將重復的東西減少,所以當然需要『配合排序過的文件』來處理啰!
3.3)wc命令:如果我想要知道 /etc/man.config 這個文件里面有多少字?多少行?多少字符的話, 可以怎么做呢?其實可以利用 wc 這個命令來達成喔!
(100)
【荔枝】
(101)
(102)
【11.6.3】雙向重定向:tee
1)想個簡單的東西,我們由前一節(jié)知道 > 會將數據流整個傳送給文件或裝置,因此我們除非去讀取該文件或裝置, 否則就無法繼續(xù)利用這個數據流。萬一我想要將這個數據流的處理過程中將某段信息存下來,應該怎么做? 利用 tee 就可以啰。
(103)
2)tee 會同時將數據流分送到文件去與屏幕 (screen);而輸出到屏幕的,其實就是 stdout ,可以讓下個命令繼續(xù)處理!
(104)
【荔枝】
(105)
(106)
(107)
【11.6.4】字符轉換命令:tr, col, join, paste, expand
1)tr命令:tr 可以用來刪除一段信息當中的文字,或者是進行文字信息的替換;
(108)
(109)
【荔枝】
(110)
(111)
(112)
(113)
補充:處理 Linux & Windows 系統(tǒng)中的人們最麻煩的一件事就是這個事情啦!亦即是 DOS 底下會自動的在每行行尾加入 ^M 這個斷行符號!這個時候我們可以使用這個 tr 來將 ^M 去除! ^M 可以使用 \r 來代替之!
2)col命令:
(114)
(115)
【荔枝】
(116)
(117)
補充1)你沒看錯!由于 man page 內有些特殊按鈕會用來作為類似特殊按鍵與顏色顯示,所以這個文件內就會出現如上所示的一堆怪異字符(有 ^ 的)。
補充2) col 經常被利用于將 man page 轉存為純文本文件以方便查閱的功能!
3)join命令:主要是在處理『兩個文件當中,有 "相同數據" 的那一行,才將他加在一起的意思。
(118)
【荔枝】
(119)
(120)
需要特別注意的是:在使用 join 之前,你所需要處理的文件應該要事先經過排序 (sort) 處理! 否則有些比對的項目會被略過呢!
4)paste命令:相對于 join 必須要比對兩個文件的數據相關性, paste 就直接『將兩行貼在一起,且中間以 [tab] 鍵隔開』而已!
(121)
【荔枝】
(122)
(123)
5)expand命令:將tab鍵 轉換成空格鍵,如下:
(124)
【荔枝】
(125)
補充:expand命令自動將 [tab] 轉成空格鍵~所以,以上面的例子來說, 使用 cat -A 就會查不到 ^I 的字符啰~此外,因為 [tab] 最大的功能就是格式排列整齊! 我們轉成空格鍵后,這個空格鍵也會依據我們自己的定義來添加大小~ 所以,并不是一個 ^I 就會換成 8 個空白喔!這個地方要特別注意的哩! 此外,您也可以參考一下 unexpand 這個將空白轉成 [tab] 的命令功能啊!
【11.6.5】切割命令: split
1)介紹: 如果你有文件太大,導致一些攜帶式設備無法復制的問題!找 split 就對了! 他可以幫你將一個大文件,依據文件大小或行數來分割,就可以將大文件分割成為小文件了!?
(126)
【荔枝】
(127)
(128)
(129)
補充:在 Windows 操作系統(tǒng)下,你要將文件分割需要如何作?傷腦筋吧!在 Linux 底下就簡單的多了!你要將文件分割的話,那么就使用 -b size 來將一個分割的文件限制其大小,如果是行數的話,那么就使用 -l line 來分割!
【11.6.6】參數代換:xargs
1)xargs作用: 產生某個命令的參數的意思! xargs 可以讀入 stdin 的數據,并且以空格符或斷行字符作為分辨,將 stdin 的數據分隔成為 arguments 。?
(130)
【荔枝】
(131)
(132)
(133)
(134)
補充: 會使用 xargs 的原因是, 很多命令其實并不支持管線命令,因此我們可以透過 xargs 來提供該命令引用 standard input 之用!
2)舉例來說,我們使用如下的范例來說明:
(135)
【11.6.7】關于減號- 的用途
1)在管線命令當中,常常會使用到前一個命令的 stdout 作為這次的 stdin , 某些命令需要用到文件名 (例如 tar) 來進行處理時,該 stdin 與 stdout 可以利用減號 "-" 來替代, 舉例來說:
(136)
【補充】上面這個例子是說: 我將 /home 里面的文件給他打包,但打包的數據不是紀錄到文件,而是傳送到 stdout; 經過管線后,將 tar -cvf - /home 傳送給后面的 tar -xvf - 。后面的這個 - 則是取用前一個命令的 stdout, 因此,我們就不需要使用 file 了!這是很常見的例子喔!注意注意!
1)介紹:其實殼程序的功能只是提供用戶操作系統(tǒng)的一個接口,因此這個殼程序需要可以呼叫其他軟件才好。命令,包括 man, chmod, chown, vi, fdisk, mkfs 等等命令,這些命令都是獨立的應用程序, 但是我們可以透過殼程序 (就是命令列模式) 來操作這些應用程序,讓這些應用程序呼叫核心來運行所需的工作哩!?也就是說,只要能夠操作應用程序的接口都能夠稱為shell,即殼程序。
【11.1.3】
1)那么目前我們的 Linux (以 CentOS 5.x 為例) 有多少我們可以使用的 shells 呢? 你可以檢查一下 /etc/shells 這個文件,至少就有底下這幾個可以用的 shells:
(1)
補充:bash == Bourne Again SHell, 這個shell是 Bourne Shell的增強版本,基于GNU的架構下發(fā)展出來的。
2)為什么我們系統(tǒng)上合法的 shell 要寫入 /etc/shells 這個文件啊? 這是因為系統(tǒng)某些服務在運行過程中,會去檢查使用者能夠使用的 shells ,而這些 shell 的查詢就是藉由 /etc/shells 這個文件啰!
3)我這個用戶什么時候可以取得 shell 來工作呢?還有, 我這個使用者默認會取得哪一個 shell 啊?
看個荔枝:? 當我登陸的時候,系統(tǒng)就會給我一個 shell 讓我來工作了。 而這個登陸取得的 shell 就記錄在 /etc/passwd 這個文件內!這個文件的內容是啥?
(2)
【11.1.4】bash shell的功能
1)bash 優(yōu)點如下:
命令記憶功能;
命令與文件補全功能;
命令別名設置功能;
作用控制,前后臺控制;
程序腳本;
通配符;
【11.1.5】bash shell的內置命令:type
【荔枝】type命令:怎么知道這個命令是來自于外部命令(指的是其他非 bash 所提供的命令) 或是內建在 bash 當中的呢。
(3)
(4)
總結:type 主要在找出執(zhí)行文件而不是一般文件名!所以,這個 type 也可以用來作為類似 which 命令的用途啦;
【11.2】shell的變量功能
【11.2.1】什么是變量?
變量的可變性與方便性;
影響bash環(huán)境操作的變量;
腳本程序設計的幫手;
【11.2.2】變量的顯示與設置:echo, unset?
1)變量顯示 echo
(5)
【荔枝】變量設置與顯示
(6)
(7)
(8)
補充:什么是『子程序』呢?就是說,在我目前這個 shell 的情況下,去激活另一個新的 shell ,新的那個 shell 就是子程序啦!在一般的狀態(tài)下,父程序的自定義變量是無法在子程序內使用的。但是透過 export 將變量變成環(huán)境變量后,就能夠在子程序底下應用了!
(9)
補充:其實上面的命令可以說是作了兩次動作,亦即是:
? 1. 先進行反單引號內的動作『uname -r』并得到核心版本為 2.6.18-128.el5
? 2. 將上述的結果帶入原命令,故得命令為:『cd /lib/modules/2.6.18-128.el5/kernel/』
【荔枝】在變量的配置當中,單引號與雙引號的用途有何不同?
答:單引號與雙引號的最大不同在于雙引號仍然可以保有變量的內容,但單引號內僅能是一般字符 ,而不會有特殊符號。
(10)
【荔枝】反單引號 `(~破浪號的兄弟)代表何種意義?
在一串命令中,在 ` 之內的命令將會被先運行,而其運行出來的結果將做為外部的輸入信息!例如 uname -r 會顯示出目前的核心版本,而我們的核心版本在 /lib/modules 里面,因此,你可以先運行 uname -r 找出核心版本,然后再以『 cd 目錄』到該目錄下,當然也可以運行如同上面范例六的運行內容啰。
(11)
【注意】老實說,使用『 version=$(uname -r) 』來取代『 version=`uname -r` 』比較好,因為反單引號大家老是容易打錯或看錯! 所以現在鳥哥都習慣使用 $( 命令 ) 來介紹這個功能!
【11.2.3】環(huán)境變量的功能
1)目前我的 shell 環(huán)境中, 有多少默認的環(huán)境變量啊?我們可以利用兩個命令來查閱,分別是 env 與 export 呢!
【荔枝】用 env 觀察環(huán)境變量與常見環(huán)境變量說明
(12)
環(huán)境變量分析如下:
home:用戶的主文件夾;
shell:目前這個環(huán)境使用的是哪個shell程序;
histsize:記錄多少條歷史命令;
mail:當我們使用 mail 這個命令在收信時,系統(tǒng)會去讀取的郵件信箱文件 (mailbox)。
path:就是執(zhí)行文件搜尋的路徑啦~目錄與目錄中間以冒號(:)分隔, 由于文件的搜尋是依序由 PATH 的變量內的目錄來查詢,所以,目錄的順序也是重要的喔。
lang:語系數據;一般來說,我們中文編碼通常是 zh_TW.Big5 或者是 zh_TW.UTF-8,這兩個編碼偏偏不容易被解譯出來,所以,有的時候,可能需要修訂一下語系數據。?
RANDOM:隨機數變量;目前大多數的 distributions 都會有隨機數生成器,那就是 /dev/random 這個文件。 我們可以透過這個隨機數文件相關的變量 ($RANDOM) 來隨機取得隨機數值喔。
在 BASH 的環(huán)境下,這個 RANDOM 變量的內容,介于 0~32767 之間,所以,你只要 echo $RANDOM 時,系統(tǒng)就會主動的隨機取出一個介于 0~32767 的數值。萬一我想要使用 0~9 之間的數值呢?呵呵~利用 declare 宣告數值類型, 然后這樣做就可以了:
【荔枝】RANDOM隨機數生成器
(13)
2)用set 查看所有變量(含有環(huán)境變量與自定義變量)
2.1)bash 可不只有環(huán)境變量喔,還有一些與 bash 操作接口有關的變量,以及用戶自己定義的變量存在的。
2.2)set 除了環(huán)境變量之外, 還會將其他在 bash 內的變量通通顯示出來哩!
[root@server-2 ~]# set BASH=/bin/bash BASHOPTS=checkwinsize:cmdhist:expand_aliases:extquote:force_fignore:hostcomplete:interactive_comments:login_shell:progcomp:promptvars:sourcepath BASH_ALIASES=() BASH_ARGC=() BASH_ARGV=() BASH_CMDS=() BASH_LINENO=() BASH_SOURCE=() BASH_VERSINFO=([0]="4" [1]="1" [2]="2" [3]="1" [4]="release" [5]="i386-redhat-linux-gnu") BASH_VERSION='4.1.2(1)-release' COLORS=/etc/DIR_COLORS COLUMNS=102 DIRSTACK=() EUID=0 GROUPS=() G_BROKEN_FILENAMES=1 HISTCONTROL=ignoredups HISTFILE=/root/.bash_history HISTFILESIZE=1000 HISTSIZE=1000 HOME=/root HOSTNAME=server-2 HOSTTYPE=i386 ID=0 IFS=$' \t\n' JAVA_HOME=/usr/local/software/java/jdk1.8.0_162 JRE_HOME=/usr/local/software/java/jdk1.8.0_162/jre KAFKA_HOME=/usr/local/software/kafka/kafka_2.12-1.1.0 LANG=zh_CN.UTF-8 LESSOPEN='|/usr/bin/lesspipe.sh %s' LINES=29 LOGNAME=root LS_COLORS='rs=0:di=01;34:ln=01;36:mh=00:pi=40;33:so=01;35:do=01;35:bd=40;33;01:cd=40;33;01:or=40;31;01:mi=01;05;37;41:su=37;41:sg=30;43:ca=30;41:tw=30;42:ow=34;42:st=37;44:ex=01;32:*.tar=01;31:*.tgz=01;31:*.arj=01;31:*.taz=01;31:*.lzh=01;31:*.lzma=01;31:*.tlz=01;31:*.txz=01;31:*.zip=01;31:*.z=01;31:*.Z=01;31:*.dz=01;31:*.gz=01;31:*.lz=01;31:*.xz=01;31:*.bz2=01;31:*.tbz=01;31:*.tbz2=01;31:*.bz=01;31:*.tz=01;31:*.deb=01;31:*.rpm=01;31:*.jar=01;31:*.rar=01;31:*.ace=01;31:*.zoo=01;31:*.cpio=01;31:*.7z=01;31:*.rz=01;31:*.jpg=01;35:*.jpeg=01;35:*.gif=01;35:*.bmp=01;35:*.pbm=01;35:*.pgm=01;35:*.ppm=01;35:*.tga=01;35:*.xbm=01;35:*.xpm=01;35:*.tif=01;35:*.tiff=01;35:*.png=01;35:*.svg=01;35:*.svgz=01;35:*.mng=01;35:*.pcx=01;35:*.mov=01;35:*.mpg=01;35:*.mpeg=01;35:*.m2v=01;35:*.mkv=01;35:*.ogm=01;35:*.mp4=01;35:*.m4v=01;35:*.mp4v=01;35:*.vob=01;35:*.qt=01;35:*.nuv=01;35:*.wmv=01;35:*.asf=01;35:*.rm=01;35:*.rmvb=01;35:*.flc=01;35:*.avi=01;35:*.fli=01;35:*.flv=01;35:*.gl=01;35:*.dl=01;35:*.xcf=01;35:*.xwd=01;35:*.yuv=01;35:*.cgm=01;35:*.emf=01;35:*.axv=01;35:*.anx=01;35:*.ogv=01;35:*.ogx=01;35:*.aac=01;36:*.au=01;36:*.flac=01;36:*.mid=01;36:*.midi=01;36:*.mka=01;36:*.mp3=01;36:*.mpc=01;36:*.ogg=01;36:*.ra=01;36:*.wav=01;36:*.axa=01;36:*.oga=01;36:*.spx=01;36:*.xspf=01;36:' MACHTYPE=i386-redhat-linux-gnu MAIL=/var/spool/mail/root MAILCHECK=60 OPTERR=1 OPTIND=1 OSTYPE=linux-gnu PATH=/usr/local/sbin:/usr/local/bin:/sbin:/bin:/usr/sbin:/usr/bin:/usr/local/nginx/sbin:/usr/local/git/bin:/usr/local/software/java/jdk1.8.0_162/bin:/usr/local/software/java/jdk1.8.0_162/jre/bin:/usr/local/software/zookeeper/zookeeper-3.4.11/bin:/usr/local/software/kafka/kafka_2.12-1.1.0/bin:/sbin:/root/bin PIPESTATUS=([0]="0") PPID=1285 PROMPT_COMMAND='printf "\033]0;%s@%s:%s\007" "${USER}" "${HOSTNAME%%.*}" "${PWD/#$HOME/~}"' PS1='[\u@\h \W]\$ ' PS2='> ' PS4='+ ' PWD=/root SELINUX_LEVEL_REQUESTED= SELINUX_ROLE_REQUESTED= SELINUX_USE_CURRENT_RANGE= SHELL=/bin/bash SHELLOPTS=braceexpand:emacs:hashall:histexpand:history:interactive-comments:monitor SHLVL=1 SSH_CLIENT='192.168.186.1 50886 22' SSH_CONNECTION='192.168.186.1 50886 192.168.186.103 22' SSH_TTY=/dev/pts/0 TERM=xterm UID=0 USER=root ZOOKEEPER_HOME=/usr/local/software/zookeeper/zookeeper-3.4.11 _=clear colors=/etc/DIR_COLORS【荔枝】幾個重要的變量如下:
環(huán)境變量1)PS1:(提示字符的配置): 是 PS1 (數字的 1 不是英文字母),這個東西就是我們的『命令提示字符』喔! 當我們每次按下 [Enter] 按鍵去運行某個命令后,最后要再次出現提示字符時, 就會主動去讀取這個變量值了。
你可以用 man bash (注3)去查詢一下 PS1 的相關說明,以理解底下的一些符號意義。
? ● \d :可顯示出『星期 月 日』的日期格式,如:"Mon Feb 2"
? ● \H :完整的主機名。舉例來說,鳥哥的練習機為『www.vbird.tsai』
? ● \h :僅取主機名在第一個小數點之前的名字,如鳥哥主機則為『www』后面省略
? ● \t :顯示時間,為 24 小時格式的『HH:MM:SS』
? ● \T :顯示時間,為 12 小時格式的『HH:MM:SS』
? ● \A :顯示時間,為 24 小時格式的『HH:MM』
? ● \@ :顯示時間,為 12 小時格式的『am/pm』樣式
? ● \u :目前使用者的賬號名稱,如『root』;
? ● \v :BASH 的版本信息,如鳥哥的測試主板本為 3.2.25(1),僅取『3.2』顯示
? ● \w :完整的工作目錄名稱,由根目錄寫起的目錄名稱。但家目錄會以 ~ 取代;
? ● \W :利用 basename 函數取得工作目錄名稱,所以僅會列出最后一個目錄名。
? ● \# :下達的第幾個命令。
? ● \$ :提示字符,如果是 root 時,提示字符為 # ,否則就是 $ 啰~
環(huán)境變量2)$:(關于本 shell 的 PID): 錢字號本身也是個變量喔!這個咚咚代表的是『目前這個 Shell 的線程代號』,亦即是所謂的 PID (Process ID)。
環(huán)境變量3)問號?: 表示上一個執(zhí)行命令的回傳值;
(14)
3)export:自定義變量轉換為環(huán)境變量
3.1)介紹: 這兩者的差異在于 該變量是否被子進程所繼續(xù)引用;
3.2)這個程序概念與變量有啥關系啊?? 因為子程序僅會繼承父程序的環(huán)境變量, 子程序不會繼承父程序的自定義變量啦!所以你在原本 bash 的自定義變量在進入了子程序后就會消失不見, 一直到你離開子程序并回到原本的父程序后,這個變量才會又出現!
3.3)export 變量名稱, 把自定義變量轉換為環(huán)境變量
3.4)如果僅下達 export 而沒有接變量時,那么此時將會把所有的『環(huán)境變量』秀出來喔!例如:
[root@server-2 ~]# export declare -x G_BROKEN_FILENAMES="1" declare -x HISTCONTROL="ignoredups" declare -x HISTSIZE="1000" declare -x HOME="/root" declare -x HOSTNAME="server-2" declare -x JAVA_HOME="/usr/local/software/java/jdk1.8.0_162" declare -x JRE_HOME="/usr/local/software/java/jdk1.8.0_162/jre" declare -x KAFKA_HOME="/usr/local/software/kafka/kafka_2.12-1.1.0" declare -x LANG="zh_CN.UTF-8" declare -x LESSOPEN="|/usr/bin/lesspipe.sh %s" declare -x LOGNAME="root" declare -x LS_COLORS="rs=0:di=01;34:ln=01;36:mh=00:pi=40;33:so=01;35:do=01;35:bd=40;33;01:cd=40;33;01:or=40;31;01:mi=01;05;37;41:su=37;41:sg=30;43:ca=30;41:tw=30;42:ow=34;42:st=37;44:ex=01;32:*.tar=01;31:*.tgz=01;31:*.arj=01;31:*.taz=01;31:*.lzh=01;31:*.lzma=01;31:*.tlz=01;31:*.txz=01;31:*.zip=01;31:*.z=01;31:*.Z=01;31:*.dz=01;31:*.gz=01;31:*.lz=01;31:*.xz=01;31:*.bz2=01;31:*.tbz=01;31:*.tbz2=01;31:*.bz=01;31:*.tz=01;31:*.deb=01;31:*.rpm=01;31:*.jar=01;31:*.rar=01;31:*.ace=01;31:*.zoo=01;31:*.cpio=01;31:*.7z=01;31:*.rz=01;31:*.jpg=01;35:*.jpeg=01;35:*.gif=01;35:*.bmp=01;35:*.pbm=01;35:*.pgm=01;35:*.ppm=01;35:*.tga=01;35:*.xbm=01;35:*.xpm=01;35:*.tif=01;35:*.tiff=01;35:*.png=01;35:*.svg=01;35:*.svgz=01;35:*.mng=01;35:*.pcx=01;35:*.mov=01;35:*.mpg=01;35:*.mpeg=01;35:*.m2v=01;35:*.mkv=01;35:*.ogm=01;35:*.mp4=01;35:*.m4v=01;35:*.mp4v=01;35:*.vob=01;35:*.qt=01;35:*.nuv=01;35:*.wmv=01;35:*.asf=01;35:*.rm=01;35:*.rmvb=01;35:*.flc=01;35:*.avi=01;35:*.fli=01;35:*.flv=01;35:*.gl=01;35:*.dl=01;35:*.xcf=01;35:*.xwd=01;35:*.yuv=01;35:*.cgm=01;35:*.emf=01;35:*.axv=01;35:*.anx=01;35:*.ogv=01;35:*.ogx=01;35:*.aac=01;36:*.au=01;36:*.flac=01;36:*.mid=01;36:*.midi=01;36:*.mka=01;36:*.mp3=01;36:*.mpc=01;36:*.ogg=01;36:*.ra=01;36:*.wav=01;36:*.axa=01;36:*.oga=01;36:*.spx=01;36:*.xspf=01;36:" declare -x MAIL="/var/spool/mail/root" declare -x OLDPWD declare -x PATH="/usr/local/sbin:/usr/local/bin:/sbin:/bin:/usr/sbin:/usr/bin:/usr/local/nginx/sbin:/usr/local/git/bin:/usr/local/software/java/jdk1.8.0_162/bin:/usr/local/software/java/jdk1.8.0_162/jre/bin:/usr/local/software/zookeeper/zookeeper-3.4.11/bin:/usr/local/software/kafka/kafka_2.12-1.1.0/bin:/sbin:/root/bin" declare -x PWD="/root" declare -x SELINUX_LEVEL_REQUESTED="" declare -x SELINUX_ROLE_REQUESTED="" declare -x SELINUX_USE_CURRENT_RANGE="" declare -x SHELL="/bin/bash" declare -x SHLVL="1" declare -x SSH_CLIENT="192.168.186.1 50886 22" declare -x SSH_CONNECTION="192.168.186.1 50886 192.168.186.103 22" declare -x SSH_TTY="/dev/pts/0" declare -x TERM="xterm" declare -x USER="root" declare -x ZOOKEEPER_HOME="/usr/local/software/zookeeper/zookeeper-3.4.11"【11.2.4】影響顯示結果的語系變量 locale
1)查看 locale 變量
(15)
補充1: 事實上,如果其他的語系變量都未配置, 且你有配置 LANG 或者是 LC_ALL 時,則其他的語系變量就會被這兩個變量所取代! 這也是為什么我們在 Linux 當中,通常說明僅配置 LANG 這個變量而已,因為他是最主要的配置變量!
補充2:那么你應該要覺得奇怪的是,為什么在 Linux 主機的終端機接口 (tty1 ~ tty6) 的環(huán)境下,如果配置『 LANG=zh_TW.big5 』這個配置值生效后,使用 man 或者其他信息輸出時, 都會有一堆亂碼,尤其是使用 ls -l 這個參數時?
因為在 Linux 主機的終端機接口環(huán)境下是無法顯示像中文這么復雜的編碼文字, 所以就會產生亂碼了。也就是如此,我們才會必須要在 tty1 ~ tty6 的環(huán)境下, 加裝一些中文化接口的軟件,才能夠看到中文啊!
3)整體系統(tǒng)默認的語系定義在 /etc/sysconfig/i18n
(16 )
【11.2.5】變量的有效范圍
1)環(huán)境變量 == 全局變量; 自定義變量 == 局部變量;
【11.2.6】變量鍵盤讀取、數組與宣告: read, array, declare
1)read:讀取鍵盤輸入;
(17)
【荔枝】
(18)
(19)
2)declare/typeset:等同于typeset,聲明變量類型;
(20)
【荔枝】
(21)
2.1)由于在默認的情況底下, bash 對于變量有幾個基本的定義:
? ● 變量類型默認為『字符串』,所以若不指定變量類型,則 1+2 為一個『字符串』而不是『計算式』。 所以上述第一個運行的結果才會出現那個情況的;
? ● bash 環(huán)境中的數值運算,默認最多僅能到達整數形態(tài),所以 1/3 結果是 0;
【其他荔枝】
(22)
3)數組類型
(23)
【11.2.7】與文件系統(tǒng)及程序的限制關系:ulimit
1)ulimit作用: bash 是可以『限制用戶的某些系統(tǒng)資源』的,包括可以開啟的文件數量, 可以使用的 CPU 時間,可以使用的內存總量等等。如何配置?用 ulimit 吧!
(24)
【荔枝】ulimit
(25)
(26)
補充:想要復原 ulimit 的配置最簡單的方法就是注銷再登陸,否則就是得要重新以 ulimit 配置才行!
【11.2.8】變量內容的刪除,替代與替換
1)變量內容的刪除
1.1)從頭到右刪除
(27)
【注意】更正提示:第2個注釋改為“從頭到右刪除匹配 /*bin: 的最長字符串”;
補充:# 與 ## 就分別代表:
? ● # :符合取代文字的『最短的』那一個;
? ● ##:符合取代文字的『最長的』那一個
1.2)從尾到左刪除
(28)
【注意】更正提示:第2個注釋改為“從頭到右刪除匹配 :*bin: 的最長字符串”;
2)變量替換
(29)
3)變量的刪除,替換總結如下:
(30)
4)變量測試:判斷某個變量是否存在?
(31)
補充:在大括號內有沒有冒號『 : 』的差別是很大的!加上冒號后,被測試的變量未被配置或者是已被配置為空字符串時, 都能夠用后面的內容 (本例中是使用 root 為內容) 來替換與配置!
(32)
4.1)其他測試方法,如下:?
底下的例子當中,那個 var 與 str 為變量,我們想要針對 str 是否有配置來決定 var 的值喔! 一般來說, str: 代表『str 沒配置或為空的字符串時』;至于 str 則僅為『沒有該變量』。
(33)
4.2)根據上表給出荔枝如下:
(34)
5)關于減號 (-) 其實上面我們談過了!這里的測試只是要讓你更加了解,這個減號的測試并不會影響到舊變量的內容。 如果你想要將舊變量內容也一起替換掉的話,那么就使用等號 (=) 吧!
(35)
6)如果舊變量不存在時,整個測試就告知我『有錯誤』,此時就能夠使用問號『 ? 』的幫忙啦!
(36)
【11.3】命令別名與歷史命令
【11.3.1】命令別名設置:alias, unalias
(37)
注意1:alias 的定義規(guī)則與變量定義規(guī)則幾乎相同。
【荔枝】如何知道別名列表
(38)
【11.3.2】歷史命令:history
(39)
1)history命令介紹
(40)
【荔枝如下】
(41)
2)在正常的情況下,歷史命令的讀取與記錄是這樣的:
? ● 當我們以 bash 登陸 Linux 主機之后,系統(tǒng)會主動的由家目錄的 ~/.bash_history 讀取以前曾經下過的命令,那么 ~/.bash_history 會記錄幾筆數據呢?這就與你 bash 的 HISTFILESIZE 這個變量配置值有關了!
? ● 假設我這次登陸主機后,共下達過 100 次命令,『等我注銷時, 系統(tǒng)就會將 101~1100 這總共 1000 筆歷史命令升級到 ~/.bash_history 當中。』 也就是說,歷史命令在我注銷時,會將最近的 HISTFILESIZE 筆記錄到我的紀錄文件當中啦!
? ● 當然,也可以用 history -w 強制立刻寫入的!那為何用『升級』兩個字呢? 因為 ~/.bash_history 記錄的筆數永遠都是 HISTFILESIZE 那么多,舊的信息會被主動的拿掉! 僅保留最新的!
3)history的其他作用
(42)
(43)
【11.4】bash shell 的操作環(huán)境
【11.4.1】路徑與命令查找順序
1)命令運行的順序可以這樣看:
? 1. 以相對/絕對路徑運行命令,例如『 /bin/ls 』或『 ./ls 』;
? 2. 由 alias 找到該命令來運行;
? 3. 由 bash 內建的 (builtin) 命令來運行;
? 4. 透過 $PATH 這個變量的順序搜尋到的第一個命令來運行。
(上面的順序貌似不正確的,應該 先通過 alias查找,再通過 相對或絕對路徑查找)
【荔枝1】你可以下達 /bin/ls 及單純的 ls 看看,會發(fā)現使用 ls 有顏色但是 /bin/ls 則沒有顏色。 因為 /bin/ls 是直接取用該命令來下達,而 ls 會因為『 alias ls='ls --color=tty' 』這個命令別名而先使用!
(44)
【荔枝】如果想要了解命令搜尋的順序,其實透過 type -a ls 也可以查詢的到啦!上述的順序最好先了解喔!
(45)
【11.4.2】bash的登錄與歡迎信息: /etc/issue, /etc/motd
1)還記得在終端機接口 (tty1 ~ tty6) 登陸的時候,會有幾行提示的字符串嗎?那就是進站畫面啊! 那個字符串寫在哪里啊?呵呵!在 /etc/issue 里面。
(46)
(47)
注意:更改上述注釋為登錄界面,而不是歡迎信息;
2)可以 man issue 配合 man mingetty 得到底下的結果:
(48)
(49)
【11.4.3】bash的環(huán)境配置文件
1)你是否會覺得奇怪,怎么我們什么動作都沒有進行,但是一進入 bash 就取得一堆有用的變量了? 這是因為系統(tǒng)有一些環(huán)境配置文件的存在,讓 bash 在啟動時直接讀取這些配置文件,以規(guī)劃好 bash 的操作環(huán)境啦!
2)如果想保留用戶我自己的命令別名,自定義變量,就需要把這些設置信息寫入到配置文件, 如下:
2.1)login 與 non-login shell:
2.2)/etc/profile (login shell 才會讀)
2.2.1)這個文件配置的變量主要有:
? ● PATH:會依據 UID 決定 PATH 變量要不要含有 sbin 的系統(tǒng)命令目錄;
? ● MAIL:依據賬號配置好使用者的 mailbox 到 /var/spool/mail/賬號名;
? ● USER:根據用戶的賬號配置此一變量內容;
? ● HOSTNAME:依據主機的 hostname 命令決定此一變量內容;
? ● HISTSIZE:歷史命令記錄筆數。CentOS 5.x 配置為 1000 ;
2.2.2)/etc/profile 可不止會做這些事而已,他還會去呼叫外部的配置數據喔!在 CentOS 5.x 默認的情況下, 底下這些數據會依序的被呼叫進來:
/etc/inputrc:不建議修改;
/etc/profile.d/*.sh: 只要在 /etc/profile.d/ 這個目錄內且擴展名為 .sh ,另外,使用者能夠具有 r 的權限, 那么該文件就會被 /etc/profile調用。在 CentOS 5.x 中,這個目錄/etc/profile 底下的文件規(guī)范了 bash 操作接口的顏色、 語系、ll 與 ls 命令的命令別名、vi 的命令別名、which 的命令別名等等。如果你需要幫所有使用者配置一些共享的命令別名時, 可以在這個目錄底下自行創(chuàng)建擴展名為 .sh 的文件,并將所需要的數據寫入即可喔!
(50)
/etc/sysconfig/i18n: 這個文件是由 /etc/profile.d/lang.sh 調用的!這也是我們決定 bash 默認使用何種語系的重要配置文件! 文件里最重要的就是 LANG 這個變量的配置啦!
[root@localhost ~]# cat /etc/sysconfig/i18n
LANG="zh_CN.UTF-8"
總結:反正你只要記得,bash 的 login shell 情況下所讀取的整體環(huán)境配置文件其實只有 /etc/profile;
2.3)~/.bash_profile (login shell 才會讀): bash 在讀完了整體環(huán)境配置的 /etc/profile 并藉此調用其他配置文件后,接下來則是會讀取使用者的個人配置文件。 在 login shell 的 bash 環(huán)境中,所讀取的個人偏好配置文件其實主要有三個,依序分別是:
? 1. ~/.bash_profile
? 2. ~/.bash_login
? 3. ~/.profile
2.3.1)注意:其實 bash 的 login shell 配置只會讀取上面三個文件的其中一個, 而讀取的順序則是依照上面的順序。也就是說,如果 ~/.bash_profile 存在,那么其他兩個文件不論有無存在,都不會被讀取。 如果 ~/.bash_profile 不存在才會去讀取 ~/.bash_login,而前兩者都不存在才會讀取 ~/.profile 的意思。 會有這么多的文件,其實是因應其他 shell 轉換過來的使用者的習慣而已。
【荔枝】~/.bash_profile 的文件內容
(51)
2.3.2)bash 配置文件的讀入方式比較有趣,主要是透過一個命令『 source 』來讀取的!也就是說 ~/.bash_profile 其實會再調用 ~/.bashrc 的配置內容喔!
2.4)最后,我們來看看整個 login shell 的讀取流程:
(52)
2.4.1)source命令:讀入環(huán)境配置文件的命令。修改參數配置,如/etc/profile 文件后,通常情況下,需要重啟后才生效;而輸入 source /etc/profile 可以將修改內容立即生效;
(53)
2.5)~/.bashrc (non-login shell 會讀):
(54)
2.5.1)CentOS 5.x 還會主動調用 /etc/bashrc 這個文件喔!為什么需要調用 /etc/bashrc 呢? 因為 /etc/bashrc 幫我們的 bash 定義出底下的數據:
? ● 依據不同的 UID 規(guī)范出 umask 的值;
? ● 依據不同的 UID 規(guī)范出提示字符 (就是 PS1 變量);
? ● 調用 /etc/profile.d/*.sh 的配置
【注意】你要注意的是,這個 /etc/bashrc 是 CentOS 特有的 (其實是 Red Hat 系統(tǒng)特有的),其他不同的 distributions 可能會放置在不同的檔名就是了。由于這個 ~/.bashrc 會呼叫 /etc/bashrc 及 /etc/profile.d/*.sh , 所以,萬一你沒有 ~/.bashrc (可能自己不小心將他刪除了),那么你會發(fā)現你的 bash 提示字符可能會變成這個樣子:
-bash-3.2$??
【11.4.4】終端機的環(huán)境設置: stty, set
1)那么如何查閱目前的一些按鍵內容呢?可以利用 stty (setting tty 終端機的意思) 呢! stty 也可以幫助配置終端機的輸入按鍵代表意義喔!
(55)
(56)
[root@localhost ~]# stty -a speed 38400 baud; rows 45; columns 102; line = 0; intr = ^C; quit = ^\; erase = ^?; kill = ^U; eof = ^D; eol = <undef>; eol2 = <undef>; swtch = <undef>; start = ^Q; stop = ^S; susp = ^Z; rprnt = ^R; werase = ^W; lnext = ^V; flush = ^O; min = 1; time = 0; -parenb -parodd cs8 -hupcl -cstopb cread -clocal -crtscts -cdtrdsr -ignbrk -brkint -ignpar -parmrk -inpck -istrip -inlcr -igncr icrnl ixon -ixoff -iuclc -ixany -imaxbel -iutf8 opost -olcuc -ocrnl onlcr -onocr -onlret -ofill -ofdel nl0 cr0 tab0 bs0 vt0 ff0 isig icanon iexten echo echoe echok -echonl -noflsh -xcase -tostop -echoprt echoctl echoke分析1)如果出現 ^ 表示 [Ctrl] 那個按鍵的意思。舉例來說, intr = ^C 表示利用 [ctrl] + c 來達成的。
分析2)幾個重要的代表意義是:
? ● eof? ?: End of file 的意思,代表『結束輸入』。
? ● erase : 向后刪除字符,
? ● intr? : 送出一個 interrupt (中斷) 的訊號給目前正在 run 的程序;
? ● kill? : 刪除在目前命令列上的所有文字;
? ● quit? : 送出一個 quit 的訊號給目前正在 run 的程序;
? ● start : 在某個程序停止后,重新啟動他的 output
? ● stop? : 停止目前屏幕的輸出;
? ● susp? : 送出一個 terminal stop 的訊號給正在 run 的程序。
【荔枝】如果你想要用 [ctrl]+h 來進行字符的刪除,那么可以下達: stty erase ^h
2)set的設置功能:我們之前提到一些變量時,可以利用 set 來顯示,除此之外,其實 set 還可以幫我們配置整個命令輸出/輸入的環(huán)境。 例如記錄歷史命令、顯示錯誤內容等等。
(57)
(58)
(59)
(60)
【補充】/etc/inputrc 文件中存儲了其他按鍵設置功能:
[root@localhost ~]# cat /etc/inputrc # do not bell on tab-completion #set bell-style noneset meta-flag on set input-meta on set convert-meta off set output-meta on# Completed names which are symbolic links to # directories have a slash appended. set mark-symlinked-directories on$if mode=emacs# for linux console and RH/Debian xterm "\e[1~": beginning-of-line "\e[4~": end-of-line # commented out keymappings for pgup/pgdown to reach begin/end of history #"\e[5~": beginning-of-history #"\e[6~": end-of-history "\e[5~": history-search-backward "\e[6~": history-search-forward "\e[3~": delete-char "\e[2~": quoted-insert "\e[5C": forward-word "\e[5D": backward-word "\e[1;5C": forward-word "\e[1;5D": backward-word# for rxvt "\e[8~": end-of-line "\eOc": forward-word "\eOd": backward-word# for non RH/Debian xterm, can't hurt for RH/DEbian xterm "\eOH": beginning-of-line "\eOF": end-of-line# for freebsd console "\e[H": beginning-of-line "\e[F": end-of-line $endif【總結】bash 默認的組合鍵匯總如下:
(61)
【11.4.5】通配符與特殊符號
1)常用通配符如下:
(62)
2)通配符荔枝
2.1)利用通配符配合 ls 查找文件看看:荔枝如下:
(63)
(64)
(65)
(66)
2.2)bash 環(huán)境中的特殊符號有哪些呢?
(67)
【注意】以上為 bash 環(huán)境中常見的特殊符號匯整!理論上,你的文件名盡量不要使用到上述的字符啦。
【11.5】數據流重定向
【11.5.1】什么是數據流重定向?
1)數據流重導向就是將某個命令運行后應該要出現在屏幕上的數據, 給他傳輸到其他的地方,例如文件或者是裝置 (例如打印機之類的)!
2)數據流重導向可以將 standard output (簡稱 stdout) 與 standard error output (簡稱 stderr) 分別傳送到其他的文件或裝置去,而分別傳送所用的特殊字符則如下所示:
? 1. 標準輸入 (stdin) :代碼為 0 ,使用 < 或 << ;
? 2. 標準輸出 (stdout):代碼為 1 ,使用 > 或 >> ;
? 3. 標準錯誤輸出(stderr):代碼為 2 ,使用 2> 或 2>> ;
(68)
【補充】
補充1)符號 > 表示覆蓋文件內容; 符號 >> 表示追加內容到文件;
補充2)rootfile文件的創(chuàng)建方式是:
? 1. 該文件 (本例中是 ~/rootfile) 若不存在,系統(tǒng)會自動的將他創(chuàng)建起來,但是
? 2. 當這個文件存在的時候,那么系統(tǒng)就會先將這個文件內容清空,然后再將數據寫入!
? 3. 也就是若以 > 輸出到一個已存在的文件中,那個文件就會被覆蓋掉啰!
3)上面談到的是 standard output 的正確數據,那如果是 standard error output 的錯誤數據呢?那就透過 2> 及 2>> 啰!同樣是覆蓋 (2>) 與累加 (2>>) 的特性!詳情如下:
? ● 1> :以覆蓋的方法將『正確的數據』輸出到指定的文件或裝置上;
? ● 1>>:以累加的方法將『正確的數據』輸出到指定的文件或裝置上;
? ● 2> :以覆蓋的方法將『錯誤的數據』輸出到指定的文件或裝置上;
? ● 2>>:以累加的方法將『錯誤的數據』輸出到指定的文件或裝置上;
【荔枝】將 stdout 與 stderr 分存到不同的文件去
(69)
4)/dev/null 垃圾桶黑洞設備與特殊寫法: 如果我知道錯誤信息會發(fā)生,所以要將錯誤信息忽略掉而不顯示或儲存呢? 這個時候黑洞裝置 /dev/null 就很重要了!這個 /dev/null 可以吃掉任何導向這個裝置的信息喔!
【荔枝】 /dev/null 黑洞設備
(70)
【荔枝】將正確與錯誤數據通通寫入同一個文件去呢?
(71)
5)標準輸入: < 與 <<
< 表示 將原本需要由鍵盤輸入的數據,改由文件內容來取代;
【荔枝】通過 cat 命令操作來了解一下什么叫做『鍵盤輸入』吧
(72)
【荔枝】用某個文件的內容來取代鍵盤的敲擊呢: 用 stdin 取代鍵盤的輸入以創(chuàng)建新文件的簡單流程
(73)
【荔枝】 << 代表的是結束的輸入字符的意思! 舉例來講:我要用 cat 直接將輸入的信息輸出到 catfile 中, 且當由鍵盤輸入 eof 時,該次輸入就結束。
(74)
6)總結:為何要使用命令輸出重導向呢?我們來說一說吧!
? ● 屏幕輸出的信息很重要,而且我們需要將他存下來的時候;
? ● 背景運行中的程序,不希望他干擾屏幕正常的輸出結果時;
? ● 一些系統(tǒng)的例行命令 (例如寫在 /etc/crontab 中的文件) 的運行結果,希望他可以存下來時;
? ● 一些運行命令的可能已知錯誤信息時,想以『 2> /dev/null 』將他丟掉時;
? ● 錯誤信息與正確信息需要分別輸出時。
【11.5.2】命令執(zhí)行的判斷依據: 分號; , 雙and符號&&,雙豎線 ||;
1)背景:在某些情況下,很多命令我想要一次輸入去運行,而不想要分次運行時,該如何是好?基本上你有兩個選擇, 一個是透過第十三章要介紹的 shell script 撰寫腳本去運行,一種則是透過底下的介紹來一次輸入多重命令喔。
2)cmd ; cmd (不考慮命令相關性的連續(xù)命令下達)
【荔枝】例如在關機的時候我希望可以先運行兩次 sync 同步化寫入磁盤后才 shutdown 計算機,那么可以怎么作呢?
(75)
3)$? (命令回傳值) 與 && 或 ||
3.1)復習:若前一個命令運行的結果為正確,在 Linux 底下會回傳一個 $? = 0 的值;怎么透過這個回傳值來判斷后續(xù)的命令是否要運行呢?這就得要藉由『 && 』及『 || 』的幫忙了! 注意喔,兩個 & 之間是沒有空格的!
(76)
【荔枝】ls 查閱目錄 /tmp/abc 是否存在,若存在則用 touch 創(chuàng)建 /tmp/abc/hehe:
(77)
【荔枝】測試 /tmp/abc 是否存在,若不存在則予以創(chuàng)建,若存在就不作任何事情:
(78)
(79)
(80)
結果分析如下:
? ● (1)若 /tmp/abc 不存在故回傳 $?≠0,則 (2)因為 || 遇到非為 0 的 $? 故開始 mkdir /tmp/abc,由于 mkdir /tmp/abc 會成功進行,所以回傳 $?=0 (3)因為 && 遇到 $?=0 故會運行 touch /tmp/abc/hehe,最終 hehe 就被創(chuàng)建了;
? ● (2)若 /tmp/abc 存在故回傳 $?=0,則 (2)因為 || 遇到 0 的 $? 不會進行,此時 $?=0 繼續(xù)向后傳,故 (3)因為 && 遇到 $?=0 就開始創(chuàng)建 /tmp/abc/hehe 了!最終 /tmp/abc/hehe 被創(chuàng)建起來。
【荔枝】以 ls 測試 /tmp/vbirding 是否存在,若存在則顯示 "exist" ,若不存在,則顯示 "not exist"!
(81)
【11.6】管道命令
1)管線命令主要有兩個比較需要注意的地方:
? ● 管線命令僅會處理 standard output,對于 standard error output 會予以忽略;
? ● 管線命令必須要能夠接受來自前一個命令的數據成為 standard input 繼續(xù)處理才行。
【11.6.1】選取命令: cut, grep
1)cut命令(篩選列):cut 不就是『切』嗎?沒錯啦!這個命令可以將一段信息的某一段給他『切』出來。
(82)
【荔枝】
(83)
(84)
(85)
(86)
【cut命令總計】cut 主要的用途在于將『同一行里面的數據進行分解!』最常使用在分析一些數據或文字數據的時候! 這是因為有時候我們會以某些字符當作分割的參數,然后來將數據加以切割,以取得我們所需要的數據。
2)grep命令(篩選行):剛剛的 cut 是將一行信息當中,取出某部分我們想要的,而 grep 則是分析一行信息, 若當中有我們所需要的信息,就將該行拿出來;
【荔枝】
(87)
(88)
(89)
(90)
(91)
3)排序命令:sort, wc, uniq
3.1)sort命令:
注意:排序的字符與語系的編碼有關,因此, 如果您需要排序時,建議使用 LANG=C 來讓語系統(tǒng)一,數據排序比較好一些。
(92)
(93)
【荔枝】
(94)
(95)
(96)
3.2)uniq 命令:如果我排序完成了,想要將重復的數據僅列出一個顯示;
(97)
(98)
(99)
補充: 這個命令用來將『重復的行刪除掉只顯示一個』,舉個例子來說, 你要知道這個月份登陸你主機的用戶有誰,而不在乎他的登陸次數,那么就使用上面的范例, (1)先將所有的數據列出;(2)再將人名獨立出來;(3)經過排序;(4)只顯示一個! 由于這個命令是在將重復的東西減少,所以當然需要『配合排序過的文件』來處理啰!
3.3)wc命令:如果我想要知道 /etc/man.config 這個文件里面有多少字?多少行?多少字符的話, 可以怎么做呢?其實可以利用 wc 這個命令來達成喔!
(100)
【荔枝】
(101)
(102)
【11.6.3】雙向重定向:tee
1)想個簡單的東西,我們由前一節(jié)知道 > 會將數據流整個傳送給文件或裝置,因此我們除非去讀取該文件或裝置, 否則就無法繼續(xù)利用這個數據流。萬一我想要將這個數據流的處理過程中將某段信息存下來,應該怎么做? 利用 tee 就可以啰。
(103)
2)tee 會同時將數據流分送到文件去與屏幕 (screen);而輸出到屏幕的,其實就是 stdout ,可以讓下個命令繼續(xù)處理!
(104)
【荔枝】
(105)
(106)
(107)
【11.6.4】字符轉換命令:tr, col, join, paste, expand
1)tr命令:tr 可以用來刪除一段信息當中的文字,或者是進行文字信息的替換;
(108)
(109)
【荔枝】
(110)
(111)
(112)
(113)
補充:處理 Linux & Windows 系統(tǒng)中的人們最麻煩的一件事就是這個事情啦!亦即是 DOS 底下會自動的在每行行尾加入 ^M 這個斷行符號!這個時候我們可以使用這個 tr 來將 ^M 去除! ^M 可以使用 \r 來代替之!
2)col命令:
(114)
(115)
【荔枝】
(116)
(117)
補充1)你沒看錯!由于 man page 內有些特殊按鈕會用來作為類似特殊按鍵與顏色顯示,所以這個文件內就會出現如上所示的一堆怪異字符(有 ^ 的)。
補充2) col 經常被利用于將 man page 轉存為純文本文件以方便查閱的功能!
3)join命令:主要是在處理『兩個文件當中,有 "相同數據" 的那一行,才將他加在一起的意思。
(118)
【荔枝】
(119)
(120)
需要特別注意的是:在使用 join 之前,你所需要處理的文件應該要事先經過排序 (sort) 處理! 否則有些比對的項目會被略過呢!
4)paste命令:相對于 join 必須要比對兩個文件的數據相關性, paste 就直接『將兩行貼在一起,且中間以 [tab] 鍵隔開』而已!
(121)
【荔枝】
(122)
(123)
5)expand命令:將tab鍵 轉換成空格鍵,如下:
(124)
【荔枝】
(125)
補充:expand命令自動將 [tab] 轉成空格鍵~所以,以上面的例子來說, 使用 cat -A 就會查不到 ^I 的字符啰~此外,因為 [tab] 最大的功能就是格式排列整齊! 我們轉成空格鍵后,這個空格鍵也會依據我們自己的定義來添加大小~ 所以,并不是一個 ^I 就會換成 8 個空白喔!這個地方要特別注意的哩! 此外,您也可以參考一下 unexpand 這個將空白轉成 [tab] 的命令功能啊!
【11.6.5】切割命令: split
1)介紹: 如果你有文件太大,導致一些攜帶式設備無法復制的問題!找 split 就對了! 他可以幫你將一個大文件,依據文件大小或行數來分割,就可以將大文件分割成為小文件了!?
(126)
【荔枝】
(127)
(128)
(129)
補充:在 Windows 操作系統(tǒng)下,你要將文件分割需要如何作?傷腦筋吧!在 Linux 底下就簡單的多了!你要將文件分割的話,那么就使用 -b size 來將一個分割的文件限制其大小,如果是行數的話,那么就使用 -l line 來分割!
【11.6.6】參數代換:xargs
1)xargs作用: 產生某個命令的參數的意思! xargs 可以讀入 stdin 的數據,并且以空格符或斷行字符作為分辨,將 stdin 的數據分隔成為 arguments 。?
(130)
【荔枝】
(131)
(132)
(133)
(134)
補充: 會使用 xargs 的原因是, 很多命令其實并不支持管線命令,因此我們可以透過 xargs 來提供該命令引用 standard input 之用!
2)舉例來說,我們使用如下的范例來說明:
(135)
【11.6.7】關于減號- 的用途
1)在管線命令當中,常常會使用到前一個命令的 stdout 作為這次的 stdin , 某些命令需要用到文件名 (例如 tar) 來進行處理時,該 stdin 與 stdout 可以利用減號 "-" 來替代, 舉例來說:
(136)
【補充】上面這個例子是說: 我將 /home 里面的文件給他打包,但打包的數據不是紀錄到文件,而是傳送到 stdout; 經過管線后,將 tar -cvf - /home 傳送給后面的 tar -xvf - 。后面的這個 - 則是取用前一個命令的 stdout, 因此,我們就不需要使用 file 了!這是很常見的例子喔!注意注意!
總結
以上是生活随笔為你收集整理的linux-basic(11)认识和学习bash的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: linux locale命令(linux
- 下一篇: linux-basic(12)正则表达式