이 스크립트가 있습니다.
#!/bin/bash
# -> dump.$pid
ulimit -c unlimited
# trap ERR
set -o errexit
# also trap error in the middle of a pipe (1)
# otherwise it will only trap the error on (2)
set -o pipefail
trap 'echo "ERR $?"' ERR
echo "a"
echo "1" | ./crash | cat
echo "b"
echo "2" | ./crash
echo "c"
예상대로 작동합니다.
$ ./script.sh >& script.log
$ echo "$?"
139
$ cat script.log
a
Segmentation fault (core dumped)
ERR 139
( pipefail
그것이 없으면 "ab"가 인쇄되고, 없으면 errexit
"ab c"가 인쇄됩니다)
그러나 이는 더 큰 파이프라인의 일부이고 배치 시스템에서 실행되기 때문에 충돌이 많이 발생할 수 있고 파일 argv
에 정보가 충분하지 않습니다 dump.?????
.
그렇다면 스크립트 오류를 발생시킨 프로세스의 PID(및 예상되는 코어 덤프 파일 이름)를 나머지 모든 프로세스와 함께 기록할 수 있도록 어떻게 인쇄합니까?
충돌하는 프로그램은 더 큰 파이프라인의 일부일 수 있습니다(특히 파이프의 끝에 항상 있는 것은 아니므로 를 사용함 pipefail
). 모든 호출을 래퍼 코드로 둘러싸거나 할 수 없는 상황을 피하고 싶습니다. 프로그램 간에 직접 데이터를 전송합니다.
답변1
SIGSEGV
작업 제어를 활성화하면 문제가 해결되는 것으로 나타났습니다. 하지만 자세한 출력을 방지하는 트랩 및 설정이 없는 경우에만 가능합니다 .
set -o errexit
set -o pipefail
set -o monitor
trap 'echo "ERR $?"' ERR
echo "hi" | ./docrash | cat
echo "not reached"
이를 실행하면 내가 찾고 있는 결과와 그 이상을 정확히 얻을 수 있습니다. 각 하위 프로세스의 PID를 인쇄하고 오류를 표시합니다.
$ ./err.sh >& err.log
$ cat err.log
./err.sh: line 21: 25110 Done echo "hi"
25111 Segmentation fault (core dumped) | ./docrash
25112 | cat
ERR 139
$ gdb docrash core.25111
...
파이프라인 실패를 확인하되 스크립트를 중단하지 않으려면 다음 설정을 결합할 수 있습니다.
set -o pipefail
set -o monitor
echo "hi" | ./docrash | cat
echo "pipe returned $?"
추적을 인쇄하고 계속합니다.
$ ./err.sh
./err.sh: line 21: 25110 Done echo "hi"
25111 Segmentation fault (core dumped) | ./docrash
25112 | cat
pipe returned 139