Shell

變量

  • 定義變量變量和等號(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)(是否為空,是否定義等)來改變他的值
形式 說明
${var} 變量本來的值
${var:-word} 如果變量var為空或已被刪除,那么返回word,但不改變var的值。
${var:=word} 如果變量var為空或已被刪除(unset),那么返回word,并將var的值設(shè)置為word。
${var:?message} 如果變量var為空或已被刪除(unset),那么將消息message送到標(biāo)準(zhǔn)錯(cuò)誤輸出,可以用來檢測(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來實(shí)現(xiàn)。
a=10
b=20
val=`expr $a + $b`
echo "value: $val"
運(yùn)算符 說明 舉例
+ 加法 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ò)誤的,必須寫成[ $a = $b ]。

  • 關(guān)系運(yùn)算符只支持?jǐn)?shù)字,不支持字符串,除非字符串的值是數(shù)字。
運(yùn)算符 說明 舉例
-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)算符 說明 舉例
! 非運(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)算符 說明 舉例
= 檢測(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)字符串中的變量是無效的,
    單引號(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ù)組元素可以用“空格”符隔開,也可以單獨(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 語句
a=10
b=20
if [ $a == $b ]
then
echo "a is equal to b"
fi # if ... fi
# 最后必須以fi來結(jié)尾閉合,fi就是if倒過來拼寫。

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 語句可以與test命令結(jié)合使用,test命令用于檢查某個(gè)條件是否成立,與方括號(hào)([])類似。

if test $[2*3] -eq $[1+5]; then echo 'The two numbers are equal!'; fi;
# if ... else 語句也可以寫成一行,以命令的形式運(yùn)行
  • case esac語句
case 值 in # case  in  關(guān)鍵字
模式1)  # 每個(gè)模式必須以右括號(hào)結(jié)束
    command1
    command2
    command3
    ;; # ;; 相當(dāng)于break
模式2)
    command1
    command2
    command3
    ;;
*) # 如果沒有匹配的模式,使用*捕獲該值
    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è)值通過空格分隔。
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開頭的文件
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 nn是個(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語句,如果不加。會(huì)將最后一條命令運(yùn)行結(jié)果作為返回值。
函數(shù)返回值只能是贈(zèng)書,一般用來表示函數(shù)是否執(zhí)行成功,0表示成功,其他表示失敗。
如果一定要返回字符串,可以先定義一個(gè)變量,用來接收函數(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)部,通過$n的形式來獲取參數(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}來獲取參數(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流中寫入錯(cuò)誤信息。
命令 說明
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 將開始標(biāo)記 tag 和結(jié)束標(biāo)記 tag 之間的內(nèi)容作為輸入。

文件包含

包含腳本有兩種方式

. filename
source filename

簡(jiǎn)單起見,一般使用點(diǎn)號(hào)(.)

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
平臺(tái)聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點(diǎn),簡(jiǎn)書系信息發(fā)布平臺(tái),僅提供信息存儲(chǔ)服務(wù)。

推薦閱讀更多精彩內(nèi)容