Bash 스크립트 syntax error near unexpected token 에러 해결법

최근 악성 Bash 스크립트를 분석하며 동적으로 실행하고 테스트하던 와중, 문법적으로 전혀 문제가 없음에도 syntax error near unexpected token
또는 unexpected end of file
에러가 출력되는 일이 발생하여 글을 작성하게 되었다.
필자가 겪은 상황은 악성 스크립트를 실행하다가 생겼지만, 문제의 본질은 악성 여부와는 상관 없이 모든 bash 스크립트에서 발생할 수 있으므로 이와 같은 에러를 경험한 분들에게 이 글이 도움이 되길 바란다.
1. 문제 상황
아래 Bash 스크립트는 W3School 에서 IF 문의 사용법을 보여주는 간단한 예제다. num
변수의 값이 10 이상이면 문자열을 출력하는 간단한 비교문이다.
# Basic if statement
num=15
if [ $num -gt 10 ]; then
echo "Number is greater than 10"
fi
복잡하지 않은 간단한 스크립트임에도 불구하고, Windows Host 에서 스크립트 파일을 생성, Kali linux 환경으로 스크립트를 복사해 bash
명령어로 실행하니 syntax error near unexpected token
에러가 발생했다.

syntax error near unexpected token
에러 발생2. 해결책
2.1 문법이 잘못된 경우
가장 일반적인 문제 발생 원인은 잘못된 bash 문법을 사용한 경우다. 위 예제에서는 해당 사항이 없지만 bash 스크립트에서 if
키워드를 사용하면 끝날 때 fi
키워드를 사용해서 닫아주어야 한다. 이외에도 for
, until
,while
과 같은 반복문 키워드가 종료되면 done
키워드를 사용해 적절하게 닫아주어야 한다.
또는 공백을 적절하게 사용하지 않아서 발생할 수도 있다. 예를 들어 if [ 비교문 ]
과 같은 구문을 사용할 때는 반드시 if
와 [
, ]
사이에 공백이 하나 이상 존재해야 한다. 다른 스크립트는 이런 부분에서 관대한 반면 bash 스크립트는 굉장히 엄격하다.
이 밖에도 괄호를 적절하게 닫아주지 않았거나, 쌍따옴표를 닫지 않았거나 하는 문법적인 이슈로 인해 에러가 발생할 수 있다. 이러한 문제는 에러 메시지를 천천히 읽어 보고 에러가 발생한 line 주변의 토큰과 문법을 자세히 보면 해결할 수 있다.
2.2 잘못된 줄 바꿈 문자 사용
만약 위에서 본 예제처럼 bash 문법을 제대로 지켰음에도 에러가 발생한다면 잘못된 줄 바꿈 문자를 사용하고 있을 가능성이 높다. Windows OS에서는 줄 바꿈 문자로 \r\n
(0x0D 0x0A)을 사용하는 반면, Unix, Linux 에서는 \n
(0x0A) 를 사용한다. 스크립트 파일에서 bash 문법을 제대로 지켰어도 줄 바꿈 문자를 Unix,Linux 에 맞게 적절하게 변환하지 않으면 시스템에서 정상적으로 실행하지 못하고 에러를 발생시킨다.
아래는 예제 스크립트가 Windows 줄 바꿈 문자인 \r\n
을 사용하는 경우다.

\r\n
을 줄 바꿈 문자로 사용하는 Windows 방식아래 이미지는 줄 바꿈 문자를 Unix 형식인 \n
변환한 내용이다.

\n
을 줄 바꿈 문자로 사용하는 Unix 방식Windows 줄 바꿈 문자로 저장된 스크립트 파일의 줄 바꿈 문자를 변경하는 방법은 크게 2가지가 있다.
2.2.1 dos2ux
Linux 환경이 준비되어 있다면 dos2unix
명령어로 간단하게 줄 바꿈 문자를 변경할 수 있다.
$ dos2unix windows_cr_lf.sh
dos2unix: converting file windows_cr_lf.sh to Unix format...
2.2.2 notepad++
일반적으로 많이 사용되는 텍스트 뷰어 프로그램인 notepad++
에서는 줄 바꿈 문자를 선택할 수 있는 기능이 존재한다.
notepad++
뷰어 하단에는 현재 선택된 파일이 어떤 줄 바꿈 문자를 사용하고 있는지 보여준다. 아래 이미지에서는 Windows (CR LF)
를 쓰고 있음을 보여준다.

편집
- 줄의 끝문자(EOL) 변환
- UNIX 형식으로 변환
을 클릭하면 현재 선택된 텍스트 파일의 줄 바꿈 문자를 Unix 형식으로 변환할 수 있다.

마찬가지로 뷰어 하단에서 줄 바꿈 문자가 Unix (LF)
로 변경된 것을 확인할 수 있다.
