1 shell for循環(huán)語法
for 變量 in 列表
do
? ? command1
? ? command2
? ? ...
? ? commandN
done
1.1 讀取列表中的值
#!/bin/bash
for test in apple boy cat dog
do
? echo The next state is $test
done
結(jié)果:
The next state is apple
The next state is boy
The next state is cat
The next state is dog
1.2 讀取列表中的復(fù)雜值
有兩種解決辦法:
#使用轉(zhuǎn)義字符(反斜線)來將單引號轉(zhuǎn)移嘴办;
#使用雙引號來定義用到單引號的值买鸽。
#!/bin/bash
for test in I don\'t think if "this'll" work
do
? echo The next state is $test
done
結(jié)果是:
The next state is I
The next state is don't
The next state is think
The next state is if
The next state is this'll
The next state is work
*記住,for命令用空格來劃分列表中的每個(gè)值眼五。如果在單獨(dú)的數(shù)據(jù)值中有空格,就必須用雙引號將這些值圈起來看幼。
1.3 從變量讀取列表
將一系列的值都集中存儲在一個(gè)變量中,然后需要遍歷變量中的整個(gè)列表桌吃。
#!/bin/bash
list="helllo world"
#向已有列表中添加或拼接一個(gè)值
list=$list" ok"
for state in $list
do
? echo "this word? is $state"
done
結(jié)果是:
this word is helllo
this word? is world
this word? is ok
1.4 從命令讀取值
有兩種方式可以將命令輸出賦值給變量:?
(1)反引號字符(``)?
(2)$()格式
如:
for i in $(who)
do
? echo "visit beautiful $i"
done
輸出結(jié)果:
visit beautiful etldev
visit beautiful pts/0
visit beautiful 2019-05-15
visit beautiful 09:31
visit beautiful (112.64.161.227)
visit beautiful root
visit beautiful pts/1
visit beautiful 2019-05-09
visit beautiful 07:41
visit beautiful (10.1.1.62)
visit beautiful etldev
visit beautiful pts/3
visit beautiful 2019-05-15
visit beautiful 09:34
visit beautiful (112.64.161.227)
visit beautiful etldev
visit beautiful pts/4
visit beautiful 2019-05-15
visit beautiful 10:49
visit beautiful (112.64.161.227)
*who默認(rèn)輸出當(dāng)前登錄的所有用戶的信息如下所示
etldev pts/0? ? ? ? 2019-05-15 09:31 (112.64.161.227)
root? ? pts/1? ? ? ? 2019-05-09 07:41 (10.1.1.62)
etldev? pts/3? ? ? ? 2019-05-15 09:34 (112.64.161.227)
etldev? pts/4? ? ? ? 2019-05-15 10:49 (112.64.161.227)
1.5?更改字段分隔符
造成這個(gè)問題的原因是特殊的環(huán)境變量IFS,叫作內(nèi)部字段分隔符。默認(rèn)情況下搬卒,bash shell會將下列字符當(dāng)作字段分隔符:
*空格
*制表符
*換行符
如果bash shell在數(shù)據(jù)中看到這些字符中的任意一個(gè),它就會假定這表明了列表中一個(gè)新數(shù)據(jù)字段的開始契邀。
想修改IFS的值,使其只能識別換行符,那就必須:
IFS=$'\n'
將這個(gè)語句加入到腳本中微饥,告訴bash shell在數(shù)據(jù)值中忽略空格和制表符。
一個(gè)可參考的安全實(shí)踐是在改變IFS之前保存原來的IFS值欠橘,之后再恢復(fù)它。
實(shí)現(xiàn):
IFS.OLD=$IFS
IFS=$'\n'
<在代碼中使用新的IFS值>
IFS=$IFS.OLD
這就保證了在腳本的后續(xù)操作中使用的是IFS的默認(rèn)值肃续。
遍歷一個(gè)文件中用冒號分隔的值:
IFS=:
如果要指定多個(gè)IFS字符,只要將它們在賦值行串起來就行始锚。
IFS=$'\n':;"
這個(gè)賦值會將換行符刽酱、冒號、分號和雙引號作為字段分隔符棵里。如何使用IFS字符解析數(shù)據(jù)沒有任何限制。
1.6?用通配符讀取目錄
for file in /proc/*;?
do?
echo $file is file path \! ;?
done
2?類C風(fēng)格for循環(huán)的語法格式
for((expr1; expr2; expr3))
do?
? ? command?
? ? command?
? ? ...?
done
有些部分并沒有遵循bash shell標(biāo)準(zhǔn)的for命令:?
*變量賦值可以有空格?
*條件中的變量不以美元符開頭?
*迭代過程的算式為用expr命令格式
#!/bin/bash
#使用類C風(fēng)格for循環(huán)輸出1~5
?for ((integer = 1; integer <= 5; integer++))
?do
? ?echo "$integer"??
done?
結(jié)果:
1
2
3
4
5
使用類C風(fēng)格for循環(huán)要注意以下事項(xiàng):
a.如果循環(huán)條件最初的退出狀態(tài)為非0衍慎,則不會執(zhí)行循環(huán)體
b.當(dāng)執(zhí)行更新語句時(shí),如果循環(huán)條件的退出狀態(tài)永遠(yuǎn)為0皮钠,則for循環(huán)將永遠(yuǎn)執(zhí)行下去稳捆,從而產(chǎn)生死循環(huán)
c.Linux shell中不運(yùn)行使用非整數(shù)類型的數(shù)作為循環(huán)變量
d.如果循環(huán)體中的循環(huán)條件被忽略,則默認(rèn)的退出狀態(tài)為0
e.在類C風(fēng)格的for循環(huán)中麦轰,可以將三個(gè)語句全部忽略掉乔夯,下面是合法的for循環(huán)
for((; ; ))?
do?
? ? echo "hello world"?
done