docker에 대한 많은 entrypoint.sh 스크립트가 다음과 같은 작업을 수행한다는 것을 알았습니다.
#!/bin/bash
set -e
... code ...
exec "$@"
무엇 set -e
과은 exec "$@"
을 위해?
답변:
기본적으로 전달 된 모든 명령 줄 인수 entrypoint.sh
를 사용하여 명령으로 실행합니다. 의도는 기본적으로 "이 .sh 스크립트에서 모든 작업을 수행 한 다음 동일한 쉘에서 사용자가 명령 줄에서 전달하는 명령을 실행합니다"입니다.
보다:
exec "$@"
현재 실행중인 프로세스를 전달 된 인수에 대해 생성 된 새 프로세스로 대체합니다. Docker 신호에 중요 : stackoverflow.com/a/32261019/99717
set -e
실행중인 명령이 0이 아닌 종료 코드로 종료되는 경우 즉시 종료하도록 셸 옵션을 설정합니다. 스크립트는 실패한 명령의 종료 코드와 함께 반환됩니다. bash man 페이지에서 :
-e 설정 :
파이프 라인 (단일 간단한 명령으로 구성 될 수 있음), 목록 또는 복합 명령 (위의 SHELL GRAMMAR 참조)이 0이 아닌 상태로 종료되면 즉시 종료합니다. 실패한 명령이 while 또는 until 키워드 바로 뒤에 오는 명령 목록의 일부, if 또는 elif 예약어 다음에 오는 테스트의 일부, && 또는 ||에서 실행되는 명령의 일부인 경우 쉘은 종료되지 않습니다. 마지막 && 또는 || 뒤에 오는 명령, 파이프 라인에 있지만 마지막 명령을 제외한 모든 명령 또는 명령의 반환 값이!로 반전되는 경우. -e가 무시되는 동안 명령이 실패하여 서브 쉘 이외의 복합 명령이 0이 아닌 상태를 리턴하면 쉘이 종료되지 않습니다. ERR에 대한 트랩이 설정된 경우 쉘이 종료되기 전에 실행됩니다.
-e가 무시되는 컨텍스트에서 복합 명령 또는 쉘 함수가 실행되는 경우, 복합 명령 또는 함수 본문 내에서 실행 된 명령은 -e가 설정되고 명령이 a 실패 상태. -e가 무시되는 컨텍스트에서 실행하는 동안 복합 명령 또는 쉘 함수가 -e를 설정하면 해당 설정은 복합 명령 또는 함수 호출을 포함하는 명령이 완료 될 때까지 영향을주지 않습니다.
exec "$@"
일반적으로 진입 점을 통과 한 다음 docker 명령을 실행하는 데 사용됩니다. 현재 실행중인 셸을 "$@"
가리키는 명령으로 대체합니다 . 기본적으로 해당 변수는 명령 줄 인수를 가리 킵니다.
entrypoint.sh를 가리키는 진입 점이있는 이미지가 있고 컨테이너를로 docker run my_image server start
실행 entrypoint.sh server start
하면 컨테이너에서 실행 되는 것으로 변환됩니다 . exec 라인 entrypoint.sh
에서 pid 1로 실행되는 쉘은 자신을 명령으로 대체합니다 server start
.
이것은 신호 처리에 중요합니다. 사용하지 않고 exec
는 server start
위의 예에서 다른 PID로 실행 것이고, 그것이 종료 후, 당신은 당신의 쉘 스크립트로 반환합니다. pid 1의 쉘을 사용하면 SIGTERM이 기본적으로 무시됩니다. 즉 docker stop
, 컨테이너로 보내는 우아한 중지 신호 는 server
프로세스에서 수신되지 않습니다 . 10 초 후 (기본적으로) docker stop
정상 종료를 포기하고 앱을 강제로 종료하는 SIGKILL을 전송하지만 잠재적 인 데이터 손실 또는 네트워크 연결이 끊어지면 앱 개발자가 신호를 수신하면 코드를 작성할 수 있습니다. 또한 컨테이너가 정지하는 데 항상 10 초가 걸립니다.
쉘 명령이 좋아에주의 shift
하고 set --
, 당신의 값을 변경할 수 있습니다 "$@"
. 예를 들어 /bin/sh -c "..."
다음은 도커의 쉘 구문을 사용하는 경우 나타날 수있는 명령에서을 제거하는 스크립트의 짧은 부분입니다 CMD
.
# convert `/bin/sh -c "server start"` to `server start`
if [ $# -gt 1 ] && [ x"$1" = x"/bin/sh" ] && [ x"$2" = x"-c" ]; then
shift 2
eval "set -- $1"
fi
....
exec "$@"
test
사양을 참조하십시오 -a
. [ "$#" -gt 1 ] && [ "$1" = /bin/sh ]
올바른 대체입니다 ( x"$1"
구식이 아닌 구문 만 사용하는 경우 해커 가 필요 없음 ).
shift 2; set -- $1
방법과 전혀 동일하지 않습니다 eval
. 고려 /bin/sh -c 'printf "%s\n" "hello world" "goodbye world"'
당신은 콘크리트 테스트 케이스를 원하고 볼 경우, 인수에 문자열을 변환 할 때 배쉬 구문 분석 따옴표하지 않습니다 .
eval
여전히 /bin/sh -c
문자열에 대한 동작을 미러링하고 싶지만 누락 된 것이 있으면 알려주십시오.
exec
확실히 리디렉션을 수행하는 사용 모드가 있지만 이것은 그 모드가 아닙니다.
set -e
오류가 발생하기 쉬운 손으로 쓴 오류 처리보다 훨씬 더 간주됩니다. (급한 경우 아래 연습에 대한 상단의 비유를 건너 뜁니다).