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
的参数)。
可以以此来判定除以-
开头的参数外还有没有其它参数