Istnieje praktyczna różnica.
curl -sSL https://get.docker.com/ | sh
rozpoczyna się curl
i sh
jednocześnie łączy wyjście curl
z wejściem sh
. curl
rozpocznie się pobieranie (z grubsza) tak szybko, jak sh
można uruchomić skrypt. Serwer może wykryć nieprawidłowości w czasie i wstrzyknąć szkodliwy kod niewidoczny po prostu pobierając zasób do pliku lub bufora lub przeglądając go w przeglądarce.
W sh -c "$(curl -sSL https://get.docker.com/)"
, curl
prowadzony jest ściśle zanim sh
zostanie uruchomiona. Cała zawartość zasobu jest pobierana i przekazywana do powłoki przed sh
uruchomieniem. Twoja powłoka uruchamia się dopiero sh
po curl
wyjściu i przekazuje do niej tekst zasobu. Serwer nie może wykryć sh
połączenia; jest uruchamiany dopiero po zakończeniu połączenia. Jest to podobne do pobrania najpierw skryptu do pliku.
(Może to nie mieć znaczenia w przypadku dokera, ale może to być ogólnie problem i podkreśla praktyczną różnicę między tymi dwoma poleceniami.)
vulnerable to server-side detection
frazy. Prowadzi do postu na blogu, który szczegółowo wyjaśnia, jak to osiągnąć. TL; DR: prześpij się w swoim skrypcie i obserwuj opóźnienie w odbiorze na serwerze.Uważam, że są praktycznie identyczne. Są jednak rzadkie przypadki, w których są różne.
$(cmd)
zostaje zastąpiony wynikamicmd
. Jeśli długość tego polecenia wyniku przekracza maksymalną wartość długości argumentu zwróconą przezgetconf ARG_MAX
, spowoduje obcięcie wyniku, co może skutkować nieprzewidywalnymi wynikami.Opcja potoku nie ma tego ograniczenia. Każdy wiersz wyniku
curl
polecenia zostanie wykonany pobash
nadejściu z potoku.Ale ARG_MAX ma zwykle zakres 256 000 znaków. W przypadku instalacji dokera jestem pewien, że skorzystam z dowolnej metody. :-)
źródło
ARG_MAX
, bash ogranicza pojedynczy argument do 131072 bajtów w moim systemie podczasgetconf ARG_MAX
drukowania2097152
. Ale tak czy inaczej, błąd lub obcięcie, to nie zadziałałoby.W
curl -sSL https://get.docker.com/ | sh
:Oba polecenia
curl
ish
będą uruchamiane jednocześnie w odpowiednich podpowłokachSTDOUT z
curl
zostanie przekazany jako STDIN dosh
(to robi rura|
, robi)Natomiast w
sh -c "$(curl -sSL https://get.docker.com/)"
:Podstawienie polecenia
$()
, zostanie wykonane jako pierwsze, tzn. Najpierwcurl
zostanie uruchomione w podpowłocePodstawienie polecenia
$()
, zostanie zastąpione przez STDOUT zcurl
sh -c
(nieinteraktywna powłoka niezalogowana) wykona STDOUT zcurl
źródło
Jedną z różnic między nimi (wziętymi z innych odpowiedzi w Internecie) jest to, że jeśli nie pobierzesz całego skryptu naraz, może on odciąć się w połowie skryptu w nieznanym punkcie i zmienić znaczenie polecenia, tak aby było wykonany. Wydaje się więc, że najpierw należy pobrać cały plik, a następnie go ocenić.
źródło