Hay una diferencia práctica.
curl -sSL https://get.docker.com/ | sh
comienza curl
y, sh
al mismo tiempo, conecta la salida de curl
con la entrada de sh
. curl
se llevará a cabo con la descarga (aproximadamente) tan rápido como sh
pueda ejecutar el script. El servidor puede detectar las irregularidades en el tiempo e inyectar código malicioso que no es visible cuando simplemente descarga el recurso en un archivo o búfer o cuando lo ve en un navegador.
En sh -c "$(curl -sSL https://get.docker.com/)"
, curl
se ejecuta estrictamente antes de que sh
se ejecute. Todo el contenido del recurso se descarga y se pasa a su shell antes de que sh
se inicie. Su shell solo comienza sh
cuando curl
ha salido y le pasa el texto del recurso. El servidor no puede detectar la sh
llamada; solo se inicia después de que finaliza la conexión. Es similar a descargar el script en un archivo primero.
(Esto puede no ser relevante en el caso de la ventana acoplable, pero puede ser un problema en general y resalta una diferencia práctica entre los dos comandos).
vulnerable to server-side detection
frase. Lleva a una publicación de blog que explica con gran detalle cómo lo logran. TL; DR: suspenda su script y observe el retraso en la recepción en el servidor.Creo que son prácticamente idénticos. Sin embargo, hay casos raros en los que son diferentes.
$(cmd)
se sustituye con los resultados decmd
. Si la longitud de ese comando de resultado excede el valor máximo de longitud de argumento devuelto porgetconf ARG_MAX
, truncará el resultado, lo que puede dar lugar a resultados impredecibles.La opción de tubería no tiene esta limitación. Cada línea de salida del
curl
comando se ejecutará abash
medida que llegue desde la tubería.Pero ARG_MAX generalmente está en el rango de 256,000 caracteres. Para una instalación de docker, estaría seguro de usar cualquiera de los métodos. :-)
fuente
ARG_MAX
, bash limita un argumento individual a 131072 bytes en mi sistema, cuandogetconf ARG_MAX
imprime2097152
. Pero de cualquier manera, error o truncamiento, no funcionaría.En
curl -sSL https://get.docker.com/ | sh
:Ambos comandos,
curl
ysh
, comenzarán al mismo tiempo, en subcapas respectivasEl STDOUT de se
curl
pasará como el STDIN ash
(esto es lo que hace la tubería|
)Mientras que en
sh -c "$(curl -sSL https://get.docker.com/)"
:La sustitución del comando
$()
, se ejecutará primero, es decircurl
, se ejecutará primero en una subshellLa sustitución del comando
$()
, será reemplazada por el STDOUT decurl
sh -c
(shell no interactivo, sin inicio de sesión) ejecutará STDOUT desdecurl
fuente
Una diferencia entre los dos (tomados de otras respuestas en la web) es que si no descarga el script completo a la vez, podría cortar la mitad del script en un punto desconocido y cambiar el significado del comando para que sea ejecutado. Entonces parece que primero se descarga todo el archivo y luego evaluarlo sería mejor.
fuente