it-swarm-korea.com

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

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
23
yael

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

$ 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을 잡은 다음 현재 줄 번호 + bash 명령으로 failure() 함수를 호출하여 작동합니다.

여기서는 f1, f2, f3 또는 f4 파일을 만들 때주의를 기울이지 않았습니다. 위의 스크립트를 실행할 때 :

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

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

32
slm

현재 줄 번호를 포함하는 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 다른 사람:

15
ilkkachu

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에서 오류가 발생한 명령을 찾을 수 있습니다 (리디렉션 등은 아님).

14
meuh