답변:
실질적인 차이가 있습니다.
curl -sSL https://get.docker.com/ | sh
시작 curl
및 sh
출력 연결 동시에 curl
의 입력을 가진 sh
. 스크립트를 실행할 수있는 한 curl
빨리 다운로드합니다 (대략) sh
. 서버는 리소스를 파일이나 버퍼로 다운로드하거나 브라우저에서 볼 때 타이밍에서 불규칙성을 감지하여 보이지 않는 악성 코드를 주입 할 수 있습니다.
에서 sh -c "$(curl -sSL https://get.docker.com/)"
, curl
(가) 엄격하기 전에 실행되는 sh
실행됩니다. 리소스 sh
가 시작 되기 전에 리소스의 전체 내용이 다운로드되어 셸로 전달됩니다 . 쉘 은 종료 sh
되었을 때만 시작 curl
되고 자원의 텍스트를 전달합니다. 서버가 sh
통화를 감지 할 수 없습니다 . 연결이 종료 된 후에 만 시작됩니다. 스크립트를 파일로 먼저 다운로드하는 것과 비슷합니다.
(이는 도커의 경우에는 관련이 없지만 일반적으로 문제가 될 수 있으며 두 명령의 실제 차이점을 강조합니다.)
vulnerable to server-side detection
문구에 링크를 넣었습니다 . 블로그 게시물을 통해 어떻게 달성하는지 자세히 설명합니다. TL; DR : 스크립트에서 휴면 상태를 유지하고 서버에서 수신 지연을 관찰하십시오.
나는 그들이 실질적으로 동일하다고 생각합니다. 그러나 드문 경우가 있습니다.
$(cmd)
의 결과로 대체됩니다 cmd
. 해당 결과 명령의 길이가에 의해 반환 된 최대 인수 길이 값을 초과하면 결과 getconf ARG_MAX
가 잘리고 예기치 않은 결과가 발생할 수 있습니다.
파이프 옵션에는이 제한이 없습니다. curl
명령 의 각 출력 라인은 bash
파이프에서 도착할 때 실행됩니다 .
그러나 ARG_MAX는 일반적으로 256,000 자 범위입니다. 도커 설치의 경우 두 방법 중 하나를 사용한다고 확신합니다. :-)
ARG_MAX
합니다 .bash getconf ARG_MAX
는 인쇄 할 때 시스템에서 개별 인수를 131072 바이트로 제한 합니다 2097152
. 그러나 오류 또는 잘림은 작동하지 않습니다.
에서 curl -sSL https://get.docker.com/ | sh
:
두 명령, curl
그리고 sh
, 각각의 서브 쉘에서, 같은 시간에 시작됩니다
STDOUT curl
은 STDIN으로 전달됩니다 sh
(이것은 파이프 |
가 수행하는 것입니다).
반면 sh -c "$(curl -sSL https://get.docker.com/)"
:
대체 명령 $()
은 먼저 실행 curl
됩니다. 즉 , 서브 쉘에서 먼저 실행됩니다.
명령 $()
대체는에서 STDOUT으로 대체됩니다.curl
sh -c
(비 대화식, 비 로그인 셸)에서 STDOUT을 실행합니다. curl