Bash의 조건부 파이프(사용자 정의 스크립트)

Bash의 조건부 파이프(사용자 정의 스크립트)

명령을 파이프하고 스크립트 내에서 파이프를 끊어야 할지 여부를 결정하려면 어떻게 해야 합니까?

그것은 비슷하다이 질문. 하지만 대신 awk내 스크립트를 사용하고 싶습니다.

check_ip | update_bind9

check_ip외부 IP( curl -s ifconfig.co)를 찾아 파일( ~/.ip)에 저장된 IP와 비교해야 합니다.

주요 질문은 다음과 같습니다.

IP가 변경된 경우 check_ip파이프를 통해 IP를 전달해야 합니다. 그렇지 않으면 파이프가 파손될 수 있습니다.

check_ip파이프가 끊어지는 건가요, 아니면 IP update_bind9로 호출되지 않으면 호출을 무시하는 건가요?

몇 가지 테스트를 수행했습니다. 전화: check_ip | echo "ok".

나는 exit 0, exit 1, return true, 하려고 노력했다 return false. . set -e​성공하지 못했습니다.

답변1

파이프라인의 모든 구성요소동시에 시작– 첫 번째 명령에서 무슨 일이 일어나든 두 번째 명령은 항상 시작됩니다.

따라서 빈 stdin을 처리해야 하는 두 번째 명령입니다.


그러나 나는 파이프가 우선 이것에 대한 좋은 선택이 아니라고 말하고 싶습니다.

|(아마도 (파이프)와 (부울 OR) 을 혼동하고 계십니까 ||? 후자~이다if/then에 대한 짧은 대안으로 자주 사용됩니다. 예를 들어 x || yx가 실패할 때만 y를 호출합니다. 마찬가지로 x && yx가 성공할 때만 y를 호출합니다.)

일반적으로 if/then 블록을 사용해야 합니다. 예를 들어, check_ip주소가 다를 때 자체적으로 0(성공)을 반환하고 동일할 때 1(실패)을 반환하는 경우 다음과 같습니다.

if addr=$(check_ip); then
    echo "$addr" | update_bind9
fi

또는 update_bind9가 (stdin을 읽지 않고) 자체적으로 주소를 결정할 수 있다면 다음과 같습니다.

if check_ip_needs_updating; then
    update_bind9
fi

답변2

이 다른 답변좋다. 그러나 실제로 조건부로 파이프해야 하는 경우 다음을 찾을 수 있습니다.ifne유용한:

ifne표준 입력이 비어 있지 않은 경우에만 다음 명령을 실행합니다.

귀하의 경우에는 check_ip | ifne update_bind9.

ifne기본적으로 Linux에 설치되지 않을 가능성이 높습니다 . 내 데비안 10에서는 패키지에 들어 있습니다 moreutils. check_ip언급된 답변과 같이 출력을 변수에 저장하고 조건부로 재사용할 수 있기 때문에 추가 도구가 완전히 과도하다고 생각할 수 있습니다.

if addr=$(check_ip); then
    echo "$addr" | update_bind9
fi

조건은 [ -n "$addr" ]무엇이든 될 수 있습니다. 중요한 것은 변수를 사용한다는 것입니다. 위와 같은 코드는 문제를 해결할 수 있지만 일반적으로 최소한 세 가지 문제가 있습니다. command1 | command2대신 가정합니다 check_ip | update_bind9. 솔루션은 다음과 같이 일반화됩니다.

if foo=$(command1); then
    echo "$foo" | command2
fi

그런 다음:

  1. foo=$(command1)의 출력에서 ​​모든 후행 줄 바꿈을 제거합니다 command1. 그러면 echo "$foo"(혹은printf … "$foo")은 정확히 하나의 개행 문자(또는 각각 고정된 개수)를 추가합니다. 이러한 이유로 command2에서 정확한 출력을 얻지 못할 수 있습니다 command1.

  2. command1NUL 문자가 포함된 출력을 생성할 수 있습니다. Bash는 NUL을 변수에 저장할 수 없습니다(대부분의 쉘은 할 수 없습니다. zsh는 할 수 있습니다). NUL이 나타나면 command2에서 정확한 출력을 얻을 수 없습니다 command1.

  3. command1거대하거나 끝없는 스트림을 생성할 수 있으므로 변수에 저장하는 것이 불가능할 수 있습니다.

변수 대신 파일을 사용하면 마지막 문제를 제외한 모든 문제가 해결됩니다. command1 | ifne command2세 가지 문제 모두에 면역입니다.

관련 정보