bash에서 "exec echo some; echo test"를 실행하면 "some test"가 인쇄되지 않습니까?

bash에서 "exec echo some; echo test"를 실행하면 "some test"가 인쇄되지 않습니까?

exec echo "some "; echo "test"bash에서 실행하면 "일부 테스트"가 인쇄되지 않습니까?

exec나는 작은 쉘 스크립트를 작성 중이고 명령이 호출된 후에는 아무것도 계속하지 않기를 원하기 때문에 이 질문에 대한 확인을 구하고 싶습니다 .

상담 후 이해한 바에 따르면 걱정할 필요가 없다고 생각합니다.

  • man 3 exec
  • man 1p exec

쉘 스크립트는 쉘에 의해 실행될 때 다음을 수행합니다.

  1. 쉘은 프로그램을 실행합니다 exec.
  2. exec***스크립트를 실행하던 쉘/배시를 대체하는 패밀리 시스템 호출을 사용합니다 .방해하는셸의 추가 작업("교체"됨)

이전에 설명했듯이 이 질문의 주요 목표는 exec 이후에 스크립트에서 발생하는 모든 항목(예: echo test)이 실행되는 것을 방지하기 위해 내 추론에 대한 확인을 구하는 것입니다.

가능한 한 일반적인 답변(POSIX)을 주시면 감사하겠습니다. 하지만 특수한 경우에는 GNU/Linux 및 GNU/Bash에 가장 관심이 있습니다.

답변1

그렇군요. 성공하면 exec현재 쉘을 대체하므로 다음 명령은 실행되지 않습니다.

하지만,적어도 Bash에서는, 다음과 같은 경우에도 쉘이 종료됩니다.exec 실패하다:

exec [-cl] [-a name] [command [arguments]]

만약에명령제공되면 새 프로세스를 생성하지 않고 셸을 교체합니다. [...] 만약에명령어떤 이유로든 실행될 수 없는 경우, 쉘 옵션이 활성화되어 있지 않으면 비대화형 쉘이 종료됩니다 execfail. 이 경우 실패를 반환합니다.

따라서 유사한 것조차도 bash -c 'exec /bin/nosuchfile; echo foo'누락된 프로그램 파일에 대한 오류 메시지를 인쇄합니다. 스크립트의 오류를 처리하려면 다음과 같은 것이 필요합니다.

#!/bin/bash
shopt -s execfail
exec /someprogram
echo whoops, it failed

그러나 여전히 에서 오류 메시지가 나타납니다 exec. 에 리디렉션을 설정 exec하면그것은 유효하다실패한 후에도 스크립트가 계속되는 경우 exec.

답변2

내장 exec(명령 인수 1 포함)은 셸 프로세스 ²를 대체합니다. 쉘 프로세스의 후속 코드는 실행되지 않습니다.

따라서 exec echo "some "; echo "test"인쇄할 수 있는 유일한 방법 은 PATH에 some text호출된 실행 가능 명령이 있고 이 실행 파일이 . 실행 파일이 이라는 명령에서 예상한 대로 동작하는 일반적인 상황에서는 이런 일이 발생할 수 없습니다 .echosome textsomeechoecho

echoPATH에 호출된 실행 파일이 없거나 실행에 실패하면 exec오류 메시지를 표시하고 셸을 종료합니다. 이 경우에도 echo "test"실행되지 않습니다.

¹ 명령 인수가 없으면 다른 짐승입니다. 이는 쉘 프로세스를 대체하지 않고 단지 리디렉션을 적용합니다. ² 하위 셸에서는 하위 셸만 영향을 받으며 상위 셸은 정상적으로 계속 실행됩니다. exec

답변3

exec항상 스크립트를 끝냅니다만약에명령을 실행하고 성공적으로 수행합니다(명령의 종료 코드와 관련이 없지만 시작과 관련이 있음).

exec매우 유용한 방법으로 명령 없이 실행할 수 있습니다. 파일 설명자를 영구적으로 리디렉션하려면 다음을 수행하세요.

exec 3>/path/to/file

명령을 시작할 수 없는 경우 쉘 동작은 구성에 따라 달라집니다. bash기본적으로 종료됩니다.

대신 함수를 사용하는 것이 가장 좋을 수 있습니다.

safe_exec () {
    cmd="$1"
    if test -z "$cmd" || ! test -f "$cmd" || ! test -x "$cmd"; then
        exit 1
    else
        exec "$@"
    fi
}

safe_exec echo "some "; echo "test"

관련 정보