【问题标题】:Why do some linux commands work with a "*" in a list of files but others do not?为什么某些 linux 命令在文件列表中使用“*”而其他命令不使用?
【发布时间】:2014-11-03 08:14:14
【问题描述】:

为什么,例如,

ls -1 /path/to/something/data*data/file*.txt 

工作正常,但类似以下内容会返回错误:

tar -xzvf *tar.gz
tar: evsClient-v.0.0.6.tar.gz: Not found in archive
tar: evsClient-v.0.0.7.tar.gz: Not found in archive

【问题讨论】:

  • 因为 globbing 是由 shell 在启动程序之前完成的。
  • FWIW,您可以使用 xargs 或 shell for 循环来解决此问题。

标签: linux glob


【解决方案1】:

tar-f 选项只需要一个参数来指定要处理的文件。如果像 tar -xzvf 那样使用 glob 表达式,并且结果有多个文件被扩展,则第一个文件之后的文件将被视为 tar 的常规参数,而不是 -f 的选项参数。

由于您使用的是-xtar 处于提取模式,并且它将其他文件作为要从正在操作的存档中提取的文件的名称。

【讨论】:

    【解决方案2】:

    * 不被引用时,包含它的任何单词都被视为一个shell 模式,它会扩展为与该模式匹配的文件名列表。

    在您的第一个示例中,模式扩展为现有文件列表,ls 然后尽职尽责地显示。

    在您的第二个示例中,模式再次扩展为匹配文件列表。但是,只有该列表的第一个成员被视为 f 选项的参数。其余项是您要从第一个文件中提取的文件的名称,这不是您想要的。

    一般规则是该模式仅提供文件名列表;您可以确保生成的文件列表是您正在运行的命令的正确参数集。

    【讨论】:

    • 谢谢,我明白了。在这种情况下,我只有一个问题:在实践中,有没有办法知道或预期会发生哪种情况?例如,有没有一种方法可以让我先验地知道这对scp 有效,但对tar 无效?
    • 你只需要知道你的命令需要什么参数。没有命令实际看到*;在调用命令之前,模式被替换为匹配的内容。从命令的角度来看,ls foo*ls foo.c foo.txt 如果是当前目录中仅有的两个匹配文件,则它们之间没有区别。
    • 好的,我明白你在说什么,我不接受。谢谢,我现在接受答案。
    【解决方案3】:

    “*”实际上是由 shell 扩展的,然后将生成的文件名列表作为相关命令的参数呈现。

    “ls”命令支持文件名列表,“tar”命令也是如此。但是 tar 的签名是:

    tar option(s) archive_name file_name(s)
    

    所以 - 在您的示例中,我假设命令行扩展为:

    tar -xzvf evsClient-v.0.0.5.tar.gz evsClient-v.0.0.6.tar.gz evsClient-v.0.0.7.tar.gz
    

    给你错误,因为后两个档案无法从第一个中提取。

    【讨论】:

      猜你喜欢
      • 2013-01-28
      • 1970-01-01
      • 2020-01-20
      • 1970-01-01
      • 2016-07-12
      • 2014-11-18
      • 1970-01-01
      • 1970-01-01
      • 2017-01-02
      相关资源
      最近更新 更多