Linux Shell 指令碼攻略閱讀筆記第1章 小試牛刀,第1章小試
一、簡介
1.Bash(Bourne Again Shell),目前大多數GNU/Linux系統預設的shell環境。
命令都是在shell終端中輸入並執行。開啟終端後,提示符的形式:username@hostname$ 或 root@hostname # ($表示普通使用者,#表示管理使用者root)
2.shell指令碼是一個以#!(shebang)起始的文字檔,如下: #!/bin/bash
shebang是一個文本行,其中#!位於解譯器路徑之前。/bin/bash是Bash的解譯器命令路徑。
3.兩種運行指令碼的方式。
一種是將指令碼作為bash到命令列參數
buxizhizhou@ubuntu:~/lssc/chpt1$ bash test_script.sh hello,world
另一種是授予指令碼執行許可權,將其變為可執行檔。chmod a+x script.sh
buxizhizhou@ubuntu:~/lssc/chpt1$ chmod a+x test_script.sh buxizhizhou@ubuntu:~/lssc/chpt1$ ./test_script.sh hello,world
核心會讀取指令碼的首行,注意到shebang為#! /bin/bash。它識別出/bin/bash,並在內部像這樣執行該指令碼:$ /bin/bash test_script.sh
其中,test_script.sh檔案內容如下:
#!/bin/bashecho hello,world
3.5.當啟動shell時,它一開始會執行一組命令來定義諸如提示文本、顏色等設定。這組命令在指令檔~/.bashrc中,對於登入shell則是~/.bash_profile。Bash還維護了一個記錄檔案~/.bash_history儲存使用者運行過的命令。
4.~表示主目錄,通常是/home/user,其中user是使用者名稱;若是root使用者,則為/root。
5.登入shell是登入主機後獲得的那個shell。如果是登入圖形介面環境如GNOME、KDE後開啟了一個shell,就不是登入shell。
6.Bash中,每個命令或命令序列是以分號或分行符號來分隔。#指明注釋的開始,延續到行尾。如 $ cmd1 ; cmd2 等同於 $ cmd1 $ cmd2
二、終端列印
終端是互動式工具,可以通過它與shell環境進行互動。
1.echo.預設在每次調用後添加一個分行符號。-n 忽略結尾分行符號。
2.echo的三種形式列印:直接列印、單引號、雙引號
buxizhizhou@ubuntu:~/lssc/chpt1$ echo "Welcome to Bash"Welcome to Bashbuxizhizhou@ubuntu:~/lssc/chpt1$ echo Welcome to BashWelcome to Bashbuxizhizhou@ubuntu:~/lssc/chpt1$ echo 'Welcome to Bash'Welcome to Bash
三種方法的副作用:
直接列印:不能顯示文本中的分號——分號在Bash中是命令定界符。echo hello;hello被認為是兩個命令echo hello和hello。
單引號:變數替換在單引號中無效。單引號中不進行變數替換。
buxizhizhou@ubuntu:~/lssc/chpt1$ echo $var and '$var' and "$var"value and $var and value
雙引號:不能列印歎號!。或將其轉義,\!。確切地說,歎號在末尾、或者歎號後沒有空格,則不能正常列印。如下面測試,可以看到,歎號後面有空格時還是可以列印的。
buxizhizhou@ubuntu:~/lssc/chpt1$ echo "Hello world !"bash: !": event not foundbuxizhizhou@ubuntu:~/lssc/chpt1$ echo "cannot include exclamation - ! within"cannot include exclamation - ! withinbuxizhizhou@ubuntu:~/lssc/chpt1$ echo "c!c"bash: !c": event not foundbuxizhizhou@ubuntu:~/lssc/chpt1$ echo "c ! c"c ! cbuxizhizhou@ubuntu:~/lssc/chpt1$ echo "c! c"c! cbuxizhizhou@ubuntu:~/lssc/chpt1$ echo "c !c"bash: !c": event not found
3.printf.無自動換行符。參數類似於C語言,參數以空格分隔。如下:
#!/bin/bash#檔案名稱:printf.shprintf "%-5s %-10s %-4s\n" No Name Markprintf "%-5s %-10s %-4.2f\n" 1 Sarath 80.3456printf "%-5s %-10s %-4.2f\n" 2 James 90.9989printf "%-5s %-10s %-4.2f\n" 3 Jeff 77.564
運行後顯示:
buxizhizhou@ubuntu:~/lssc/chpt1$ bash printf.sh No Name Mark1 Sarath 80.352 James 91.003 Jeff 77.56
4.使用echo和printf,選項要在字串之前。否則,選項被Bash視為另一個字串。
echo -e "包含逸出序列到字串"
<pre name="code" class="plain">buxizhizhou@ubuntu:~/lssc/chpt1$ echo -e "1\t2\t3"123buxizhizhou@ubuntu:~/lssc/chpt1$ echo -e "!"bash: !: event not foundbuxizhizhou@ubuntu:~/lssc/chpt1$ echo -e "\!"\!buxizhizhou@ubuntu:~/lssc/chpt1$ echo "1\t2\t2"1\t2\t2buxizhizhou@ubuntu:~/lssc/chpt1$ echo "\!"\!
彩色輸出
buxizhizhou@ubuntu:~/lssc/chpt1$ echo -e "\e[1;31m This is red text \e[0m" <span style="color:#ff0000;">This is red text</span>
\e[1;31 將顏色設為紅色,\e[0m 將顏色重新置回。替換31就可以設定其他顏色,黑色=40,紅色=41,綠色=42,黃色=43,藍色=44,洋紅=45,青色=46,白色=47。
三、變數和環境變數
指令碼語言通常不需要在使用變數前聲明其類型,直接賦值即可。Bash中,每一個變數的值都是字串。一些特殊的變數會被shell環境和作業系統用來儲存一些特別的值,成為環境變數。
1.使用env命令查看與終端相關到環境變數。
上述命令返回的環境變數以name=value的形式給出,彼此間由null字元(\0)分隔。
$pgrep 進程名 獲得該程式的進程ID。
替換命令 tr '\0' '\n' ,將Null 字元替換為分行符號。
izhou@ubuntu:~/lssc/chpt1$ pgrep openvpn1098buxizhizhou@ubuntu:~/lssc/chpt1$ sudo cat /proc/1098/environUPSTART_INSTANCE=runlevel=2UPSTART_JOB=rcTERM=linuxPATH=/sbin:/usr/sbin:/bin:/usr/binRUNLEVEL=2PREVLEVEL=NUPSTART_EVENTS=runlevelPWD=/previous=NVERBOSE=nobuxizhizhou@ubuntu:~/lssc/chpt1$ sudo cat /proc/1098/environ | tr '\0' '\n'UPSTART_INSTANCE=runlevel=2UPSTART_JOB=rcTERM=linuxPATH=/sbin:/usr/sbin:/bin:/usr/binRUNLEVEL=2PREVLEVEL=NUPSTART_EVENTS=runlevelPWD=/previous=NVERBOSE=no
2.變數賦值var=value
var是變數名,value是要賦的值。若value不包含任何空白字元,則不需使用引號;否則必須用單或雙引號。
var = value 是相等操作。
使用$變數名或${變數名},獲得變數的值。
buxizhizhou@ubuntu:~/lssc/chpt1$ var=valuebuxizhizhou@ubuntu:~/lssc/chpt1$ echo $varvaluebuxizhizhou@ubuntu:~/lssc/chpt1$ echo ${var}valuebuxizhizhou@ubuntu:~/lssc/chpt1$ var1= valueNo command 'value' found, did you mean: Command 'pvalue' from package 'radiance' (universe)value: command not foundbuxizhizhou@ubuntu:~/lssc/chpt1$ var1 =valuevar1: command not foundbuxizhizhou@ubuntu:~/lssc/chpt1$ var1 = valuevar1: command not found
3.export設定環境變數。此後從當前shell指令碼執行的任何應用程式都繼承該變數。
標準環境變數,如PATH。在給出所要執行的命令後,shell會自動在PATH環境變數所包含的目錄中尋找對應的可執行檔。(目錄路徑以冒號分隔)PATH通常定義在/etc/environment或/etc/profile或~/.bashrc。若需要在PATH中添加一條新路徑,可使用
export PATH="$PATH:/home/user/bin" 或 $ PATH="$PATH:/home/user/bin",$ export PATH。
其他常見環境變數:HOME、PWD、USER、UID、SHELL等
4.擷取變數值的長度${#var}
buxizhizhou@ubuntu:~/lssc/chpt1$ var=1234567890buxizhizhou@ubuntu:~/lssc/chpt1$ echo ${#var}10
利用PS1環境變數定製提示文本。預設的shell提示文本是在檔案~/.bashrc中的某行設定的。
buxizhizhou@ubuntu:~/lssc/chpt1$ cat ~/.bashrc | grep PS1[ -z "$PS1" ] && return PS1='${debian_chroot:+($debian_chroot)}\[\033[01;32m\]\u@\h\[\033[00m\]:\[\033[01;34m\]\w\[\033[00m\]\$ ' PS1='${debian_chroot:+($debian_chroot)}\u@\h:\w\$ ' PS1="\[\e]0;${debian_chroot:+($debian_chroot)}\u@\h: \w\a\]$PS1"buxizhizhou@ubuntu:~/lssc/chpt1$ PS1="PROMPT>"PROMPT>PROMPT>PROMPT>PS1='${debian_chroot:+($debian_chroot)}\u@\h:\w\$ 'buxizhizhou@ubuntu:~/lssc/chpt1$
一些特殊的字元可擴充成系統參數。如:\u擴充為使用者名稱,\h擴充為主機名稱,\w擴充為當前工作目錄。
四、使用函數添加環境變數