1 for命令
bash shell提供了for命令,允許我們創(chuàng)建一個(gè)遍歷一系列值的循環(huán)。每次迭代都使用其中一個(gè)
值來(lái)執(zhí)行已定義好的一組命令。下面是bash shell中for命令的基本格式:
for var in list
do
commands
done
在list參數(shù)中,需要提供迭代中要用到的一系列值??梢酝ㄟ^(guò)幾種不同的方法指定列表中的值。
在每次迭代中,變量var會(huì)包含列表中的當(dāng)前值。第一次迭代會(huì)使用列表中的第一個(gè)值,第
二次迭代使用第二個(gè)值,以此類推,直到列表中的所有值都過(guò)一遍。
在do和done語(yǔ)句之間輸入的命令可以是一條或多條標(biāo)準(zhǔn)的bash shell命令。在這些命令中,$var變量包含著這次迭代對(duì)應(yīng)的當(dāng)前列表項(xiàng)中的值。
也可以這么表示:
for var in list; do
1.1 讀取列表中的值
for test in Alabama Alaska Arizona Arkansas California Colorado; do
echo The next state is $test
done
$ bash test1.sh
The next state is Alabama
The next state is Alaska
The next state is Arizona
The next state is Arkansas
The next state is California
The next state is Colorado
每次for命令遍歷值列表,它都會(huì)將列表中的下個(gè)值賦給$test變量。
test變量可以像for命令語(yǔ)句中的其他腳本變量一樣使用。在最后一次迭代后,$test變量的值會(huì)在shell腳本的剩余部分一直保持有效。
for test in Alabama Alaska Arizona Arkansas California Colorado; do
echo "The next state is $test"
done
echo "The last state we visited was $test"
test=Connecticut
echo "Wait, now we are visiting $test"
$ bash test1.sh
The next state is Alabama
The next state is Alaska
The next state is Arizona
The next state is Arkansas
The next state is California
The next state is Colorado
The last state we visited was Colorado
Wait, now we are visiting Connecticut
$test變量保持了其值,也允許我們修改它的值,并在for命令循環(huán)之外跟其他變量一樣使用。
1.2 讀取列表中的復(fù)雜值
有兩種辦法可解決這個(gè)問(wèn)題:
? 使用轉(zhuǎn)義字符(反斜線)來(lái)將單引號(hào)轉(zhuǎn)義;
? 使用雙引號(hào)來(lái)定義用到單引號(hào)的值。
for test in I don\'t know if "this'll" work; do
echo "word:$test"
done
$ bash test2.sh
word:I
word:don't
word:know
word:if
word:this'll
word:work
在第一個(gè)有問(wèn)題的地方添加了反斜線字符來(lái)轉(zhuǎn)義don't中的單引號(hào)。在第二個(gè)有問(wèn)題的地方
將this'll用雙引號(hào)圈起來(lái)。兩種方法都能正常辨別出這個(gè)值。
可能遇到的另一個(gè)問(wèn)題是有多個(gè)詞的值。記住,for循環(huán)假定每個(gè)值都是用空格分割的。
for命令用空格來(lái)劃分列表中的每個(gè)值。如果在單獨(dú)的數(shù)據(jù)值中有空格,就必須用雙引號(hào)將這些值圈起來(lái):
for test in Nevada "New Hampshire" "New Mexico" "New York"; do
echo "Now going to $test"
done
Now going to Nevada
Now going to New Hampshire
Now going to New Mexico
Now going to New York
1.3 從變量讀取列表
通常shell腳本遇到的情況是,你將一系列值都集中存儲(chǔ)在了一個(gè)變量中,然后需要遍歷變量
中的整個(gè)列表。也可以通過(guò)for命令完成這個(gè)任務(wù)。
list="Alabama Alaska Arizona Arkansas Colorado"
list=$list" Connecticut"
for state in $list; do
echo "Have you ever visited $state?"
done
Have you ever visited Alabama?
Have you ever visited Alaska?
Have you ever visited Arizona?
Have you ever visited Arkansas?
Have you ever visited Colorado?
Have you ever visited Connecticut?
list變量包含了用于迭代的標(biāo)準(zhǔn)文本值列表。注意,代碼還是用了另一個(gè)賦值語(yǔ)句向$list變量包含的已有列表中添加(或者說(shuō)是拼接)了一個(gè)值。
這是向變量中存儲(chǔ)的已有文本字符串尾部添加文本的一個(gè)常用方法。
1.4 從命令讀取值
生成列表中所需值的另外一個(gè)途徑就是使用命令的輸出??梢杂妹钐鎿Q來(lái)執(zhí)行任何能產(chǎn)生
輸出的命令,然后在for命令中使用該命令的輸出。
file="states"
for state in $(cat $file); do
echo "Visit beautiful $state"
done
$ cat states
Alabama
Alaska
Arizona
Arkansas
Colorado
Connecticut
Delaware
Florida
Georgia
$ bash test1.sh
Visit beautiful Alabama
Visit beautiful Alaska
Visit beautiful Arizona
Visit beautiful Arkansas
Visit beautiful Colorado
Visit beautiful Connecticut
Visit beautiful Delaware
Visit beautiful Florida
Visit beautiful Georgia
這個(gè)例子在命令替換中使用了cat命令來(lái)輸出文件states的內(nèi)容。
我們會(huì)注意到states文件中每一行有一個(gè)州,而不是通過(guò)空格分隔的。for命令仍然以每次一行的方式遍歷了cat命令的輸出,假定每個(gè)州都是在單獨(dú)的一行上。
1.5 更改字段分隔符
默認(rèn)情況下,bash shell會(huì)將下列字符當(dāng)作字段分隔符:
? 空格
? 制表符
? 換行符
例如,如果我們想修改IFS的值,使其只能識(shí)別換行符,那就必須這么做:
IFS=$'\n'
將這個(gè)語(yǔ)句加入到腳本中,告訴bash shell在數(shù)據(jù)值中忽略空格和制表符。對(duì)前一個(gè)腳本使用
這種方法,將獲得如下輸出。
file="states"
IFS=$'\n'
for state in $(cat $file); do
echo "Visit beautiful $state"
done
$ bash test1.sh
Visit beautiful Alabama
Visit beautiful Alaska
Visit beautiful Arizona
Visit beautiful Arkansas
Visit beautiful Colorado
Visit beautiful Connecticut
Visit beautiful Delaware
Visit beautiful Florida
Visit beautiful Georgia
Visit beautiful New York
Visit beautiful New Hampshire
Visit beautiful Carolina
現(xiàn)在,shell腳本舊能夠使用列表中含有空格的值了。
注意
在處理代碼量較大的腳本時(shí),可能在一個(gè)地方需要修改IFS的值,然后忽略這次修改,在腳本的其他地方繼續(xù)沿用IFS的默認(rèn)值。一個(gè)可參考的安全實(shí)踐是在改變IFS之前保存原來(lái)的IFS值,之后再恢復(fù)它。
這種技術(shù)可以這樣實(shí)現(xiàn):
IFS.OLD=$IFS
IFS=$'\n'
<在代碼中使用新的IFS值>
IFS=$IFS.OLD
這就保證了在腳本的后續(xù)操作中使用的是IFS的默認(rèn)值。
假定我們要遍歷一個(gè)文件中用冒號(hào)分隔的值(比如在/etc/passwd文件中)。我們要做的就是將IFS的值設(shè)為冒號(hào)。
IFS=:
如果要指定多個(gè)IFS字符,只要將它們?cè)谫x值行串起來(lái)就行。
IFS=$'\n':;"
這個(gè)賦值會(huì)將換行符、冒號(hào)、分號(hào)和雙引號(hào)作為字段分隔符。
1.6 用通配符讀取目錄
最后,可以用for命令來(lái)自動(dòng)遍歷目錄中的文件。
for file in /home/kaoku/data/*; do
if [ -d "$file" ]
then
echo "$file is a directory"
elif [ -f "$file" ]
then
echo "$file is a file"
fi
done
for命令會(huì)遍歷/home/kaoku/data/*輸出的結(jié)果。
該代碼用test命令測(cè)試了每個(gè)條目(使用方括號(hào)方法),以查看它是目錄(通過(guò)-d參數(shù))還是文件(通過(guò)-f參數(shù))。
也可以在for命令中列出多個(gè)目錄通配符,將目錄查找和列表合并進(jìn)同一個(gè)for語(yǔ)句。
for file in /home/kaoku/data/.b* /home/kaoku/badtest; do
if [ -d "$file" ]
then
echo "$file is a directory"
elif [ -f "$file" ]
then
echo "$file is a file"
else
echo "$file doesn't exist"
fi
done
for語(yǔ)句首先使用了文件擴(kuò)展匹配來(lái)遍歷通配符生成的文件列表,然后它會(huì)遍歷列表中的下
一個(gè)文件??梢詫⑷我舛嗟耐ㄅ浞胚M(jìn)列表中。
補(bǔ)充:循環(huán) for
for i in a.txt b.txt; do
for i in 'ls data/*.txt'; do 匹配某類文件作為輸入
for i in 'cat list.txt'; do 使用文本為輸入列表
for i in 'cat list.txt|cut -f 1'; do 指定某列作為輸入文件名
plot_heatmap.sh -i data/${i} -o heatmap/${i}.pdf
done
1.7 C 語(yǔ)言風(fēng)格的for 命令
for (i = 0; i < 10; i++)
{
printf("The next number is %d\n", i);
}
for (( i=1; i <= 10; i++ ))
do
echo "The next number is $i"
done
The next number is 1
The next number is 2
The next number is 3
The next number is 4
The next number is 5
The next number is 6
The next number is 7
The next number is 8
The next number is 9
The next number is 10
for (( a=1, b=10; a <= 10; a++, b-- ))
do
echo "$a - $b"
done
1 - 10
2 - 9
3 - 8
4 - 7
5 - 6
6 - 5
7 - 4
8 - 3
9 - 2
10 - 1
2 while命令
while命令某種意義上是if-then語(yǔ)句和for循環(huán)的混雜體。
while命令允許定義一個(gè)要測(cè)試的命令,然后循環(huán)執(zhí)行一組命令,只要定義的測(cè)試命令返回的是退出狀態(tài)碼0。它會(huì)在每次迭代的一開(kāi)始測(cè)試test命令。在test命令返回非零退出狀態(tài)碼時(shí),while命令會(huì)停止執(zhí)行那組命令。
2.1 while的基本格式
while命令的格式是:
while test command
do
other commands
done
while命令的關(guān)鍵在于所指定的test command的退出狀態(tài)碼必須隨著循環(huán)中運(yùn)行的命令而改變。如果退出狀態(tài)碼不發(fā)生變化, while循環(huán)就將一直不停地進(jìn)行下去。
最常見(jiàn)的test command的用法是用方括號(hào)來(lái)檢查循環(huán)命令中用到的shell變量的值。
var1=10
while [ $var1 -gt 0 ];do
echo $var1
var1=$[ $var1 -1 ]
done
$ bash test1.sh
10
9
8
7
6
5
4
3
2
1
while命令定義了每次迭代時(shí)檢查的測(cè)試條件:
while [ $var1 -gt 0 ]
只要測(cè)試條件成立,while命令就會(huì)不停地循環(huán)執(zhí)行定義好的命令。在這些命令中,測(cè)試條件中用到的變量必須修改,否則就會(huì)陷入無(wú)限循環(huán)。在本例中,我們用shell算術(shù)來(lái)將變量值減一:
var1=$[ $var1 - 1 ]
while循環(huán)會(huì)在測(cè)試條件不再成立時(shí)停止。
2.2 使用多個(gè)測(cè)試命令
while命令允許我們?cè)趙hile語(yǔ)句行定義多個(gè)測(cè)試命令。只有最后一個(gè)測(cè)試命令的退出狀態(tài)碼
會(huì)被用來(lái)決定什么時(shí)候結(jié)束循環(huán)。
var1=10
while echo $var1
[ $var1 -ge 0 ];do
echo "This is inside the loop"
var1=$[ $var1 - 1 ]
done
10
This is inside the loop
9
This is inside the loop
8This is inside the loop
7
This is inside the loop
6
This is inside the loop
5
This is inside the loop
4
This is inside the loop
3
This is inside the loop
2
This is inside the loop
1
This is inside the loop
0
This is inside the loop
-1
while語(yǔ)句中定義了兩個(gè)測(cè)試命令。
while echo $var1
[ $var1 -ge 0 ]
第一個(gè)測(cè)試簡(jiǎn)單地顯示了var1變量的當(dāng)前值。第二個(gè)測(cè)試用方括號(hào)來(lái)判斷var1變量的值。在循環(huán)內(nèi)部,echo語(yǔ)句會(huì)顯示一條簡(jiǎn)單的消息,說(shuō)明循環(huán)被執(zhí)行了。
注意當(dāng)運(yùn)行本例時(shí)輸出是如何結(jié)束的。
This is inside the loop
-1
while循環(huán)會(huì)在var1變量等于0時(shí)執(zhí)行echo語(yǔ)句,然后將var1變量的值減一。接下來(lái)再次執(zhí)行測(cè)試命令,用于下一次迭代。echo測(cè)試命令被執(zhí)行并顯示了var變量的值(現(xiàn)在小于0了)。直到shell執(zhí)行test測(cè)試命令,whle循環(huán)才會(huì)停止。
3 until命令
until命令和while命令工作的方式完全相反。
until命令要求指定一個(gè)通常返回非零退出狀態(tài)碼的測(cè)試命令。只有測(cè)試命令的退出狀態(tài)碼不為0,bash shell才會(huì)執(zhí)行循環(huán)中列出的命令。一旦測(cè)試命令返回了退出狀態(tài)碼0,循環(huán)就結(jié)束了。
until命令的格式:
until test commands; do
other commands
done
和while命令類似,我們可以在until命令語(yǔ)句中放入多個(gè)測(cè)試命令。只有最后一個(gè)命令的退
出狀態(tài)碼決定了bash shell是否執(zhí)行已定義的other commands。
var1=100
until [ $var1 -eq 0 ]; do
echo $var1
var1=$[ $var1 -25 ]
done
100
75
50
25
本例中會(huì)測(cè)試var1變量來(lái)決定until循環(huán)何時(shí)停止。只要該變量的值等于0,until命令就會(huì)停止循環(huán)。
var1=100
until echo $var1
[ $var1 -eq 0 ]; do
echo Inside the loop: $var1
var1=$[ $var1 -25 ]
done
$ bash test1.sh
100
Inside the loop: 100
75
Inside the loop: 75
50
Inside the loop: 50
25
Inside the loop: 25
0
shell會(huì)執(zhí)行指定的多個(gè)測(cè)試命令,只有在最后一個(gè)命令成立時(shí)停止。
4 嵌套循環(huán)
這里有個(gè)在for循環(huán)中嵌套for循環(huán)的簡(jiǎn)單例子。
for (( a=1; a<=3; a++ )); do
echo "Starting loop $a:"
for (( b=1; b<=3; b++ )); do
echo " Inside loop:$b"
done
done
$ bash test1.sh
Starting loop 1:
Inside loop:1
Inside loop:2
Inside loop:3
Starting loop 2:
Inside loop:1
Inside loop:2
Inside loop:3
Starting loop 3:
Inside loop:1
Inside loop:2
Inside loop:3
這個(gè)被嵌套的循環(huán)(也稱為內(nèi)部循環(huán),inner loop)會(huì)在外部循環(huán)的每次迭代中遍歷一次它所
有的值。注意,兩個(gè)循環(huán)的do和done命令沒(méi)有任何差別。bash shell知道當(dāng)?shù)谝粋€(gè)done命令執(zhí)行時(shí)是指內(nèi)部循環(huán)而非外部循環(huán)。
var1=5
while [ $var1 -ge 0 ]; do
echo "Out loop: $var1"
for (( var2=1; $var2<3; var2++ ));do
var3=$[ $var1*$var2 ]
echo " Inner loop: $var1 * $var2 = $var3"
done
var1=$[ $var1-1 ]
done
$ bash test1.sh
Out loop: 5
Inner loop: 5 * 1 = 5
Inner loop: 5 * 2 = 10
Out loop: 4
Inner loop: 4 * 1 = 4
Inner loop: 4 * 2 = 8
Out loop: 3
Inner loop: 3 * 1 = 3
Inner loop: 3 * 2 = 6
Out loop: 2
Inner loop: 2 * 1 = 2
Inner loop: 2 * 2 = 4
Out loop: 1
Inner loop: 1 * 1 = 1
Inner loop: 1 * 2 = 2
Out loop: 0
Inner loop: 0 * 1 = 0
Inner loop: 0 * 2 = 0
同樣,shell能夠區(qū)分開(kāi)內(nèi)部for循環(huán)和外部while循環(huán)各自的do和done命令。
5 循環(huán)處理文件數(shù)據(jù)
通常必須遍歷存儲(chǔ)在文件中的數(shù)據(jù)。這要求結(jié)合已經(jīng)講過(guò)的兩種技術(shù):
? 使用嵌套循環(huán)
? 修改IFS環(huán)境變量
通過(guò)修改IFS環(huán)境變量,就能強(qiáng)制for命令將文件中的每行都當(dāng)成單獨(dú)的一個(gè)條目來(lái)處理,即便數(shù)據(jù)中有空格也是如此。一旦從文件中提取出了單獨(dú)的行,可能需要再次利用循環(huán)來(lái)提取行中的數(shù)據(jù)。
典型的例子是處理/etc/passwd文件中的數(shù)據(jù)。這要求我們逐行遍歷/etc/passwd文件,并將IFS變量的值改成冒號(hào),這樣就能分隔開(kāi)每行中的各個(gè)數(shù)據(jù)段了。
IFS.OLD=$IFS
IFS=$'\n'
for entry in $(cat /etc/passwd); do
echo "Value in $entry -"
IFS=:
for value in $entry; do
echo " $value"
done
done
這個(gè)腳本使用了兩個(gè)不同的IFS值來(lái)解析數(shù)據(jù)。
第一個(gè)IFS值解析出/etc/passwd文件中的單獨(dú)的行。內(nèi)部for循環(huán)接著將IFS的值修改為冒號(hào),允許我們從/etc/passwd的行中解析出單獨(dú)的值。
內(nèi)部循環(huán)會(huì)解析出/etc/passwd每行中的各個(gè)值。
6 控制循環(huán)
有兩個(gè)命令能幫我們控制循環(huán)內(nèi)部的情況:
? break命令
? continue命令
6.1 break命令
break命令是退出循環(huán)的一個(gè)簡(jiǎn)單方法??梢杂胋reak命令來(lái)退出任意類型的循環(huán),包括while和until循環(huán)。
1跳出單個(gè)循環(huán)
for var1 in 1 2 3 4 5 6 7 8 9 10; do
if [ $var1 -eq 5 ]
then
break
fi
echo "Interation number: $var1"
done
echo "The for loop is completed"
$ bash test1.sh
Interation number: 1
Interation number: 2
Interation number: 3
Interation number: 4
The for loop is completed
for循環(huán)通常都會(huì)遍歷列表中指定的所有值。但當(dāng)滿足if-then的條件時(shí),shell會(huì)執(zhí)行break命令,停止for循環(huán)。
這種方法同樣適用于while和until循環(huán)。
var1=1
while[ $var1 -lt 10 ]; do
if [ $var1 -eq 5 ]
then
break
fi
echo "Interation:$var1"
var1=$[ $var1+1 ]
done
echo "The while loop is completed"
Iteration: 1
Iteration: 2
Iteration: 3
Iteration: 4
The while loop is completed
while循環(huán)會(huì)在if-then的條件滿足時(shí)執(zhí)行break命令,終止。
2跳出內(nèi)部循環(huán)
在處理多個(gè)循環(huán)時(shí),break命令會(huì)自動(dòng)終止我們所在的最內(nèi)層的循環(huán)。
for (( a=1; a<4; a++ )); do
echo "Outer loop:$a"
for (( b=1; b<100; b++ )); do
if [ $b -eq 5 ]
then
break
fi
echo " Inner loop: $b"
done
done
Outer loop: 1
Inner loop: 1
Inner loop: 2
Inner loop: 3
Inner loop: 4
Outer loop: 2
Inner loop: 1
Inner loop: 2
Inner loop: 3
Inner loop: 4
Outer loop: 3
Inner loop: 1
Inner loop: 2
Inner loop: 3
Inner loop: 4
內(nèi)部循環(huán)里的for語(yǔ)句指明當(dāng)變量b等于100時(shí)停止迭代。但內(nèi)部循環(huán)的if-then語(yǔ)句指明當(dāng)變量b的值等于5時(shí)執(zhí)行break命令。
注意,即使內(nèi)部循環(huán)通過(guò)break命令終止了,外部循環(huán)依然繼續(xù)執(zhí)行。
3跳出外部循環(huán)
break命令接受單個(gè)命令行參數(shù)值:
break n
其中n指定了要跳出的循環(huán)層級(jí)。默認(rèn)情況下,n為1,表明跳出的是當(dāng)前的循環(huán)。如果將n設(shè)為2,break命令就會(huì)停止下一級(jí)的外部循環(huán)。
for (( a=1; a<4; a++ )); do
echo "Outer loop:$a"
for (( b=1; b<100; b++ )); do
if [ $b -gt 4]
then
break2
fi
echo " Inner loop:$b"
done
done
Outer loop: 1
Inner loop: 1
Inner loop: 2
Inner loop: 3
Inner loop: 4
當(dāng)shell執(zhí)行了break命令后,外部循環(huán)就停止了。
6.2 continue命令
continue命令可以提前中止某次循環(huán)中的命令,但并不會(huì)完全終止整個(gè)循環(huán)??梢栽谘h(huán)內(nèi)部設(shè)置shell不執(zhí)行命令的條件。
for (( var1=1; var1 < 15; var1++ )); do
if [ $var1 -gt 5 ] && [ $var1 -lt 10 ]
then
continue
fi
echo "Interation number:$var1"
done
$ bash test1.sh
Interation number:1
Interation number:2
Interation number:3
Interation number:4
Interation number:5
Interation number:10
Interation number:11
Interation number:12
Interation number:13
Interation number:14
當(dāng)if-then語(yǔ)句的條件被滿足時(shí)(值大于5且小于10),shell會(huì)執(zhí)行continue命令,跳過(guò)此
次循環(huán)中剩余的命令,但整個(gè)循環(huán)還會(huì)繼續(xù)。當(dāng)if-then的條件不再被滿足時(shí),一切又回到正軌。
也可以在while和until循環(huán)中使用continue命令,但要特別小心,當(dāng)shell執(zhí)行continue命令時(shí),它會(huì)跳過(guò)剩余的命令。
和break命令一樣,continue命令也允許通過(guò)命令行參數(shù)指定要繼續(xù)執(zhí)行哪一級(jí)循環(huán):
continue n
其中n定義了要繼續(xù)的循環(huán)層級(jí)。
for (( a=1; a<=5; a++ )); do
echo "Iteration $a:"
for (( b=1; b<3; b++ )); do
if [ $a -gt 2 ] && [ $a -lt 4 ]
then
continue 2
fi
var3=$[ $a * $b ]
echo " The result of $a * $b is $var3"
done
done
$ bash test1.sh
Iteration 1:
The result of 1 * 1 is 1
The result of 1 * 2 is 2
Iteration 2:
The result of 2 * 1 is 2
The result of 2 * 2 is 4
Iteration 3:
Iteration 4:
The result of 4 * 1 is 4
The result of 4 * 2 is 8
Iteration 5:
The result of 5 * 1 is 5
The result of 5 * 2 is 10
其中的if-then語(yǔ)句:
if [ $a -gt 2 ] && [ $a -lt 4 ]
then
continue 2
fi
此處用continue命令來(lái)停止處理循環(huán)內(nèi)的命令,但會(huì)繼續(xù)處理外部循環(huán)。注意,值為3的那次迭代并沒(méi)有處理任何內(nèi)部循環(huán)語(yǔ)句,因?yàn)楸M管continue命令停止了處理過(guò)程,但外部循環(huán)依然會(huì)繼續(xù)。
7 處理循環(huán)的輸出
最后,在shell腳本中,我們可以對(duì)循環(huán)的輸出使用管道或進(jìn)行重定向。
這可以通過(guò)在done命令之后添加一個(gè)處理命令來(lái)實(shí)現(xiàn)。
for file in /home/kaoku/*; do
if [ -d "$file" ]
then
echo "$file is a directory"
elif
echo "$file is a file"
fi
done > output.txt
shell會(huì)將for命令的結(jié)果重定向到文件output.txt中,而不是顯示在屏幕上。
for (( a = 1; a < 10; a++ )); do
echo "The number is $a"
done > test23.txt
echo "The command is finished."
The command is finished.
$ cat test23.txt
The number is 1
The number is 2
The number is 3
The number is 4
The number is 5
The number is 6
The number is 7
The number is 8
The number is 9
shell創(chuàng)建了文件test23.txt并將for命令的輸出重定向到這個(gè)文件。shell在for命令之后正常顯示了echo語(yǔ)句。
這種方法同樣適用于將循環(huán)的結(jié)果管接給另一個(gè)命令。
for state in "North Dakota" Connecticut Illinois Alabama Tennessee; do
echo "$state is the next place to go"
done | sort
echo "This completes our travels"
Alabama is the next place to go
Connecticut is the next place to go
Illinois is the next place to go
North Dakota is the next place to go
Tennessee is the next place to go
This completes our travels
state值并沒(méi)有在for命令列表中以特定次序列出。for命令的輸出傳給了sort命令,該命令會(huì)改變for命令輸出結(jié)果的順序。
8 實(shí)例
8.1 查找可執(zhí)行文件
當(dāng)我們從命令行中運(yùn)行一個(gè)程序的時(shí)候,Linux系統(tǒng)會(huì)搜索一系列目錄來(lái)查找對(duì)應(yīng)的文件。
這些目錄被定義在環(huán)境變量PATH中。如果想找出系統(tǒng)中有哪些可執(zhí)行文件可供使用,只需要掃描PATH環(huán)境變量中所有的目錄就行了。
首先是創(chuàng)建一個(gè)for循環(huán),對(duì)環(huán)境變量PATH中的目錄進(jìn)行迭代。處理的時(shí)候別忘了設(shè)置IFS分隔符。
IFS=:
for folder in $PATH; do
現(xiàn)在我們已經(jīng)將各個(gè)目錄存放在了變量$folder中,可以使用另一個(gè)for循環(huán)來(lái)迭代特定目錄中的所有文件。
for file in $folder/*; do
最后一步是檢查各個(gè)文件是否具有可執(zhí)行權(quán)限,可以使用if-then測(cè)試功能來(lái)實(shí)現(xiàn)。
if [ -x $file ]
then
echo " $file"
fi
好了,搞定了!將這些代碼片段組合成腳本就行了。
IFS=:
for folder in $PATH; do
echo "$folder:"
for file in $folder/*; do
if [ -x $file ]
then
echo " $file"
fi
done
done
$ bash test1.sh | head
/root/miniconda3/condabin:
/root/miniconda3/condabin/conda
/root/miniconda3/condabin/mamba
/usr/local/sbin:
/usr/local/bin:
/usr/sbin:
/usr/sbin/aa-remove-unknown
/usr/sbin/aa-status
/usr/sbin/aa-teardown
/usr/sbin/accessdb
運(yùn)行這段代碼時(shí),我們會(huì)得到一個(gè)可以在命令行中使用的可執(zhí)行文件的列表。
以上就是結(jié)構(gòu)化命令的知識(shí)補(bǔ)充,讓我們繼續(xù)Linux實(shí)戰(zhàn)處理學(xué)習(xí)吧。
我們下一篇再見(jiàn)!