bash 스크립트를 디버깅하는 방법?


135

오류 및 예기치 않은 동작에 대해 bash의 일부 스크립트에 문제가 있습니다. 수정 사항을 적용 할 수 있도록 문제점의 원인을 조사하고 싶습니다. 더 많은 정보를 얻기 위해 bash에 대해 일종의 "디버그 모드"를 설정할 수있는 방법이 있습니까?

답변:


132

디버그 출력을 보려면 bash -x ./script.sh스크립트 set -x로 bash 스크립트를 시작하거나 스크립트에 추가 하십시오.


bash4.1 이상 추가 :

디버그 출력을 별도의 파일에 쓰려면이를 스크립트에 추가하십시오.

exec 5> debug_output.txt
BASH_XTRACEFD="5"

참조 : https://stackoverflow.com/a/25593226/3776858


줄 번호를 보려면 다음을 추가하십시오.

PS4='$LINENO: '


logger명령에 액세스 할 수 있으면이를 사용하여 타임 스탬프, 스크립트 이름 및 줄 번호와 함께 syslog를 통해 디버그 출력을 작성할 수 있습니다.

#!/bin/bash

exec 5> >(logger -t $0)
BASH_XTRACEFD="5"
PS4='$LINENO: '
set -x

# Place your code here

명령 옵션 -p을 사용 logger하여 로컬 syslog를 통해 출력을 자체 로그 파일에 쓰도록 개별 기능 및 레벨을 설정할 수 있습니다 .


7
-v도 도움이 될 수 있습니다 (실행될 때 각 줄을 인쇄합니다. -x와 결합 가능). 또한 참조 : bashdb.sourceforge.net
올리비에 Dulac

4
또 다른 훌륭한 자료는 다음과 같습니다. shellcheck.net
Olivier Dulac

"exec 5>"는 무엇을합니까?
aggsol

3
@aggsol : BASH_XTRACEFD="5"bash를 set -x사용하면 파일 디스크립터 5로 활성화 될 때 생성 된 추적 출력을 작성합니다 . exec 5> >(logger -t $0)파일 디스크립터 5의 출력을 logger명령으로 재 지정합니다 .
사이러스

1
PS4에서 줄 번호와 쉘 스크립트 경로 또는 이름을 알 수 있습니까?
iloveretards

55

사용 set -x

나는 항상 set -xand를 사용한다 set +x. 자세한 내용을보고 싶은 부분을 감쌀 수 있습니다.

#!/bin/bash

set -x
..code to debug...
set +x

log4bash

당신이 개발 작업을 수행하고 이름 log4j에 의해 이동 로거의 스타일을 잘 알고있는 것 또한 경우, log4perl, 등, 당신은 사용하게 할 수 있습니다 log4bash을 .

발췌

그것을 직시하자-평범한 오래된 에코는 그것을 자르지 않습니다. log4bash는 Bash 스크립트에 대한 로깅을 향상시키려는 시도입니다 (예 : Bash에 로깅을 줄임).

거기에서 Bash 스크립트에서 다음과 같은 작업을 수행 할 수 있습니다.

#!/usr/bin/env bash
source log4bash.sh

log "This is regular log message... log and log_info do the same thing";

log_warning "Luke ... you turned off your targeting computer";
log_info "I have you now!";
log_success "You're all clear kid, now let's blow this thing and go home.";
log_error "One thing's for sure, we're all gonna be a lot thinner.";

# If you have figlet installed -- you'll see some big letters on the screen!
log_captains "What was in the captain's toilet?";

# If you have the "say" command (e.g. on a Mac)
log_speak "Resistance is futile";

이 유형의 출력 결과 :

    ss1

log4sh

더 이식성이 좋은 것이 필요하다면 더 오래된 것 log4sh입니다. 와 유사한 작품으로 log4bash여기에 있습니다 :


우분투에는 alias say="spd-say".bashrc가 있는데 say다른 배포판이나 OS X 의 명령 을 모방합니다.
Doorknob

1
trap-trap read debug와 함께 사용하면 set -vx가 좋은 조합입니다. 이를 통해 한 줄씩 단계별로 결과를 볼 수 있습니다.
Magnus Melwin

34

많은 배포판에 설치 가능한 패키지 인 bashdb bashdb 가 있습니다. bash의 내장 확장 디버깅 모드 ( shopt -s extdebug)를 사용합니다. gdb와 매우 비슷합니다. 다음은 약간의 맛을 내기위한 샘플 세션입니다.

$ ls
1st.JPG  2ndJPG.JPG
$ cat ../foo.sh
for f in *.JPG
do
  newf=${f/JPG/jpg}
  mv $f $newf
done
$ bashdb ../foo.sh
(foo.sh:1):
1:      for f in *.JPG
bashdb<0> next
(foo.sh:3):
3:        newf=${f/JPG/jpg}
bashdb<1> next
(foo.sh:4):
4:        mv $f $newf

GDB에서와 같이, 경고문은 표시됩니다 전에 그것을 실행하는 것입니다. 따라서 변수를 검사하여 명령문이 수행하기 전에 수행 할 작업을 확인할 수 있습니다.

bashdb<2> print $f $newf
1st.JPG 1st.jpg
bashdb<3> next
(foo.sh:1):
1:      for f in *.JPG
bashdb<4> next
(foo.sh:3):
3:        newf=${f/JPG/jpg}
bashdb<5> next
(foo.sh:4):
4:        mv $f $newf
bashdb<6> print $f $newf
2ndJPG.JPG 2ndjpg.JPG

그것은 우리가 원하는 것이 아닙니다! 파라미터 확장을 다시 봅시다.

bashdb<7> print $f ${f/JPG/jpg}
2ndJPG.JPG 2ndjpg.JPG
bashdb<8> print $f ${f/JPG$/jpg}
2ndJPG.JPG 2ndJPG.JPG
bashdb<9> print $f ${f/%JPG/jpg}
2ndJPG.JPG 2ndJPG.jpg

알았어. newf올바른 값으로 설정합시다 .

bashdb<10> eval newf=${f/%JPG/jpg}
$? is 0
bashdb<11> print $f $newf
2ndJPG.JPG 2ndJPG.jpg

좋아 보인다 스크립트를 계속하십시오.

bashdb<12> next
Debugged program terminated normally. Use q to quit or R to restart.
$ ls
1st.jpg  2ndJPG.jpg

20

bash와 같은 대부분의 Bourne 기반 쉘에서 스크립트를 디버깅하는 표준 방법은 스크립트 set -x맨 위에 작성하는 것입니다. 이를 통해 bash가 수행 / 수행중인 작업과 인수 평가 방법에 대해 더 자세하게 알 수 있습니다.

-x  Print commands and their arguments as they are executed.

이것은 인터프리터 나 스크립트 내부에 유용합니다. 예를 들면 다음과 같습니다.

$ find "$fileloc" -type f -prune "$filename" -print
+ find /var/adm/logs/morelogs -type f -prune '-name *.user' -print
find: unknown predicate '-name *.user'
$ find "$fileloc" -type f -prune $filename -print
+ find /var/adm/logs/morelogs -type f -prune -name '*.user' -print
find: '/var/adm/logs/morelogs': No such file or directory

위에서 우리는 왜 작은 따옴표로 인해 find가 실패하는지 알 수 있습니다.

기능을 비활성화하려면을 입력하십시오 set +x.


13

이클립스 사용하기

아래 링크 된 "_DEBUG.sh"스크립트와 함께 Eclipse와 Shelled의 결합 된 환경을 사용할 수 있습니다.

쉘 전환

기본적으로 셸 개발 도구는 /bin/dash인터프리터로 사용 합니다. /bin/bash웹과 환경의 대부분의 쉘 예제와 더 잘 호환되도록 이것을 변경했습니다 .

참고 : -> 환경 설정 -> 셸 스크립트 -> 통역사 로 이동하여이를 변경할 수 있습니다.

설치 지침

디버거 패키지에는 _DEBUG.sh기본적으로 readme.txt 인 스크립트 디버깅에 스크립트 를 사용하는 단계 가 있습니다.

  1. 쉘 스크립트 프로젝트를 작성하십시오 ( 파일 -> 새로 작성 -> 기타 -> 쉘 스크립트 -> 쉘 스크립트 프로젝트 마법사) .
  2. Bash 스크립트 파일을 작성하십시오 ( File- > New- > File) . 이 예에서는입니다 script.sh. 확장자는 ".sh"여야하며 필수입니다.
  3. 파일 _DEBUG.sh을 프로젝트 폴더로 복사하십시오 .
  4. 파일 맨 위에 다음 텍스트를 삽입하십시오 script.sh.

    . _DEBUG.sh
  5. 파일이 Microsoft Windows에서 작성된 경우 File- > Convert Line Delimiters to- > Unix 를 실행하십시오 .

  6. 디버그 실행 구성을 설정 하십시오 . 실행 -> 디버그 구성 -> Bash 스크립트 ... 여기에는 두 개의 필드가 있습니다.

    a) "Bash script :"-Eclipse의 작업 공간에서 디버그 할 Bash 스크립트의 경로입니다.
    e) "디버거 포트 :"33333

  7. 디버그 퍼스펙티브로 전환하십시오. 디버깅 세션을 시작하십시오. script.shbash 쉘에서 시작하십시오 .

bash 디버그 UI

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

이 bash 디버거 에는 다음과 같은 표준 프로그래밍 디버거의 모든 기능이 있습니다.

  • 중단 점 토글
  • 단일 단계별 작업
  • 스텝 인, 스텝 아웃, 스텝 오버 기능 및 서브 루틴
  • 스크립트가 실행되는 동안 언제든지 코드 또는 변수 검사

Shelled (Shell Script Editor) IDE (Integrated Development Environment)에는 스크립트 작성 중에 컨텍스트 확인, 강조 표시 및 들여 쓰기를 수행하는 추가 보너스가 있습니다. 제대로 들여 쓰기되지 않으면 즉시 많은 오류를 플래그 / 지역화 할 수 있습니다.

그런 다음 과 같은 다른 IDE 이점이 있습니다.

  • TODO 작업 목록
  • Mylyn Task
  • 북마크 목록
  • 다중 창 편집
  • 환경의 원격 공유

멋진 팁. Bash를 이와 같이 디버깅 할 수 있다는 것을 알게되어 기쁩니다.
slm

8

최근 몇 년 동안 훌륭한 리소스가 등장했습니다 : http://shellcheck.net

그것은 일반적인 bash보다 더 많은 것을 보여줌으로써 성가신 닫히지 않은 따옴표 또는 중괄호 등을 쉽게 찾을 수 있습니다.

인터넷을 통해 민감한 정보 (ip, 비밀번호 등)를 붙여 넣지 마십시오 ... (특히 http, 암호화되지 않은) (shellcheck도 다운로드 할 수 있다고 생각하지만 확실하지는 않습니다)


6

간단히 사용하십시오 :

#!/bin/bash -x

쉘도 마찬가지입니다 :

#!/bin/sh -x

당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.