질문

질문

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 ...하지 않다고 생각합니다 .execenvexec

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쉘이 메모리에 쓸데없이 남아 있지 않도록 스크립트를 시작된 프로그램으로 교체 하십시오 . 또한 스크립트에 프로그램을 시작하는 중개자가 하나만 있는 경우 중개자를 수행하면 execPID가 동일하게 유지되므로 부모(스크립트의 부모, 그 다음에는 프로그램의 부모)가 자식을 더 쉽게 모니터링할 수 있습니다.

관련 정보