變量
- 定義變量變量和等號(hào)之間不能有空格, 變量定以后可從新被定義彻亲。
variableNumber=100
variableName="value"
variableName="othervalue"
使用readonly可將變量定義為只讀變量韵吨,只讀變量的值不能被改變
url="baidu.com"
readonly url
url="google.com" # ./test.sh: line 4: url: readonly variable
- 使用變量時(shí)要在變量前面加美元符號(hào)($)
name="yjzhang"
echo $name
echo ${name}
變量名外的花括號(hào)可加可不加主慰,目的是告訴解釋器識(shí)別變量的邊界,通常加上亿乳。
- 刪除變量時(shí)用
unset variable_name
硝拧,變量刪除后不能再使用径筏,unset不能刪除只讀變量 - 某些字符的變量有特殊含義,這樣的變量被稱為特殊變量
變量 | 含義 |
---|---|
$0 | 當(dāng)前腳本的文件名 |
$n | 傳遞給腳本或函數(shù)的參數(shù)障陶,n是一個(gè)數(shù)字滋恬,表示第幾個(gè)參數(shù),例如抱究,第一個(gè)參數(shù)是$1,第二個(gè)參數(shù)是$2 |
$# | 傳遞給腳本或函數(shù)的參數(shù)個(gè)數(shù) |
$@ | 傳遞給腳本或函數(shù)的所有參數(shù)恢氯。被雙引號(hào)("")包含時(shí),與$*稍有不同鼓寺,下面將會(huì)講到勋拟。 |
$? | 上個(gè)命令的退出狀態(tài),或函數(shù)的返回值妈候。 |
$$ | 當(dāng)前shell進(jìn)程ID敢靡,對(duì)于shell腳本,就是這些腳本所在的進(jìn)程ID苦银。 |
- 如果表達(dá)式中包含特殊字符啸胧,shell會(huì)進(jìn)行替換。
a=10
echo -e "value of a is $a \n" # value of is 10
這里的-e表示對(duì)轉(zhuǎn)義字符進(jìn)行替換幔虏,如果不適用-e則會(huì)原樣輸出纺念。echo的命令-E選項(xiàng)禁止轉(zhuǎn)義,默認(rèn)也是不轉(zhuǎn)義的所计,使用-n宣揚(yáng)可以禁止插入換行符柠辞。
- `command`命令替換是指shell可以先執(zhí)行命令,將輸出結(jié)果暫時(shí)保存主胧,在適當(dāng)?shù)牡胤捷敵觥?/li>
- 變量替換可以根據(jù)變量的狀態(tài)(是否為空叭首,是否定義等)來(lái)改變他的值
形式 | 說(shuō)明 |
---|---|
${var} | 變量本來(lái)的值 |
${var:-word} | 如果變量var為空或已被刪除,那么返回word踪栋,但不改變var的值焙格。 |
${var:=word} | 如果變量var為空或已被刪除(unset),那么返回word夷都,并將var的值設(shè)置為word眷唉。 |
${var:?message} | 如果變量var為空或已被刪除(unset),那么將消息message送到標(biāo)準(zhǔn)錯(cuò)誤輸出囤官,可以用來(lái)檢測(cè)變量var是否可以被正常賦值冬阳。若此替換出現(xiàn)在shell腳本中,那么腳本將停止運(yùn)行党饮。 |
${var:+word} | 如果變量var被定義肝陪,那么返回word,但不改變var的值刑顺。 |
運(yùn)算符
- 算術(shù)運(yùn)算符氯窍,原生bash不支持簡(jiǎn)單的數(shù)學(xué)運(yùn)算饲常,可以使用expr來(lái)實(shí)現(xiàn)。
a=10
b=20
val=`expr $a + $b`
echo "value: $val"
運(yùn)算符 | 說(shuō)明 | 舉例 |
---|---|---|
+ | 加法 |
expr $a + $b 結(jié)果為 30狼讨。 |
- | 減法 |
expr $a - $b 結(jié)果為 10贝淤。 |
* | 乘法 |
expr $a \* $b 結(jié)果為 200。 |
/ | 除法 |
expr $b / $a 結(jié)果為 2政供。 |
% | 取余 |
expr $b % $a 結(jié)果為 0播聪。 |
= | 賦值 | a=$b 將把變量 b 的值賦給 a。 |
== | 相等鲫骗,用于比較兩個(gè)數(shù)字犬耻,相同返回true | [ $a == $b ] 返回 false。 |
!= | 不相等执泰,用于比較兩個(gè)數(shù)字枕磁,不相同則返回true | [ $a != $b ] 返回 true。 |
表達(dá)式和運(yùn)算符之間要有空格术吝。條件表達(dá)式要放在方括號(hào)之間计济,并且要有空格,例如[$a==$b]是錯(cuò)誤的排苍,必須寫(xiě)成[ $a = $b ]沦寂。
- 關(guān)系運(yùn)算符只支持?jǐn)?shù)字,不支持字符串淘衙,除非字符串的值是數(shù)字传藏。
運(yùn)算符 | 說(shuō)明 | 舉例 |
---|---|---|
-eq | 檢測(cè)兩個(gè)數(shù)是否相等,相等返回 true彤守。 | [ $a -eq $b ] 返回 true毯侦。 |
-ne | 檢測(cè)兩個(gè)數(shù)是否相等,不相等返回 true具垫。 | [ $a -ne $b ] 返回 true侈离。 |
-gt | 檢測(cè)左邊的數(shù)是否大于右邊的,如果是筝蚕,則返回 true卦碾。 | [ $a -gt $b ] 返回 false。 |
-lt | 檢測(cè)左邊的數(shù)是否小于右邊的起宽,如果是洲胖,則返回 true。 | [ $a -lt $b ] 返回 true坯沪。 |
-ge | 檢測(cè)左邊的數(shù)是否大等于右邊的绿映,如果是,則返回 true屏箍。 | [ $a -ge $b ] 返回 false绘梦。 |
-le | 檢測(cè)左邊的數(shù)是否小于等于右邊的,如果是赴魁,則返回 true卸奉。 | [ $a -le $b ] 返回 true。 |
- 布爾運(yùn)算符
運(yùn)算符 | 說(shuō)明 | 舉例 |
---|---|---|
! | 非運(yùn)算颖御,表達(dá)式為 true 則返回 false榄棵,否則返回 true。 | [ ! false ] 返回 true潘拱。 |
-o | 或運(yùn)算疹鳄,有一個(gè)表達(dá)式為 true 則返回 true。 | [ $a -lt 20 -o $b -gt 100 ] 返回 true芦岂。 |
-a | 與運(yùn)算瘪弓,兩個(gè)表達(dá)式都為 true 才返回 true。 | [ $a -lt 20 -a $b -gt 100 ] 返回 false禽最。 |
- 字符串運(yùn)算符
a="abc"
b="efg"
運(yùn)算符 | 說(shuō)明 | 舉例 |
---|---|---|
= | 檢測(cè)兩個(gè)字符串是否相等腺怯,相等返回 true。 | [ $a = $b ] 返回 false川无。 |
!= | 檢測(cè)兩個(gè)字符串是否相等呛占,不相等返回 true。 | [ $a != $b ] 返回 true懦趋。 |
-z | 檢測(cè)字符串長(zhǎng)度是否為0晾虑,為0返回 true。 | [ -z $a ] 返回 false仅叫。 |
-n | 檢測(cè)字符串長(zhǎng)度是否為0帜篇,不為0返回 true。 | [ -z $a ] 返回 true惑芭。 |
-str | 檢測(cè)字符串是否為空坠狡,不為空返回 true。 | [ $a ] 返回 true遂跟。 |
字符串
- 字符串可用單引號(hào)逃沿,雙引號(hào),還可以不用引號(hào)
str='this is a string'
name='yjzhang'
str="hello, \"$name\"! \n"
echo str # hello, yjzhang!
- 單引號(hào)里的任何字符串都會(huì)原樣輸出幻锁,單引號(hào)字符串中的變量是無(wú)效的凯亮,
單引號(hào)字符串中不能出現(xiàn)單引號(hào)(對(duì)單引號(hào)使用轉(zhuǎn)義符后也不行)- 雙引號(hào)可以有變量
雙引號(hào)里可以出現(xiàn)轉(zhuǎn)義字符
- 拼接字符串
name="yjzhang"
test="hello, "name" !"
test_1="hello, ${name} !"
echo $test $test_1
- 獲取字符串長(zhǎng)度
str="abcd"
echo ${#str} # 輸出 4
- 提取子字符串
str="Today the weather was good"
echo ${str:1:4} # 輸出 oday
- 查找子字符串
str="Today the weather was good"
echo `expr index "$str" is`
數(shù)組
- 定義數(shù)組時(shí)數(shù)組元素可以用“空格”符隔開(kāi),也可以單獨(dú)定義數(shù)組元素哄尔。
array=(value0 value1 value2)
#或者
array1=(
value0
value1
vlaue2
)
# 或者
array2[0]=value0
array2[1]=value1
array2[2]=vlaue2
讀取元素的一般格式是:
${array[index]}
假消,使用@或*可以獲取數(shù)組中的所有元素${array[*]}
或${array[@]}
獲取數(shù)組長(zhǎng)度的方法與獲取字符串長(zhǎng)度的方法相同
# 取得數(shù)組元素的個(gè)數(shù)
length=${#array{@}}
#或者
length=${#array{*}}
# 取得數(shù)組單個(gè)元素的長(zhǎng)度
lengthn=${#array[n]}
關(guān)系運(yùn)算
- if else 語(yǔ)句
a=10
b=20
if [ $a == $b ]
then
echo "a is equal to b"
fi # if ... fi
# 最后必須以fi來(lái)結(jié)尾閉合,fi就是if倒過(guò)來(lái)拼寫(xiě)岭接。
if [ $a == $b ]
then
echo "a is equal to b"
else
echo "a is not equal to b"
fi # if ... else ... fi
if [ $a == $b ]
then
echo "a is equal to b"
elif [ $a -gt $b ]
then
echo "a is greater than b"
elif [ $a -lt $b ]
then
echo "a is less than b"
else
echo "None of the condition met"
fi # if ... elif ... fi
num1=$[2*3]
num2=$[1+5]
if test $[num1] -eq $[num2]
then
echo 'The two numbers are equal!'
else
echo 'The two numbers are not equal!'
fi
# if ... else 語(yǔ)句可以與test命令結(jié)合使用富拗,test命令用于檢查某個(gè)條件是否成立臼予,與方括號(hào)([])類似。
if test $[2*3] -eq $[1+5]; then echo 'The two numbers are equal!'; fi;
# if ... else 語(yǔ)句也可以寫(xiě)成一行啃沪,以命令的形式運(yùn)行
- case esac語(yǔ)句
case 值 in # case in 關(guān)鍵字
模式1) # 每個(gè)模式必須以右括號(hào)結(jié)束
command1
command2
command3
;; # ;; 相當(dāng)于break
模式2)
command1
command2
command3
;;
*) # 如果沒(méi)有匹配的模式粘拾,使用*捕獲該值
command1
command2
command3
;;
esac
# 例如:
echo 'Input a number between 1 to 4'
echo 'Your number is:\c'
read aNum
case $aNum in
1) echo 'You select 1'
;;
2) echo 'You select 2'
;;
3) echo 'You select 3'
;;
4) echo 'You select 4'
;;
*) echo 'You do not select a number between 1 to 4'
;;
esac
- for循環(huán)
for 變量 in 列表 # 列表是一組值(數(shù)字,字符串等)組成的序列创千,每個(gè)值通過(guò)空格分隔缰雇。
do
command1
command2
...
commandN
done
for loop in 1 2 3 4 5
do
echo "The value is: $loop"
done
for str in 'This is a string' # 順序輸出字符串中的字符
do
echo $str
done
# 顯示主目錄下以.bash開(kāi)頭的文件
for FILE in $HOME/.bash*
do
echo $FILE
done
- while循環(huán)
while command
do
Statement(s) to be executed if command is true
done
COUNTER=0
while [ $COUNTER -lt 5 ]
do
COUNTER='expr $COUNTER+1'
echo $COUNTER
done
# 用于讀取鍵盤信息,直到按<Ctrl-D>結(jié)束循環(huán)
echo 'type <CTRL-D> to terminate'
echo -n 'enter your most liked film: '
while read FILM
do
echo "Yeah! great film the $FILM"
done
- until循環(huán)
until循環(huán)執(zhí)行一系列=命令直至條件為true時(shí)停止追驴,until循環(huán)與while循環(huán)在處理方式上剛好相反械哟。
until command
do
Statement(s) to be executed until command is true
done
- break和continue命令
break命令可以跳出所有循環(huán)
while :
do
echo -n "Input a number between 1 to 5: "
read aNum
case $aNum in
1|2|3|4|5) echo "Your number is $aNum!"
;;
*) echo "You do not select a number between 1 to 5, game is over!"
break
;;
esac
done
break n
n是個(gè)整數(shù),表示跳出第幾層循環(huán)殿雪。
for var1 in 1 2 3
do
for var2 in 0 5
do
if [ $var1 -eq 2 -a $var2 -eq 0 ]
then
break 2
else
echo "$var1 $var2"
fi
done
done
continue只是跳出當(dāng)前循環(huán)
while :
do
echo -n "Input a number between 1 to 5: "
read aNum
case $aNum in
1|2|3|4|5) echo "Your number is $aNum!"
;;
*) echo "You do not select a number between 1 to 5!"
continue
echo "Game is over!"
;;
esac
done
continue后面也可以跟一個(gè)數(shù)字暇咆,表示跳出第幾層循環(huán)。
NUMS="1 2 3 4 5 6 7"
for NUM in $NUMS
do
Q=`expr $NUM % 2`
if [ $Q -eq 0 ]
then
echo "Number is an even number!!"
continue
fi
echo "Found odd number"
done
函數(shù)
- 函數(shù)的基本格式
function_name () {
list of commands
[ return value ]
}
函數(shù)的返回值可以顯示增加return語(yǔ)句丙曙,如果不加糯崎。會(huì)將最后一條命令運(yùn)行結(jié)果作為返回值。
函數(shù)返回值只能是贈(zèng)書(shū)河泳,一般用來(lái)表示函數(shù)是否執(zhí)行成功沃呢,0表示成功,其他表示失敗拆挥。
如果一定要返回字符串薄霜,可以先定義一個(gè)變量,用來(lái)接收函數(shù)的計(jì)算結(jié)果纸兔。
funWithReturn(){
echo "The function is to get the sum of two numbers..."
echo -n "Input first number: "
read aNum
echo -n "Input another number: "
read anotherNum
echo "The two numbers are $aNum and $anotherNum !"
return $(($aNum+$anotherNum))
$?表示函數(shù)的返回值
}
funWithReturn # 調(diào)用函數(shù)只需要給出函數(shù)名惰瓜,不需要加括號(hào)
# Capture value returnd by last command
ret=$?
echo "The sum of two numbers is $ret !"
刪除函數(shù)可以使用unset .f
命令
$unset .f function_name
如果想要直接從終端調(diào)用函數(shù),可以將函數(shù)定義在主目錄下的.profile文件汉矿,這樣每次登錄后崎坊,在命令提示符后面輸入函數(shù)名就可以立即調(diào)用。
- 函數(shù)參數(shù)
在函數(shù)內(nèi)部洲拇,通過(guò)$n的形式來(lái)獲取參數(shù)的值奈揍,$1表示第一個(gè)參數(shù),$2表示第二個(gè)參數(shù)赋续。
funWithParam(){
echo "The value of the first parameter is $1 !"
echo "The value of the second parameter is $2 !"
echo "The value of the tenth parameter is $10 !"
echo "The value of the tenth parameter is ${10} !"
echo "The value of the eleventh parameter is ${11} !"
echo "The amount of the parameters is $# !" # 參數(shù)個(gè)數(shù)
echo "The string of the parameters is $* !" # 傳遞給函數(shù)的所有參數(shù)男翰,與$@相似,
}
funWithParam 1 2 3 4 5 6 7 8 9 34 73
$10不能獲取第十個(gè)參數(shù)纽乱,獲取第十個(gè)參數(shù)要用${10}蛾绎,當(dāng)n>=10時(shí),需要用${n}來(lái)獲取參數(shù)。
輸入輸出重定向
- 標(biāo)準(zhǔn)輸入文件(stdin):stdin的文件描述符為0租冠,Unix程序默認(rèn)從stdin讀取數(shù)據(jù)鹏倘。
- 標(biāo)準(zhǔn)輸出文件(stdout):stdout 的文件描述符為1,Unix程序默認(rèn)向stdout輸出數(shù)據(jù)顽爹。
- 標(biāo)準(zhǔn)錯(cuò)誤文件(stderr):stderr的文件描述符為2第股,Unix程序會(huì)向stderr流中寫(xiě)入錯(cuò)誤信息。
命令 | 說(shuō)明 |
---|---|
command > file | 將輸出重定向到 file话原。 |
command < file | 將輸入重定向到 file。 |
command >> file | 將輸出以追加的方式重定向到 file诲锹。 |
n > file | 將文件描述符為 n 的文件重定向到 file繁仁。 |
n >> file | 將文件描述符為 n 的文件以追加的方式重定向到 file。 |
n >& m | 將輸出文件 m 和 n 合并归园。 |
n <& m | 將輸入文件 m 和 n 合并黄虱。 |
<< tag | 將開(kāi)始標(biāo)記 tag 和結(jié)束標(biāo)記 tag 之間的內(nèi)容作為輸入。 |
文件包含
包含腳本有兩種方式
. filename
source filename
簡(jiǎn)單起見(jiàn)庸诱,一般使用點(diǎn)號(hào)(.)