shell脚本编程系列
循环是编程不可或缺的一部分。bash shell提供了三种循环命令。
for命令允许遍历一系列的值,无论是在命令行中提供的,还是包含在变量中的,或是通过文件名通配符匹配获得的文件名和目录名。
for var in list
do
commands
done
或
for (( variable assignment ; condition ; iteration processs ))
do
commands
done
while命令提供了基于命令(使用普通命令或test命令)的循环方式。只有在命令(或条件)产生退出状态码0时,while循环才会继续迭代指定的一组命令。
while test command
do
other commands
done
until命令提供了迭代命令的另一种方式,但它的迭代建立在命令(或条件)产生非0退出状态码的基础上。这个特性允许你设置一个迭代结束前都必须满足的条件。
until test commands
do
other commands
done
可以在shell脚本中组合多种循环方式,生成多层循环。bash shell提供了continue命令和break命令,允许根据虚幻内的不同值改变循环的正常流程。
#!/bin/bash
# using until and while loops
var1=3
until [ $var1 -eq 0 ]
do
echo "Outer loop: $var1"
var2=1
while [ $var2 -lt 5 ]
do
var3=$(echo "scale=4; $var1 / $var2" | bc)
echo " Inner loop: $var1 / $var2 = $var3"
var2=$[ $var2 + 1 ]
done
var1=$[ $var1 - 1 ]
done
bash shell还允许使用标准的命令重定向和管道来改变循环的输出,你可以将循环的输出重定向至文件或是通过管道将循环的输出传给另一个命令。也可以通过输入重定向读取文件的内容。
当在命令行执行程序的时候,Linux系统会搜索一系列目录来查找对应的文件。这些目录都是在环境变量PATH当中定义的,如果想找出哪些可执行文件可以使用,只需扫描PATH环境变量中的所有目录。
首先通过IFS修改环境分隔符,然后对环境变量PATH参数进行迭代,参数值会根据分隔符拆分,将值作为列表传给for命令进行循环。
在遍历每一个PATH路径时,在后面添加通配符用于迭代该目录中的所有文件。并判断该文件是否可执行而且是文件(非目录)。最后的脚本内容如下所示
#!/bin/bash
# finding files in the PATH
IFS=:
for folder in $PATH
do
echo "$folder:"
for file in $folder/*
do
if [ -x $file ] && [ -f $file ]
then
echo " $file"
fi
done
done
shell脚本的目标是减轻系统管理员的工作负担,如果要创建一堆的用户账号,通过while循环可以降低工作的难度。可以考虑将用户账号放到一个文本当中,根据指定的格式输入要创建的账户。比如格式为loginname,name。那么此时读取文件中的数据,使用while循环如下所示
while IFS=',' read -r userid name
这里while使用了多个命令,第一个用于修改分隔符,第二个用于根据指定的格式读取文件。最后是否退出只会看最后一个命令的退出状态码,也就是read命令,而这个read命令在读取完整个文件后返回非0退出状态码(代表错误)。
另外要想把数据从文件中传入while命令,只需要在while命令尾部使用一个重定向符即可。
#!/bin/bash
# process new user accounts
input="users.csv"
while IFS=',' read -r userid name
do
echo "adding $userid"
useradd -c "$name" -m $userid
done < "$input"