두 번째 명령에서 파이프라인에 있는 첫 번째 명령의 종료 상태를 가져옵니다.

두 번째 명령에서 파이프라인에 있는 첫 번째 명령의 종료 상태를 가져옵니다.

내 문제는 다음과 비슷합니다종료 상태를 다른 프로세스로 파이프로 가져오기, 하지만 파이프라인에서 두 번째 명령의 종료 상태를 가져오고 싶습니다.이내에관로.

여기에 예가 있습니다 -

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.

관련 정보