`bash` 选项中的最后一个“-”(连字符)是什么意思?

Oma*_*AMI 19 linux bash command-line pipe

本教程中,我们需要执行以下命令:

# curl -sL https://rpm.nodesource.com/setup_6.x | sudo -E bash -
Run Code Online (Sandbox Code Playgroud)

-后面的最后一个(连字符)bash是什么意思?

我已经看到了很多与此相关的命令,但找不到合乎逻辑的解释,也找不到如何重新制定谷歌搜索的方法。它是管道命令的输出吗?

Kam*_*ski 32

当涉及到-.

POSIX说:

准则 10:
第一个--不是选项参数的参数应该被接受为指示选项结束的分隔符。任何后续参数都应视为操作数,即使它们以-字符开头。

[…]

准则 13:
对于使用操作数表示要打开以进行读取或写入的文件的实用程序,操作-数应仅用于表示标准输入(或从上下文中清楚指定输出文件时为标准输出)或文件名为-.

如果 POSIX.1-2017 的 Shell 和实用程序卷中描述的符合这些准则的实用程序需要接受或不接受-表示标准输入或输出的操作数,则在操作数部分中解释了这种用法。否则,如果这样的实用程序使用操作数来表示文件,则操作数是-代表标准输入(或标准输出)还是代表名为-.

但随后man 1 bash读到:

A--表示选项结束并禁用进一步的选项处理。之后的任何参数--都被视为文件名和参数。的参数-等价于--

所以对于 Bash 来说-既不是标准输入也不是文件,因此有点不标准。

现在你的特殊情况:

curl -sL https://rpm.nodesource.com/setup_6.x | sudo -E bash -
Run Code Online (Sandbox Code Playgroud)

怀疑这个命令的作者可能没有意识到在这种情况下-是等价的--。我怀疑作者想确保bash会从其标准输入中读取,他们希望-根据指南 13 工作。

但即使它根据指南工作,-在这里也没有必要,因为bash检测它的标准输入何时是管道并相应地采取行动(除非-c给出等)。

然而,-它不能根据指南工作,它的工作原理类似于--. --这里仍然是不必要的,因为它后面没有参数。

在我看来,最后-没有任何改变。没有它,命令也能工作。

要了解一般情况下如何--以及如何-有用,请研究以下示例。


cat在我的 Kubuntu 中遵守这两个准则,我将用它来证明-和 的用处--

让名为的文件foo存在。这将打印文件:

cat foo
Run Code Online (Sandbox Code Playgroud)

让名为的文件--help存在。这不会打印文件:

cat --help
Run Code Online (Sandbox Code Playgroud)

但这将打印名为的文件--help

cat -- --help
Run Code Online (Sandbox Code Playgroud)

这将连接命名的文件--help与来自标准输入的任何内容:

cat -- --help -
Run Code Online (Sandbox Code Playgroud)

看起来你真的不需要--,因为你总是可以通过./--help它肯定会被解释为一个文件。但考虑

cat "$file"
Run Code Online (Sandbox Code Playgroud)

当您事先不知道变量的内容是什么时。你不能只是./在它前面加上它,因为它可能是一条绝对路径并且./会破坏它。另一方面,它可能是一个名为的文件--help(因为为什么不呢?)。在这种情况下--非常有用;这是一个更强大的命令:

cat -- "$file"
Run Code Online (Sandbox Code Playgroud)


AFH*_*AFH 6

man bash, 在单字符选项的末尾有:-

--    A -- signals the end of options and disables further option processing.
      Any arguments after the -- are treated as filenames and arguments. An
      argument of - is equivalent to --.
Run Code Online (Sandbox Code Playgroud)

如果你引用了完整的命令,我看不出在这个例子中使用-after 的理由bash,但它没有坏处。


小智 5

curl -sL https://rpm.nodesource.com/setup_6.x | sudo -E bash -
Run Code Online (Sandbox Code Playgroud)

bash -意味着bash正在等待标准输入。所以实际上 bash 将执行左侧命令返回的任何内容|

一个类似但更简单的例子是:

echo hello | cat - 在这里,cat将打印“你好”。为什么?因为“hello”正在通过发送给 cat|并且cat正在等待发送给它的任何内容

现在让我们将整个命令分成两部分:

curl -sL https://rpm.nodesource.com/setup_6.x
Run Code Online (Sandbox Code Playgroud)

这个curl命令将返回bash可以理解和执行的内容

然后我们有一个管道|,它将把curl命令返回的输出发送到管道的右侧,即sudo -E bash -。最后sudo -E bash -,bash 准备好执行发送给它的任何内容