Chapter 8 Loop
有三种内置循环语句命令for, while, until
for
for var in word1 word2 ... wordn
do
command
command
...
done
for循环中,word[1-n]泪飙会依次赋值给变量var,每次赋值后执行一次do与done之间的语句。
示例:
for i in 1 2 3
do
echo $1
done
输出结果
1
2
3
for中的参数列表支持文件名替代, 所以可以有如下语句
for file in memo[1-4] # 等价于 for file in memo1 memo2 memo3 memo4
do
done
for file in *
do
done
for file in $(cat filelist) # 文件filelist中保存有一些文件名
do
done
在命令文件中接受参数时,$*代表所有参数,所以可以使用for var in $*遍历所有参数
$@
现有如下程序args
for arg in $*
do
echo $arg
done
则在命令行运行args 'a b' c得到的结果为:
a
b
c
这是因为在$*替换为参数时'a b'被拆分成了a b两个参数。这时如果使用"$@"代替$*即可。
如果不加"",则$@和$*没有区别
args
for arg in "$@"
do
echo $arg
done
for without the list
for var
do
command
done
上面的语句等效于
for var in "$@"
do
command
done
while
while [[ condition ]]; do
#statements
done
首先判定condition的exit status,如果为0(true)则执行一次do和done之间的语句。
执行完之后再次判定,直到condition判定为false为止
示例
while [[ "$#" -ne 0 ]]; do
echo "$1"
shift
done
until
until [[ condition ]]; do
#statements
done
与while不同的是,只有当condition返回非0值(false)时才会执行循环体
和while一用,循环体中的内容也可能一次都不会被执行
sleep n # 使程序暂停n秒
more on loops
breaking out of a loop
break
示例
while true; do
cmd=$(getcmd)
if [ "$cmd" = quit]; then
break
else
processcmd "$cmd"
fi
done
如果循环里嵌套着循环,则可以使用break n语句同时跳除n层循环
skipping the remaining commands in a loop
continue
continue n
executing a loop in the background
在done后面添加&即可
I/O redirection on a loop
在done后面使用>运算符可以将循环中的所有结果都导入文件中
如果循环体中某跳语句也使用了>进行输出转换,则其自身的转换会覆盖循环的转换
> /dev/tty可以将结果输出到终端显示> /dev/null不输出结果2> file将standard error输出到文件中1>&2将结果输出到终端,即使它被导向其它文件或通道
piping data into and out of a loop
将循环当成一个整体然后使用|
typing a loop on one line
for i in 1 2 3; do echo $i; done
注意,在do后面时没有;的
同样也可以对if使用;将其写成一行,注意then和else后面不加;
getopts
getopts options variable
该命令常被用与检测在命令行输入的参数。
getopts ab:c variable则表示只接受-a, -b和-c三个配置参数,且-b后需要有一个参数表示其值
while [ getopts mt: option ]; do
case "$option" in
m) command;;
t) var=$OPTARG;;
\?) echo "Usage: waitfor [-m] [-t n] user"
exit 1;;
esac
done
命令行中的输入第一个参数首先进行getopts运算,如果参数以-开头且后跟的字母在options中(这里即为mt),
则将后跟的字母保存在变量option中(变量名随意),并将exit status以0返回。下一次循环时则判定第二个参数
如果-后跟的字母不在options之中,则将?保存在变量option中,并将exit status以0返回
如果参数不是以-开头,则getopts直接返回一个非0的exit status
由于mt:中t后跟了一个:,所以如果getopts检测到参数为-t则其会继续检测该参数后面一个参数,
如果没有或者以-开头,则将?赋值给变量option,并想standard error中输出一条错误;否则将后面跟着的参数
赋值给变量OPTARG
还有一个特殊变量OPTIND,其初始值为1,每次迭代完则自动加1。
所以$OPTIND的值比以-开头的参数个数大1(不包括赋值给OPTARG的参数)。
可以以此来判定除以-开头的参数外还有没有其它参数
