for命令格式:
– list參數:迭代中要用的一系列值
– 每個迭代中,變量var會包含列表中的當前值
– do和done語句之間輸入的命令可以是一條或多條標准的bash shell命令
1
2
3
4
|
for var in list
do
commands
done
|
讀取列表中的值
- for命令最基本的用法就是遍歷for命令自身中定義的一系列值:
- 在最后一次迭代后,$test變量的值會在shell腳本的剩余部分一直保持有效,除非修改它
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
|
$cat test
#!/bin/bash
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're visiting was $test"
$./test
The next state is Alabama
The next state is Alaska
...
The last state we visited was Colorado
wait, now we're visiting Connecticut
|
讀取列表中的復雜值
- 對於單雙引號問題的解決
- 使用轉義字符來將單引號轉義
- 使用雙引號來定義用到單引號的值
1
2
3
4
5
6
7
8
9
10
11
|
$cat test
#!/bin/bash
for test in I don't know if "this'll" work
do
echo "word:$test"
done
$./test
word:I
word:don't
...
|
從變量讀取列表
- 將一些列的值都集中存儲在了一個變量中,然后遍歷整個列表
1
2
3
4
5
6
7
8
9
10
11
12
13
14
|
$cat test
#!/bin/bash
list=“Alabama Alaska Arizona Arkansas California Colorado”
list=$list" Connecticut"
for state in $list
do
echo "Have you ever visited $state?"
done
$./test
Have you ever visited Alabama?
...
Have you ever visited Connecticut?
$
|
從命令讀取值
- 生成列表中要用的值的另外一個途徑就是使用命令的輸出
- 可以使用反引號來執行任何能產生輸出的命令,然后在for命令中使用該命令的輸出
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
|
$cat test
#!/bin/bash
file="states"
for state in `cat $file`
do
echo "Visit beautiful $state"
done
$cat states
Alabama
Alaska
...
$./test
Visit beautiful Alabama
Visit beautiful Alaska
...
|
更改字段分隔符
- 默認情況下,bash shell會將下列字段當做字段分隔符
- 空格
- 制表符
- 換行符
- 可以在shell腳本中臨時更改IFS環境變量的值來限制一下被bash shell當作字段分隔符的字符
- 例如
- 修改IFS值使其只能識別換行符:IFS=$’\n’
- 遍歷一個文件中以冒號分隔的值:IFS=:
- 如果指定多個IFS字符,只要將它們在賦值行串起來就行:IFS=$’\n:;’” (將換行符、冒號、分號和雙引號作為字段分隔符)
- 常用的做法:在改變IFS值之前保存原來的IFS值,之后再回復它
- 例如
1
2
3
4
|
IFS.OLD=$IFS
IFS=$'\n'
<use the new IFS value in code>
IFS=$IFS.OLD
|
用通配符讀取目錄
- for命令可以來自動變里滿是文件的目錄,操作時,必須在文件名或路徑名中使用通配符,它會強制shell使用文件擴展匹配
- 文件擴張匹配:生成匹配指定的通配符的文件或路徑名的過程
1
2
3
4
5
6
7
8
9
10
11
12
13
|
...
for file in /home/rich/test/*
do
if [ -d "$file" ]
then
echo "$file is a directory"
elif [ -f第12章:更多結構化命令
第
6章:理解Linux文件權限.md "$file" ]
then
echo "$file is a file"
fi
done
...
|
- Linux中,目錄名和文件名中包含空格是合法的,要容納這種值,應該將$file變量用雙括號圈起來
- 可以在for命令中通過列出一系列的目錄通配符來將目錄查找的方法和列表方法結合起來
1
2
3
4
5
6
7
8
9
10
11
12
13
|
...
for file in /home/rich/.b* /home/rich/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
|
C語言的for命令
- bash中C語言風格的for循環的基本格式:for (( variable assignment : condition : iteration process ))
- 例如:for (( a = 1; a < 10; a++ ))
- 一些沒有遵循標准的bash shell for命令
- 給變量賦值可以有空格
- 條件中的變量不以美元符開頭
- 迭代過程的算式未用expr命令格式
1
2
3
4
5
6
7
8
9
10
11
|
$cat test
#!/bin/bash
for (( i=0; i<10; i++ ))
do
echo "The next number is $i"
done
$./test
The next number is 1
The next number is 2
...
|
使用多個變量
- C語言風格的for命令允許為迭代使用多個變量
- 循環會獨立處理每個變量,允許為每個變量定義不同的迭代過程
- 當有多個變量時,只能在for循環中定義一個條件
1
2
3
4
5
6
|
...
for (( a=1, b=10; a <= 10; a++, b-- ))
do
echo "$a - $b"
done
...
|
while命令的基本格式
- 格式如下:
- while命令中定義的test命令和if-then中定義是一樣的格式
- while命令的關鍵:指定的test命令的退出狀態碼必須隨着循環中運行的命令改變,否則while會不停循環下去
- 最常用的test命令用法是,用方括號來查看命令中用到的shell變量的值
1
2
3
4
5
6
7
8
9
10
11
12
13
14
|
while test command
do
other commands
done
//eg:
...
var1=10
while [ $var1 -gt 0 ]
do
echo $var1
var1=$[ $var1 - 1 ]
done
...
|
使用多個測試命令
- while命令中允許在while語句行定義多個測試命令,只有最后一個測試命令的退出狀態碼會被用來決定什么時候結束循環
until命令
- until命令和while命令工作方式完全相反
- until命令要求制定一個通常輸出非零退出狀態碼的測試命令
- 只有測試命令的退出狀態碼非零,bash shell才會指定循環中列出的那些命令
- 一旦測試命令返回了退出狀態碼0,循環就結束了
- until命令要求制定一個通常輸出非零退出狀態碼的測試命令
1
2
3
4
|
until test commands
do
other commands
done
|
- 與while命令類似,可以在until命令語句中有多個測試命令,最后一個命令的退出狀態碼決定bash shell是否執行定義好的其他命令
嵌套循環
- 腳本允許使用嵌套循環
循環處理文件數據
- 通常,必須遍歷存儲在文件中的數據,這需要結合兩種技術
- 使用嵌套循環
- 修改IFS環境變量
- 使用環境變量IFS,強制for命令將文件中的每行都當成單獨一個條目,即便數據中有空格也是如此
- 一旦從文件中提取除了單獨的行,可能需要再次循環來提取其中的數據
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
|
$cat test
#!/bin/bash
IFS.OLD=$IFS
IFS=$'\n'
for entry in `cat /etc/passwd`
do
echo "values in $entry -"
IFS=:
for value in $entry
do
echo " $value"
done
done
$./test
Value in rich:x:501:501:Rich Blum:/home/rich:/bin/bash -
rich
x
501
...
/bin/bash
Value in ...
|
控制循環
break命令
- break命令:退出任意類型的循環,包括while和until循環
- 指定跳出外部循環:break n
- n:指定要跳出的循環層級
- 默認情況下,n為1,表明跳出的是當前的循環
- 若為2:break命令就會停止下一級的外部循環
- n:指定要跳出的循環層級
continue命令
- 提早結束執行循環內部的命令但不完全終止整個循環的一個途徑
- continue命令允許使用參數來指定要繼續哪級循環:continue n
- n:要繼續的循環層級
處理循環的輸出
- 在shell腳本中,要么關節要么重定向循環的輸出
- 可以在done命令后面添加一個處理命令:
- shell會將結果重定向到文件output.txt中,而不是顯示在屏幕上
1
2
3
4
5
6
7
8
9
|
for file in /home/rich*
do
if [ -d "$file" ]
then
echo "$file is a directory"
elif
echo "$file is a file"
fi
done > output.txt
|
- 這種方法同樣適用於將循環的結果管接給另一個命令
- 以下例子說明將輸出的結果通過sort命令重新排序輸出
1
2
3
4
5
6
|
...
for ...
...
done | sort
echo "This completes our place to go"
$
|