對應的操作
|
整數操作
|
字符串操作
|
相同
|
-eq
|
=
|
不同
|
-ne
|
!=
|
大于
|
-gt
|
>
|
小于
|
-lt
|
|
大于或等于
|
-ge
|
|
小于或等于
|
-le
|
|
為空
|
-z
|
|
不為空
|
-n
|
比如:
比較字符串 a 和 b 是否相等就寫作:if [ $a = $b ]
判斷字符串 a 是否為空就寫作: if [ -z $a ]
判斷整數變量 a 是否大于 b 就寫作:if [ $a -gt $b ]
更細致的文檔推薦在字符串比較時盡量不要使用 -n ,而用 ! -z 來代替。(其中符號 "!" 表示求反操作)
BASH 中的變量除了用于對 整數 和 字符串 進行操作以外,另一個作用是作為文件變量。BASH 是 Linux 操作系統的 Shell,因此系統的文件必然是 BASH 需要操作的重要對象,如 if [ -x /root ] 可以用于判斷 /root 目錄是否可以被當前用戶進入。下表列出了 BASH 中用于判斷文件屬性的操作符:
運算符
|
含義( 滿足下面要求時返回 TRUE ) |
-e file
|
文件 file 已經存在 |
-f file
|
文件 file 是普通文件 |
-s file
|
文件 file 大小不為零 |
-d file
|
文件 file 是一個目錄 |
-r file
|
文件 file 對當前用戶可以讀取 |
-w file
|
文件 file 對當前用戶可以寫入 |
-x file
|
文件 file 對當前用戶可以執行 |
-g file
|
文件 file 的 GID 標志被設置 |
-u file
|
文件 file 的 UID 標志被設置 |
-O file
|
文件 file 是屬于當前用戶的 |
-G file
|
文件 file 的組 ID 和當前用戶相同 |
file1 -nt file2
|
文件 file1 比 file2 更新 |
file1 -ot file2
|
文件 file1 比 file2 更老 |
注意:上表中的 file 及 file1、file2 都是指某個文件或目錄的路徑。
在 BASH 程序中如果一個變量被使用了,那么直到該程序的結尾,該變量都一直有效。為了使得某個變量存在于一個局部程序塊中,就引入了局部變量的概念。BASH 中,在變量首次被賦初值時加上 local 關鍵字就可以聲明一個局部變量,如下面這個例子:
#!/bin/bash
HELLO=Hello
function hello {
local HELLO=World
echo $HELLO
}
echo $HELLO
hello
echo $HELLO
該程序的執行結果是:
Hello
World
Hello
這個執行結果表明全局變量 $HELLO 的值在執行函數 hello 時并沒有被改變。也就是說局部變量 $HELLO 的影響只存在于函數那個程序塊中。
這里我們為原來不熟悉 BASH 編程,但是非常熟悉 C 語言的程序員總結一下在 BASH 環境中使用變量需要注意的問題。
1,BASH 中的變量在引用時都需要在變量前加上 "$" 符號( 第一次賦值及在For循環的頭部不用加 "$"符號 );
2,BASH 中沒有浮點運算,因此也就沒有浮點類型的變量可用;
3,BASH 中的整形變量的比較符號與 C 語言中完全不同,而且整形變量的算術運算也需要經過 let 或 expr 語句來處理;
BASH 中幾乎含有 C 語言中常用的所有控制結構,如條件分支、循環等,下面逐一介紹。
if 語句用于判斷和分支,其語法規則和 C 語言的 if 非常相似。其幾種基本結構為:
if [ expression ]
then
statments
fi
或者
if [ expression ]
then
statments
else
statments
fi
或者
if [ expression ]
then
statments
else if [ expression ]
then
statments
else
statments
fi
或者
if [ expression ]
then
statments
elif [ expression ]
then
statments
else
statments
fi
值得說明的是如果你將 if 和 then 簡潔的寫在一行里面,就必須在 then 前面加上分號,如:if [ expression ]; then ... 。下面這個例子說明了如何使用 if 條件判斷語句:
#!/bin/bash
if [ $1 -gt 90 ]
then
echo "Good, $1"
elif [ $1 -gt 70 ]
then
echo "OK, $1"
else
echo "Bad, $1"
fi
exit 0
上面例子中的 $1 是指命令行的第一個參數,這個會在后面的“BASH 中的特殊保留字”中講解。
for 循環結構與 C 語言中有所不同,在 BASH 中 for 循環的基本結構是:
for $var in
其中 $var 是循環控制變量,
是 $var 需要遍歷的一個集合,do/done 對包含了循環體,相當于 C 語言中的一對大括號。另外如果do 和 for 被寫在同一行,必須在 do 前面加上 ";"。如: for $var in ; do 。下面是一個運用 for 進行循環的例子:#!/bin/bash
for day in Sun Mon Tue Wed Thu Fri Sat
do
echo $day
done
# 如果列表被包含在一對雙引號中,則被認為是一個元素
for day in "Sun Mon Tue Wed Thu Fri Sat"
do
echo $day
done
exit 0
注意上面的例子中,在 for 所在那行的變量 day 是沒有加 "$" 符號的,而在循環體內,echo 所在行變量 $day 是必須加上 "$" 符號的。另外如果寫成 for day 而沒有后面的 in
部分,則 day 將取遍命令行的所有參數。如這個程序:#!/bin/bash
for param
do
echo $param
done
exit 0
上面這個程序將列出所有命令行參數。for 循環結構的循環體被包含在 do/done 對中,這也是后面的 while、until 循環所具有的特點。
while 循環的基本結構是:
while [ condition ]
do
statments
done
這個結構請大家自己編寫一個例子來驗證。
until 循環的基本結構是:
until [ condition is TRUE ]
do
statments
done
這個結構也請大家自己編寫一個例子來驗證。
BASH 中的 case 結構與 C 語言中的 switch 語句的功能比較類似,可以用于進行多項分支控制。其基本結構是:
case "$var" in
condition1 )
statments1;;
condition2 )
statments2;;
...
* )
default statments;;
esac
下面這個程序是運用 case 結構進行分支執行的例子:
#!/bin/bash
echo "Hit a key, then hit return."
read Keypress
case "$Keypress" in
[a-z] ) echo "Lowercase letter";;
[A-Z] ) echo "Uppercase letter";;
[0-9] ) echo "Digit";;
* ) echo "Punctuation, whitespace, or other";;
esac
exit 0
上面例子中的第四行 "read Keypress" 一句中的 read 語句表示從鍵盤上讀取輸入。這個命令將在本講義的 BASH 的其他高級問題中講解。
熟悉 C 語言編程的都很熟悉 break 語句和 continue 語句。BASH 中同樣有這兩條語句,而且作用和用法也和 C 語言中相同,break 語句可以讓程序流程從當前循環體中完全跳出,而 continue 語句可以跳過當次循環的剩余部分并直接進入下一次循環。
BASH 是一個相對簡單的腳本語言,不過為了方便結構化的設計,BASH 中也提供了函數定義的功能。BASH 中的函數定義很簡單,只要向下面這樣寫就可以了:
function my_funcname {
code block
}
或者
my_funcname() {
code block
}
上面的第二種寫法更接近于 C 語言中的寫法。BASH 中要求函數的定義必須在函數使用之前,這是和 C 語言用頭文件說明函數方法的不同。
更進一步的問題是如何給函數傳遞參數和獲得返回值。BASH 中函數參數的定義并不需要在函數定義處就制定,而只需要在函數被調用時用 BASH 的保留變量 $1 $2 ... 來引用就可以了;BASH 的返回值可以用 return 語句來指定返回一個特定的整數,如果沒有 return 語句顯式的返回一個返回值,則返回值就是該函數最后一條語句執行的結果(一般為 0,如果執行失敗返回錯誤碼)。函數的返回值在調用該函數的程序體中通過 $? 保留字來獲得。下面我們就來看一個用函數來計算整數平方的例子:
#!/bin/bash
square() {
let "res = $1 * $1"
return $res
}
square $1
result=$?
echo $result
exit 0
保留變量
隨機數
運算符
變量的特殊操作
BASH 中有一些保留變量,下面列出了一些:
$IFS 這個變量中保存了用于分割輸入參數的分割字符,默認識空格。
$HOME 這個變量中存儲了當前用戶的根目錄路徑。
$PATH 這個變量中存儲了當前 Shell 的默認路徑字符串。
$PS1 表示第一個系統提示符。
$PS2 表示的二個系統提示符。
$PWD 表示當前工作路徑。
$EDITOR 表示系統的默認編輯器名稱。
$BASH 表示當前 Shell 的路徑字符串。
$0, $1, $2, ...
表示系統傳給腳本程序或腳本程序傳給函數的第0個、第一個、第二個等參數。
$# 表示腳本程序的命令參數個數或函數的參數個數。
$$ 表示該腳本程序的進程號,常用于生成文件名唯一的臨時文件。
$? 表示腳本程序或函數的返回狀態值,正常為 0,否則為非零的錯誤號。
$* 表示所有的腳本參數或函數參數。
$@ 和 $* 涵義相似,但是比 $* 更安全。
$! 表示最近一個在后臺運行的進程的進程號。
隨機數是經常要用到的,BASH 中也提供了這個功能,請看下面這個程序:
#!/bin/bash
# Prints different random integer from 1 to 65536
a=$RANDOM
echo $a
exit 0
這個程序可以在每次執行的時候隨機的打印出一個大小在 1 到 65536 之間的整數。
算術運算符
+ - * / % 表示加減乘除和取余運算
+= -= *= /= 同 C 語言中的含義
位操作符
= >> >>= 表示位左右移一位操作
= | |= 表示按位與、位或操作
~ ! 表示非操作
^ ^= 表示異或操作
關系運算符
> = >= == != 表示大于、小于、大于等于、小于等于、等于、不等于操作
|| 邏輯與、邏輯或操作
BASH 中還有一些對變量的簡潔、快速的操作,大家還記得 "${var}" 和 "$var" 同樣是對變量的引用吧,對 ${var} 進行一些變化就可以產生一些新功能:
${var-default} 表示如果變量 $var 還沒有設置,則保持 $var 沒有設置的狀態,并返回后面的默認值 default。
${var=default} 表示如果變量 $var 還沒有設置,則取后面的默認值 default。
${var+otherwise} 表示如果變量 $var 已經設置,則返回 otherwise 的值,否則返回空( null )。
${var?err_msg} 表示如果變量 $var 已經設置,則返回該變量的值,否則將后面的 err_msg 輸出到標準錯誤輸出上。
請同學們自己嘗試下面的例子:
#!/bin/bash
echo ${var?There is an error}
exit 0
還有下面一些用法,這些用法主要用于從文件路徑字符串中提取有用信息:
${var#pattern}, ${var##pattern} 用于從變量 $var 中剝去最短(最長)的和 pattern 相匹配的最左側的串。
${var%pattern}, ${var%%pattern} 用于從變量 $var 中剝去最短(最長)的和 pattern 相匹配的最右側的串。
另外 BASH 2 中還加入下面一些操作:
${var:pos} 表示去掉變量 $var 中前 pos 個字符。
${var:pos:len} 表示變量 $var 中去掉前 pos 個字符后的剩余字符串的前 len 個字符。
${var/pattern/replacement} 表示將變量 $var 中第一個出現的 pattern 模式替換為 replacement 字符串。
${var//pattern/replacement} 表示將變量 $var 中出現的所有 pattern 模式全部都替換為 replacment 字符串。
BASH 中對返回值的處理
用 BASH 設計簡單用戶界面
在 BASH 中讀取用戶輸入
一些特殊的慣用法
BASH 程序的調試
關于 BASH2
無論是在 Shell 中對 BASH 腳本返回值的處理,還是在腳本中對函數返回值的處理,都是通過 "$?" 系統變量來獲得。BASH 要求返回值必須為一個整數,不能用 return 語句返回字符串變量。
BASH 中提供了一個小的語句格式,可以讓程序快速的設計出一個字符界面的用戶交互選擇的菜單,該功能就是由 select 語句來實現的,select 語句的語法為:
select var in
上面的語法結構在執行后,BASH 會將
中的所有項加上數字列在屏幕上等待用戶選擇,在用戶作出選擇后,變量 $var 中就包含了那個被選中的字符串,然后就可以對該變量進行需要的操作了。我們可以從下面的例子中更直觀的來理解這個功能:#!/bin/bash
OPTIONS="Hello Quit"
select opt in $OPTIONS; do
if [ "$opt" = "Quit" ]; then
echo done
exit
elif [ "$opt" = "Hello" ]; then
echo Hello World
else
clear
echo bad option
fi
done
exit 0
大家可以試著執行上面的程序,看看是什么執行結果。
BASH 中通過 read 函數來實現讀取用戶輸入的功能,如下面這段程序:
#!/bin/bash
echo Please enter your name
read NAME
echo "Hi! $NAME !"
exit 0
上面這個腳本讀取用戶的輸入,并回顯在屏幕上。
另外 BASH 中還提供另外一種稱為 here documents 的結構?,可以將用戶需要通過鍵盤輸入的字符串改為從程序體中直接讀入,如密碼。下面的小程序演示了這個功能:
#!/bin/bash
passwd="aka@tsinghua"
ftp -n localhost FTPFTP
user anonymous $passwd
binary
bye
FTPFTP
exit 0
這個程序在用戶需要通過鍵盤敲入一些字符時,通過程序內部的動作來模擬鍵盤輸入。請注意 here documents 的基本結構為:
command SOMESPECIALSTRING
statments
...
SOMESPECIALSTRING
這里要求在需要鍵盤輸入的命令后,直接加上 符號,然后跟上一個特別的字符串,在該串后按順序輸入本來應該由鍵盤輸入的所有字符,在所有需要輸入的字符都結束后,重復一遍前面 符號后的“特別的字符串”即表示該輸入到此結束。
在 BASH 中 () 一對括號一般被用于求取括號中表達式的值或命令的執行結果,如:(a=hello; echo $a) ,其作用相當于 `...` 。
: 有兩個含義,一是表示空語句,有點類似于 C 語言中的單個 ";" 。表示該行是一個空命令,如果被用在 while/until 的頭結構中,則表示值 0,會使循環一直進行下去,如下例:
while :
do
operation-1
operation-2
...
operation-n
done
另外 : 還可以用于求取后面變量的值,比如:
#!/bin/bash
: ${HOSTNAME?} {USER?} {MAIL?}
echo $HOSTNAME
echo $USER
echo $MAIL
exit 0
在 BASH 中 export 命令用于將系統變量輸出到外層的 Shell 中了。
用 bash -x bash-script 命令,可以查看一個出錯的 BASH 腳本到底錯在什么地方,可以幫助程序員找出腳本中的錯誤。
另外用 trap 語句可以在 BASH 腳本出錯退出時打印出一些變量的值,以供程序員檢查。trap 語句必須作為繼 "#!/bin/bash" 后的第一句非注釋代碼,一般 trap 命令被寫作: trap 'message $checkvar1 $checkvar2' EXIT 。
使用 bash -version 命令可以看出當前你正在使用的 BASH 是什么版本,一般版本號為1.14或其他版本。而現在機器上一般還安裝了一個版本號為 2.0 的 BASH 。該 BASH 也在 /bin 目錄下。BASH2 提供了一些新功能,有興趣的同敘可以自己去看相關資料,或直接 man bash2 即可。
標簽:淘寶邀評 眉山 遼陽 北海 南陽 延邊 龍巖 大興安嶺
巨人網絡通訊聲明:本文標題《Linux Bash Shell入門教程》,本文關鍵詞 Linux,Bash,Shell,入門教程,;如發現本文內容存在版權問題,煩請提供相關信息告之我們,我們將及時溝通與處理。本站內容系統采集于網絡,涉及言論、版權與本站無關。