docker에 대한 많은 entrypoint.sh 스크립트가 다음과 같은 작업을 수행한다는 것을 알았습니다.
#!/bin/bash
set -e
... code ...
exec "$@"
무엇 set -e과은 exec "$@"을 위해?
답변
기본적으로 전달 된 모든 명령 줄 인수 entrypoint.sh를 사용하여 명령으로 실행합니다. 의도는 기본적으로 “이 .sh 스크립트에서 모든 작업을 수행 한 다음 동일한 쉘에서 사용자가 명령 줄에서 전달하는 명령을 실행합니다”입니다.
보다:
답변
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 "$@"
