오류가 발생했을 때 Bash에서 줄 번호를 어떻게 찾습니까?


21

Bash에서 오류가 발생한 줄 번호를 어떻게 찾습니까?

필요한 것을 설명하기 위해 줄 번호가있는 다음과 같은 간단한 스크립트를 만듭니다. 스크립트는

cp $file1 $file2
cp $file3 $file4

cp명령 중 하나가 실패하면 기능은 exit 1종료 됩니다. 함수에 기능을 추가하여 줄 번호와 함께 오류를 인쇄합니다 (예 : 8 또는 12).

이것이 가능한가?

샘플 스크립트

1 #!/bin/bash
2
3
4 function in_case_fail {
5 [[ $1 -ne 0 ]] && echo "fail on $2" && exit 1
6 }
7
8 cp $file1 $file2
9 in_case_fail $? "cp $file1 $file2"
10
11
12 cp $file3 $file4
13 in_case_fail $? "cp $file3 $file4"
14


실행 된 내용을 사용 set -x및 / 또는 set -v추적 할 수 있습니다 . 정확히 당신이 요구 한 것은 아니지만 아마도 도움이 될 것입니다.
Rolf

답변:


29

함수를 사용하는 대신이 방법을 대신 사용합니다.

$ cat yael.bash
#!/bin/bash

set -eE -o functrace

file1=f1
file2=f2
file3=f3
file4=f4

failure() {
  local lineno=$1
  local msg=$2
  echo "Failed at $lineno: $msg"
}
trap 'failure ${LINENO} "$BASH_COMMAND"' ERR

cp -- "$file1" "$file2"
cp -- "$file3" "$file4"

이것은 ERR을 잡은 다음 failure()현재 행 번호 + bash 명령으로 함수 를 호출하여 작동합니다.

여기에 내가 파일을 만들 수있는 처리되지했습니다, f1, f2, f3, 또는 f4. 위의 스크립트를 실행할 때 :

$ ./yael.bash
cp: cannot stat f1’: No such file or directory
Failed at 17: cp -- "$file1" "$file2"

행 번호와 실행 된 명령을보고하여 실패합니다.


14

LINENO현재 줄 번호 를 포함하는 것 외에도 호출 된 함수 이름과 줄 번호를 포함하는 BASH_LINENOFUNCNAME(및 BASH_SOURCE) 배열이 있습니다.

따라서 다음과 같이 할 수 있습니다.

#!/bin/bash

error() {
        printf "'%s' failed with exit code %d in function '%s' at line %d.\n" "${1-something}" "$?" "${FUNCNAME[1]}" "${BASH_LINENO[0]}"
}

foo() {
        ( exit   0 ) || error "this thing"
        ( exit 123 ) || error "that thing"
}

foo

인쇄 할 달리기

'that thing' failed with exit code 123 in function 'foo' at line 9.

을 사용 set -e하거나 trap ... ERR오류를 자동으로 감지하는 경우 몇 가지주의 사항이 있습니다. 스크립트가 당시에 한 일에 대한 설명을 포함시키는 것도 어렵습니다 (예에서와 같이). 줄 번호보다 일반 사용자에게 더 유용 할 수 있습니다.

예를 들어 다음을 참조하십시오. set -e .


13

Bash에는 $LINENO명령문에있을 때 현재 행 번호로 대체되는 내장 변수 가 있으므로 수행 할 수 있습니다.

in_case_fail $? "at $LINENO: cp $file1 $file2"

trap ... ERR명령이 실패 할 때 (결과가 테스트되지 않은 경우) 실행을 사용할 수도 있습니다 . 예 :

trap 'rc=$?; echo "error code $rc at $LINENO"; exit $rc' ERR

그런 다음과 같은 명령이 cp $file1 $file2실패하면 줄 번호와 종료와 함께 오류 메시지가 표시됩니다. 또한 변수에 오류가있는 명령을 찾을 수 있습니다 $BASH_COMMAND(리디렉션 등은 아님).

당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.