跳转到内容

Bash Shell 脚本/循环

来自维基教科书,开放的书,开放的世界

通常我们希望反复运行相同的命令序列,但略有不同。例如,假设我们要将所有名为 *.txt 的文件重命名为 *.txt.bak(“备份”)。我们可以使用文件扩展获取名为 *.txt 的文件列表,但如何使用该列表?没有明显的命令包含,例如 'foo.txt' 'bar.txt' 'baz.txt',可以执行我们需要的三个移动操作。我们需要的是一个 for 循环

for file in *.txt ; do
  mv "$file" "$file.bak"
done

上面的代码将变量 file 分配给 *.txt 展开后的每个单词。每次运行循环体。换句话说,它等效于以下代码

file='foo.txt'
mv "$file" "$file.bak"
file='bar.txt'
mv "$file" "$file.bak"
file='baz.txt'
mv "$file" "$file.bak"

这里没有关于文件名扩展的特殊之处;我们可以使用相同的方法迭代任何其他参数列表,例如 1 到 20 的整数(使用花括号扩展)

for i in {1..20} ; do
  echo "$i"
done

或者位置参数 "$@"

for arg in "$@" ; do
  echo "$arg"
done

事实上,这个特定的用例非常常见,因此 Bash 提供了等效的简写 for arg ; do,其中 in "$@" 是隐含的。(但最好还是使用显式形式。)

另一种循环是 while 循环。它类似于 if 语句,不同之处在于只要其测试命令继续成功,它就会反复循环。例如,假设我们需要等到 wait.txt 文件被删除。一种方法是“休眠”几秒钟,然后“唤醒”并查看它是否仍然存在。我们可以以这种方式反复循环

while [[ -e wait.txt ]] ; do
  sleep 3 # "sleep" for three seconds
done

相反,我们可以使用 until 循环,直到给定的命令成功为止;例如,上面的代码的相反操作可能是

until [[ -e proceed.txt ]] ; do
  sleep 3 # "sleep" for three seconds
done

当然,这与将 while! 组合相同,但在某些情况下,它可能更易读。

  • if 一样,while 以相同的方式判断 truefalse。自己试一试。
华夏公益教科书