programing

Bash 스크립트를 디버그하려면 어떻게 해야 합니까?

padding 2023. 4. 28. 20:19
반응형

Bash 스크립트를 디버그하려면 어떻게 해야 합니까?

Bash 스크립트를 디버깅할 수 있는 방법이 있습니까?

예를 들어, "1번 회선 호출", "2번 회선 호출" 등과 같은 일종의 실행 로그를 인쇄하는 것입니다.

sh -x script [arg1 ...]
bash -x script [arg1 ...]

실행 중인 작업을 추적할 수 있습니다.(답변 하단의 '명확한 설명'도 참조하십시오.)

스크립트 내에서 디버깅을 제어해야 하는 경우도 있습니다.그런 경우 치토가 알려준 대로 다음을 사용할 수 있습니다.

set -x

디버깅이 켜집니다.그런 다음 다음을 사용하여 다시 끌 수 있습니다.

set +x

는 (분석을통현추상확수있다태습니인할를적재해▁(▁by분)$- 래그대, 해에현에 대한 의 기x.)

으로 '한셸은일으로옵제또다니공합션을반적▁'다▁options니또▁also제' 옵션을 제공합니다.-n무집행'에 -v이를 조합하여 셸이 스크립트를 실행할 수 있다고 생각하는지 확인할 수 있습니다. 가끔 불균형 따옴표가 있는 경우 유용합니다.


'라는 주장이 있습니다.-xBash의 옵션은 다른 셸과 다릅니다(댓글 참조).Bash 설명서에는 다음과 같이 나와 있습니다.

  • -x

    합니다.for 명령,case 명령,select및 령, 술for명령 및 해당 인수 또는 관련 단어 목록은 명령을 확장한 후 실행하기 전에 표시됩니다.PS4변수가 확장되고 명령과 확장된 인수 앞에 결과 값이 인쇄됩니다.

그 정도는 전혀 다른 행동을 나타내는 것 같지 않습니다.'에 대한 다른 관련 언급은 보이지 않습니다.-x.시작 순서의 차이에 대해서는 설명하지 않습니다.

명확화:일반적인 Linux 박스와 같은 시스템의 경우, 여기서 '/bin/sh에 대한 기호 링크입니다./bin/bash(또는 Bash 실행 파일이 발견되는 곳이면 어디든) 두 명령줄은 실행 추적을 사용하여 스크립트를 실행하는 것과 동등한 효과를 제공합니다.Solaris 및의 경우, "" ("Solaris" 또는 ""Linux")"서는/bin/sh는 Bash가 아니며 두 명령줄은 (약간) 다른 결과를 제공합니다.가장 주목할 만한 것은, '/bin/sh하지 못하는 Bash의 될 수 (Solaris의 전혀 인 의 식 하 지 못 Bash의 구 습 있 니 다 수 될 동 우 경 혼 로 해 조 인 는 하 Solaris 의,/bin/sh는 본 셸이며, 현대의 리눅스에서는 Dash(더 작고 더 엄격한 POSIX 전용 셸)이다.)행('이게이쉐불름로러행 '방렇면오 '으' ''쉐 '(▁(' '▁when '#!/bin/bash'#!/bin/sh파일의 시작 부분에 있는 ')는 내용이 해석되는 방식에 영향을 주지 않습니다.

Bash 매뉴얼에는 Bash POSIX 모드에 대한 섹션이 있으며, 이는 이 답변의 오래되었지만 잘못된 버전(아래 주석 참조)과는 달리 'Bash 호출됨:sh그리고 'Bash는 다음과 같이 호출되었습니다.bash'.

(Bash) 셸 스크립트를 디버깅할 때, 셰방 라인에 이름이 붙은 셸을 사용하는 것이 현명하고 제정신일 것입니다.-x이 다를 수 그렇지 않으면 스크립트를 실행할 때와 디버깅할 때의 동작이 다를 수 있습니다.

스크립트를 디버깅하기 위해 다음 방법을 사용했습니다.

set -e외부 프로그램이 0이 아닌 종료 상태를 반환하는 경우 스크립트를 즉시 중지합니다.이 기능은 스크립트가 모든 오류 사례를 처리하려고 하고 이를 처리하지 못할 경우 유용합니다.

set -x위에서 언급되었으며 모든 디버깅 방법 중 가장 유용합니다.

set -n스크립트에서 구문 오류를 확인하려는 경우에도 유용할 수 있습니다.

strace상황을 확인하는 데도 유용합니다.스크립트를 직접 작성하지 않은 경우 특히 유용합니다.

조나단 레플러의 대답은 타당하고 유용합니다.

그러나 "표준" 스크립트 디버깅 방법은 비효율적이고, 직관적이지 않으며, 사용하기 어렵다는 것을 알게 되었습니다.모든 것을 쉽게 처리하고 쉬운 문제(그리고 어려운 문제의 경우 가능)를 쉽게 처리하는 정교한 GUI 디버거에 익숙한 사람들에게 이러한 솔루션은 그다지 만족스럽지 않습니다.

는 DDD와 bashdb의 조합을 사용합니다.전자는 후자를 실행하고 후자는 스크립트를 실행합니다.이를 통해 멀티 윈도우 UI는 컨텍스트를 머릿속에 유지하거나 소스를 계속 재목록화하려는 끊임없는 정신적 노력 없이 컨텍스트에서 코드를 단계적으로 처리하고 변수, 스택 등을 볼 수 있는 기능을 제공합니다.

DDDBASHDB에서 설정하는 방법에 대한 지침이 있습니다.

는 셸체크 유틸리티를 찾았고 아마 어떤 사람들은 그것을 흥미롭게 여길 것입니다.

약간의 예:

$ cat test.sh
ARRAY=("hello there" world)

for x in $ARRAY; do
  echo $x
done

$ shellcheck test.sh

In test.sh line 3:
for x in $ARRAY; do
         ^-- SC2128: Expanding an array without an index only gives the first element.

버그를 수정합니다.첫 번째 시도...

$ cat test.sh
ARRAY=("hello there" world)

for x in ${ARRAY[@]}; do
  echo $x
done

$ shellcheck test.sh

In test.sh line 3:
for x in ${ARRAY[@]}; do
         ^-- SC2068: Double quote array expansions, otherwise they're like $* and break on spaces.

다시 시도해 보겠습니다...

$ cat test.sh
ARRAY=("hello there" world)

for x in "${ARRAY[@]}"; do
  echo $x
done

$ shellcheck test.sh

지금 발견!

그것은 단지 작은 예시일 뿐입니다.

스크립트 내에서 "set -x"를 작성할 수도 있습니다.

Visual Studio Code를 설치한 다음 Bash 디버그 확장을 추가하면 비주얼 모드에서 디버그할 수 있습니다.여기서 실제로 확인해 보십시오.

여기에 이미지 설명 입력

셸링된 플러그인 및 BashEclipse와 함께 Eclipse를 사용합니다.

쉘드의 경우:ZIP 파일을 다운로드하여 메뉴 도움말 → 새 소프트웨어 설치: 로컬 보관을 통해 이클립스로 가져옵니다.Bash Eclipse의 경우:JAR 파일을 Eclipse의 dropins 디렉토리에 복사합니다.

BashEclipse 파일에 제공된 단계를 따릅니다.

여기에 이미지 설명 입력

저는 Bash에서 많은 스크린샷으로 튜토리얼을 작성했습니다: Bash 프로그래밍을 위한 Eclipse 활성화 | 플러그인(쉘 에디터)

저는 Bash 디버거를 만들었습니다. Bash 디버깅 Bash.한번 해보세요.

set +x = @ECHO OFF, set -x = @ECHO ON.

다니있을 할 수 .-xv다음과 같이 표준 셰방에 대한 옵션:

#!/bin/bash -xv

-x명령 및 해당 인수를 실행할 때 표시합니다. -v셸 입력 라인을 읽을 때 표시합니다.


ltracestrace와 유사한 또 다른 Linux 유틸리티입니다.하지만,ltrace실행 파일 또는 실행 중인 프로세스에서 호출되는 모든 라이브러리 호출을 나열합니다.이름 자체는 라이브러리 호출 추적에서 비롯되었습니다.

예:

ltrace ./executable <parameters>
ltrace -p <PID>

원천

Bash 디버거인 http://bashdb.sourceforge.net/ 을 사용해 볼 수 있을 것 같습니다.

셸의 글로벌 변수를 통한 셸 스크립트 로깅에 대한 자세한 내용이 있습니다.셸 스크립트에서 유사한 종류의 로깅을 에뮬레이트할 수 있습니다. 스크립트에 대한 로그 추적 메커니즘입니다.

게시물에는 INFO, DEBUG, ERROR와 같은 로그 수준을 소개하는 세부 정보가 있습니다.스크립트 항목, 스크립트 종료, 함수 항목, 함수 종료와 같은 세부 정보를 추적합니다.

샘플 로그:

여기에 이미지 설명 입력

Bash 스크립트를 디버깅하는 몇 가지 방법:

용사를 합니다.set -[nvx]

에 더하여

set -x

그리고.

set +x

덤프 중지용.

저는 에 대해 말하고 싶습니다.set -v덜 발달된 출력만큼 작은 덤프를 만듭니다.

bash <<<$'set -x\nfor i in {0..9};do\n\techo $i\n\tdone\nset +x' 2>&1 >/dev/null|wc -l
21

for arg in x v n nx nv nvx;do echo "- opts: $arg"
    bash 2> >(wc -l|sed s/^/stderr:/) > >(wc -l|sed s/^/stdout:/) <<eof
        set -$arg
        for i in {0..9};do
            echo $i
          done
        set +$arg
        echo Done.
eof
    sleep .02
  done
- opts: x
stdout:11
stderr:21
- opts: v
stdout:11
stderr:4
- opts: n
stdout:0
stderr:0
- opts: nx
stdout:0
stderr:0
- opts: nv
stdout:0
stderr:5
- opts: nvx
stdout:0
stderr:5

변수를 덤프하거나 즉시 추적

일부 변수를 테스트하기 위해 다음을 사용합니다.

bash <(sed '18ideclare >&2 -p var1 var2' myscript.sh) args

추가할 경우:

declare >&2 -p var1 var2

편집할 필요 없이 결과 스크립트(인수 포함)를 실행할 수 있습니다.

물론, 이것은 다음을 추가하는 데 사용될 수 있습니다.set [+-][nvx]:

bash <(sed '18s/$/\ndeclare -p v1 v2 >\&2/;22s/^/set -x\n/;26s/^/set +x\n/' myscript) args

은 니다됩추를 추가할 입니다.declare -p v1 v2 >&2 선, 18번 선, 18번 선,set -x과 22행 .set +x 2626보다

약간의 샘플:

bash <(sed '2,3s/$/\ndeclare -p LINENO i v2 >\&2/;5s/^/set -x\n/;7s/^/set +x\n/' <(
        seq -f 'echo $@, $((i=%g))' 1 8)) arg1 arg2
arg1 arg2, 1
arg1 arg2, 2
declare -i LINENO="3"
declare -- i="2"
/dev/fd/63: line 3: declare: v2: not found
arg1 arg2, 3
declare -i LINENO="5"
declare -- i="3"
/dev/fd/63: line 5: declare: v2: not found
arg1 arg2, 4
+ echo arg1 arg2, 5
arg1 arg2, 5
+ echo arg1 arg2, 6
arg1 arg2, 6
+ set +x
arg1 arg2, 7
arg1 arg2, 8

참고: 주의 사항$LINENO그것은 즉석 수정의 영향을 받을 것입니다!

drop (drop)만 됩니다.bash <(그리고.) arg1 arg2)

단계별, 실행 시간

Bash 스크립트를 프로파일링하는 방법에 대한 답변을 확인합니다.

언급URL : https://stackoverflow.com/questions/951336/how-can-i-debug-a-bash-script

반응형