exec
둘 중 하나를 분기하지 마십시오 . env
다음 예를 참조하십시오.
docker run --rm -it ubuntu:18.04 sh -c 'exec sleep 1 & ps -Ho pid,ppid,cmd'
PID PPID CMD
1 0 sh -c exec sleep 1 & ps -Ho pid,ppid,cmd
7 1 sleep 1
8 1 ps -Ho pid,ppid,cmd
docker run --rm -it ubuntu:18.04 sh -c 'env sleep 1 & ps -Ho pid,ppid,cmd'
PID PPID CMD
1 0 sh -c env sleep 1 & ps -Ho pid,ppid,cmd
7 1 sleep 1
8 1 ps -Ho pid,ppid,cmd
질문
많은 사람들이 사용하는 것을 보지만 과 같지 않기 때문에 필요 exec env ...
하지 않다고 생각합니다 .exec
env
exec
exec env
대신 사용해야 하는 사용 사례가 있나요 env
?
답변1
env
(아마도) 자신을 분기하지 않고 실행하는 프로그램으로 자신을 대체합니다. 그러나 이는 상위 쉘을 분기하거나 env
단순히 env
.
예를 들어 다음 두 가지를 비교하십시오.
$ bash -c 'env ls > /dev/null; echo hi'
hi
$ bash -c 'exec env ls > /dev/null; echo hi'
[no output]
를 사용하면 exec
쉘 자체가 교체되고 다음이 echo
실행되지 않습니다.
물론 당신은 exec env ... &
. 를 사용하면 &
쉘은 어쨌든 백그라운드 프로세스를 시작하기 위해 분기되며 분기되지 않을 수 있습니다.다시백그라운드 작업에서 단일 명령을 실행합니다. 적어도 Bash는 이 상황을 최적화합니다. 예를 들면 다음과 같습니다.
$ bash -c 'ps -Ho pid,ppid,cmd; echo x'
PID PPID CMD
11967 1545 -/bin/bash
14851 11967 bash -c ps -Ho pid,ppid,cmd; echo x
14852 14851 ps -Ho pid,ppid,cmd
x
$ bash -c 'ps -Ho pid,ppid,cmd'
PID PPID CMD
11967 1545 -/bin/bash
14853 11967 ps -Ho pid,ppid,cmd
후자가 중간 프로세스를 표시하지 않으면 bash
해당 프로세스가 존재하는 것처럼 동작합니다 exec
. ( -/bin/bash
내 대화형 쉘입니다.)
Bash는 단일 명령에 대해서만 이 작업을 수행합니다. 명령이 여러 개인 경우 쉘은 마지막 명령이 종료될 때까지 기다립니다. 사용하는 방법 exec
은 다를 것입니다:
$ bash -c 'echo x; ps -Ho pid,ppid,cmd'
x
PID PPID CMD
11967 1545 -/bin/bash
14929 11967 bash -c echo x; ps -Ho pid,ppid,cmd
14930 14929 ps -Ho pid,ppid,cmd
$ bash -c 'echo x; exec ps -Ho pid,ppid,cmd'
x
PID PPID CMD
11967 1545 -/bin/bash
14933 11967 ps -Ho pid,ppid,cmd
의 경우 &
이는 다음과 동일합니다 exec ps
.
$ bash -c 'ps -Ho pid,ppid,cmd & sleep 1'
PID PPID CMD
11967 1545 -/bin/bash
14867 11967 bash -c ps -Ho pid,ppid,cmd & sleep 1
14868 14867 ps -Ho pid,ppid,cmd
14869 14867 sleep 1
그러나 복합 블록을 통해 백그라운드 셸 프로세스도 볼 수 있습니다.
$ bash -c '{ ps -Ho pid,ppid,cmd; } & sleep 1'
PID PPID CMD
11967 1545 -/bin/bash
14877 11967 bash -c { ps -Ho pid,ppid,cmd; } & sleep 1
14878 14877 bash -c { ps -Ho pid,ppid,cmd; } & sleep 1
14880 14878 ps -Ho pid,ppid,cmd
14879 14877 sleep 1
이 사람들이 무엇을 했는지에 대한 구체적인 출처를 제공하지 않았기 exec env
때문에 그들의 정확한 상황을 알 수 없습니다. 그러나 셸을 다른 프로세스로 바꾸려면 다음 exec env
과 같은 방법을 사용할 수 있습니다. exec anyprogram
예를 들어 다음 시뮬레이션 예는 다음과 같습니다.
#!/bin/bash
. someconfigfile
if [ "$someconfig" = blah ]; then
exec env myprogram some args...
echo "failed to start" >&2
exit 1
elif
... whatever
fi
exec
쉘이 메모리에 쓸데없이 남아 있지 않도록 스크립트를 시작된 프로그램으로 교체 하십시오 . 또한 스크립트에 프로그램을 시작하는 중개자가 하나만 있는 경우 중개자를 수행하면 exec
PID가 동일하게 유지되므로 부모(스크립트의 부모, 그 다음에는 프로그램의 부모)가 자식을 더 쉽게 모니터링할 수 있습니다.