Pipefail은 명령 대체가 pgrep을 평가하는 것을 방지합니까?

Pipefail은 명령 대체가 pgrep을 평가하는 것을 방지합니까?

pgrep lftp -c내 목표는 스크립트에서 명령을 실행하여 이미 실행 중인지 shell확인하는 것입니다 .lftp

그러나 다음 스크립트는 "테스트" 출력을 초과하지 않습니다. 해당 줄을 완전히 제거한 경우에만 스크립트가 실행됩니다 pipefail. 왜?

#!/usr/bin/env bash

set -e pipefail 

echo test

EXISTING="$(pgrep lftp -c)"
echo $EXISTING

답변1

먼저, 쉘 스크립팅 모범 사례 지침에 대한 참고 사항: 자체 변수 이름에 대문자를 사용하지 마십시오. 전역 환경 변수와 이름 지정 충돌이 발생할 수 있습니다. 명확한 예를 들자면, 변수 이름을 으로 지정하면 PATH전역 PATH변수가 덮어쓰여 실행 파일이 더 이상 예상 위치에서 발견되지 않습니다.

이제 보여주신 스크립트에는 문제가 없습니다. 예상대로 정확하게 작동합니다. set -e명령이 0이 아닌 종료 상태를 반환하는 경우 "명령이 실패하면 종료"를 의미합니다. 아무 것도 발견 되지 않으면 pgrep0이 아닌 상태로 종료되므로 스크립트가 거기서 끝납니다.

수동으로 시도하면 실제로 작동하는 것을 볼 수 있습니다.

$ pgrep lftp -c
0
$ echo $?
1

이를 방지하려면 wc대신 을 사용할 수 있습니다. 행 개수가 0이면 0이 아닌 상태로 종료되지 않기 pgrep -c때문입니다 .wc

#!/usr/bin/env bash

set -e  

echo test

existing="$(pgrep lftp | wc -l)"
echo "Found $existing instances of lftp"

lftp실행 중인 프로세스가 없으면 다음과 같은 출력이 생성됩니다.

$ foo.sh
test
Found 0 instances of lftp

bash 옵션을 설정하려면 대신 해당 옵션이 pipefail필요합니다 . 아마도 당신이 정말로 원하는 것은 다음과 같습니다.set -o pipefailset -e

#!/usr/bin/env bash

set -o pipefail 

echo test

existing="$(pgrep -c lftp)"
echo "Found $existing instances of lftp"

관련 정보