파이프라인 어딘가에서 발생하는 명령의 종료 상태를 캡처하고 싶습니다.앞으로최종 위치. 예를 들어 파이프라인이 다음과 같다면
command_1 ... | command_2 ... | command_3 ... | ... | command_n
command_1
... , command_2
또는 등 의 종료 상태를 캡처하는 방법을 알고 싶습니다 . (물론 command_3
캡쳐된 종료상태는 간단합니다.)command_n
또한 중요한 경우 이 파이프는 zsh 쉘 함수 내부에서 발생합니다.
command_1
다음과 같은 것을 사용하여 종료 상태를 캡처 하려고했습니다 .
function_with_pipeline () {
local command_1_status=-999999 # sentinel value
{ command_1 ...; command_1_status=$? } | command_2 ... | ... | command_n
...
}
...하지만 파이프라인을 실행한 후에도 command_1_status
변수 값은 여전히 센티널 값입니다.
FWIW, 다음은 파이프라인에 두 개의 명령만 있는 작업 예입니다.
foo ... | grep ...
foo
이 예에 대해 정의된 함수는 다음과 같습니다.
foo () {
(( $1 & 1 )) && echo "a non-neglible message"
(( $1 & 2 )) && echo "a negligible message"
(( $1 & 4 )) && echo "error message" >&2
return $(( ( $1 & 4 ) >> 2 ))
}
foo
목표는 파이프라인에서 호출의 종료 상태를 캡처하는 것입니다.
이 함수는 function_with_pipeline
이를 수행하기 위해 위에서 설명한 (궁극적으로 비효율적인) 전략을 구현합니다.
function_with_pipeline () {
local foo_status=-999999 # sentinel value
{ foo $1; foo_status=$? } | grep -v "a negligible message"
printf '%d\ndesired: %d; actual: %d\n\n' $1 $(( ( $1 & 4 ) >> 2 )) $foo_status
}
다음 루프는 이 function_with_pipeline
기능을 실행합니다. 출력은 지역 변수의 값이 foo_status
처음과 다르지 않게 종료됨을 보여줍니다.
for i in $(seq 0 7)
do
function_with_pipeline $i
done
# 0
# desired: 0; actual: -999999
#
# a non-neglible message
# 1
# desired: 0; actual: -999999
#
# 2
# desired: 0; actual: -999999
#
# a non-neglible message
# 3
# desired: 0; actual: -999999
#
# error message
# 4
# desired: 1; actual: -999999
#
# error message
# a non-neglible message
# 5
# desired: 1; actual: -999999
#
# error message
# 6
# desired: 1; actual: -999999
#
# error message
# a non-neglible message
# 7
# desired: 1; actual: -999999
#
local
정의에서 선언을 생략하면 동일한 결과를 얻게 됩니다 foo_status
.
답변1
특별한 배열이 있으니 시도해 보세요 pipestatus
.zsh
command_1 ... | command_2 ... | command_3
그리고
echo $pipestatus[1] $pipestatus[2] $pipestatus[3]
귀하의 접근 방식이 작동하지 않는 이유는 각 파이프가 별도의 하위 쉘에서 실행되고 하위 쉘이 종료되면 자체 변수가 파괴되기 때문입니다.
PIPESTATUS
참고로 (대문자) 형식 입니다 bash
.
답변2
mispipe
모든 쉘에서 작동합니다. 일반 파이프와 비교하여 구문은 다음과 같이 작동합니다.
mispipe true false ; echo $? # returns exit code of 1st command `true`
true | false ; echo $? # returns exit code of 2nd command `false`
산출:
0
1
프로그램이 2개 이상인 경우 수행할 작업:
# this still returns exit code of 1st command `true`
mispipe true 'false | false | false' ; echo $?
산출:
0
가시성이 부족함에도 불구하고 |
여전히 파이프처럼 작동합니다.
yes | mispipe head 'wc -c'
산출:
20