Programing

bash 스크립트를 디버깅하는 방법은 무엇입니까?

lottogame 2020. 6. 8. 07:49
반응형

bash 스크립트를 디버깅하는 방법은 무엇입니까? [닫은]


bash 스크립트를 디버깅하는 방법이 있습니까? 예를 들어 "calling line 1", "calling line 2"등과 같은 일종의 실행 로그를 인쇄하는 것.


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

이것들은 실행중인 것을 추적합니다. (답변 하단의 '설명'도 참조하십시오.)

때로는 스크립트 내에서 디버깅을 제어해야합니다. 이 경우 Cheeto가 상기 한 것처럼 다음을 사용할 수 있습니다.

set -x

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

set +x

$-에 대한 현재 플래그 를 분석하여 현재 추적 상태를 찾을 수 있습니다 x.

또한 쉘은 일반적으로 ' -n'실행 없음 ' 의 경우' '및 -v'verbose '모드의 경우 ' ' 옵션을 제공 합니다. 이것들을 조합하여 사용하면 쉘이 스크립트를 실행할 수 있다고 생각하는지 알 수 있습니다. 어딘가에 불균형 한 따옴표가있는 경우 유용합니다.


-xBash 의 ' '옵션이 다른 쉘과 다르다는 주장이 있습니다 (주석 참조). 배쉬 설명서는 말한다 :

  • -엑스

    간단한 명령, for명령, case명령, select명령 및 산술 for명령과 인수 또는 관련 단어 목록을 확장 한 후 실행하기 전에 추적하십시오 . PS4변수 이 확장되고 결과 값이 명령 및 확장 인수 앞에 인쇄됩니다.

그다지 다른 행동을 나타내는 것은 아닙니다. -x매뉴얼 에 ' '에 대한 다른 관련 참조가 없습니다 . 시작 순서의 차이점에 대해서는 설명하지 않습니다.

설명 : 일반적인 Linux 상자와 같은 시스템에서 ' /bin/sh'는 ' '에 대한 심볼릭 링크 /bin/bash(또는 Bash 실행 파일이있는 곳)이면 두 명령 줄은 실행 추적이 설정된 상태에서 스크립트를 실행하는 것과 동일한 효과를 얻습니다. 다른 시스템 (예 : Solaris 및 일부 최신 Linux 변형)에서는 /bin/shBash가 아니며 두 명령 행은 (약간) 다른 결과를 제공합니다. 특히 ' /bin/sh'는 Bash의 구문에 의해 전혀 인식되지 않는 혼란 스러울 것입니다. (Solaris에서 /bin/shBourne 쉘이며, 현대 Linux에서는 때때로 더 작고 더 엄격하게 POSIX 전용 쉘인 Dash입니다.) 이와 같은 이름으로 'shebang'행 ( ' #!/bin/bash'vs '#!/bin/sh'

Bash 매뉴얼에는 Bash POSIX 모드 에 대한 섹션이 있는데,이 대답의 오래되었지만 잘못된 버전 (아래 주석 참조)과 달리 'Bash invoked sh'와 'Bash invoked' 의 차이점을 상세하게 설명합니다. bash'.

(Bash) 쉘 스크립트를 디버깅 할 때 shebang 행에 이름이 지정된 쉘을 -x옵션 과 함께 사용하는 것이 합리적이고 제정신 입니다. 그렇지 않으면 스크립트를 실행할 때와 디버깅 할 때 다른 동작이 나타날 수 있습니다.


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

set -e외부 프로그램이 0이 아닌 종료 상태를 리턴하면 스크립트가 즉시 중지됩니다. 이것은 스크립트가 모든 오류 사례를 처리하려고 시도하고 실패한 경우를 포착해야하는 경우에 유용합니다.

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

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

strace무슨 일이 일어나고 있는지 볼 때도 유용합니다. 스크립트를 직접 작성하지 않은 경우 특히 유용합니다.


이 답변은 유효하고 유용합니다 : https://stackoverflow.com/a/951352

그러나 "표준"스크립트 디버깅 방법은 비효율적이며 직관적이지 않으며 사용하기 어렵다는 것을 알게되었습니다. 복잡한 GUI 디버거에 익숙한 사용자라면 모든 문제를 쉽게 해결할 수 있고 작업이 쉬워 쉽게 문제를 해결할 수 있습니다 (어려운 문제는 가능).이 솔루션은 그다지 만족스럽지 않습니다.

내가하는 일은 DDD와 bashdb의 조합을 사용하는 것입니다. 전자는 후자를 실행하고 후자는 스크립트를 실행합니다. 이를 통해 다중 창 UI에 컨텍스트를 유지하거나 소스를 계속 나열하려는 지속적인 정신적 노력없이 컨텍스트에서 코드를 단계별로 실행하고 변수, 스택 등을 볼 수 있습니다.

여기에 설정에 대한 지침이 있습니다 : http://ubuntuforums.org/showthread.php?t=660223


나는 shellcheck 유틸리티를 발견했고 어떤 사람들은 그것을 재미 있다고 생각할지도 모른다 https://github.com/koalaman/shellcheck

작은 예 :

$ 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"를 쓸 수도 있습니다.


VSCode를 설치 한 다음 bash 디버그 확장을 추가하면 비주얼 모드에서 디버그 할 준비가됩니다. 실제로 여기참조하십시오 .

여기에 이미지 설명을 입력하십시오


Bash 디버거를 만들었습니다. 시도해보십시오. https://sourceforge.net/projects/bashdebugingbash 도움이되기를 바랍니다.


플러그인 쉘 및 basheclipse와 함께 이클립스를 사용하십시오.

https://sourceforge.net/projects/shelled/?source=directory https://sourceforge.net/projects/basheclipse/?source=directory

껍질이있는 경우 : zip을 다운로드하고 도움말을 통해 일식으로 가져 오기-> 새 소프트웨어 설치 : 로컬 아카이브 basheclipse의 경우 : 항아리를 일식의 dropins 디렉토리에 복사하십시오.

https://sourceforge.net/projects/basheclipse/files/?source=navbar 제공 단계를 따르십시오

여기에 이미지 설명을 입력하십시오

I wrote a tutorial with many screenshots at http://dietrichschroff.blogspot.de/2017/07/bash-enabling-eclipse-for-bash.html


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


You can add -xv option to the standard Shebang as follows:

#!/bin/bash -xv  

-x : Display commands and their arguments as they are executed.
-v : Display shell input lines as they are read.


ltrace is another Linux Utility similar to strace. However, ltrace lists all the library calls being called in an executable or a running process. Its name itself comes from library-call tracing. For example:

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

Source


I think you can try this Bash debugger: http://bashdb.sourceforge.net/.


Some trick to debug scripts:

Using set -[nvx]

In addition to

set -x

and

set +x

for stopping dump.

I would like to speak about set -v wich dump as smaller as less developped output.

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

Dump variables or tracing on the fly

For testing some variables, I use sometime this:

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

for adding:

declare >&2 -p var1 var2

at line 18 and running resulting script (with args), without having to edit them.

of course, this could be used for adding set [+-][nvx]:

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

will add declare -p v1 v2 >&2 after line 18, set -x before line 22 and set +x before line 26.

little sample:

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

Note: Care about $LINENO will be affected by on-the-fly modifications!

( To see resulting script whithout executing, simply drop bash <( and ) arg1 arg2 )

Step by step, execution time

Have a look at my answer about how to profile bash scripts


셸의 전역 변수를 통한 셸 스크립트 로깅에 대한 자세한 내용이 있습니다. 쉘 스크립트에서 비슷한 종류의 로깅을 에뮬레이트 할 수 있습니다 : http://www.cubicrace.com/2016/03/log-tracing-mechnism-for-shell-scripts.html

이 게시물에는 INFO, DEBUG, ERROR와 같은 로그 수준 소개에 대한 세부 정보가 있습니다. 스크립트 입력, 스크립트 종료, 기능 입력, 기능 종료와 같은 세부 사항 추적

샘플 로그 :

여기에 이미지 설명을 입력하십시오

참고 URL : https://stackoverflow.com/questions/951336/how-to-debug-a-bash-script

반응형