"exec"명령은 무엇을합니까?


108

bash 명령을 이해하지 못합니다 exec. 모든 출력을 파일로 리디렉션하기 위해 스크립트 내부에서 사용되는 것을 보았습니다 ( this 참조 ). 그러나 그것이 어떻게 작동하는지 또는 일반적으로 무엇을하는지 이해하지 못합니다. 매뉴얼 페이지를 읽었지만 이해할 수 없습니다.


프로세스 에 대한 지식 이 있습니까?
fkraiem

1
@fkraiem 무슨 뜻인가요?
becko September

"무엇"을 의미하는 것이 미안합니다. : p 그러나 대답은 '아니오'인 것 같습니다.
fkraiem

그러나 실제로 스크립트는 exec훨씬 더 간단하게 설명 할 수있는 특별한 방식으로 사용합니다 . 나는 답을 쓸 것입니다.
fkraiem

답변:


88

man bash 말한다 :

exec [-cl] [-a name] [command [arguments]]
      If command is specified, it replaces the shell.  No new  process
      is  created.  The arguments become the arguments to command.  If
      the -l option is supplied,  the  shell  places  a  dash  at  the
      beginning  of  the  zeroth  argument passed to command.  This is
      what login(1) does.  The -c option causes command to be executed
      with  an empty environment.  If -a is supplied, the shell passes
      name as the zeroth argument to the executed command.  If command
      cannot  be  executed  for  some  reason, a non-interactive shell
      exits, unless the execfail shell option  is  enabled.   In  that
      case,  it returns failure.  An interactive shell returns failure
      if the file cannot be executed.  If command  is  not  specified,
      any  redirections  take  effect  in  the  current shell, and the
      return status is 0.  If there is a redirection error, the return
      status is 1.

마지막 두 줄이 중요합니다. exec명령없이 단독으로 실행하면 리디렉션이 현재 셸에 적용됩니다. 를 실행할 때 터미널 대신에 command > file출력 command이 쓰여진다는 것을 알고있을 것입니다 file( 리디렉션 이라고 함 ). exec > file대신 실행 하면 리디렉션이 전체 셸에 적용됩니다. 셸에서 생성 된 모든 출력이 file터미널 대신 작성됩니다 . 예를 들어 여기

bash-3.2$ bash
bash-3.2$ exec > file
bash-3.2$ date
bash-3.2$ exit
bash-3.2$ cat file
Thu 18 Sep 2014 23:56:25 CEST

먼저 새로운 bash쉘을 시작합니다 . 그런 다음이 새로운 셸에서 exec > file모든 출력이로 리디렉션되도록을 실행 합니다 file. 실제로 그 후에는 실행 date되지만 출력이 리디렉션되기 때문에 출력이 없습니다 file. 그런 다음 쉘을 종료하고 (더 이상 리디렉션이 적용되지 않음) file실제로 date이전에 실행 한 명령 의 출력이 포함되어 있음을 알 수 있습니다 .


42
이것은 부분 설명 일뿐입니다. exec현재 쉘 프로세스를 명령으로 대체하여 부모가 길을 가고 자식이 pid를 소유하도록합니다. 이것은 리디렉션만을위한 것이 아닙니다. 이 정보를 추가해주세요
Sergiy Kolodyazhnyy

3
@SergiyKolodyazhnyy의 의견에 이어, 내가 방금 마주 친 예제는 docker-entrypoint.sh이며 nginx 설정에서 다양한 작업을 수행 한 후 스크립트의 마지막 줄은입니다 exec nginx <various nginx arguments>. 이것은 nginx가 bash 스크립트의 pid를 인계하고 이제 nginx는 스크립트가 아닌 컨테이너의 주요 실행 프로세스입니다. 다른 사람이 더 구체적인 이유를 알지 않는 한 이것이 청결에 불과하다고 생각합니까?
Luke Griffiths

1
@Luke "래퍼 스크립트"라고합니다. 이것의 예는 또한 gnome-terminal적어도 14.04에 인수를 설정하는 래퍼 스크립트를 가지고있는입니다. 그리고 그것은 그들의 유일한 목적이며, 실제로 예술과 환경을 설정합니다. 새 첫번째 프로세스의 이전 인스턴스를 죽이고 시작 - 또 다른 경우는 청소하는 것
세르지 Kolodyazhnyy

다른 exec받는 유사한 예를 nginx@LukeGriffiths에 의해 주어진 예제입니다 ~/.vnc/xstartup스크립트 vncserver다음 VNC 서버 프로세스 및 구성하는 데 사용 exec gnome-session또는 exec startkde등등을.
Trevor Boyd Smith

exec컨테이너 시작 스크립트에서 주된 이유 인 @LukeGriffiths는 컨테이너의 ENTRYPOINT 인 PID 1이 Docker에서 특별한 의미를 갖기 때문입니다. 신호를 수신하는 주요 프로세스이며, 존재하는 경우 컨테이너도 종료됩니다. exec단지 방법이 걸릴 sh명령의 사슬에서, 데몬에게 용기의 주 과정을합니다.
kkm

46

exec 하나 이상의 인수가 사용되는지 또는 전혀 인수가 사용되지 않는지 여부에 따라 두 가지 고유 한 동작을 가진 명령입니다.

  • 최소한 하나의 인수가 전달되면 첫 번째 인수는 명령 이름으로 사용되며 exec나머지 인수는 해당 명령에 전달하고 재 지정 (있는 경우)을 관리하는 명령으로 실행하십시오.

  • 첫 번째 인수로 전달 된 명령이 존재하지 않으면 exec 명령뿐만 아니라 현재 쉘도 오류로 종료됩니다.

  • 명령이 존재하고 실행 가능하면 현재 쉘을 대체합니다. 즉 exec, 스크립트에 나타나는 경우 exec 호출 다음에 나오는 명령 은 절대로 실행되지 않습니다 ( exec서브 쉘 자체가 아닌 한 ). exec절대 반환하지 않습니다. "EXIT"와 같은 쉘 트랩도 트리거되지 않습니다.

  • 인수가 전달되지 않으면 exec현재 쉘 파일 설명자를 재정의하는 데만 사용됩니다. 쉘은 exec이전의 경우와 달리, 이후에 계속 되지만 표준 입력, 출력, 오류 또는 경로 재 지정된 파일 설명자가 적용됩니다.

  • 일부 리디렉션에서을 사용하는 /dev/null경우 해당 입력은 EOF를 반환하고 모든 출력은 삭제됩니다.

  • -소스 또는 대상 으로 사용하여 파일 디스크립터를 닫을 수 있습니다 ( 예 :) exec <&-. 이후의 읽기 또는 쓰기가 실패합니다.

다음은 두 가지 예입니다.

echo foo > /tmp/bar
exec < /tmp/bar # exec has no arguments, will only affect current shell descriptors, here stdin
cat # simple command that read stdin and write it to stdout

이 스크립트는 "foo"를 cat 명령으로 출력합니다. 일반적인 경우와 같이 사용자 입력을 기다리지 않고 foo를 포함하는 / tmp / bar 파일에서 입력을받습니다.

echo foo > /tmp/bar
exec wc -c < /tmp/bar # exec has two arguments, the control flow will switch to the wc command
cat

이 스크립트는 4(/ tmp / bar의 바이트 수)를 표시하고 즉시 종료됩니다. cat명령이 실행되지 않습니다.


4
`일부 오래된 게시물은 실제로 오래되지 않습니다 ... +1.
Cbhihe

3
일부 리디렉션에서 / dev / null을 사용하면 관련 파일 설명자가 닫힙니다. 아니요, 실제로로 /에서 리디렉션 /dev/null하므로 쓰기는 여전히 성공하고 읽기 EOF를 읽습니다. close(2)fd에서 읽기 / 쓰기 시스템 호출로 인해 오류가 발생하고 exec 2>&-예를 들어 이를 수행합니다 .
Peter Cordes

2
직접 시도해보십시오 : exec 3</dev/null; ls -l /proc/self/fd: fd 3은 / dev / null에서 읽기 전용으로 열립니다. 그런 다음으로 다시 닫으면 쉘 프로세스에 더 이상 fd 3이 없음 exec 3<&-ls -l /proc/$$/fd다시 알 수 있습니다 . (stdin을 닫으면 exec <&-스크립트에서 유용 할 수 있지만 대화식으로 로그 아웃됩니다.)
Peter Cordes

@PeterCordes 당신은 절대적으로 맞습니다. 답변이 업데이트되었습니다. 감사!
jlliagre

1
이 답변은 현재 가장 많이 찬성 된 답변 의 두 가지 유스 케이스가 exec한 유스 케이스에 대해서만 이야기하고 g_p에 의한 다른 대답은 다른 유스 케이스에 대해서만 이야기하기 때문에 훌륭합니다. 그리고이 답변은 그러한 복잡한 주제에 대해 훌륭하고 간결하고 읽을 수 있습니다.
Trevor Boyd Smith

33

이해하려면 exec먼저 이해해야 fork합니다. 짧게 유지하려고합니다.

  • 도로에서 분기점에 올 때 일반적으로 두 가지 옵션이 있습니다. 리눅스 프로그램은 fork()시스템 콜을 했을 때이 포크에 도달합니다 .

  • 일반 프로그램은 시스템에서 컴파일 된 형태로 존재하는 시스템 명령입니다. 이러한 프로그램이 실행되면 새로운 프로세스가 생성됩니다. 이 하위 프로세스는 상위 프로세스와 동일한 환경을 가지며 프로세스 ID 번호 만 다릅니다. 이 절차를 포크 라고 합니다.

  • 분기는 기존 프로세스가 새로운 프로세스를 시작할 수있는 방법을 제공합니다. 그러나 하위 프로세스가 상위 프로세스와 동일한 프로그램의 일부가 아닌 상황이있을 수 있습니다. 이 경우 exec에 사용됩니다. exec 현재 실행중인 프로세스의 내용을 프로그램 바이너리의 정보로 바꿉니다.
  • 분기 프로세스 이후에 하위 프로세스의 주소 공간이 새 프로세스 데이터로 덮어 쓰기됩니다. 이것은 시스템에 대한 exec 호출을 통해 수행됩니다.

3
exec내가 게시 한 링크에서와 같이 스크립트 출력을 리디렉션 할 수있는 이유를 설명 할 수 있습니까?
becko

1
"그러나 자식 프로세스가 부모 프로세스와 같은 프로그램의 일부가 아닌 상황이있을 수 있습니다"
cdosborn

6

에서 bash할 경우 help exec:

$ help exec
exec: exec [-cl] [-a name] [command [arguments ...]] [redirection ...]
    Replace the shell with the given command.

    Execute COMMAND, replacing this shell with the specified program.
    ARGUMENTS become the arguments to COMMAND.  If COMMAND is not specified,
    any redirections take effect in the current shell.

    Options:
      -a name   pass NAME as the zeroth argument to COMMAND
      -c        execute COMMAND with an empty environment
      -l        place a dash in the zeroth argument to COMMAND

    If the command cannot be executed, a non-interactive shell exits, unless
    the shell option `execfail' is set.

    Exit Status:
    Returns success unless COMMAND is not found or a redirection error occurs.

관련 비트 :

If COMMAND is not specified, any redirections take effect in the current shell.

execA는 쉘 내장 의 쉘과 동일, exec가족 시스템이 호출하는 것을 G_P가 말한다 (누구의 맨 페이지를 읽고 것으로 보인다). 그것은 단지가 POSIX 위임 명령을 지정하지 않으면 현재 쉘에 영향을 미치는 기능을.

당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.