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