
파이프라인 어딘가에서 발생하는 명령의 종료 상태를 캡처하고 싶습니다.~ 전에마지막 위치. 예를 들어 파이프라인이 다음과 같은 경우
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
두 개 이상의 프로그램이 있는 경우 수행할 작업:
# this still returns exit code of 1st command `true`
mispipe true 'false | false | false' ; echo $?
산출:
0
visible 이 부족함에도 불구하고 |
여전히 파이프처럼 작동합니다.
yes | mispipe head 'wc -c'
산출:
20