use*_*938 4 windows shell-script newlines
当我将我的 bash 脚本从 Notepad++ 复制到一个带有 nano 编辑器的新文件中并保存时。它运行良好。(sh ./安装)。
但是如果我保存文件(完全相同的内容),上传到我的网络服务器,在同一台机器上使用 Wget 下载它。我收到语法错误。我检查了编码,它们似乎是一样的。从那以后,我使用了大量的字符编码来查看它是否能解决问题。使用 wget 下载文件后,我还将文件设置为可执行文件!
该文件运行良好,使用 nano 复制和粘贴时我的错误为零。知道这可能是什么吗?
我愿意打赌这个问题与行尾有关。您可能正在沿线某处使用非 *nix 机器。我还遇到了一个问题apache
(在 Linux 上运行)向上传的文本文件添加 Windows 样式的行尾,因此您可能会看到类似的内容。
要进行测试,请获取您下载的文件并通过od
. 如果它是一个长文件,只需抓取前几行:
head script.sh | od -c
Run Code Online (Sandbox Code Playgroud)
查看输出并检查您是否有以下内容:
f o o \r \n
Run Code Online (Sandbox Code Playgroud)
这\r
是一个回车,在 Windows 上,行以与*nix\r\n
相对的结尾\n
。如果事实证明这确实是问题所在,您可以通过删除回车符来修复您的文件:
sed -i 's/\r//g' script.sh
Run Code Online (Sandbox Code Playgroud)
正如@graeme 敏锐地指出的那样,因为您在服务器上都有两种形式的脚本,您可以执行一个简单的操作diff
来确定工作版本和有问题的版本之间有什么不同。
$ diff working.sh broken.sh
Run Code Online (Sandbox Code Playgroud)
你也可以像这样并排比较:
$ diff -y working.sh broken.sh
Run Code Online (Sandbox Code Playgroud)
如果脚本由于某种拼写错误而无法运行,您通常可以通过将-x
开关添加到来检测这些问题bash
,这会导致它变得冗长。
$ bash -x broken.sh
Run Code Online (Sandbox Code Playgroud)
您还可以将此开关合并到#!/bin/bash
脚本顶部的 shebang ( ) 中,如下所示:
#!/bin/bash -x
Run Code Online (Sandbox Code Playgroud)
这通常是将文件从 Windows 移动到 Unix/Linux 系统时的问题。问题与如何在 2 个平台上表示行的末端有关。您可以在 Wikipedia 上阅读更多相关信息,标题为:换行符。
制作示例文件
$ echo -e "This is a file.\nThat I made on Unix.\n" > unixfile.txt
Run Code Online (Sandbox Code Playgroud)
正如@terdon 在他的回答中所描述的那样,您可以使用sed
来去除这些内容,您也可以经常使用一个名为的工具dos2unix
来做同样的事情。您可以通过以下两种方式之一使用它:
$ dos2unix unixfile.txt
Run Code Online (Sandbox Code Playgroud)
或者如果您不想覆盖现有文件:
$ dos2unix -n oldfile.txt newfile.txt
Run Code Online (Sandbox Code Playgroud)
当您使用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.
Run Code Online (Sandbox Code Playgroud)
您将无法辨别差异,只是它们就在那里。@terdon 的回答再次显示了一种使用od
. 您当然可以使用多种方法来弄清楚发生了什么。
与file
cmd。
$ file unixfile.txt
winfile.txt: ASCII text
$ file winfile.txt
unixfile.txt: ASCII text, with CRLF line terminators
Run Code Online (Sandbox Code Playgroud)
上面强调了一个问题,即来自 Windows 的文件具有 CRLF(也就是行尾的回车符 + 换行符)。这些字符是十六进制的 0x0D 和 0x0A,如果您想了解更多信息,请再次参阅维基百科关于换行符的文章。
您也可以使用vim
来查看问题:
$ vim winfile.txt
Run Code Online (Sandbox Code Playgroud)
这是一个小序列,显示了如何vim
查看问题。CRLF 字符在 Unix 中通常显示为^M
,即Ctrl+ M。
该序列显示我重新打开文件,winfile.txt
作为格式化的 Unix 文件 ( :e ++ff=unix
)。这告诉vim
不要自动检测文件是否为 Windows 格式化,因此它将显示^M
行终止字符。