![在 Windows 上编辑的 Bash/Korn shell 脚本会抛出错误“...^M:未找到”](https://linux22.com/image/27235/%E5%9C%A8%20Windows%20%E4%B8%8A%E7%BC%96%E8%BE%91%E7%9A%84%20Bash%2FKorn%20shell%20%E8%84%9A%E6%9C%AC%E4%BC%9A%E6%8A%9B%E5%87%BA%E9%94%99%E8%AF%AF%E2%80%9C...%5EM%EF%BC%9A%E6%9C%AA%E6%89%BE%E5%88%B0%E2%80%9D.png)
我使用 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 shell 时,我遇到了同样的问题。似乎在行尾添加了不正确的字符。
笔记: 我找到了解决方案并发布了与答案相同的内容。请随意更新或改进它,以帮助可能面临相同问题的其他初学者。谢谢!
答案1
在浏览了各种论坛和一些 Stack-overflow 帖子后,我发现了这个问题。
以下是为了更好地理解和“查看”错误的根本原因的解释。
首先,如果您在 Windows 上编写代码,最好用 Notepad++ 武装自己。在我看来,它基本上是文本编辑器的瑞士军刀。
现在要查看 EOL(行尾)字符和其他控制符号,请执行以下操作:
1.在Notepad++中打开文件。
从菜单栏中选择视图 > 显示符号 > 显示所有字符
您现在应该看到如下符号:
啊哈! Windows/MS-DOS 使用 CR+LF 来指示行结束。现在UNIX使用LF字符来指示行终止符(EOL字符)。
2.1.让我们将 Windows EOL 转换为 UNIX EOL:
选择编辑 > 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
参考:
- 欲了解更多信息线路终止 和 r 和 n 之间有什么区别请参考这些链接。
答案2
您的脚本包含 CRLF 行结尾,而 Unix 使用 LF 行结尾。如果您有 GNU sed
,以下命令将删除它们:
sed -i 's/\r$//' cxStopAllServicesOnSERVER.sh
如果您没有 GNU sed
,请写入临时文件,然后将其移至旧文件的顶部。
顺便说一句,如果您使用 调用脚本sh
,您将覆盖 shebang。这可能不是你想要的。