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)(是否為空叭首,是否定義等)來(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 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語(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)(.)

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
  • 序言:七十年代末捻浦,一起剝皮案震驚了整個(gè)濱河市,隨后出現(xiàn)的幾起案子桥爽,更是在濱河造成了極大的恐慌朱灿,老刑警劉巖,帶你破解...
    沈念sama閱讀 217,509評(píng)論 6 504
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件钠四,死亡現(xiàn)場(chǎng)離奇詭異盗扒,居然都是意外死亡,警方通過(guò)查閱死者的電腦和手機(jī)缀去,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 92,806評(píng)論 3 394
  • 文/潘曉璐 我一進(jìn)店門侣灶,熙熙樓的掌柜王于貴愁眉苦臉地迎上來(lái),“玉大人缕碎,你說(shuō)我怎么就攤上這事褥影。” “怎么了咏雌?”我有些...
    開(kāi)封第一講書(shū)人閱讀 163,875評(píng)論 0 354
  • 文/不壞的土叔 我叫張陵凡怎,是天一觀的道長(zhǎng)。 經(jīng)常有香客問(wèn)我赊抖,道長(zhǎng)栅贴,這世上最難降的妖魔是什么? 我笑而不...
    開(kāi)封第一講書(shū)人閱讀 58,441評(píng)論 1 293
  • 正文 為了忘掉前任熏迹,我火速辦了婚禮檐薯,結(jié)果婚禮上,老公的妹妹穿的比我還像新娘。我一直安慰自己坛缕,他們只是感情好墓猎,可當(dāng)我...
    茶點(diǎn)故事閱讀 67,488評(píng)論 6 392
  • 文/花漫 我一把揭開(kāi)白布曲梗。 她就那樣靜靜地躺著顽频,像睡著了一般。 火紅的嫁衣襯著肌膚如雪骇陈。 梳的紋絲不亂的頭發(fā)上宠页,一...
    開(kāi)封第一講書(shū)人閱讀 51,365評(píng)論 1 302
  • 那天左胞,我揣著相機(jī)與錄音,去河邊找鬼举户。 笑死烤宙,一個(gè)胖子當(dāng)著我的面吹牛,可吹牛的內(nèi)容都是我干的俭嘁。 我是一名探鬼主播躺枕,決...
    沈念sama閱讀 40,190評(píng)論 3 418
  • 文/蒼蘭香墨 我猛地睜開(kāi)眼,長(zhǎng)吁一口氣:“原來(lái)是場(chǎng)噩夢(mèng)啊……” “哼供填!你這毒婦竟也來(lái)了拐云?” 一聲冷哼從身側(cè)響起,我...
    開(kāi)封第一講書(shū)人閱讀 39,062評(píng)論 0 276
  • 序言:老撾萬(wàn)榮一對(duì)情侶失蹤近她,失蹤者是張志新(化名)和其女友劉穎叉瘩,沒(méi)想到半個(gè)月后,有當(dāng)?shù)厝嗽跇?shù)林里發(fā)現(xiàn)了一具尸體粘捎,經(jīng)...
    沈念sama閱讀 45,500評(píng)論 1 314
  • 正文 獨(dú)居荒郊野嶺守林人離奇死亡房揭,尸身上長(zhǎng)有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點(diǎn)故事閱讀 37,706評(píng)論 3 335
  • 正文 我和宋清朗相戀三年,在試婚紗的時(shí)候發(fā)現(xiàn)自己被綠了晌端。 大學(xué)時(shí)的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片捅暴。...
    茶點(diǎn)故事閱讀 39,834評(píng)論 1 347
  • 序言:一個(gè)原本活蹦亂跳的男人離奇死亡,死狀恐怖咧纠,靈堂內(nèi)的尸體忽然破棺而出蓬痒,到底是詐尸還是另有隱情,我是刑警寧澤漆羔,帶...
    沈念sama閱讀 35,559評(píng)論 5 345
  • 正文 年R本政府宣布梧奢,位于F島的核電站,受9級(jí)特大地震影響演痒,放射性物質(zhì)發(fā)生泄漏亲轨。R本人自食惡果不足惜,卻給世界環(huán)境...
    茶點(diǎn)故事閱讀 41,167評(píng)論 3 328
  • 文/蒙蒙 一鸟顺、第九天 我趴在偏房一處隱蔽的房頂上張望惦蚊。 院中可真熱鬧器虾,春花似錦、人聲如沸蹦锋。這莊子的主人今日做“春日...
    開(kāi)封第一講書(shū)人閱讀 31,779評(píng)論 0 22
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽(yáng)莉掂。三九已至葛圃,卻和暖如春,著一層夾襖步出監(jiān)牢的瞬間憎妙,已是汗流浹背库正。 一陣腳步聲響...
    開(kāi)封第一講書(shū)人閱讀 32,912評(píng)論 1 269
  • 我被黑心中介騙來(lái)泰國(guó)打工, 沒(méi)想到剛下飛機(jī)就差點(diǎn)兒被人妖公主榨干…… 1. 我叫王不留厘唾,地道東北人褥符。 一個(gè)月前我還...
    沈念sama閱讀 47,958評(píng)論 2 370
  • 正文 我出身青樓,卻偏偏與公主長(zhǎng)得像阅嘶,于是被迫代替她去往敵國(guó)和親。 傳聞我的和親對(duì)象是個(gè)殘疾皇子载迄,可洞房花燭夜當(dāng)晚...
    茶點(diǎn)故事閱讀 44,779評(píng)論 2 354

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