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
結果:
The next state is apple
The next state is boy
The next state is cat
The next state is dog
1.2 讀取列表中的復雜值
有兩種解決辦法:
#使用轉(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
結果是:
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命令用空格來劃分列表中的每個值。如果在單獨的數(shù)據(jù)值中有空格,就必須用雙引號將這些值圈起來。
1.3 從變量讀取列表
將一系列的值都集中存儲在一個變量中,然后需要遍歷變量中的整個列表。
#!/bin/bash
list="helllo world"
#向已有列表中添加或拼接一個值
list=$list" ok"
for state in $list
do
? echo "this word? is $state"
done
結果是:
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
輸出結果:
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默認輸出當前登錄的所有用戶的信息如下所示
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?更改字段分隔符
造成這個問題的原因是特殊的環(huán)境變量IFS,叫作內(nèi)部字段分隔符。默認情況下,bash shell會將下列字符當作字段分隔符:
*空格
*制表符
*換行符
如果bash shell在數(shù)據(jù)中看到這些字符中的任意一個,它就會假定這表明了列表中一個新數(shù)據(jù)字段的開始。
想修改IFS的值,使其只能識別換行符,那就必須:
IFS=$'\n'
將這個語句加入到腳本中,告訴bash shell在數(shù)據(jù)值中忽略空格和制表符。
一個可參考的安全實踐是在改變IFS之前保存原來的IFS值,之后再恢復它。
實現(xiàn):
IFS.OLD=$IFS
IFS=$'\n'
<在代碼中使用新的IFS值>
IFS=$IFS.OLD
這就保證了在腳本的后續(xù)操作中使用的是IFS的默認值。
遍歷一個文件中用冒號分隔的值:
IFS=:
如果要指定多個IFS字符,只要將它們在賦值行串起來就行。
IFS=$'\n':;"
這個賦值會將換行符、冒號、分號和雙引號作為字段分隔符。如何使用IFS字符解析數(shù)據(jù)沒有任何限制。
1.6?用通配符讀取目錄
for file in /proc/*;?
do?
echo $file is file path \! ;?
done
2?類C風格for循環(huán)的語法格式
for((expr1; expr2; expr3))
do?
? ? command?
? ? command?
? ? ...?
done
有些部分并沒有遵循bash shell標準的for命令:?
*變量賦值可以有空格?
*條件中的變量不以美元符開頭?
*迭代過程的算式為用expr命令格式
#!/bin/bash
#使用類C風格for循環(huán)輸出1~5
?for ((integer = 1; integer <= 5; integer++))
?do
? ?echo "$integer"??
done?
結果:
1
2
3
4
5
使用類C風格for循環(huán)要注意以下事項:
a.如果循環(huán)條件最初的退出狀態(tài)為非0,則不會執(zhí)行循環(huán)體
b.當執(zhí)行更新語句時,如果循環(huán)條件的退出狀態(tài)永遠為0,則for循環(huán)將永遠執(zhí)行下去,從而產(chǎn)生死循環(huán)
c.Linux shell中不運行使用非整數(shù)類型的數(shù)作為循環(huán)變量
d.如果循環(huán)體中的循環(huán)條件被忽略,則默認的退出狀態(tài)為0
e.在類C風格的for循環(huán)中,可以將三個語句全部忽略掉,下面是合法的for循環(huán)
for((; ; ))?
do?
? ? echo "hello world"?
done