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_MAXprint 时,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