2 回答
TA贡献883条经验 获得超454个赞
for 语句中的 in 后面的内容就是需要被循环的哪些项。 比如 for i in A B C 在循环时,i 就分别是 A、B、C 这三个单词。
你理解这个 for 循环里的 i 是要在哪些项里循环吗?
你的例子中这些项就是 $(ls *.tar.gz *.gz) 这个东西。
先不管 $ 和 (),单看 ls *.tar.gz *.gz,这是一个 ls 命令,会列出当前目录下所有的 .tar.gz .gz 结尾的文件。而所列出的这些文件名就是需要循环的项。
也就是说你想要的循环项不是“ls *.tar.gz *.gz”这三个字,而是这句 ls 命令的执行结果。
像这样,想要在 bash 脚本中得到一个命令的执行结果,叫做“命令替换”。它的语法就是用 $( ) 把命令括起来,到脚本运行时这里就会替换为该命令的执行结果了。
所以你这里既然需要的是 ls 的执行结果,那就要写 $(ls *.tar.gz *.gz)。
既然 $(...) 是“命令替换”的语法格式,那当然不能去掉 $ 了。
多说一些:
如果去掉 $ 会怎么样呢? 只剩下 (ls *.tar.gz *.gz),这里出现小括号是不合法的,所以脚本在执行到这里时会直接报错。
再多说一些:
前面说 in 后面的这些“字”就是循环项。 其实呢,for 语句会尝试对这些“字”做“路径名展开”。“路径名展开”就是指展开那些路径通配符 * ? 什么的。
所以如果你在 in 后面直接写 *.tar.gz,这里会直接被替换为所有 *.tar.gz 结尾的文件名,这样你甚至不需要用 ls 命令来帮你列出它们。
所以这句你直接写成 for i in *.tar.gz *.gz 也是可以的。
但有一点:如果没能成功进行路径名展开(也就是说目录下没有这样的文件),那 *tar.gz(或 *.gz)还是会被当作一个单纯的字来用。
最后多说一点:
对于前面一人的回答。$ 放在变量名前才是“变量展开”。而这里根本就没有变量的事,这只是“命令替换”而已。
- 2 回答
- 0 关注
- 1985 浏览
添加回答
举报