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

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

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

# curl -sL https://rpm.nodesource.com/setup_6.x | sudo -E bash -

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

我见过很多这样的命令,但找不到合理的解释,也找不到如何重新组织谷歌搜索。它是管道命令的输出吗?

答案1

当谈到时,Bash 的行为有点非标准-

POSIX说:

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

[…]

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

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

但是之后man 1 bash内容如下:

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

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

现在你的具体情况是:

curl -sL https://rpm.nodesource.com/setup_6.x | sudo -E bash -

怀疑此命令的作者可能没有意识到在本例中-相当于。我--怀疑作者希望确保bash将从其标准输入读取,他们希望-按照指南 13 进行工作。

但即使它按照指南工作,-在这里也是不必要的,因为bash检测其标准输入是否是管道并采取相应的行动(除非-c给出等)。

然而,-根据指南,它不起作用,它的工作方式类似于--。 Still--在这里是不必要的,因为它后面没有参数。

我认为最后一条-并没有什么改变。即使没有它,命令仍可正常工作。

要了解---通常如何有用,请研究下面的例子。


cat在我的 Kubuntu 中遵循这两条准则,我将用它来证明-和的有用性--

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

cat foo

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

cat --help

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

cat -- --help

这会将名为的文件--help与来自标准输入的内容连接起来:

cat -- --help -

似乎你真的不需要--,因为你总是可以传递./--help它,它肯定会被解释为文件。但考虑一下

cat "$file"

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

cat -- "$file"

答案2

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 --.

如果您已经引用了完整的命令,我看不出在这种情况下使用-after 的理由bash,但它没有坏处。

答案3

curl -sL https://rpm.nodesource.com/setup_6.x | sudo -E bash -

bash -表示bash正在等待 stdin。因此实际上 bash 将执行左侧命令返回的任何内容|

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

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

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

curl -sL https://rpm.nodesource.com/setup_6.x

此 curl 命令将返回一些可以被 bash 理解和执行的内容

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

相关内容