내 문제는 다음과 비슷합니다종료 상태를 다른 프로세스로 파이프로 가져오기, 하지만 파이프라인에서 두 번째 명령의 종료 상태를 가져오고 싶습니다.이내에관로.
여기에 예가 있습니다 -
false | echo $?
0
기대보다는 보상1
PIPESTATUS
이전 오류 코드 제공
false | echo $PIPESTATUS
0
처음으로 반환 한 다음 을 반환하여 1
작업 자체 후에 결과를 제공합니다. 내 의도는 다음과 같은 함수를 만드는 것입니다.
debug() {
# Eventually will be formatted as JSON
echo "$(cat) was the result and the error code was $?"
}
(
echo "Foo"
false # To simulate an error
) | debug # debug should return "Foo was the result and the error code was 1"
답변1
파이프라인의 양쪽 절반이 모두 실행되므로 이 작업을 수행할 수 없습니다.동시에, 따라서 오른쪽은 왼쪽이 성공했는지 알 수 없습니다. 원하는 작업을 수행하려면 먼저 왼쪽에 있는 명령을 실행한 다음 종료될 때까지 기다려야 합니다. 그런 다음 명령의 출력과 종료 코드를 표시할 수 있습니다.
다음 코드 조각이 귀하의 목적에 더 적합할 수 있습니다.
myfunc() {
echo foo
read
}
out="$(myfunc)"
rc=$?
printf '%s was the result and the error code was %d\n' "$out" $rc
$ yes | ./test.sh
foo was the result and the error code was 0
$ ./test.sh < /dev/null
foo was the result and the error code was 1
답변2
짐의 대답물론 맞습니다. 그러나 내 특정 사용 사례에서는 이 trap
명령이 파이프의 깔끔한 구문을 제공하면서도 여전히 오류를 포착한다는 사실을 발견했습니다 .
저는 결국 이렇게 선택했습니다.
set -E
trap 'catch $? $LINENO' ERR
catch() {
echo "{ \"type\": \"error\", \"error\": \"$1\", \"line\": \"$2\" }"
exit $1
}
debug() {
# Eventually will be formatted as JSON
echo "$(cat) was the result"
}
(
echo "Foo"
# Simulate an error
false
echo "This should not be run!"
) | debug
출력:
Foo
{ "type": "error", "error": "1", "line": "18" } was the result
보시다시피, echo "This should not be run!"
결코 실행되지 않았습니다!
마지막으로 newlines 를 대체하기 위해 JSON 형식을 지정하면 \n
다음과 같은 결과를 얻게 됩니다.
{ "content": "Foo\n{ "error": "1", "line": "18" }" }
stdin
특히 중첩된 따옴표를 수정하거나 입력과 출력을 분리하는 등 일부 후처리가 필요합니다 trap
.