Answers:
有实际的区别。
curl -sSL https://get.docker.com/ | sh
启动curl
,sh
同时将的输出curl
与的输入连接sh
。curl
将以大约sh
可以运行脚本的速度(大致)执行下载。当将资源简单地下载到文件或缓冲区中或在浏览器中查看时,服务器可以检测到时间的不规律性并注入不可见的恶意代码。
在中sh -c "$(curl -sSL https://get.docker.com/)"
,curl
严格在运行之前sh
运行。在sh
启动之前,将下载资源的全部内容并将其传递给您的Shell 。您的外壳程序仅sh
在curl
退出时启动,并将资源文本传递给它。服务器无法检测到sh
呼叫;它仅在连接结束后才启动。这类似于先将脚本下载到文件中。
(这在docker情况下可能不相关,但通常可能是一个问题,突出了这两个命令之间的实际区别。)
vulnerable to server-side detection
短语上添加了一个链接。它导致了一篇博客文章,其中详细解释了他们如何实现它。TL; DR:在脚本中入睡,并观察服务器上的接收延迟。
我相信它们实际上是相同的。但是,在少数情况下它们会有所不同。
$(cmd)
替换为的结果cmd
。如果该result命令的长度超过所返回的最大参数长度值getconf ARG_MAX
,它将截断结果,这可能导致不可预测的结果。
管道选项没有此限制。curl
命令的每一行输出都将从bash
管道到达时执行。
但是ARG_MAX通常在256,000个字符范围内。对于docker安装,我有信心使用这两种方法。:-)
ARG_MAX
,当getconf ARG_MAX
print 时,bash将我系统上的单个参数限制为131072字节2097152
。但是无论是错误还是截断,它都不起作用。
在curl -sSL https://get.docker.com/ | sh
:
curl
和和这两个命令sh
将在各自的子shell中同时启动
来自的STDOUT curl
将作为STDIN传递到sh
(这是管道“ |
做什么” )
而在sh -c "$(curl -sSL https://get.docker.com/)"
:
$()
将首先执行命令替换,即curl
首先在子shell中运行
命令替换$()
将会被STDOUT替换为curl
sh -c
(非交互式,非登录Shell)将从以下位置执行STDOUT: curl