【问题标题】:bash order of commands? [closed]bash命令的顺序? [关闭]
【发布时间】:2021-04-15 03:11:45
【问题描述】:

在想知道如何将 ls 导入 cat 以输出一堆文件后,我意识到更好的方法是 cat $ $(ls *.py),但也意识到 $(ls *.py) cat $ 不起作用:

$(ls *.py) cat $                                                   1 ⨯
bash: command not found: 1.py

对我来说这很奇怪,为什么会这样?

【问题讨论】:

  • 您有一个 $() 并且在该上下文中 ls 正在执行。所以返回的内容会被执行。当它返回 1.py 等时,它以 $(1.py 2.py) 的形式执行。 ls 显示输出,为什么你又需要一只猫?我对这里的要求感到困惑。
  • 有几个原因可以避免解析ls 的输出(参见unix.stackexchange.com/q/128985)。您的命令失败的原因是您忘记了管道符号,例如ls *.py | cat 应该可以,但最好使用cat *.py

标签: linux bash cat ls


【解决方案1】:

首先:不要使用$(ls *.py),只需使用*.py。添加$(ls) 并没有做任何有用的事情,但它确实增加了几层处理和潜在的混乱。有关详细信息,请参阅this question,但我会在接近尾声时给出一个简短的总结。

第二:当你使用$(ls *.py)*.py 作为命令的一部分时,shell 会在执行命令之前“扩展”它。对于*.py,这意味着将其替换为当前目录中与*.py 匹配的文件的名称。所以如果你使用cat *.py,它会扩展为:

cat 1.py 2.py file.py otherfile.py

...这就是你想要的。但是*.py cat 会扩展为:

1.py 2.py file.py otherfile.py cat

...它尝试将1.py 作为命令名称执行(它不作为命令存在,因此您会收到“找不到命令”错误),并使用其他文件名和“cat”作为参数。

使用$(ls *.py) cat,它首先通过扩展*.py并运行ls 1.py 2.py file.py otherfile.py,捕获其输出(“1.py 2.py file.py otherfile.py”),将其拆分为“单词” (这可能正确地将其拆分为文件名...除非任何文件有空格或您更改了IFS)然后尝试扩展任何看起来像通配符的文件(就像最初的@987654338一样@),然后最终从这些 + cat 构建一个命令。就像以前一样,结果是:

1.py 2.py file.py otherfile.py cat

如你所见,失败了。

【讨论】:

    猜你喜欢
    • 2017-06-12
    • 2019-03-21
    • 1970-01-01
    • 1970-01-01
    • 2015-08-02
    • 2013-01-11
    • 2019-06-28
    • 2020-01-16
    • 2013-07-14
    相关资源
    最近更新 更多