SHELL腳本-第二課
- 回顧
- 基礎知識
-
- 特殊字元
- 參考資料
回顧
- shell腳本程式設計的不适用場景的列舉;1
- 簡單的shell腳本展示;
- 解釋器說明及注意事項;
- 腳本的運作方式。
基礎知識
在此,我們将對一些特殊字元,變量命名及常見使用方式做一些介紹,以便你做基本的了解。首先,我們來看看看有哪些特殊的字元值得注意。
特殊字元
腳本中常常會出現一些特殊的字元,他們都表示一些特定的含義,我們接下來對它們做一一的介紹。
-
:以一個#開頭的行 (#!是例外) 是注釋行。例如:#
-
:【指令分割符】用分割符允許在同一行裡有兩個或更多的指令。例如:;
echo hello; echo there if [ -x "$filename" ]; then # 注意:"if" and "then"需要分隔符 # 思考一下這是為什麼? echo "File $filename exists."; cp $filename $filename.bak else echo "File $filename not found."; touch $filename fi; echo "File test complete."
-
:case語句分支的結束符[雙分号]。例如:;;
case "$variable" in abc) echo "\$variable = abc" ;; xyz) echo "\$variable = xyz" ;; esac
-
:'STRING’能引用STRING裡的所有字元(包括特殊字元也會被原樣引用)。這是一個比使用雙引号(“)更強的引用。 例如:'
運作結果如下所示:#! /bin/bash hello="A B C D" echo $hello echo "$hello" echo '$hello'
$bash string
A B C D
A B C D
$hello
會僅僅被認為是一個普通的字元,而不是變量的字首。$
-
:"STRING"的引用會使STRING裡的特殊字元能夠被解釋。其中例子如上所示。"
-
.
:等同于source。這是一個bash的内建指令。
在這邊
符号可以在腳本中的作用類似于.
語言中的C
,可以直接調用#include
中的變量以及函數。調用#include
腳本如下:./bbb
接下來,通過另外一個腳本調用其中的變量以及函數。例如:# This is a data file loaded by a script. # Files of this type may contain variables, functions, etc. # It may be loaded with a 'source' or '.' command by a shell script. # Let's initialize some variables. variable1=22 variable2=474 variable3=5 variable4=97 message1="Hello, how are you?" message2="Enough for now. Goodbye." print_message () { #Echoes any message passed to it. if [ -z "$1" ] then return 1 # Error, if argument missing. fi echo until [ -z "$1" ] do # Step through arguments passed to function. echo -n "$1" # Echo args one at a time, suppressing line feeds. echo -n " " # Insert spaces between words. shift # Next one. done echo return 0 }
運作結果如下所示:#!/bin/bash . bbb # Load a data file. echo "variable1 (from data-file) = $variable1" echo "variable3 (from data-file) = $variable3" let "sum = $variable2 + $variable4" echo "Sum of variable2 + variable4 (from data-file) = $sum" echo "message1 (from data-file) is \"$message1\"" exit 0
$ sh kkk
variable1 (from data-file) = 22
variable3 (from data-file) = 5
Sum of variable2 + variable4 (from data-file) = 571
message1 (from data-file) is “Hello, how are you?”
-n This
-n
-n is
-n
-n the
-n
-n message-print
-n
-n function
-n
-n in
-n
-n the
-n
-n data-file.
-n
-
:逗号操作符用于連接配接一連串的數學表達式。這一串的數學表達式每一個都被求值,但隻有最後一個被傳回。例如:,
-
:用于單個字元的引用機制。\
"轉義"字元為\X
。X
-
:分隔一個檔案路徑的各個部分。例如:/
。/home/bozo/projects/Makefile
- `:(由于這個符号比較特殊我就直接用這種方式表示了)将會重新配置設定一個指令甚至是多個指令的輸出;它會将指令的輸出如實地添加到另一個上下文中。例如:
運作結果如下所示(下面都是目前目錄下的檔案):#!/bin/bash textfile_listing=`ls *` echo "$textfile_listing"
$ sh commandchange
bbb
commandchange
kkk
string
-
:這個指令意思是空操作(即什麼操作也不做). 它一般被認為是和shell的内建指令true是一樣的。冒号":" 指令是Bash自身内建的, and its它的退出狀态碼是真(即0)。例如::
if condition then : # 什麼也不做的分支 else take-some-action fi
的特殊使用方法如下所示::
運算結果如下所示:#!/bin/bash # 用10種不同的方法計數到11. n=1; echo -n "$n " let "n = $n + 1" # let "n = n + 1"也可以. echo -n "$n " :$((n = $n + 1)) # ":"是需要的, #+ 否則Bash會嘗試把"$((n = $n + 1))"作為指令運作. echo -n "$n " (( n = n + 1 )) # 上面是更簡單的可行的辦法. echo -n "$n " n=$(($n + 1)) echo -n "$n " : $[ n = $n + 1 ] # ":"是需要的, #+ 否則Bash會嘗試把"$[ n = $n + 1 ]"作為指令運作. # 即使"n"被當作字元串來初始化也能工作. echo -n "$n " n=$[ $n + 1 ] # 即使"n"被當作字元串來初始化也能工作. #* 應避免這種使用這種結構,因為它是被廢棄并不可移植的. echo -n "$n " # 現在是C風格的增加操作. # 多謝Frank Wang指出這一點. let "n++" # let "++n"也可以. echo -n "$n " (( n++ )) # (( ++n )也可以. echo -n "$n " : $(( n++ )) # : $(( ++n ))也可以. echo -n "$n " : $[ n++ ] # : $[ ++n ]]也可以. echo -n "$n " echo exit 0
$ sh compoperater
-n 1
-n 2
-n 3
-n 4
-n 5
-n 6
-n 7
-n 8
-n 9
-n 10
-n 11
-
:取反一個測試結果或退出狀态。!
-
:星号(*)字元在用于比對檔案名擴充的一個通配符,它自動比對給定的目錄下的每一個檔案。 在計算時,星号*
表示乘法運算符。兩個星号*
表示求幂運算符。**
-
:字元?被用于檔案名擴充特性的檔案名表達式的單字元比對,同時也在擴充正規表達式中比對任意一個字元。?
-
:變量替換 (引用一個變量的内容)。$
var1=5 var2=23skidoo echo $var1 # 5 echo $var2 # 23skidoo
-
:在背景運作作業。 一個後面跟一個&
的指令會在背景運作。&
-
:管道。把上一個指令的輸出傳給下一個指令,或是shell。這是連接配接指令的一種方法。|
-
:儲存退出碼值的變量. 變量$?儲存了一個指令,一個函數,或一個腳本的退出狀态碼的值。$?
-
:位置參數。$*, $@
-
:參數替換。${}
-
:指令組。一組由圓括号括起來的指令是新開一個子shell來執行的。因為是在子shell裡執行,在圓括号裡的變量不能被腳本的其他部分通路。因為父程序(即腳本程序)不能存取子程序(即子shell)建立的變量。例如:()
a=123 ( a=321; ) echo "a = $a" # a = 123 # 在圓括号裡的變量"a"實際上是一個局部變量,作用局域隻是在圓括号内用于數組始初化
-
:這個結構也是一組指令代碼塊,事實上,它是匿名的函數。然而與一個函數所不同的,在代碼塊裡的變量仍然能被腳本後面的代碼通路。例如:{}
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 # 查詢該軟體包能否被安裝. 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手冊來了解上面所用的選項。 39 40 exit 0
-
:> &> >& >> <
-
:重定向scriptname的輸出到檔案filename中去。如果檔案filename存在則将會被覆寫。sciptname >filename
-
:會重定向指令command标準輸出(stdout)和标準錯誤(stderr)到檔案filename中。command &>filename
-
:把指令command的标準輸出(stdout)重定向到标準錯誤(stderr)。command >&2
-
:appends把腳本scriptname的輸出追加到檔案filename。如果filename不存在,則它會被建立。scriptname >>filename
-
-
:先前的工作目錄。 指令-
可以回到原來的工作目錄.它使用了cd -
環境變量。$OLDPWD
-
:目前工作目錄。它與外部變量~+
是一緻的。$PWD
-
:先前的工作目錄。它與外部變量~-
是一緻的。$OLDPWD
以上即為常見的特殊字元,可更有利于運用特殊字元來簡化腳本程式設計。
參考資料
- SHELL腳本-第一課 ↩︎