Bash 스크립트를 실행하지 않고 구문을 확인하려면 어떻게합니까?


답변:


380
bash -n scriptname

아마도 명백한주의 사항 : 이것은 구문의 유효성을 검사하지만 bash 스크립트가 경로 ech hello대신에 없는 명령을 실행하려고하는지 확인하지 않습니다 echo hello.


9
bash 맨 페이지의 "SHELL BUILTIN COMMANDS / set"에 -n이 문서화되어 있으며 맨 페이지 상태의 시작 부분에서 bash는 모든 단일 문자 옵션을 해석합니다 set.
ephemient

24
(나를 위해) 명백하지 않은 경고에 추가하기 위해, if ["$var" == "string" ]대신 공간이 부족하여 발생하는 오류를 포착하지 않습니다.if [ "$var" == "string" ]
Brynjar

11
@Brynjar 그것은 단지 구문 검사이기 때문입니다. 열린 괄호는 구문이 아니며 실행할 함수의 이름입니다. type ["[는 내장 쉘입니다." 궁극적으로 test프로그램에 위임 되지만 닫는 괄호도 기대됩니다. 따라서 이것은 if test"$var"저자의 의미는 아니지만 구문 적으로 유효합니다 ($ var의 값이 "a"인 경우 "bash : testa : command not found"). 요점은 구문 상으로는 누락 된 공간이 없다는 것입니다.
Joshua Cheek

2
@JoshuaCheek : [이 경우 빈 문자열$var 로 확장되는 경우에만 Builtin 이 호출됩니다 . 경우 A와 팽창 비어 있지 않은 문자열이 됩니다 연결된 그 문자열과로 해석됩니다 명령 이름 ( 기능 이다 배쉬, 그리고, 그래, 이름) 구문 분명히, 당신 상태로, 의도하지 유효하지만. 셸 대신 키워드 를 사용 하지만을 대신 사용 하면 의도하지 않은 문자열 연결이 여전히 키워드 인식을 무시하기 때문에 동일한 결과를 얻을 수 있습니다. $var[[[[[[
mklement0

2
@JoshuaCheek는 : 배쉬는 여전히 구문 여기 -checking :이 점검있어 간단한 명령 호출 구문 : ["$var"이다 구문 적으로 유효한 명령 이름의 표현; 마찬가지로 토큰 =="$string"유효한 명령 인수 입니다. (일반적으로 내장이 [와 구문 분석 명령 반면, 구문 [[- 쉘로 키워드 - 다른 구문 분석됩니다.) 쉘 내장은 [않습니다 하지 위임 은 "에 test프로그램"(외부 유틸리티) : bash, dash, ksh, zsh모두가 내장 모두의 버전 [test외부 유틸리티 상대를 호출 하지 않습니다 .
mklement0

127

시간은 모든 것을 바꿉니다. 다음은 쉘 스크립트에 대한 온라인 구문 검사를 제공 하는 웹 사이트 입니다.

일반적인 오류를 감지하는 것이 매우 강력하다는 것을 알았습니다.

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

ShellCheck에 대하여

ShellCheck 는 sh / bash 스크립트를위한 정적 분석 및 보푸라기 도구입니다. 주로 초급 및 중급 구문 오류와 함정을 다루는 데 중점을 둡니다. 쉘은 단순한 오류 메시지 또는 이상한 동작을 제공하지만 코너 케이스가 지연된 오류를 일으킬 수있는 몇 가지 고급 문제에 대해서도보고합니다.

하스켈 소스 코드는 GitHub에서 구할 수 있습니다!


5
좋은 팁; OSX에 당신은 지금 또한 shellcheck.net CLI를 설치할 수 있습니다 shellcheck통해, 브루 : brew install shellcheck.
mklement0

3
또한 debian & friends에서 :apt-get install shellcheck
그 다른 사람

Ubuntu trusty의 경우이 패키지를에서 설치해야합니다 trusty-backports.
Peterino

위에서 언급했듯이, 신뢰할 수있는 의존성이 필요하며 우분투 14.04에서 다음과 같이 설치할 수 있습니다 : sudo apt-get -f install, 다음 : sudo sudo apt-get install shellcheck
zhihong

이것은 실제로 유용하지만 Bash 파서는 사용하지 않고 자체 파서를 사용합니다. 대부분의 경우 이것은 충분하며 구문 분석 및 기타 문제를 모두 식별 할 수 있지만, 완전히 동일한 방식으로 구문 분석하지 않는 하나 이상의 엣지 케이스 (및 아마도 보지 않은 다른 경우)가 있습니다.
Daniel H

38

또한 추가 검사를 수행하기 위해 작성한 모든 bash 스크립트에서 'u'옵션을 활성화합니다.

set -u 

다음 스크립트 'check_init.sh'와 같이 초기화되지 않은 변수의 사용법을보고합니다.

#!/bin/sh
set -u
message=hello
echo $mesage

스크립트 실행 :

$ check_init.sh

다음을보고합니다.

./check_init.sh[4] : 메시지 : 매개 변수가 설정되지 않았습니다.

오타를 잡는 데 매우 유용


4
나는이를 통과하면, 그것의 좋은 "pipefail -o 세트", "설정 -o errexit" "세트 -o nounset를"가서, 내 bash는 스크립트에서 항상 이러한 플래그를 설정
μολὼν.λαβέ

set -u오류 메시지를 받으려면 스크립트를 실행해야하기 때문에이 질문에 실제로 대답하지는 않지만 +1입니다 . bash -n check_init.sh그 경고 조차 보여
주지

23
sh  -n   script-name 

이것을 실행하십시오. 스크립트에 구문 오류가 있으면 동일한 오류 메시지를 반환합니다. 오류가 없으면 메시지를 표시하지 않고 나옵니다. 을 사용하여 즉시 확인할 수 있으며 실수없이 성공적으로 확인 echo $?을 반환 0합니다.

그것은 나를 위해 잘 작동했습니다. Linux OS Bash Shell에서 실행했습니다.


1
bash 구문 검사와 정확히 관련은 없지만 전체 스크립트 또는 스크립트 섹션을 디버깅하기 위해 set -x 및 set + x를 사용하는 것이 매우 유용합니다.
GuruM

감사합니다 -n에 대해 몰랐지만 내가 원하는 것은 @GuruM> sh -x test.sh였습니다. 스크립트의 생성 된 출력을 표시하기 때문에
zzapper

1
예. 명령 행에서 다음을 수행 할 수 있음을 언급하지 않았습니다. 1) bash -x test.sh #이 명령은 전체 스크립트를 '디버그 모드'에서 실행합니다. 2) set + x; bash test.sh; set -x # 스크립트 실행 전 / 후 디버그 모드 설정 / 해제 스크립트에서 : a) #! / bin / bash -x # 스크립트 상단에 '디버그 모드'추가 b) set + x; 암호; 스크립트의 모든 섹션에 대해 -x #add '디버그 모드'
GuruM

sh -n스크립트가 유효한 Bash 스크립트인지 확인하지 못할 것입니다. 잘못된 부정을 줄 수 있습니다. sh보통 Bash가 아닌 Bourne 쉘 변형입니다. 예를 들어 우분투 리눅스에서는 realpath -e $(command -v sh)/ bin / dash를 제공합니다.
jarno

4

실제로 find도구를 사용하여 실행하지 않고 구문 오류가 있는지 현재 디렉토리의 모든 bash 스크립트를 확인합니다 .

예:

find . -name '*.sh' -exec bash -n {} \;

단일 파일에 사용하려면 파일 이름으로 와일드 카드를 편집하십시오.


3

null 명령 [콜론]은 변수 값을 확인하기 위해 디버깅 할 때도 유용합니다.

set -x
for i in {1..10}; do
    let i=i+1
    : i=$i
done
set - 

이 매개 변수 확장 사용
mug896

이것은 set -x실행되기 전에 모든 줄을 보여 주기 때문에 작동합니다
rubo77


1

변수 (디렉토리에있는 모든 파일의 유효성 (git pre-commit hook, build lint script)이 변수에 필요하면 "sh -n"또는 "bash -n"명령의 stderr 출력을 포착 할 수 있습니다 (기타 참조). 답변)를 변수에 입력하고이를 기반으로하는 "if / else"

bashErrLines=$(find bin/ -type f -name '*.sh' -exec sh -n {} \;  2>&1 > /dev/null)
  if [ "$bashErrLines" != "" ]; then 
   # at least one sh file in the bin dir has a syntax error
   echo $bashErrLines; 
   exit; 
  fi

필요에 따라 "bash"로 "sh"변경

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