Shell 脚本在使用 nano 保存时有效,但在使用 Notepad++ 保存时无效

Shell 脚本在使用 nano 保存时有效,但在使用 Notepad++ 保存时无效

当我将 Notepad++ 中的 bash 脚本复制到 SSH 内的 Nano 编辑器的新文件中并保存时。它运行良好。 (sh ./安装)。

但是,如果我保存文件(完全相同的内容),上传到我的网络服务器,然后在同一台计算机上使用 Wget 下载它。我收到语法错误。我检查了编码,它们似乎是相同的。此后我使用了大量的字符编码来查看是否可以解决该问题。当我使用 wget 下载该文件后,我还将该文件设置为可执行文件!

该文件运行良好,并且使用 nano 复制和粘贴时出现零错误。知道这可能是什么吗?

答案1

我愿意打赌该问题与行结尾有关。您可能正在沿线的某个地方使用非 *nix 机器。我还遇到过一个问题,apache(在 Linux 上运行)向上传的文本文件添加 Windows 样式的行结尾,因此您可能会看到类似的内容。

要进行测试,请获取您下载的文件并将其传递给od.如果它是一个长文件,只需抓住前几行:

head script.sh | od -c

查看输出并检查是否有类似以下内容:

f   o   o  \r  \n

这是一个回车符,在 Windows 上,行以*nix不同的方式\r结束。如果事实证明这确实是问题所在,您可以通过删除回车符来修复文件:\r\n\n

sed -i 's/\r//g' script.sh

答案2

正如@graeme 敏锐地指出的那样,由于服务器上有两种形式的脚本,因此您可以执行简单的操作diff来确定工作版本和有问题的版本之间的不同之处。

$ diff working.sh broken.sh

您还可以像这样进行并排比较:

$ diff -y working.sh broken.sh

如果脚本由于某种拼写错误而无法工作,您通常可以通过将-x开关添加到 来检测这些错误bash,这会导致脚本变得冗长。

$ bash -x broken.sh

#!/bin/bash您还可以将此开关合并到脚本顶部的shebang ( ) 中,如下所示:

#!/bin/bash -x

行结尾

将文件从 Windows 移动到 Unix/Linux 系统时,这通常是问题。该问题与两个平台上如何表示行尾有关。您可以在维基百科上阅读更多相关信息,标题为:换行符

制作一个样本文件

$ echo -e "This is a file.\nThat I made on Unix.\n" > unixfile.txt

正如 @terdon 在他的回答中所描述的,您可以使用它sed来删除这些内容,您也可以经常使用名为 的工具dos2unix来执行相同的操作。您可以通过以下两种方式之一使用它:

$ dos2unix unixfile.txt

或者如果您不想覆盖现有文件:

$ dos2unix -n oldfile.txt newfile.txt

当您使用我之前提到的上述内容时,diff当您比较这两个文件时,您将得到如下输出:

$ diff -y unixfile.txt winfile.txt 
This is a couple                            |   This is a couple
of lines of sample                          |   of lines of sample
text.                                       |   text.

您将无法辨别差异,只是它们确实存在。 @terdon 的答案再次展示了一种使用 解决问题的方法od。当然,您可以使用多种方法来弄清楚发生了什么。

使用vim

filecmd。

$ file unixfile.txt
winfile.txt: ASCII text 

$ file winfile.txt 
unixfile.txt: ASCII text, with CRLF line terminators

上面强调了这个问题,即 Windows 中的文件具有 CRLF(又名:行尾的回车符 + 换行符)。这些字符是十六进制的 0x0D 和 0x0A,再次参见维基百科关于换行符的文章如果你想了解更多。

您也可以使用vim来查看问题:

$ vim winfile.txt

以下是一个小序列,展示了如何vim查看该问题。 CRLF 字符在 Unix 中通常显示为^M,即Ctrl+ M

                                       vim 的 ss

该序列显示我重新打开该文件,winfile.txt作为格式化的 Unix 文件 ( :e ++ff=unix)。这告诉vim不要自动检测文件的格式是否适用于 Windows,因此它将显示^M行终止字符。

相关内容