.png)
명령을 파이프하고 스크립트 내에서 파이프를 끊어야 할지 여부를 결정하려면 어떻게 해야 합니까?
그것은 비슷하다이 질문. 하지만 대신 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 || y
x가 실패할 때만 y를 호출합니다. 마찬가지로 x && y
x가 성공할 때만 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
그런 다음:
foo=$(command1)
의 출력에서 모든 후행 줄 바꿈을 제거합니다command1
. 그러면echo "$foo"
(혹은printf … "$foo"
)은 정확히 하나의 개행 문자(또는 각각 고정된 개수)를 추가합니다. 이러한 이유로command2
에서 정확한 출력을 얻지 못할 수 있습니다command1
.command1
NUL 문자가 포함된 출력을 생성할 수 있습니다. Bash는 NUL을 변수에 저장할 수 없습니다(대부분의 쉘은 할 수 없습니다. zsh는 할 수 있습니다). NUL이 나타나면command2
에서 정확한 출력을 얻을 수 없습니다command1
.command1
거대하거나 끝없는 스트림을 생성할 수 있으므로 변수에 저장하는 것이 불가능할 수 있습니다.
변수 대신 파일을 사용하면 마지막 문제를 제외한 모든 문제가 해결됩니다. command1 | ifne command2
세 가지 문제 모두에 면역입니다.