Linux에서 Bash 스크립트의 오류를 트래핑하는 방법

0
143
Linux에서 Bash 스크립트의 오류를 트래핑하는 방법
Fatmawati achmad zaenuri/Shutterstock.com

기본적으로 Linux의 Bash 스크립트는 오류를 보고하지만 계속 실행됩니다. 다음에 발생해야 할 일을 결정할 수 있도록 오류를 직접 처리하는 방법을 보여줍니다.

스크립트의 오류 처리

오류 처리는 프로그래밍의 일부입니다. 완벽한 코드를 작성하더라도 여전히 오류 조건이 발생할 수 있습니다. 컴퓨터의 환경은 소프트웨어를 설치 및 제거하고, 디렉터리를 만들고, 업그레이드 및 업데이트를 수행함에 따라 시간이 지남에 따라 변경됩니다.

PowerShell에서 매개변수 유효성 검사 오류 사용자 지정

관련된PowerShell에서 매개변수 유효성 검사 오류 사용자 지정

예를 들어 문제 없이 실행되던 스크립트가 디렉토리 경로가 변경되거나 파일에 대한 권한이 변경되면 문제가 발생할 수 있습니다. Bash 셸의 기본 동작은 오류 메시지를 출력하고 스크립트를 계속 실행하는 것입니다. 이것은 위험한 기본값입니다.

실패한 작업이 스크립트에서 나중에 발생하는 다른 처리나 작업에 중요한 경우 해당 중요한 작업은 성공하지 못합니다. 그것이 얼마나 비참한지는 당신의 스크립트가 무엇을 하려고 하는지에 달려 있습니다.

보다 강력한 체계는 오류를 감지하고 스크립트를 종료해야 하거나 오류 상태를 수정해야 하는 경우 스크립트가 작동하도록 합니다. 예를 들어, 디렉토리나 파일이 누락된 경우 스크립트에서 이를 다시 생성하는 것으로 만족할 수 있습니다.

스크립트에 복구할 수 없는 문제가 발생한 경우 스크립트가 종료될 수 있습니다. 스크립트를 종료해야 하는 경우 임시 파일을 제거하거나 오류 조건 및 종료 이유를 로그 파일에 기록하는 등 필요한 모든 정리를 수행할 수 있습니다.

종료 상태 감지

명령과 프로그램은 종료될 때 운영 체제로 전송되는 값을 생성합니다. 이를 종료 상태라고 합니다. 오류가 없으면 값이 0이고 오류가 발생하면 0이 아닌 값이 있습니다.

스크립트가 사용하는 명령의 종료 상태(반환 코드라고도 함)를 확인하고 명령이 성공했는지 여부를 결정할 수 있습니다.

Bash에서 0은 true와 같습니다. 명령의 응답이 true가 아닌 경우 문제가 발생했음을 알고 적절한 조치를 취할 수 있습니다.

이 스크립트를 편집기에 복사하고 “bad_command.sh”라는 파일에 저장합니다.

#!/bin/bash

if ( ! bad_command ); then
  echo "bad_command flagged an error."
  exit 1
fi

다음을 사용하여 스크립트를 실행 가능하게 만들어야 합니다. chmod 명령. 이것은 스크립트를 실행 가능하게 만드는 데 필요한 단계이므로 자신의 컴퓨터에서 스크립트를 시도하려면 각 스크립트에 대해 이 작업을 수행하는 것을 기억하십시오. 각 경우에 적절한 스크립트의 이름을 대체하십시오.

chmod +x bad_command.sh

chmod를 사용하여 스크립트를 실행 가능하게 만들기

스크립트를 실행하면 예상한 오류 메시지가 표시됩니다.

./bad_command.sh

오류가 있는지 여부를 확인하기 위해 명령의 종료 상태 확인

“bad_command”와 같은 명령은 없으며 스크립트 내의 함수 이름도 아닙니다. 실행할 수 없으므로 응답은 다음과 같습니다. ~ 아니다 영. 응답이 0이 아닌 경우 – 느낌표가 여기에서 논리적으로 사용됩니다. NOT 연산자 – 본문 if 문이 실행됩니다.

실제 스크립트에서 이것은 우리의 예와 같이 스크립트를 종료하거나 오류 조건을 수정하려고 시도할 수 있습니다.

다음과 같이 보일 수 있습니다. exit 1 라인이 중복됩니다. 결국 스크립트에는 다른 것이 없으며 어쨌든 종료됩니다. 그러나 사용 exit 명령을 사용하면 종료 상태를 쉘에 다시 전달할 수 있습니다. 스크립트가 두 번째 스크립트 내에서 호출된 경우 해당 두 번째 스크립트는 이 스크립트에 오류가 발생했음을 알 수 있습니다.

당신은 논리를 사용할 수 있습니다 OR 연산자를 명령의 종료 상태와 함께 사용하고 첫 번째 명령에서 0이 아닌 응답이 있는 경우 스크립트에서 다른 명령이나 함수를 호출합니다.

command_1 || command_2

이것은 첫 번째 명령이 실행되기 때문에 작동합니다. OR 두번째. 맨 왼쪽 명령이 먼저 실행됩니다. 성공하면 두 번째 명령이 실행되지 않습니다. 그러나 첫 번째 명령이 실패하면 두 번째 명령이 실행됩니다. 따라서 우리는 이와 같은 코드를 구성할 수 있습니다. 이것은 “logical-or./sh”입니다.

#!/bin/bash

error_handler()
{
  echo "Error: ($?) $1"
  exit 1
}

bad_command || error_handler "bad_command failed, Line: ${LINENO}"

라는 함수를 정의했습니다. error_handler . 이것은 변수에 보관된 실패한 명령의 종료 상태를 인쇄합니다. $? 함수가 호출될 때 전달되는 텍스트 줄입니다. 이것은 변수에 보관됩니다. $1. 이 함수는 종료 상태가 1인 스크립트를 종료합니다.

스크립트가 실행을 시도합니다. bad_command 이것은 분명히 실패하므로 논리적 오른쪽에 있는 명령 OR 운영자, ||, 실행됩니다. 이것은 error_handler 함수를 실행하고 실패한 명령의 이름을 지정하고 실패한 명령의 행 번호를 포함하는 문자열을 전달합니다.

스크립트를 실행하여 오류 처리기 메시지를 확인한 다음 echo를 사용하여 스크립트의 종료 상태를 확인합니다.

./logical-or.sh
echo $?

논리적 OR 연산자를 사용하여 스크립트에서 오류 처리기 호출

우리 작은 error_handler 함수는 실행 시도의 종료 상태를 제공합니다. bad_command, 명령 이름 및 줄 번호. 이것은 스크립트를 디버깅할 때 유용한 정보입니다.

스크립트의 종료 상태는 1입니다. 에서 보고한 127 종료 상태 error_handler “명령을 찾을 수 없음”을 의미합니다. 원한다면 그것을 스크립트의 종료 상태로 사용할 수 있습니다. exit 명령.

또 다른 접근법은 확장하는 것입니다. error_handler 이 유형의 구성을 사용하여 종료 상태의 다른 가능한 값을 확인하고 그에 따라 다른 작업을 수행합니다.

exit_code=$?

if [ $exit_code -eq 1 ]; then
  echo "Operation not permitted"

elif [ $exit_code -eq 2 ]; then
  echo "Misuse of shell builtins"
.
.
.
elif [ $status -eq 128 ]; then
  echo "Invalid argument"
fi

강제 종료 설정 사용

오류가 있을 때마다 스크립트가 종료되기를 원한다면 강제로 종료할 수 있습니다. 이는 스크립트가 오류를 감지하는 즉시 종료되기 때문에 정리 또는 추가 손상 가능성을 포기한다는 의미입니다.

이렇게 하려면 다음을 사용하십시오. set 명령 -e (오류) 옵션. 이것은 명령이 실패하거나 0보다 큰 종료 코드를 반환할 때마다 스크립트를 종료하도록 지시합니다. 또한, 사용 -E 옵션은 쉘 함수에서 오류 감지 및 트래핑이 작동하도록 합니다.

Linux의 Bash 스크립트에서 set 및 pipefail을 사용하는 방법

관련된Linux의 Bash 스크립트에서 set 및 pipefail을 사용하는 방법

초기화되지 않은 변수도 잡으려면 다음을 추가하십시오. -u (설정되지 않음) 옵션. 파이프 시퀀스에서 오류가 감지되었는지 확인하려면 다음을 추가하십시오. -o pipefail 옵션. 이것이 없으면 파이프된 명령 시퀀스의 종료 상태는 결정적인 순서대로 명령합니다. 파이프된 시퀀스 중간에 실패한 명령은 감지되지 않습니다. 그만큼 -o pipefail 옵션은 옵션 목록에 있어야 합니다.

스크립트 상단에 추가할 순서는 다음과 같습니다.

set -Eeuo pipefail

다음은 설정되지 않은 변수가 포함된 “unset-var.sh”라는 짧은 스크립트입니다.

#!/bin/bash

set -Eeou pipefail

echo "$unset_variable"

echo "Do we see this line?"

스크립트를 실행하면 unset_variable이 초기화되지 않은 변수로 인식되고 스크립트가 종료됩니다.

./unset-var.sh

스크립트에서 set 명령을 사용하여 오류 발생 시 스크립트 종료

두번째 echo 명령이 실행되지 않습니다.

오류가 있는 트랩 사용

Bash 트랩 명령을 사용하면 특정 신호가 발생할 때 호출되어야 하는 명령이나 함수를 지정할 수 있습니다. 일반적으로 이것은 다음과 같은 신호를 잡는 데 사용됩니다. SIGINT Ctrl+C 키 조합을 누르면 발생합니다. 이 스크립트는 “signint.sh”입니다.

#!/bin/bash

trap "echo -e 'nTerminated by Ctrl+c'; exit" SIGINT

counter=0

while true
do 
  echo "Loop number:" $((++counter))
  sleep 1
done

그만큼 trap 명령에는 echo 명령과 exit 명령. 다음과 같은 경우에 트리거됩니다. SIGINT 제기된다. 나머지 스크립트는 간단한 루프입니다. 스크립트를 실행하고 Ctrl+C를 누르면 다음 메시지가 표시됩니다. trap 정의하고 스크립트가 종료됩니다.

./sigint.sh

스크립트에서 트랩을 사용하여 Ctrl+c 잡기

우리는 사용할 수 있습니다 trap 이랑 ERR 오류가 발생하면 이를 잡아내도록 신호를 보냅니다. 그런 다음 명령이나 기능에 공급할 수 있습니다. “trap.sh”입니다. 라는 함수에 오류 알림을 보내고 있습니다. error_handler.

#!/bin/bash

trap 'error_handler $? $LINENO' ERR

error_handler() {
  echo "Error: ($1) occurred on $2"
}

main() {
  echo "Inside main() function"
  bad_command
  second
  third
  exit $?
}

second() {
  echo "After call to main()"
  echo "Inside second() function"
}

third() {
  echo "Inside third() function"
}

main

스크립트의 대부분은 내부에 있습니다. main 를 호출하는 함수 second 그리고 third 기능. 오류가 발생한 경우 – 이 경우 bad_command 존재하지 않는다 – trap 명령문은 오류를 error_handler 기능. 실패한 명령의 종료 상태와 줄 번호를 error_handler 기능.

./trap.sh

ERR과 함께 트랩을 사용하여 스크립트에서 오류 포착

우리의 error_handler 함수는 단순히 오류의 세부 사항을 터미널 창에 나열합니다. 원하는 경우 추가할 수 있습니다. exit 스크립트를 종료하도록 함수에 명령을 입력합니다. 또는 일련의 if/elif/fi 다른 오류에 대해 다른 작업을 수행하는 명령문.

일부 오류를 수정하는 것이 가능할 수도 있고 다른 오류는 스크립트를 중지해야 할 수도 있습니다.

마지막 팁

오류를 포착한다는 것은 종종 잘못될 수 있는 일을 선점하고 이러한 결과가 발생할 경우 처리할 코드를 넣는 것을 의미합니다. 이는 스크립트의 실행 흐름과 내부 논리가 올바른지 확인하는 것 외에도 있습니다.

이 명령을 사용하여 스크립트를 실행하면 Bash는 스크립트가 실행될 때 추적 출력을 표시합니다.

bash -x your-script.sh

Bash는 터미널 창에 추적 출력을 씁니다. 인수가 있는 경우 각 명령을 해당 인수와 함께 표시합니다. 이것은 명령이 확장된 후 실행되기 전에 발생합니다.

찾기 힘든 버그를 추적하는 데 큰 도움이 될 수 있습니다.

관련된: Linux Bash 스크립트를 실행하기 전에 구문을 확인하는 방법