我遇到的问题是,由于某种原因,通配符量化器不会通过xargs传递给命令。
假设我们的文件 file1 包含以下内容:
-l
-a
f*
我们需要通过 xargs 将参数传递给 ls 。
cat file1 | xargs -n3 ls
输出相当于 ls -la 命令,带有来自终端的additon,
ls: cannot access f*: No such file or directory.
但是文件在目录中(ls -la f*
返回合适的输出)
例如,如果我们将f *替换为 file1 ,我们也会有正确的输出。
你能解释一下,为什么会这样?感谢。
有趣的是,我们如何将文件file1
中的参数通过shell解释器传递给ls
命令。以下是示例:
ls `xargs -n3 < file1`
现在在ls
调用之前进行shell扩展,导致与ls -la f*
相同的输出
答案 0 :(得分:2)
file
的内容通过标准输入传递给xargs
,因此shell永远不会看到它们处理glob。 xargs
然后将它们传递给ls
,再次没有shell看到它们,因此f*
被视为文字的双字符文件名。
答案 1 :(得分:2)
f*
表达式也称为shell glob,应该由shell解释。您可以通过运行echo f*
当您从shell运行ls -la f*
时,shell会根据您的目录内容对其进行解释,并使用扩展版本调用ls
,例如:ls -la file1 file2 file3
。如果它与没有文件匹配且命令需要一个命令,你可能会对这个命令感到困惑。
但是当你将该参数传递给ls
到xargs
时,shell没有机会展开它,而ls
感觉就像ls -la f*
那样被调用了}。它将-la
识别为选项,将f*
识别为要列出的文件名。该文件不存在,因此它会因您看到的错误消息而失败。
你可以通过更常用的文件名来使它失败:
$ ls non_existing_file
ls: cannot access non_existing_file: No such file or directory.
或者你可以通过实际拥有该名称的文件来获得成功:
$ touch 'f*'
$ xargs ls -la <<< 'f*'
-rw-rw-r-- 1 jb jb 0 2013-11-13 23:08 f*
$ rm 'f*'
注意我必须使用单引号,以便在创建和删除它时,shell 不将f*
解释为glob。
不幸的是,当它从xargs
直接传递到ls
时,你无法扩展它,因为那里没有shell。