Windows에서 편집된 Bash/Korn 쉘 스크립트에서 "...^M: 찾을 수 없음" 오류가 발생합니다.

Windows에서 편집된 Bash/Korn 쉘 스크립트에서 "...^M: 찾을 수 없음" 오류가 발생합니다.

저는 Notepad++를 사용하여 Windows에서 Bash 스크립트를 작성했습니다.

cxStopAllServicesOnSERVER.sh

#!/usr/bin/bash
cd "/some/path"
echo "Hi. Logs can be found at "`pwd`"/cxStartStopLogger.log"
echo "["`date`"]*** STOPPING ALL SERVICES ON SERVER ***" >> "cxStartStopLogger.log"
exit

이제 업로드하고 필요한 파일 권한을 설정한 후 다음과 같이 실행해 봅니다.

bash-3.00$ cat cxStopAllServicesOnSERVER.sh #Let's have a look at the code.
#!/usr/bin/bash
cd "/some/path/"
echo "Hi. Logs can be found at "`pwd`"/cxStartStopLogger.log"
echo "["`date`"]*** STOPPING ALL SERVICES ON SERVER ***" >> "cxStartStopLogger.log"

bash-3.00$ # Code and hashbang 'looks' correct, 
bash-3.00$ # if there is any issue with the format (EOL characters and such) 
bash-3.00$ # we cannot see it using cat.
bash-3.00$ 
bash-3.00$ sh cxStopAllServicesOnSERVER.sh
cxStopAllServicesOnSERVER.sh[2]: /some/path^M:  not found
Hi. Logs can be found at /some/path/cxStartStopLogger.log
bash-3.00$ # Note that ^M appears at the end of the line.

bash-3.00$ bash -x cxStopAllServicesOnSERVER.sh
+ cd $'/some/path\r'
: No such file or directory1.sh: line 2: cd: /some/path
++ pwd
' echo 'Hi. Logs can be found at /some/path/cxStartStopLogger.log
Hi. Logs can be found at /some/path/cxStartStopLogger.log
++ date
+ echo '[Sun' Nov 18 00:28:17 EST '2012]*** STOPPING ALL SERVICES ON SERVER ***'
bash-3.00$ # Note that '\r' return character appears at the end of the line.

질문: 코드를 korn 쉘로 변경했을 때도 같은 문제에 직면했습니다. 줄 끝에 잘못된 문자가 추가된 것 같습니다.

노트: 해결책을 찾았고 답변과 동일한 내용을 게시했습니다. 같은 문제에 직면할 수 있는 다른 초보자에게 도움이 되도록 자유롭게 업데이트하거나 개선하시기 바랍니다. 감사해요!

답변1

다양한 포럼과 스택 오버플로 게시물을 검색한 후 이 문제를 발견했습니다.

다음은 오류의 근본 원인을 더 잘 이해하고 "확인"하기 위한 설명입니다.

첫째, Windows에서 코딩하는 경우 Notepad++로 무장하는 것이 좋습니다. 제 생각에는 기본적으로 텍스트 편집기의 스위스 군용 칼입니다.

이제 EOL(줄 끝) 문자 및 기타 제어 기호를 보려면 다음을 수행합니다.

1. Notepad++에서 파일을 엽니다.

메뉴 표시줄에서 보기 > 기호 표시 > 모든 문자 표시를 선택합니다.

이제 다음과 같은 기호가 표시됩니다. Notepad++ 스크린샷: Windows에서 UNIX 스크립트 편집

아하! Windows/MS-DOS에서는 CR+LF를 사용하여 줄 끝을 나타냅니다. UNIX에서는 이제 LF 문자를 사용하여 줄 끝 문자(EOL 문자)를 나타냅니다.

2.1. Windows EOL을 UNIX EOL로 변환해 보겠습니다.

편집 > EOL 변환 > UNIX 형식을 선택합니다.

다음과 같은 내용이 표시됩니다.

Notepad++ 스크린샷: EOL에서 UNIX 형식으로 이는 줄 끝에 "\r" 문자가 추가되는 이유를 설명합니다. 이는 UNIX가 "\n" 또는 LF(줄 바꿈)를 줄 종료/EOL 문자로 인식하지만 "\r" 또는 ^M(캐리지 리턴) 문자를 무시하기 때문입니다.

또한 EOL 문제를 테스트할 수도 있습니다.

bash-3.00$ head myScript.sh | cat -vet | head -1
#usr/bin/bash^M$
bash-3.00$ #We see that ^M, that is \r is found at the end of each line. 

2.2. Windows에서 UNIX에서 UNIX EOL 형식으로 파일을 변환하려는 경우 이 문제를 해결하는 두 가지 방법이 있습니다.

$ dos2unix myScript.sh

또는

제공된 솔루션을 사용하세요@크리스다운다음과 같이:

$ sed -i 's/\r$//' myScript.sh

인용하다:

  1. 자세한 내용은라인이 종료됨 그리고 r과 n의 차이점은 무엇입니까이 링크를 참조하세요.

답변2

스크립트에는 CRLF 줄 끝이 포함되어 있는 반면 Unix는 LF 줄 끝을 사용합니다. GNU가 있는 경우 sed다음 명령을 사용하면 해당 GNU가 제거됩니다.

sed -i 's/\r$//' cxStopAllServicesOnSERVER.sh

GNU가 없으면 sed임시 파일에 쓰고 이를 이전 파일 위로 옮깁니다.

그런데 call 스크립트를 사용하면 shshebang이 무시됩니다. 이것은 당신이 원하는 것이 아닐 수도 있습니다.

관련 정보