在本教程我们需要执行以下命令:
# 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 准备执行发送给它的任何内容