Computer >> 컴퓨터 >  >> 프로그램 작성 >> BASH 프로그래밍

셸 추적을 사용하여 셸 스크립트에서 명령 실행을 추적하는 방법

쉘 스크립트 디버깅 시리즈의 이 기사에서는 쉘 추적인 세 번째 쉘 스크립트 디버깅 모드에 대해 설명하고 작동 방식과 사용 방법을 보여주는 몇 가지 예를 살펴보겠습니다.

이 시리즈의 이전 부분은 다른 두 가지 셸 스크립트 디버깅 모드인 상세 모드에 대해 명확하게 설명합니다. 및 구문 확인 이 모드에서 쉘 스크립트 디버깅을 활성화하는 방법에 대한 이해하기 쉬운 예가 있는 모드입니다.

  1. Linux에서 셸 스크립트 디버깅 모드를 활성화하는 방법 – 1부
  2. 셸 스크립트에서 구문 검사 디버깅 모드를 수행하는 방법 – 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부작 시리즈와 관련된 질문이나 피드백을 처리할 수 있습니다.