sourcetip

bash 스크립트에서 set -e는 무엇을 의미합니까?

fileupload 2023. 4. 13. 21:07
반응형

bash 스크립트에서 set -e는 무엇을 의미합니까?

패키지가 Debian 아카이브(.deb) 파일에서 압축 해제되기 전에 스크립트가 실행하는 preinst 파일의 내용을 검토하고 있습니다.

스크립트에는 다음 코드가 있습니다.

#!/bin/bash
set -e
# Automatically added by dh_installinit
if [ "$1" = install ]; then
   if [ -d /usr/share/MyApplicationName ]; then
     echo "MyApplicationName is just installed"
     return 1
   fi
   rm -Rf $HOME/.config/nautilus-actions/nautilus-actions.conf
   rm -Rf $HOME/.local/share/file-manager/actions/*
fi
# End automatically added section

첫 번째 질문은 라인에 대한 것입니다.

set -e

나머지 스크립트는 매우 간단하다고 생각합니다.Debian/Ubuntu 패키지 매니저가 설치 작업을 실행하고 있는지 확인합니다.설정되어 있는 경우는, 애플리케이션이 시스템에 인스톨 되고 있는지 확인합니다.설치되어 있는 경우 스크립트는 "My Application Name is just installed" 라는 메시지를 인쇄하고 종료합니다(return 1" 오류"로 끝나는 말은, 그렇지 않나요?'오류'로 끝나는 거죠?

사용자가 Debian/Ubuntu 패키지 시스템에 내 패키지를 설치하도록 요청하면 스크립트는 두 개의 디렉토리도 삭제합니다.

이게 맞나? 아니면 내가 뭘 놓쳤나?

터에서help set :: ::

  -e  Exit immediately if a command exits with a non-zero status.

그러나 일부(bash FAQ 및 ircfreenode #bash FAQ 작성자)에서는 이를 악습으로 간주하고 있습니다.다음을 사용하는 것이 좋습니다.

trap 'do_something' ERR

리 달을 하다do_something오류가 발생할 때 기능기능을 합니다.

http://mywiki.wooledge.org/BashFAQ/105 를 참조해 주세요.

set -e명령 또는 파이프라인에 오류가 있는 경우 스크립트의 실행을 중지합니다.이것은 스크립트의 오류를 무시하는 기본 셸 동작과는 반대입니다.「」라고 입력합니다.help set이 삽입 명령어 매뉴얼을 참조할 수 있습니다.

이 게시물은 다음 이유로 인해 중단된 스크립트의 종료 상태를 확인하던 중 발견되었습니다.set -e그 답은 명백해 보이지 않았다.그래서 이 답변이 나왔다.기본적으로는 명령어(셸 스크립트 등)의 실행을 중단하고 실패한 명령어의 종료 상태 코드(외부 스크립트가 아닌 내부 스크립트)를 반환합니다.

해 보겠습니다.outer-test.sh:

#!/bin/sh
set -e
./inner-test.sh
exit 62;

★★★의 inner-test.sh 말합니다

#!/bin/sh
exit 26;

★★★★★★★★★★★★★★★를 실행했을 때,outer-script.sh명령줄에서 외부 스크립트는 내부 스크립트의 종료 코드로 종료됩니다.

$ ./outer-test.sh
$ echo $?
26

Bash에 따라 - 기본 제공 설정 매뉴얼,-e/errexit를 설정하면 단일 단순 명령어, 목록 명령어 또는 복합 명령어로 구성된 파이프라인이0 이외의 상태를 반환하면 셸이 즉시 종료됩니다.

입니다.단, 이 경우는 예외입니다.pipefail옵션은 활성화되어 있습니다(기본적으로 비활성화되어 있습니다).

이 경우 파이프라인이 0이 아닌 상태로 종료하기 위한 마지막(오른쪽 끝) 명령의 반환 상태 또는 모든 명령이 성공적으로 종료된 경우 0입니다.

때 를 실행하고 때는 을 정의해 .trap예를 들어 다음과 같습니다.

trap onexit EXIT

서 ''는onexit는, 다음과 같은 작업을 종료시에 실시하는 기능입니다.이것은 단순한 스택트레이스를 인쇄하는 것입니다.

onexit(){ while caller $((n++)); do :; done; }

대신 ERR에 트랩되는 유사한 옵션 /errtrace이 있습니다.다음은 예를 제시하겠습니다.

trap onerr ERR

제로 상태의 예:

$ true; echo $?
0

0이 아닌 상태의 예:

$ false; echo $?
1

상태 부정 예시:

$ ! false; echo $?
0
$ false || true; echo $?
0

스트로 합니다.pipefail★★★★★★★★★★★★★★★★★★:

$ bash -c 'set +o pipefail -e; true | true | true; echo success'; echo $?
success
0
$ bash -c 'set +o pipefail -e; false | false | true; echo success'; echo $?
success
0
$ bash -c 'set +o pipefail -e; true | true | false; echo success'; echo $?
1

스트로 합니다.pipefail★★★★★★★★★★★★★★★★★★:

$ bash -c 'set -o pipefail -e; true | false | true; echo success'; echo $?
1

이지만, 논하고 있지 않습니다.set -e a a a aset -o errexitDebian 패키지 처리 스크립트에 포함되어 있습니다.이러한 스크립트에서는 Debian 정책에 따라 이 옵션의 사용은 필수입니다.처리되지 않은 에러 상태의 가능성을 회피하는 것이 목적이라고 생각됩니다.

실제로는 실행하는 명령어가 오류를 반환할 수 있는 조건을 이해하고 각각의 오류를 명시적으로 처리해야 합니다.

일반적인 곶차는 예를 들어 다음과 같습니다. diff 때 한다) 및 (차이가 있을 때 오류를 발견한다)grep(일치하지 않는 경우는 에러가 발생합니다).명시적 처리를 통해 오류를 방지할 수 있습니다.

diff this that ||
  echo "$0: there was a difference" >&2
grep cat food ||
  echo "$0: no cat in the food" >&2

(또한 현재 스크립트의 이름을 메시지에 포함하도록 주의하고 표준 출력이 아닌 표준 오류에 진단 메시지를 쓰는 방법도 주의해 주십시오).

정말로 필요하거나 도움이 되는 명시적인 처리가 없는 경우는, 명시적으로 아무것도 실시하지 말아 주세요.

diff this that || true
grep cat food || :

(셸의사사))):불명확하지만 으로 볼 수 있습니다no-op 명령어는 no-op 명령어입니다.

다시 한 번 말씀드리지만

something || other

의 줄임말이다

if something; then
    : nothing
else
    other
fi

'아,아,아,아,아,아,아,아,아,아,아,아,아,아,아,아,아,아,아,아,아,아,아,아other은 반드시 되어야 한다.something이 나쁘다. 손잡이if셸 제어 (예: (셀플로우 제어 스테이트먼트))while,until그렇지셸에는 「」가 붙어 있습니다).set -e 문을 할 수 flow control 문을 포함할 수 없습니다.

분명히 에는, 이 핸들러가 없는 경우에는, 이 핸들러를 사용할 수 없습니다.set -e 경우 스크립트 실패하고 합니다.diff하거나 ()grep일치하는 것을 찾지 못했습니다.

한편, 일부 명령어는 원하는 시간에 오류 종료 상태를 생성하지 않습니다.일반적으로 문제가 있는 명령어는 다음과 같습니다.find되지 않음) 및 (파일이 실제로 발견되었는지 여부를 나타내지 않음)sed(프로세서 상태는 스크립트가 입력을 받았는지 또는 실제로 명령을 성공적으로 수행했는지 여부를 나타내지 않습니다).시나리오에 따라서는 출력이 없을 경우 비명을 지르는 명령어에 파이프로 접속하는 것이 간단한 가드입니다.

find things | grep .
sed -e 's/o/me/' stuff | grep ^

파이프라인의 종료 상태는 해당 파이프라인의 마지막 명령어 종료 상태입니다. 위의 는 실제로 .find ★★★★★★★★★★★★★★★★★」sed , , , , , , , , , , , ,의.grep디어성성 성성성다다

는 (Bash)가 있다.set -o pipefail features , Debian "Bash" "Bash" "Bash" "Bash" "Bash" "Bash" "Bash" "Bash" "Bash" "Bash"은 POSIX의 하고 있습니다.sh이러한 스크립트의 경우는, 반드시 그렇지만은 않습니다).

대부분의 경우, 이것은 방어적으로 코딩할 때 별도로 주의해야 할 사항입니다.때로는 예를 들어 임시 파일을 통해 출력을 생성한 명령어가 정상적으로 완료되었는지 여부를 확인할 수 있어야 합니다. 예를 들어 관용어와 편의상 셸 파이프라인을 사용하도록 지시하는 경우에도 마찬가지입니다.

저는 문제의 대본이 빨리 실패하는 것이 목적이라고 생각합니다.

그냥 하세요.set -e 그럼 이번에는 '마음', '마음', '마음', ''을 실행해 보세요.ls이치노 이제 ㅇ, ㅇ, ㅇ, ㅇ, ㅇ, ㅇ, ㅇ, ㅇ, ㅇ, ㅇlsd. 이에).set -e를 참조해 주세요.

이것을 「스크립트」의 맥락에서 이해하려면 , 다음의 간단한 스크립트를 사용합니다.

#!/bin/bash 
# set -e

lsd 

ls

ls코멘트set -e다시 하면, 리스트는 되지 않습니다 때, 는 처리를 합니다.lsd.

set - e set - e 옵션은 명령어 [1]의 종료 상태가 0이 아닌 경우 즉시 종료하도록 bash에게 지시합니다.명령줄 셸에 이 설정을 하고 싶지 않을 수도 있지만 스크립트에서는 매우 유용합니다.널리 사용되는 모든 범용 프로그래밍 언어에서 처리되지 않은 런타임 오류(Java에서 예외 발생, C에서 세그멘테이션 오류, Python에서 구문 오류 등)는 프로그램 실행을 즉시 중단하고 후속 행은 실행되지 않습니다.

  • 기본적으로는 bash는 이 작업을 수행하지 않습니다.이 기본 동작은 명령줄에서 bash를 사용하는 경우 원하는 동작입니다.
  • 오타가 있으면 로그아웃하지 마세요!하지만 대본에서는, 당신은 정말로 그 반대를 원한다.
  • 스크립트의 한 행이 실패했지만 마지막 행이 성공했을 경우 스크립트 전체에 종료 코드가 표시됩니다.그러면 오류를 쉽게 놓칠 수 있습니다.
  • 다시 말씀드리지만 bash를 명령줄 셸로 사용하고 스크립트에서 사용할 때 필요한 것은 서로 다릅니다.스크립트에서 오류를 허용하지 않는 것이 훨씬 더 좋습니다. 이것이 set -e가 제공하는 것입니다.

복사원 : https://gist.github.com/mohanpedala/1e2ff5661761d3abd0385e8223e16425

이것은 당신에게 도움이 될 것입니다.

Script 1: without setting -e
#!/bin/bash
decho "hi"
echo "hello"
This will throw error in decho and program continuous to next line

Script 2: With setting -e
#!/bin/bash
set -e
decho "hi" 
echo "hello"
# Up to decho "hi" shell will process and program exit, it will not proceed further

명령이 실패하면 스크립트의 실행을 중지합니다.

할 만한 는 " " " 입니다.if예: 예:

set -e
false
echo never executed
set -e
if false; then
  echo never executed
fi

echo executed

false

echo never executed
cat a.sh
#! /bin/bash

#going forward report subshell or command exit value if errors
#set -e
(cat b.txt)
echo "hi"

./a.sh; echo $?
cat: b.txt: No such file or directory
hi
0

set - e comment out을 지정하면 에코 "hi" 종료 상태가 보고되고 hi가 출력됩니다.

cat a.sh
#! /bin/bash

#going forward report subshell or command exit value if errors
set -e
(cat b.txt)
echo "hi"

./a.sh; echo $?
cat: b.txt: No such file or directory
1

대신 b.txt 오류가 보고되고 hi가 출력되지 않습니다.

따라서 셸 스크립트의 기본 동작은 명령어오류를 무시하고 처리를 계속하여 마지막 명령어 종료 상태를 보고하는 것입니다.오류 발생 시 종료하고 상태를 보고하려면 -e 옵션을 사용할 수 있습니다.

언급URL : https://stackoverflow.com/questions/19622198/what-does-set-e-mean-in-a-bash-script

반응형