为什么我收到“第 1 行:$':\r':找不到命令”?

TPh*_*ham 12 bash cygwin shell-script newlines

我在笔记本电脑 (DOS) 上使用 Cygwin。我收集了同事的脚本和我自己的脚本。我不是 IT 人员,对 Unix 不了解。我正在遵循我同事的语法并且能够管理一些简单的事情。

这些脚本在我的旧笔记本电脑上运行良好。我刚换了笔记本电脑并安装了 Cygwin。当我运行我的脚本时,它们不起作用。这是我收到的错误消息的一个示例:

line 1: $':\r': command not found
line 5: syntax error near unexpected token `$'\r''
line 5: `fi
Run Code Online (Sandbox Code Playgroud)

这是我脚本的前 5 行

:
iter=1
if [ -f iter.txt ]
   then rm ./iter.txt 
fi  
Run Code Online (Sandbox Code Playgroud)

有人可以解释一下我如何解决这个问题吗?

Wil*_*ard 28

你有 Windows 风格的行尾。

no-op 命令:读作:<carriage return>,显示为 ,:\r或更完整地显示为$':\r'

dos2unix scriptname,你应该没事的。


如果您没有dos2unix,以下内容几乎可以在任何地方使用(并且我在 Windows 上的 MobaXterm 上进行了测试):

vi -b filename
Run Code Online (Sandbox Code Playgroud)

然后在 中vi,键入:

:%s/\r$//
:x
Run Code Online (Sandbox Code Playgroud)

你很高兴去。


在 中vim,这就是您在 Cygwin 上使用的内容vi,有多种方法可以做到这一点。另一个涉及fileformat设置,它可以采用值dosunix。在加载文件后显式更改它

设置文件格式=unix
或在写出文件时显式强制文件格式

:w +文件格式=unix

有关更多信息,请参阅此处涵盖该主题的许多问题和答案,包括:

  • 请注意,`vi -b`、`\r` 无论如何都是 vim 扩展。不是 POSIX,不是 nvi、elvis、Solaris vi... (2认同)

Kus*_*nda 10

这是因为脚本已被使用 DOS 行尾的编辑器(例如 Notepad++)保存。您必须从脚本中删除这些。

为此,请dos2unix在脚本文件上使用,或

$ tr -d '\r' <script >script.new && mv script.new script
Run Code Online (Sandbox Code Playgroud)

(这将从脚本中的任何地方删除所有回车)


至于脚本中的代码:

:
iter=1
if [ -f iter.txt ]
   then rm ./iter.txt 
fi  
Run Code Online (Sandbox Code Playgroud)

这应该看起来像

iter=1
if [ -f "./$iter.txt" ]; then
   rm "./$iter.txt"
fi
Run Code Online (Sandbox Code Playgroud)

1.txt将从当前目录中删除文件(如果存在)。该:命令(几乎)不执行任何操作并且可能会被删除。该iter变量的值应尽可能使用$iter,并报价。然后我可能比需要更明确地使用./说需要在当前目录中找到文件。

如果你打算把它变成一个循环(在这里,删除所有文件1.txt, 2.txt, ..., 10.txt):

iter=1
while [ "$iter" -le 10 ]; then
    if [ -f "./$iter.txt" ]; then
        rm "./$iter.txt"
    fi
    iter=$(( iter + 1 ))
done
Run Code Online (Sandbox Code Playgroud)

或者,如果我们觉得偷偷摸摸/懒惰,

rm -f {1..10}.txt
Run Code Online (Sandbox Code Playgroud)

在理解大括号扩展的壳中。

  • Notepad++ 实际上可以选择使用 Windows/Mac/Linux 换行符。您只需要进入编辑菜单,然后进入 EOL Conversion-&gt;Unix (LF)。或者您可以双击右下角的“Windows (CR LF)”并将其更改为“Unix (LF)” (3认同)

Fox*_*Fox 5

您的脚本有错误的行尾。Windows 使用 CR+LF (\r\n),Unix 使用 LF (\n),而 Classic MacOS 使用 CR (\r)。您需要使用文本编辑器或独立工具(如dos2unix.

FTP 和 SVN 等版本控制系统往往能够适当地转换行尾,因此您可能希望在将来研究这些选项以传输文件。

如果这些文件没有被传输,而只是在一台机器上使用,那么您将需要在首选文本编辑器中找到行尾的设置。大多数标榜为“程序员”的人都会有这样的选择。