[shell] 도커 진입 점 스크립트에 대해 set -e 및 exec“$ @”의 기능은 무엇입니까?
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 "$@"