태그 보관물: newline

^M 개행문자로 인한 Shell Script 오류

Shell Script bad interpreter error

  • Shell Script를 윈도우 환경에서 작성했거나 FTP로 전송하고 리눅스 환경에서 실행하면 아래와 같은 에러 메시지를 마주할 때가 있습니다.
[root@localhost ~]# ./temp.sh 
 -bash: ./temp.sh: /bin/bash^M: bad interpreter: No such file or directory
  • 결론적으로는 윈도우와 리눅스의 개행문자의 차이로 인해 발생하는 현상으로 윈도우는 CRLF, 리눅스는 LF입니다. 대강의 의미는 아래와 같습니다.
LF : Line Feed커서를 한칸 아래로 이동 = 새로운 행 추가(new line feed)
CR : Carriage Return커서를 맨왼쪽으로 이동 = 시작위치로 복귀(return)
https://zetawiki.com/wiki/%EA%B0%9C%ED%96%89%EB%AC%B8%EC%9E%90,%EB%9D%BC%EC%9D%B8%ED%94%BC%EB%93%9C,%EC%BA%90%EB%A6%AC%EC%A7%80%EB%A6%AC%ED%84%B4
  • Binary 타입으로 윈도우의 에디터에서 파일을 저장하거나 FTP로 전송하게 되면 윈도우의 개행문자 “\r\n”가 리눅스의 개행문자 “\n”으로 변환 되지 않게 되어 처음과 같은 현상이 발생하게 됩니다.
  • 해당 상태를 정확히 확인하기 위해서는 vi 편집기를 Binary모드로 실행하면 되고 아래와 같이 확인이 가능합니다.
[root@localhost ~]# vim -b temp.sh

!/bin/bash^M
^M
ls -lh^M
  • 단순히 ^M만 삭제후 저장해도 해결 가능하지만 수백줄이상의 스크립트에서는 작업하기 곤란한 방식이므로 검색, 치환 기능을 이용해 변경할 수 있습니다.
  • 개행문자 ^M은 “Shift + 6”, “Shift + m” 이 아닌 “Ctrl + v + m” 입력해야 합니다.
[root@localhost ~]# vim -b temp.sh

:%s/^M//g
  • 또는 기본 모드로 vi를 실행 후 Last Line Mode에서 설정 입력 후 저장 하는 방법이 있습니다.
[root@localhost ~]# vim temp.sh

:set fileformat=unix
:wq
  • vi 편집기를 사용하기 곤란한 환경에서는 sed 명령으로 해당 개행문자를 치환 할 수 있습니다.
[root@localhost ~]# sed -i -e 's/\r$//' temp.sh

[root@localhost ~]# sed -i -e 's/^M$//' temp.sh     // ^M은 "Ctrl + v + m" 입력
  • 저장하거나 전송할 때 파일 포멧을 선택할 수 있으므로 사전에 신경을 쓰는게 시행착오를 방지하는 방법입니다. 🙂