猿问

linux for循环

cd /root/test

for i in $(ls *.tar.gz *.gz)

       do

           tar -zxf $i

      done

为什么(ls *.tar.gz *.gz)前面要加$,不加行不行

qq_爱上你_0
浏览 1986回答 2
2回答

onemoo

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)还是会被当作一个单纯的字来用。最后多说一点:对于前面一人的回答。$ 放在变量名前才是“变量展开”。而这里根本就没有变量的事,这只是“命令替换”而已。

孤独的小猪

不加$符号当然不可以了,shell里面加$符号才知道这是变量,想得到返回值
随时随地看视频慕课网APP
我要回答