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


15

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

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

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

我已经看到了很多与此相关的命令,找不到自己合理的解释,也找不到如何重新构造Google搜索的方法。它是管道命令的输出吗?



2
从网络上下载内容并将其直接传送到sudo bash声音中确实很可怕。尝试寻找不鼓励这种做法的教程。
hmakholm在莫妮卡(Monica)

它的npm教程,但我同意你的看法……
Omar BISTAMI

1
如果您需要搜索带有符号的东西,请尝试symbolhound.com

Answers:


31

谈到Bash时,它的行为有些不规范-

POSIX说:

准则10:应该接受不是选项参数
的第一个--参数作为指示选项结束的定界符。以下所有参数都应视为操作数,即使它们以-字符开头。

[…]

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

当需要在POSIX.1-2017的Shell and Utilities卷中描述的符合这些准则的实用程序是接受还是不接受-表示标准输入或输出的操作数时,此用法将在OPERANDS部分中进行说明。否则,如果这样的实用程序使用操作数来表示文件,则操作数是-代表标准输入(或标准输出)还是代表的文件,由实现定义-

但随后man 1 bash显示:

A --表示选项结束,并禁用进一步的选项处理。后面的所有参数--均视为文件名和参数。的参数-等效于--

因此,对于Bash而言,-既不是标准输入也不是文件,因此有点不标准。

现在您的特殊情况:

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

怀疑此命令的作者可能没有意识到在这种情况下-是否等效--。我怀疑作者想确保bash可以从标准输入中读取内容,并希望它们-能够按照准则13进行操作。

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

但是-按照指导方针是行不通的,它的工作方式类似于----这里仍然没有必要,因为后面没有任何参数。

在我看来,最后一-无所改变。没有它,该命令将起作用。

要了解总体上如何使用---有用,请研究以下示例。


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

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

cat foo

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

cat --help

但这将打印名为--help

cat -- --help

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

cat -- --help -

似乎您并不需要--,因为您始终./--help可以将其肯定地传递为文件。但是考虑一下

cat "$file"

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

cat -- "$file"

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

如果您引用了complete命令,那么在这种情况下,我看不到有理由使用-after bash,但这没有害处。


谢谢您的回答,是的,我已经引用了完整的命令。因此-或-之后的任何内容都不会被视为选项,而会被视为文件名或参数,您能否举一个有用的示例?
奥马尔·比斯塔米

1
确实允许名称以开头开头的脚本-,这是一个不太可能的要求,但是-/ --可以实现。
AFH

1
@OmarBISTAMI引用命令将影响Shell对其进行扩展的方式,但不会影响其后的任何参数。如果您在合法参数周围加上引号,则它们将成为命令名称的一部分,而这也不是您想要的名称。有些命令将文件名作为参数,但是默认情况下不使用标准输入。人为设计的示例使您可以将输入(来自终端或管道)夹在两个文件之间。cat file1 - file2 > file3

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

bash -表示bash正在等待标准输入。因此,实际上bash会执行左侧命令的返回内容|

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

echo hello | cat - 在这里,cat将打印“ hello”。为什么?因为“ hello”正被发送给猫,|并且cat正在等待发送给它的任何东西

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

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

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

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

By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.