Sar*_*rke 30 shell pipe curl command-substitution docker
Docker 的一种简单安装方法(例如)是这样的:
curl -sSL https://get.docker.com/ | sh
Run Code Online (Sandbox Code Playgroud)
但是,我也看到了一些看起来像这样的(使用 Docker 示例):
sh -c "$(curl -sSL https://get.docker.com/)"
Run Code Online (Sandbox Code Playgroud)
它们在功能上似乎相同,但是否有理由使用一个而不是另一个?或者这只是一种偏好/审美?
(请注意,运行来自未知来源的脚本时要非常小心。)
Jon*_*fer 47
有一个实际的区别。
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 案例中可能不相关,但它可能是一般问题,并突出了两个命令之间的实际差异。)
Gre*_*rsa 12
我相信它们实际上是相同的。但是,在极少数情况下它们是不同的。
$(cmd)
被替换为 的结果cmd
。如果该结果命令的长度超过 返回的最大参数长度值getconf ARG_MAX
,它将截断结果,这可能会导致不可预测的结果。
管道选项没有这个限制。curl
命令的每一行输出将在bash
它从管道到达时执行。
但 ARG_MAX 通常在 256,000 个字符范围内。对于 docker 安装,我有信心使用任何一种方法。:-)
在curl -sSL https://get.docker.com/ | sh
:
这两个命令,curl
并且sh
,将在同一时间开始,在各自的子shell
来自的 STDOUTcurl
将作为 STDIN 传递到sh
(这就是管道的|
作用)
而在sh -c "$(curl -sSL https://get.docker.com/)"
:
命令替换 ,$()
将首先执行,即curl
首先在子shell中运行
命令替换 ,$()
将被来自的 STDOUT 替换curl
sh -c
(非交互式、非登录 shell)将从中执行 STDOUT curl
归档时间: |
|
查看次数: |
22646 次 |
最近记录: |