다음을 수행하는 쉘 스크립트가 있습니다.
export FOO=foo # step 1
/usr/bin/java my-server # step 2
쉘 스크립트는 2단계에서 시작된 프로세스의 PID를 알아야 하는 상위 프로그램에 의해 시작됩니다. 현재 이 작업은 exec
서버에서 실행 명령을 실행하여 셸을 2단계의 명령으로 바꾸는 방식으로 수행됩니다. 따라서 쉘 스크립트의 PID와 스크립트를 실행하는 프로세스는 "my-server" 프로세스의 PID가 됩니다.
이제 2단계에서 시작된 서버를 빠르게 확인하려면 이 셸 스크립트에 다른 명령을 추가해야 합니다. 이제 내 프로그램은 다음과 같아야 합니다.
export FOO=foo # step 1
exec /usr/bin/java my-server & # step 2
/usr/bin/java my-validation # step 3
위와 같이 3단계를 추가할 수 있나요? 이 접근 방식의 대안은 무엇입니까?
답변1
다른 답변과 의견을 결합하여 다음을 추가합니다.
exec your_command &
무의미한. 명령줄은 비동기 서브셸에서 실행되며exec
기본적으로 무시됩니다.- 그건근소한단순화하다. 우리가 말한다면
(명령 1;명령 2)&
그런 다음 비동기 서브셸에서 실행됩니다(완료되면). 하지만 우리가 말한다면command1
command2
command2
command1
(구현하다 명령 1;명령 2)&
그러면 실행되지만 실행되지는 않습니다.command1
command2
- 그건근소한단순화하다. 우리가 말한다면
- 리디렉션뿐만 아니라 스크립트에서 올바르게 구성된 명령을
exec
따르는 모든 항목은 무시됩니다.exec
실패 하더라도 후속 행을 실행하지 않고 쉘이 종료됩니다(command exec ...
또는 옵션bash
을 사용하여 실패 시 쉘이 종료되는 것을execfail
방지 할 수 있습니다).exec
- in 또는 또는 와
exec
같은 하위 쉘에서 실행되는 경우 해당 하위 쉘만 종료됩니다.exec cmd &
exec cmd | cmd2
(exec cmd3)
- 확인 명령에서 서버 프로세스의 PID를 알아야 한다면 운이 좋지 않을 수도 있습니다.
그렇지 않고 서버가 시작될 때까지 verify 명령이 자동으로 잠시 기다리는 경우 다음을 수행할 수 있습니다.
export FOO=foo # step 1 /usr/bin/java my-validation & # step 1½ exec /usr/bin/java my-server # step 2
그렇지 않으면 이렇게 할 수 있습니다
export FOO=foo # step 1 (sleep 10; /usr/bin/java my-validation) & # step 1½ exec /usr/bin/java my-server # step 2
경고: "my-server" 프로세스가 빠르게 종료되면 "my-validation" 명령이 실행되기 전에 스크립트가 종료될 가능성이 높으며 상위 프로세스가 제어권을 되찾고 실행을 재개합니다. 상위 프로세스와 "my-validation" 명령이 모두 동일한 위치에 출력을 쓰는 경우 혼합될 수 있습니다.
그러나 상위 프로세스가 스크립트가 종료될 때까지 기다리지 않으면 이는 문제가 되지 않을 수 있습니다.
답변2
exec program
스크립트의 프로세스를 new 로 대체하므로 program
의미가 있는 경우에만 사용해야 합니다. 즉, 현재 스크립트가 사라지고 후속 명령이 실행될 수 없습니다( exec program
실패하지 않는 한).
exec program
셸 스크립트의 마지막 줄은 program
오랫동안 실행될 때 유용하고 쓸모없는 셸 프로세스가 종료될 때까지 프로세스 트리에 남아 있는 것을 원하지 않기 때문입니다 program
. 또는 기타 처리 도구를 사용하여 pstree
다음 간의 차이점을 확인하세요.
#!/bin/sh
echo $$
sleep 9999
그리고
#!/bin/sh
echo $$
exec sleep 9999
exec program
이후에 다른 쉘 명령을 실행하려는 경우에는 전혀 exec
유용 하지 않습니다.도달하지 못함( exec
실패하지 않는 한).
실제로 시작 후 무언가를 확인하는 것은 매우 까다롭습니다. /usr/bin/java my-server
시작하는 데 시간이 걸리기 때문입니다. (Java는 이와 관련하여 매우 느릴 수 있습니다. Java 프로세스가 사용 가능해지거나 자체 종료되는 데 45초 이상이 걸리는 것으로 기억합니다...) 시스템 사용량에 따라 다릅니다. 학위나 일정에 따라 검증 프로세스가 my-server
이전 또는 이후에 실행될 수 있습니다. 크루거로서 다음과 같은 방법으로 검증 단계를 지연시킬 수 있습니다.
export FOO=foo
/usr/bin/java my-server &
sleep 10
exec /usr/bin/java my-validation
자체 시작 하는 데 10초가 주어지는데 my-server
, 이는 시스템 사용량과 my-server
시작하는 데 걸리는 시간에 따라 충분할 수도 있고 충분하지 않을 수도 있습니다. 이번에도 Java 프로세스를 시작하는 데 45초 이상이 걸리고 사용량이 많은 시스템에서는 더 오래 걸릴 수 있다는 사실을 발견했습니다. 일어나서 실행될 때까지 기다릴 만큼 똑똑하다면 이것이 sleep
필요하지 않을 수도 있습니다.my-validation
my-server
그냥 서버를 시작하는 것이 더 합리적일 수 있습니다.
#!/bin/sh
export FOO=foo
exec /usr/bin/java my-server
서비스가 실행 중인지 확인합니다.모니터링 프레임워크를 통해,다른 장소들.
또 다른 접근 방식은 systemd
셸 스크립트보다 더 나은 프로세스 제어를 제공하는 다른 최신 init 프레임워크와 통합하는 것입니다. 예를 들어 프로세스가 systemd
올바르게 시작되었는지 여부에 대한 정보를 반환하거나 systemd
다양한 조건에서 서비스가 자동으로 다시 시작될 수 있습니다.