?? abs_guide_cn.txt
字號:
. .字符匹配,這是作為正則表達是的一部分,用來匹配任何的單個字符.
" 部分引用."STRING"阻止了一部分特殊字符,具體見第5章.
' 全引用. 'STRING' 阻止了全部特殊字符,具體見第5章.
, 逗號鏈接了一系列的算術操作,雖然里邊所有的內容都被運行了,但只有最后一項被
返回.
如:
1 let "t2 = ((a = 9, 15 / 3))" # Set "a = 9" and "t2 = 15 / 3"
\ 轉義字符,如\X等價于"X"或'X',具體見第5章.
/ 文件名路徑分隔符.或用來做除法操作.
` 后置引用,命令替換,具體見第14章
: 空命令,等價于"NOP"(no op,一個什么也不干的命令).也可以被認為與shell的內建命令(true)作用相同.":"命令是一
個bash的內建命令,它的返回值為0,就是shell返回的true.
如:
1 :
2 echo $? # 0
死循環,如:
1 while :
2 do
3 operation-1
4 operation-2
5 ...
6 operation-n
7 done
8
9 # 與下邊相同:
10 # while true
11 # do
12 # ...
13 # done
在if/then中的占位符,如:
1 if condition
2 then : # 什么都不做,引出分支.
3 else
4 take-some-action
5 fi
在一個2元命令中提供一個占位符,具體見Example 8-2,和"默認參數".如:
1 : ${username=`whoami`}
2 # ${username=`whoami`} 如果沒有":"的話,將給出一個錯誤,除非"username"是
3 # 個命令
在here document中提供一個占位符,見Example 17-10.
使用"參數替換"來評估字符串變量(見Example 9-14).如:
1 : ${HOSTNAME?} ${USER?} ${MAIL?}
2 # 如果一個或多個必要的環境變量沒被設置的話,
3 #+ 就打印錯誤信息.
"變量擴展/子串替換"
在和 > (重定向操作符)結合使用時,把一個文件截斷到0長度,沒有修改它的權限.
如果文件在之前并不存在,那么就創建它.如:
1 : > data.xxx #文件"data.xxx"現在被清空了.
2
3 #與 cat /dev/null >data.xxx 的作用相同
4 #然而,這不會產生一個新的進程,因為":"是一個內建命令.
具體參見Example 12-14.
在和>>重定向操作符結合使用時,將不會對想要附加的文件產生任何影響.
如果文件不存在,將創建.
注意: 這只適用于正規文件,而不是管道,符號連接,和某些特殊文件.
也可能用來作為注釋行,雖然我們不推薦這么做.使用#來注釋的話,將關閉剩余行的
錯誤檢查,所以可以在注釋行中寫任何東西.然而,使用:的話將不會這樣.如:
1 : This is a comment thar generates an error,(if [ $x -eq 3] ).
":"還用來在/etc/passwd和$PATH變量中用來做分隔符.
bash$ echo $PATH
/usr/local/bin:/bin:/usr/X11R6/bin:/sbin:/usr/sbin:/usr/games
! 取反操作符,將反轉"退出狀態"結果,(見Example 6-2).也會反轉test操作符的意義.比
如修改=為!=.!操作是Bash的一個關鍵字.
在一個不同的上下文中,!也會出現在"間接變量引用"見Example 9-22.
在另一種上下文中,!還能反轉bash的"history mechanism"(見附錄J 歷史命令)
需要注意的是,在一個腳本中,"history mechanism"是被禁用的.
* 萬能匹配字符,用于文件名匹配(這個東西有個專有名詞叫file globbing),或者是正則
表達式中.注意:在正則表達式匹配中的作用和在文件名匹配中的作用是不同的.
bash$ echo *
abs-book.sgml add-drive.sh agram.sh alias.sh
* 數學乘法.
**是冪運算.
? 測試操作.在一個確定的表達式中,用?來測試結果.
(())結構可以用來做數學計算或者是寫c代碼,那?就是c語言的3元操作符的
一個.
在"參數替換"中,?測試一個變量是否被set了.
? 在file globbing中和在正則表達式中一樣匹配任意的單個字符.
$ 變量替換
1 var1=5
2 var2=23skidoo
3
4 echo $var1 # 5
5 echo $var2 # 23skidoo
$ 在正則表達式中作為行結束符.
${} 參數替換,見9.3節.
$*,$@ 位置參數
$? 退出狀態變量.$?保存一個命令/一個函數或者腳本本身的退出狀態.
$$ 進程ID變量.這個$$變量保存運行腳本進程ID
() 命令組.如:
1 (a=hello;echo $a)
注意:在()中的命令列表,將作為一個子shell來運行.
在()中的變量,由于是在子shell中,所以對于腳本剩下的部分是不可用的.
如:
1 a=123
2 ( a=321; )
3
4 echo "a = $a" # a = 123
5 # 在圓括號中a變量,更像是一個局部變量.
用在數組初始化,如:
1 Array=(element1,element2,element3)
{xxx,yyy,zzz...}
大括號擴展,如:
1 cat {file1,file2,file3} > combined_file
2 # 把file1,file2,file3連接在一起,并且重定向到combined_file中.
3
4
5 cp file22.{txt,backup}
6 # 拷貝"file22.txt" 到"file22.backup"中
一個命令可能會對大括號中的以逗號分割的文件列表起作用[1]. file globbing將對
大括號中的文件名作擴展.
注意: 在大括號中,不允許有空白,除非這個空白是有意義的.
echo {file1,file2}\ :{\ A," B",' C'}
file1 : A file1 : B file1 : C file2 : A file2 : B file2 : C
{} 代碼塊.又被稱為內部組.事實上,這個結構創建了一個匿名的函數.但是與函數不同的
是,在其中聲明的變量,對于腳本其他部分的代碼來說還是可見的.如:
bash$
{
local a;
a= 123;
}
bash中的local申請的變量只能夠用在函數中.
1 a=123
2 { a=321; }
3 echo "a = $a" # a = 321 (說明在代碼塊中對變量a所作的修改,影響了外邊的變量a)
4
5 # Thanks, S.C.
下邊的代碼展示了在{}結構中代碼的I/O重定向.
Example 3-1. 代碼塊和I/O重定向
################################Start Script#######################################
1 #!/bin/bash
2 # 從 /etc/fstab中讀行
3
4 File=/etc/fstab
5
6 {
7 read line1
8 read line2
9 } < $File
10
11 echo "First line in $File is:"
12 echo "$line1"
13 echo
14 echo "Second line in $File is:"
15 echo "$line2"
16
17 exit 0
18
19 # 現在,你怎么分析每行的分割域
20 # 暗示: 使用 awk.
################################End Script#########################################
Example 3-2. 將一個代碼塊的結果保存到文件
################################Start Script#######################################
1 #!/bin/bash
2 # rpm-check.sh
3
4 # 這個腳本的目的是為了描述,列表,和確定是否可以安裝一個rpm包.
5 # 在一個文件中保存輸出.
6 #
7 # 這個腳本使用一個代碼塊來展示
8
9 SUCCESS=0
10 E_NOARGS=65
11
12 if [ -z "$1" ]
13 then
14 echo "Usage: `basename $0` rpm-file"
15 exit $E_NOARGS
16 fi
17
18 {
19 echo
20 echo "Archive Description:"
21 rpm -qpi $1 # 查詢說明
22 echo
23 echo "Archive Listing:"
24 rpm -qpl $1 # 查詢列表
25 echo
26 rpm -i --test $1 # 查詢rpm包是否可以被安裝
27 if [ "$?" -eq $SUCCESS ]
28 then
29 echo "$1 can be installed."
30 else
31 echo "$1 cannot be installed."
32 fi
33 echo
34 } > "$1.test" # 把代碼塊中的所有輸出都重定向到文件中
35
36 echo "Results of rpm test in file $1.test"
37
38 # 查看rpm的man頁來查看rpm的選項
39
40 exit 0
################################End Script#########################################
注意: 與()中的命令不同的是,{}中的代碼塊將不能正常地開啟一個新shell.[2]
{} \; 路徑名.一般都在find命令中使用.這不是一個shell內建命令.
注意: ";"用來結束find命令序列的-exec選項.
[] test.
test的表達式將在[]中.
值得注意的是[是shell內建test命令的一部分,并不是/usr/bin/test中的擴展命令
的一個連接.
[[]] test.
test表達式放在[[]]中.(shell關鍵字)
具體查看[[]]結構的討論.
[] 數組元素
Array[1]=slot_1
echo ${Array[1]}
[] 字符范圍
在正則表達式中使用,作為字符匹配的一個范圍
(()) 數學計算的擴展
在(())結構中可以使用一些數字計算.
具體參閱((...))結構.
>&>>&>><
重定向.
scriptname >filename 重定向腳本的輸出到文件中.覆蓋文件原有內容.
command &>filename 重定向stdout和stderr到文件中
command >&2 重定向command的stdout到stderr
scriptname >>filename 重定向腳本的輸出到文件中.添加到文件尾端,如果沒有文件,
則創建這個文件.
進程替換,具體見"進程替換部分",跟命令替換極其類似.
(command)>
<(command)
<和> 可用來做字符串比較
<和> 可用在數學計算比較
<< 重定向,用在"here document"
<<< 重定向,用在"here string"
<,> ASCII比較
1 veg1=carrots
2 veg2=tomatoes
3
4 if [[ "$veg1" < "$veg2" ]]
5 then
6 echo "Although $veg1 precede $veg2 in the dictionary,"
7 echo "this implies nothing about my culinary preferences."
8 else
9 echo "What kind of dictionary are you using, anyhow?"
10 fi
\<,\> 正則表達式中的單詞邊界.如:
bash$grep '\<the\>' textfile
| 管道.分析前邊命令的輸出,并將輸出作為后邊命令的輸入.這是一種產生命令鏈的
好方法.
1 echo ls -l | sh
2 # 傳遞"echo ls -l"的輸出到shell中,
3 #+ 與一個簡單的"ls -l"結果相同.
4
5
6 cat *.lst | sort | uniq
7 # 合并和排序所有的".lst"文件,然后刪除所有重復的行.
管道是進程間通訊的一個典型辦法,將一個進程的stdout放到另一個進程的stdin中.
標準的方法是將一個一般命令的輸出,比如cat或echo,傳遞到一個過濾命令中(在這個
過濾命令中將處理輸入),得到結果,如:
cat $filename1 | $filename2 | grep $search_word
當然輸出的命令也可以傳遞到腳本中.如:
################################Start Script#######################################
1 #!/bin/bash
2 # uppercase.sh : 修改輸出,全部轉換為大寫
3
4 tr 'a-z' 'A-Z'
5 # 字符范圍必須被""引用起來
6 #+ 來阻止產生單字符的文件名.
7
8 exit 0
################################End Script#########################################
現在讓我們輸送ls -l的輸出到一個腳本中.
bash$ ls -l | ./uppercase.sh
-RW-RW-R-- 1 BOZO BOZO 109 APR 7 19:49 1.TXT
-RW-RW-R-- 1 BOZO BOZO 109 APR 14 16:48 2.TXT
-RW-R--R-- 1 BOZO BOZO 725 APR 20 20:56 DATA-FILE
注意:管道中的一個進程的stdout必須被下一個進程作為stdin讀入.否則,數據流會阻
塞,并且管道將產生非預期的行為.
如:
1 cat file1 file2 | ls -l | sort
2 #從"cat file1 file2"中的輸出并沒出現
作為子進程的運行的管道,不能夠改變腳本的變量.
1 variable="initial_value"
2 echo "new_value" | read variable
3 echo "variable = $variable" #variable = initial_value
如果管道中的某個命令產生了一個異常,并中途失敗,那么這個管道將過早的終止.
這種行為被叫做a broken pipe,并且這種狀態下將發送一個SIGPIPE信號.
>| 強制重定向(即使設置了noclobber選項--就是-C選項).這將強制的覆蓋一個現存文件.
|| 或-邏輯操作.
& 后臺運行命令.一個命令后邊跟一個&,將表示在后臺運行.
bash$sleep 10 &
[1] 850
[1]+ Done sleep 10
在一個腳本中,命令和循環都可能運行在后臺.
Example 3-3. 在后臺運行一個循環
################################Start Script#######################################
?? 快捷鍵說明
復制代碼
Ctrl + C
搜索代碼
Ctrl + F
全屏模式
F11
切換主題
Ctrl + Shift + D
顯示快捷鍵
?
增大字號
Ctrl + =
減小字號
Ctrl + -