Bash 的 for 复合命令 (compound command) 可以用于循环执行指定的语句。
该命令有两种不同的格式,查看 man bash 里面对 for 命令的说明,分别描述如下。
for name [ [ in [ word ... ] ] ; ] do list ; done
for name [ [ in [ word ... ] ] ; ] do list ; done
The list of words following in is expanded, generating a list of items. The variable name is set to each element of this list in turn, and list is executed each time.
If the in word is omitted, the for command executes list once for each positional parameter that is set. The return status is the exit status of the last command that executes.
If the expansion of the items following in results in an empty list, no commands are executed, and the return status is 0.
这种格式的 for 命令先扩展 word 列表,得到一个数组,然后把 name 变量依次赋值为 word 列表的每一个元素,每次赋值都执行 list 指定的语句。
如果没有提供 word 列表,则遍历传入脚本、或者传入函数的参数列表。
假设有一个 testfor_each.sh 脚本,内容如下:
#!/bin/bash
for word in This is a sample of "for."; do
echo -n "$word " | tr a-z A-Z
done
echo
for param; do
echo -n "$param " | tr A-Z a-z
done
echo
这个脚本先使用 for 命令遍历 This is a sample of "for." 这个字符串的每一个单词,然后打印单词内容,用 tr 命令把小写字母转换为大写字母。
之后,继续使用 for 命令遍历执行脚本时的参数列表,打印参数值,并把大写字母转换为小写字母。
for param 语句没有提供 in word 参数,默认会遍历传入脚本的位置参数(positional parameters)。
执行 testfor_each.sh 脚本,结果如下:
$ ./testfor_each.sh TEST "FOR" COMMAND WITH POSITIONAL PARAMETER
THIS IS A SAMPLE OF FOR.
test "for" command with positional parameter
对这个执行结果有个地方需要注意,在 This is a sample of "for." 这个字符串中,用双引号把 for. 括起来,但是打印出来的结果没有带双引号,这是因为 bash 在解析的时候,会去掉双引号。
这里的双引号并不是字符串自身的内容,只是用于限定双引号内部的字符串是一个整体。
如果想要打印出双引号,需要用 " 来进行转义,如上面的 "FOR",打印结果包含了双引号。
for (( expr1 ; expr2 ; expr3 )) ; do list ; done
for (( expr1 ; expr2 ; expr3 )) ; do list ; done
First, the arithmetic expression expr1 is evaluated according to the rules described below under ARITHMETIC EVALUATION.
The arithmetic expression expr2 is then evaluated repeatedly until it evaluates to zero.
Each time expr2 evaluates to a non-zero value, list is executed and the arithmetic expression expr3 is evaluated.
If any expression is omitted, it behaves as if it evaluates to 1.
The return value is the exit status of the last command in list that is executed, or false if any of the expres‐sions is invalid.
注意:这种格式的 for 命令里面,expr1、expr2、expr3 都是算术表达式,要使用 bash 算术表达式的写法,具体写法可以查看 man bash 里面的 "ARITHMETIC EVALUATION" 小节和 "((expression))" 表达式的说明。
假设有一个 testfor_expr.sh 脚本,内容如下:
#!/bin/bash
declare count
declare count_str
MAX=10
for ((i = 0; i < MAX; ++i)); do
((count+=$i))
count_str+=$i
done
echo "count = $count"
echo "count_str = $count_str"
执行该脚本的结果如下:
$ ./testfor_expr.sh
count = 45
count_str = 0123456789
可以看到,要使用 ((count+=$i)) 这种写法才是进行算术运算,count 变量值才会像整数一样进行加减。
写为 count_str+=$i 的形式,其实是进行字符串拼接。
在上面的两个小括号里面引用 MAX 变量值时没有加 $ 符号,这是允许的。当然,写成 $MAX 也可以。
如果要提前跳出循环,可以使用 break 命令。查看 man bash 对 break 命令说明如下:
break [n]
Exit from within a for, while, until, or select loop. If n is specified, break n levels. n must be ≥ 1. If n is greater than the number of enclosing loops, all enclosing loops are exited.
The return value is 0 unless n is not greater than or equal to 1.
即,break 命令可以跳出 for 循环、while 循环、until 循环、和 select 循环。