Hay una diferencia práctica.
curl -sSL https://get.docker.com/ | shcomienza curly, shal mismo tiempo, conecta la salida de curlcon la entrada de sh. curlse llevará a cabo con la descarga (aproximadamente) tan rápido como shpueda 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/)", curlse ejecuta estrictamente antes de que shse ejecute. Todo el contenido del recurso se descarga y se pasa a su shell antes de que shse inicie. Su shell solo comienza shcuando curlha salido y le pasa el texto del recurso. El servidor no puede detectar la shllamada; 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 detectionfrase. 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
curlcomando se ejecutará abashmedida 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_MAXimprime2097152. Pero de cualquier manera, error o truncamiento, no funcionaría.En
curl -sSL https://get.docker.com/ | sh:Ambos comandos,
curlysh, comenzarán al mismo tiempo, en subcapas respectivasEl STDOUT de se
curlpasará 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 decurlsh -c(shell no interactivo, sin inicio de sesión) ejecutará STDOUT desdecurlfuente
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