쉘 스크립트 디버깅 시리즈의 이 기사에서는 쉘 추적인 세 번째 쉘 스크립트 디버깅 모드에 대해 설명하고 작동 방식과 사용 방법을 보여주는 몇 가지 예를 살펴보겠습니다.
이 시리즈의 이전 부분은 다른 두 가지 셸 스크립트 디버깅 모드인 상세 모드에 대해 명확하게 설명합니다. 및 구문 확인 이 모드에서 쉘 스크립트 디버깅을 활성화하는 방법에 대한 이해하기 쉬운 예가 있는 모드입니다.
- Linux에서 셸 스크립트 디버깅 모드를 활성화하는 방법 – 1부
- 셸 스크립트에서 구문 검사 디버깅 모드를 수행하는 방법 – 2부
셸 추적은 단순히 셸 스크립트에서 명령 실행을 추적하는 것을 의미합니다. 쉘 추적을 켜려면 -x
를 사용하십시오. 디버깅 옵션.
이것은 쉘이 실행될 때 터미널에 모든 명령과 해당 인수를 표시하도록 지시합니다.
sys_info.sh
를 사용합니다. 시스템 날짜 및 시간, 로그인한 사용자 수 및 시스템 가동 시간을 간략하게 인쇄하는 아래의 셸 스크립트. 그러나 여기에는 찾아서 수정해야 하는 구문 오류가 포함되어 있습니다.
#!/bin/bash #script to print brief system info ROOT_ID="0" DATE=`date` NO_USERS=`who | wc -l` UPTIME=`uptime` check_root(){ if [ "$UID" -ne "$ROOT_ID" ]; then echo "You are not allowed to execute this program!" exit 1; } print_sys_info(){ echo "System Time : $DATE" echo "Number of users: $NO_USERS" echo "System Uptime : $UPTIME } check_root print_sys_info exit 0
파일을 저장하고 스크립트를 실행 가능하게 만드십시오. 스크립트는 루트로만 실행할 수 있으므로 sudo 명령을 사용하여 아래와 같이 실행합니다.
$ chmod +x sys_info.sh $ sudo bash -x sys_info.sh
위의 출력에서 우리는 출력이 변수 값으로 대체되기 전에 명령이 먼저 실행되었음을 알 수 있습니다.
예를 들어 날짜 처음 실행되었고 출력이 DATE 변수의 값으로 대체되었습니다. .
다음과 같이 구문 오류만 표시하도록 구문 검사를 수행할 수 있습니다.
$ sudo bash -n sys_info.sh
쉘 스크립트를 비판적으로 살펴보면 if statement
닫는 fi
가 누락되었습니다. 단어. 따라서 이를 추가하고 새 스크립트는 다음과 같이 표시되어야 합니다.
#!/bin/bash #script to print brief system info ROOT_ID="0" DATE=`date` NO_USERS=`who | wc -l` UPTIME=`uptime` check_root(){ if [ "$UID" -ne "$ROOT_ID" ]; then echo "You are not allowed to execute this program!" exit 1; fi } print_sys_info(){ echo "System Time : $DATE" echo "Number of users: $NO_USERS" echo "System Uptime : $UPTIME } check_root print_sys_info exit 0
파일을 다시 저장하고 루트로 호출하고 일부 구문 검사를 수행합니다.
$ sudo bash -n sys_info.sh
위의 구문 검사 작업 결과는 여전히 21행 스크립트에 버그가 하나 더 있음을 보여줍니다. . 따라서 아직 구문 수정이 필요합니다.
스크립트를 한 번 더 분석적으로 살펴보면 21행의 오류가 닫는 큰따옴표 (”)
가 누락되었기 때문입니다. print_sys_info
내부의 마지막 echo 명령에서 기능.
echo에 닫는 큰따옴표를 추가합니다. 명령을 실행하고 파일을 저장합니다. 변경된 스크립트는 다음과 같습니다.
#!/bin/bash #script to print brief system info ROOT_ID="0" DATE=`date` NO_USERS=`who | wc -l` UPTIME=`uptime` check_root(){ if [ "$UID" -ne "$ROOT_ID" ]; then echo "You are not allowed to execute this program!" exit 1; fi } print_sys_info(){ echo "System Time : $DATE" echo "Number of users: $NO_USERS" echo "System Uptime : $UPTIME" } check_root print_sys_info exit 0
이제 문법적으로 스크립트를 한 번 더 확인하십시오.
$ sudo bash -n sys_info.sh
스크립트가 이제 구문적으로 정확하기 때문에 위의 명령은 출력을 생성하지 않습니다. 두 번째로 스크립트 실행을 추적할 수도 있으며 잘 작동해야 합니다.
$ sudo bash -x sys_info.sh
이제 스크립트를 실행하십시오.
$ sudo ./sys_info.sh
셸 스크립트 실행 추적의 중요성
셸 스크립트 추적은 구문 오류와 더 중요하게는 논리적 오류를 식별하는 데 도움이 됩니다. 예를 들어 check_root
sys_info.sh
의 기능 스크립트는 수퍼유저만 실행할 수 있으므로 사용자가 루트인지 여부를 확인하기 위한 셸 스크립트입니다.
check_root(){ if [ "$UID" -ne "$ROOT_ID" ]; then echo "You are not allowed to execute this program!" exit 1; fi }
여기서 마법은 if statement
에 의해 제어됩니다. 식 [ "$UID" -ne "$ROOT_ID" ]
, 적절한 숫자 연산자(-ne
)를 사용하지 않으면 이 경우 같지 않음을 의미) 논리적 오류가 발생할 수 있습니다.
-eq
를 사용했다고 가정합니다. ( 같음을 의미함), 이것은 루트 사용자뿐만 아니라 모든 시스템 사용자가 스크립트를 실행할 수 있도록 허용하므로 논리적 오류가 발생합니다.
check_root(){ if [ "$UID" -eq "$ROOT_ID" ]; then echo "You are not allowed to execute this program!" exit 1; fi }
참고 :이 시리즈의 시작 부분에서 이전에 보았듯이 set shell 내장 명령은 쉘 스크립트의 특정 섹션에서 디버깅을 활성화할 수 있습니다.
따라서 아래 줄은 실행을 추적하여 함수에서 이 논리적 오류를 찾는 데 도움이 됩니다.
논리적 오류가 있는 스크립트:
#!/bin/bash #script to print brief system info ROOT_ID="0" DATE=`date` NO_USERS=`who | wc -l` UPTIME=`uptime` check_root(){ if [ "$UID" -eq "$ROOT_ID" ]; then echo "You are not allowed to execute this program!" exit 1; fi } print_sys_info(){ echo "System Time : $DATE" echo "Number of users: $NO_USERS" echo "System Uptime : $UPTIME" } #turning on and off debugging of check_root function set -x ; check_root; set +x ; print_sys_info exit 0
파일을 저장하고 스크립트를 호출하면 일반 시스템 사용자가 sudo 없이 스크립트를 실행할 수 있음을 알 수 있습니다. 아래 출력과 같이. USER_ID의 값 때문입니다. 100입니다. 루트 ROOT_ID와 같지 않음 0입니다. .
$ ./sys_info.sh
자, 여기까지입니다. 쉘 스크립트 디버깅 시리즈가 끝났습니다. 아래 응답 양식을 사용하여 이 가이드 또는 전체 3부작 시리즈와 관련된 질문이나 피드백을 처리할 수 있습니다.피>