grep으로 인해 "bash -e" 스크립트가 조기 종료되지 않도록 방지

grep으로 인해 "bash -e" 스크립트가 조기 종료되지 않도록 방지

스크립트는 출력되지 않습니다 after.

#!/bin/bash -e

echo "before"

echo "anything" | grep e # it would if I searched for 'y' instead

echo "after"
exit

Shebang 라인에서 옵션을 제거하여 이 문제를 해결할 수 있지만 -e스크립트가 오류 발생 시 중지되도록 유지하고 싶습니다. 나는 grep일치하는 것을 찾는 것이 버그라고 생각하지 않습니다 . 갑자기 종료되는 것을 어떻게 방지할 수 있나요?

답변1

echo "anything" | { grep e || true; }

설명하다:

  • 오류가 발생합니다.
    $ echo "anything" | grep e
    $ echo $?
    1
    
  • 이것은 오류를 발생시키지 않습니다
    $ echo "anything" | { grep e || true; }
    $ echo $?
    0
    
  • 오류를 발생시키지 않는 DopeGhoti의 "no-op" 버전( true내장 프로세스가 아닌 경우 프로세스 생성을 피할 수 있음)
    $ echo "anything" | { grep e || :; }
    $ echo $?
    0
    

"또는" 이라는 뜻입니다 ||. 명령의 첫 번째 부분이 "실패"하면( grep e0이 아닌 종료 코드를 반환함을 의미) ||실행 후 부분은 성공하고 종료 코드로 0을 반환합니다( true항상 0이 반환됨).

답변2

안전하고 믿을 수 있는 방법선택적으로 grep정보:

echo something | grep e || [[ $? == 1 ]] ## print 'something', $? is 0
echo something | grep x || [[ $? == 1 ]] ## no output, $? is 0
echo something | grep --wrong-arg e || [[ $? == 1 ]] ## stderr output, $? is 1

~에 따르면POSIX 매뉴얼, 종료 코드:

  • 1선택된 행이 없음을 나타냅니다.
  • > 1오류를 의미합니다.

답변3

grep을 사용 중이고 set -euo pipefail레코드를 찾을 수 없을 때(종료 코드 = 1) 종료하고 싶지 않지만 여전히 다른 종료 코드로 인해 실패하도록 하려면 다음을 사용할 수 있습니다.

#!/bin/bash
set -euo pipefail

echo "anything" | { grep e || test $? = 1; } | { grep e2 || test $? = 1; }

파이프 내의 grep은 종료 상태 = 1만 무시합니다. 이렇게 하면 사용을 잃을 필요가 없습니다 set -euo pipefail.

이 예에서는 개념을 설명하지 못할 수도 있는 두 개의 파이프라인 grep을 의도적으로 포함했습니다.

myrdd의 게시물을 참조하세요.거기.

답변4

또 다른 옵션:

...
set +e
echo "anything" | grep e
set -e
...

관련 정보