为什么量化器不会通过xargs

时间:2013-11-13 22:02:30

标签: bash shell xargs

我遇到的问题是,由于某种原因,通配符量化器不会通过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 ,我们也会有正确的输出。

你能解释一下,为什么会这样?感谢。

EDIT1:

有趣的是,我们如何将文件file1中的参数通过shell解释器传递给ls命令。以下是示例:

ls `xargs -n3 < file1`

现在在ls调用之前进行shell扩展,导致与ls -la f*相同的输出

2 个答案:

答案 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。如果它与没有文件匹配且命令需要一个命令,你可能会对这个命令感到困惑。

但是当你将该参数传递给lsxargs时,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。