sh/bash script備忘錄
—-
字元
有意義字元
” ” – 雙引號,括起一個字串,被包括的字元皆作一般字元。
‘ ‘ – 單引號,意義同雙引號。
` ` – 反單引號,執行引號內之指令,並以該指令之輸出結果替換本身。
; – 指令分行。
& – 將指令放至背景執行。
$ – 變數提示字元。
{ } – 變數名稱與一般字元分隔符號。
# – 註解提示字元,其後之內容不視為指令。
>, >> – 將左式行程之輸出資料,輸入到右式指定設備儲存。
< , << - 將右式指定設備之輸入資料,輸出給左式行程處理。
| - 將左式行程之資料輸出管線,連接到右式行程之資料輸入管線。
通用字元
* - 代表零或無限個任意字元。
? - 代表一個任意字元。
[...] - 代表一個符合字元集正面列表的字元。
[!...]- 代表一個不符合字元集負面列表的字元。
轉義字元
\ - 將上述有意義字元,當作一般字元。
----
變數
自定變數
以 name=value 的格式設定。 等號兩邊若有空格,將被視為name及value
的一部份。
欲在指令或字串中引用變數時,在變數名稱前冠上'$'符號,如: $name 。
若有需要,可以 { } 括起變數名稱,如: ${name} 。
變數定義後,只在目前之行程空間中可用,若要擴大可見範圍,供其他行程使
用,則須以 export 指令,將變數匯出至行程之期間(session)中。
如: export name。
參數變數
代表傳遞給 shell script 的參數內容的變數,以數字表示, $1 表示第一個
參數, $2 表示第二個參數,以下類推,最大到 $9 。
shift 指令將使參數變數向前位移一位,使 $2, $3,... 變為 $1, $2,... ,
同時,參數的個數亦相對減一。
預先定義變數
由 shell 所預先定義之變數,常用的預定變數有:
$? 代表上一個在前景執行的命令之返回值。
$! 代表上一個在背景執行的命令之PID。
$@ 代表所有的參數。
變數之替換
語法 意義
------------------------------------------------------------------
name1=${name2-word} 若變數name2有置值,則以其值替換變數name1的值
,否則以word之內容替換name1之值。
name1=${name2+word} 若變數name2有置值,則以word之內容替換name1之
值,否則不替換。
name1=${name2?word} 若變數name2有置值,則以name2之值替換name1之值
,否則印出word之內容並跳出shell。
${name=word} 若變數name之值為空,則以word之內容替換name之
值。
------------
流程控制指令
shell script 以 0 為 true ,非零值為 false 。
1.if
if expr1; then
cmd1 block
elif expr2; then
cmd2 block
else
cmd3 block
fi
若 expr1 之值為 true ,則執行 cmd1 ;否則,若 expr2 之值為 true ,則
執行 cmd2 ;若皆不為 true ,執行 cmd3 。
elif 及 else 可省略。
註: then 原本要放獨立一行,但不美觀,故多將其與 if, elif 放在同一行,
但兩行指令間,要以 ';' 分段。
2.while
while expr; do
cmd block
done
若 expr 之值為 true ,則執行 cmd 。
3.until
until expr; do
cmd block
done
若 expr 之值為不為 true ,則執行 cmd 。
4.for
for 變數name; do
cmd block
done
或
for 變數name in 字串列; do
cmd block
done
順序取字串列之內容為變數name之值,每取一次,則執行一次cmd。
若字串列省略時,表示取全部參數做為字串列。
5.case
case 字串 in
pattern1)
cmd1 block
pattern2)
cmd2 block
.
.
.
esac
pattern為 regular expression 。將字串與 pattern 之內容做匹配動作,
若匹配則執行該 pattern 之動作。
注意,pattern後要加 ')' 符號。
6.其他
break 中斷 cmd block 的執行,跳到流程控制指令的下個指令。
continue 中斷 cmd block 的執行,跳到流程控制指令的開始。
exit 中斷 shell script 的執行。
------------
test測試運算
1.
一般使用 [ ] 括起 expression ,括號前後皆要空格。
2.數字比較
-eq equal 相等
-ne not equal 不等
-gt great then 大於
-ge geart then or equal 大於或等於
-lt little then 小於
-le little then or equal 小於或等於
3.字串比較
= 相同
!= 不相同
-z 字串 字串長度為零。
-n 字串 字串長度不為零。
4.邏輯運算
-a And
-o Or
! Not
5.檔案測試
-r readable and existing
-w writeable and existing
-f regular file
-t directory
-s Not empty file
-x executable
-u SetUID
-g SetGID
--------
其他指令
1.eval 字串
解譯並執行字串的內容。
2.exec 命令
執行命令,該命令將被載入並取代 shell 在行程空間中之位置。
3.read 變數名稱串列
自標準輸入中謮取一列內容,第一字的內容指定給第一個變數,以下類推。
當有讀取到資料時, read 返回 true ,否則(遇到eof)返回 false 。
變數名稱前不用加 '$' 提示。
4.set
無參數時,顯示各變數的值。若有參數,則將第一個參數置為 $1 ,第二個
參數置為 $2 ,以下類推。
--------------
資料輸出入管線
在 unix 下,資料被視為位元串流 (術語稱為 streaming) ,而假想在設備間,
存在著一條條的管線 (術語稱為 pipe) ,資料串流就藉由這些管線,在設備間
流動。
當使用者簽入系統後, shell 便會開啟三個虛擬設備做為預設的資料輸出入設
備,此三者為: STDIN, STDOUT, STDERR 。 通常 STDIN 是鍵盤(輸入),
STDOUT 及 STDERR 則為顯示器(輸出)。
由於多數的程式皆由 shell 啟動 (fork + exec),因此也繼承了那三個設備,
故不須特別設定,便可接受來自使用者的鍵盤輸入,將結果輸出至顯示器。
而 shell 提供一種機制,可以改變那三個虛擬設備所連接的實際設備,藉此改
變程式的輸出入目標,這個動作,就像是將管線的一頭,從一個設備改接到另
一個設備,便可讓資料串流導向其他設備,因此一般稱為「重導」。
shell 提供五個符號進行資料的重導,分別是 >, >>, < , <<, | 。
1. >, >>
此符號可改變程序的 STDOUT 資料輸出串流的方向,符號的左式為要執行的
程式,而右式必須為一有效的設備。
例如:
# who > Onlineuser.txt
# ps > /dev/null
若設備為一正規檔案,則檔案原有內容將被清除。欲保留原有內容,則改用
>> 符號,此符號可讓資料新增在原有內容之後。
若想將 STDERR 的輸出導向到 STDOUT ,則寫成’ 2>&1 ‘,例如:
# make 2>&1
2 是 STDERR 的檔案描述子, 1 是 STDOUT 的檔案描述子。
2. < , << 此符號可改變程序的 STDIN 資料輸入串流的方向,符號的左式為要執行的程 式,而右式必須為一有效的設備。 例如: # adduser < userlist.txt 下例示範在 script 中,如何將一段文字加入指定檔案中: ----------------------------------------------------- #!/bin/sh cat >> test.txt < < LABEL 在此之後的文字,一直到 LABEL 為止的內容,都將被加入指定 檔案中。 LABEL cat test.txt ----------------------------------------------------- 3. | 此符號連接兩程序間的輸出入設備,符號左右兩式則為要執行的程式,執行 後,左式的程序之 STDOUT 將被連接到右式的程序之 STDIN 。 例如: # ps -ax | more ps -ax 將資料送至 STDOUT ,而 more 則將來自 STDIN 的資料內容,做分頁 顯示,藉由 | 連接兩程序的 STDOUT 及 STDIN 後,便可將 ps -ax 的資料串 流,直接流向 more 的 STDIN ,而由 more 進行分頁顯示。 這項重導符號皆可組合使用,例如: # dd if=/dev/fd0 bs=1k count=1440 | gzip -9 > disk_image.gz
dd 從 /dev/fd0 (第一台軟碟機) 設備讀取 1440 KB 的資料,輸出到其
STDOUT,而 dd 的 STDOUT 連接到 gzip 的 STDIN ,因此 gzip 可由其
STDIN 中,讀取資料,進行壓縮處理,處理過的資料,再被存入
disk_image.gz 這個正規檔案中。