time 명령과 유사하게 명령의 종료 코드를 기록합니다.

time 명령과 유사하게 명령의 종료 코드를 기록합니다.

사용

time sleep 1

생산하다:

$ time sleep 1

real    0m1.005s
user    0m0.001s
sys     0m0.001s

sleep종료 코드 나 실행하려는 명령을 인쇄하는 데 사용할 수 있는 명령이 있습니까 ?

내가 좋아하는 것:

$ log-exit-code sleep 1

어쩌면 그것으로 충분할까요?

sleep 1 && echo "$?"

답변1

cmd && echo "$?"반드시 0만 인쇄하기 때문에 작동하지 않습니다( echo이전 명령이 성공적으로 완료된 경우에만 실행됨).

다음은 짧은 쉘 함수입니다:

tellexit () {
    "$@"

    local err="$?"
    printf 'exit code\t%d\n' "$err" >/dev/tty
    return "$err"
}

이것은 command 와 비슷한 방식으로 주어진 명령의 종료 코드를 인쇄합니다 time.

$ tellexit echo "hello world"
hello world
exit code       0

$ tellexit false
exit code       1

함수 내에서 리디렉션하여 printf표준 출력이나 오류 스트림에서 쓰레기를 얻지 않고도 리디렉션을 사용할 수 있습니다./dev/ttytellexit

$ tellexit bash -c 'echo hello; echo world >&2' >out 2>err
exit code       0
$ cat out
hello
$ cat err
world

종료 코드를 변수에 저장하면 이를 호출자에게 반환할 수 있습니다.

$ tellexit false || echo 'failed'
exit code       1
failed

동일한 함수의 고급 버전은 종료 코드가 128보다 큰 경우(신호로 인해 종료되었음을 의미) 명령을 종료한 신호도 인쇄합니다.

tellexit () {
    "$@"

    local err="$?"

    if [ "$err" -gt 128 ]; then
        printf 'exit code\t%d (%s)\n' "$err" "$(kill -l "$err")" >/dev/tty
    else
        printf 'exit code\t%d\n' "$err" >/dev/tty
    fi

    return "$err"
}

시험:

$ tellexit sh -c 'kill $$'
exit code       143 (TERM)

$ tellexit sh -c 'kill -9 $$'
Killed
exit code       137 (KILL)

( // / local가 필요 하거나 다른 쉘도 이해할 수 있는 형식 으로 변경할 수 있습니다 .)ashpdkshbashzshtypeset

답변2

암소 비슷한 일종의 영양time옵션이 있습니다:

time -f %x sleep 1
0

신호 2 에 의해 종료되지 않는 한 종료 코드 1 로 :

$ /usr/bin/time -f %x sleep 1; echo $?
0
0

$ /usr/bin/time -f %x sleep 2x; echo $?
sleep: invalid time interval ‘2x’
Try 'sleep --help' for more information.
1
1

$ /usr/bin/time -f %x sleep 60s; echo $? # Press ^C before a minute elapses
0
2

신호 종료를 이해/처리하려면 -v문자열의 stderr을 전달하고 grep하십시오 Command terminated by signal.


1 종료 코드가 통과되었음을 알려준 Olivier Dulac에게 감사드립니다 .
2또한 킬 신호 종료 코드를 전달할 수 없다는 점을 지적한 Stéphane Chazelas에게 감사드립니다.

답변3

쉘 래퍼 기능과 같은 것을 사용하십시오. 다른 이름이 있을 수 있습니다.

$ exito() { "$@"; echo $?; }
$ exito true
0
$ exito false
1
$ exito echo "test test"      
test test
0
$ 

(이것은 물론 표준 출력을 손상시키므로 tty@Kusalananda가 보여주는 것을 사용하거나 대화형 컨텍스트 외부에서 사용하지 마십시오.)

이식 불가능한 영역으로 전환하면 일부 셸은 전체 파이프라인의 실패를 보고하려는 경우 ZSH와 같이 마지막 명령뿐만 아니라 파이프라인의 모든 명령 상태를 보고할 수 있습니다.

% TRAPZERR() { print >/dev/tty $pipestatus }
% perl -e 'exit 42' | perl -e 'exit 99'
42 99
% false | perl -e 'exit 42' | perl -e 'exit 99'
1 42 99
% perl -e 'exit 42' | perl -e 'exit 99' | true
% 

TRAPZERR그렇지 않으면 오류가 없을 때 트리거되지 않습니다("뉴스가 없는 것은 좋은 뉴스" 원칙에 따라).

답변4

다른 모든 답변에 대해 마음에 들지 않는 점(그 독창성은 정말 마음에 들지만): 종료 코드를 표시하지만 변경하기도 합니다. (표시 부분이 true이므로 후속 반환 코드는 0입니다)

이것은 수정된 버전입니다:

do_and_tell () {
   "$@"
   returncode="$?"
   printf "Execution of : \n%s\n yelded a return code of: \n%s\n" "$*" "$returncode"
   return $returncode  # the interresting addition... keeps the commands return value.
}

## usage:

prompt$ do_and_tell true
Execution of : 
true
 yelded a return code of: 
0

prompt$ echo $?
0

prompt$ do_and_tell false
Execution of : 
false
 yelded a return code of: 
1

prompt$ echo $?
1

관련 정보