因爲Shell主要是字符串處理語言,因此利用Shell變量對字符串作不少事。然而,由於算術運算也是必要的,因此POSIX Shell也提供利用Shell變量執行算術運算的機制。java
export與readonly函數
export用於修改或打印環境變量,readonly則使得變量不得修改。測試
因爲許多商用UNIX系統裏的/bin/sh,仍然不是POSIX兼容版本。所以,export與readonly的變量賦值形式可能沒法工做。要實現嚴格的可移植性,可以使用:命令行
FOO=somevalue排序
export FOO字符串
BAR=anothervalue字符串處理
readonly BARstring
export命令最多見的用法出如今設置環境變量中:it
PATH=$PATH:/usr/local/bin 更新PATHio
export PATH 導出
export命令可用於顯示當前環境:
$ export -p
刪除環境變量:
env -i PATH=$PATH HOME=$HOME LC_ALL=C awk '...' file1 file2
unset命令從執行中的Shell中刪除變量與函數:
unset full_name 刪除full_name變量
unset -v first middle last 刪除其餘變量
unset -f刪除函數:
who_is_on() { 定義函數
who | awk '{ print $1 }' | sort -u 產生排序後的用戶列表
}
unset -f who_is_on 刪除函數
位置參數:
因爲歷史緣由,當整數大於9時,就應該以花括號({})括起來:
echo first arg is $1
echo tenth arg is ${10}
特殊變量$#,$*,$@,"$*","$@"
shift命令是用來截取來自列表的位置參數,從左開始。一旦執行shift,$1的初始值會永遠消失,取而代之的是$2的舊值。$#值則會逐次減1.
$ set -- hello "hi there" greetings
$ echo there are $# total arguments
there are 3 total arguments
[root@bsg-1 dict]# for i in $*
> do echo i is $i
> done
i is hello
i is hi
i is there
i is greetings
[root@bsg-1 dict]# for i in $@
> do echo i is $i
> done
i is hello
i is hi
i is there
i is greetings
[root@bsg-1 dict]# for i in "$*"
> do echo i is $i
> done
i is hello hi there greetings
[root@bsg-1 dict]# for i in "$@"
> do echo i is $i
> done
i is hello
i is hi there
i is greetings
[root@bsg-1 dict]# shift
[root@bsg-1 dict]# echo there are now $# arguments
there are now 2 arguments
[root@bsg-1 dict]# for i in "$@"
> do echo i is $i
> done
i is hi there
i is greetings
if...then...elif...then...else...fi:
固然 &&、||也有若是...就/不...
好比 some_command && { one command a second command and a third command }
只有在some_command成功時他們才被執行。使用if可讓它更爲簡潔:
if some_command
then
one command
a second command
and a third command
fi
test命令:用來測試文件屬性、比較字符串以及比較數字
case語句:能夠類比java或C中的switch...case
case $1 in
-f)
...
;;
-d | --directory)
...
;;
*)
echo $1: unknown option > $2
exit 1
# 在"esac"以前的;;形式是一個號習慣,不過並不是必要
esac
雖然你可能會以爲在每一個模式列表以後的不對稱的右圓括號有點奇怪,不過這也是Shell語言裏不對稱
定界符的惟一實例
*模式是傳統用法,但非必須,它是做爲一個默認的狀況。
循環:for循環裏的in列表(list)是可選的,若是省略,Shell循環會遍歷整個命令行參數。
這就好像你已經輸入了for i in "$@":
for i # 循環經過命令行參數
do
case $i in
-f)
...
;;
...
esac
done
while與until
while與until惟一的不一樣之處在於,如何對待condition的退出狀態。只要condition是成功退出,while會繼續循環。只要condition未成功結束,until則執行循環
例如:
pattern=... 模式會控制字符串的縮減
while [ -n "$string" ] 當字符串不是空時
do
處理$string的當前值
string=${string%$pattern} 截去部分字符串
done
break與continue:這個從C借用來的,這裏再也不細說
最後要重點講下的是函數
函數是指一段單獨的程序代碼,用以執行一些定義完整的單項工做,
函數在使用以前必須先定義。
[root@bsg-1 ~]# wait_for_user() {
> until who | grep "$1" > /dev/null
> do
> sleep $(2:-30)
> done
> }
[root@bsg-1 ~]# wait_for_user root
[root@bsg-1 ~]# wait_for_user root 60
在函數體中,位置參數($1,$2,...,$#,$*,以及$@)都是函數的參數,父腳本的參數則臨時地被函數參數所掩蓋或隱藏。
在Shell函數裏,return命令的功能與工做方式都與exit相同:
answer_the_question() {
...
return 42
}
好了,這一節就到這兒,下一節講下I/O及文件與命令執行!