我在笔记本电脑 (DOS) 上使用 Cygwin。我收集了我同事和我自己的剧本。我不是IT人,不懂Unix。我遵循同事的语法并能够管理一些简单的事情。
这些脚本在我的旧笔记本电脑上运行良好。我刚刚更换了笔记本电脑并安装了 Cygwin。当我运行脚本时,它们不起作用。以下是我收到的错误消息的一个示例:
line 1: $':\r': command not found
line 5: syntax error near unexpected token `$'\r''
line 5: `fi
这是我脚本的前 5 行
:
iter=1
if [ -f iter.txt ]
then rm ./iter.txt
fi
有人可以解释一下我如何解决这个问题吗?
答案1
你有 Windows 风格的行结尾。
相反,无操作命令:
被读取为:<carriage return>
、显示为:\r
或更完整地为$':\r'
。
跑吧dos2unix scriptname
,你应该没问题。
如果你没有dos2unix
,以下应该可以工作几乎任何地方(我在 Windows 上的 MobaXterm 上进行了测试):
vi -b filename
然后在 中vi
输入:
:%s/\r$//
:x
你可以走了。
在 中vim
,即您在 Cygwin 上使用的vi
,有多种方法可以执行此操作。另一种涉及fileformat
设置,可以采用值dos
或unix
。加载文件后显式更改它
设置文件格式=unix或者在写出文件时显式强制文件格式
:w +文件格式=unix
有关这方面的更多信息,请参阅此处涉及该主题的许多问题和答案,包括:
答案2
这是因为脚本是由使用 DOS 行结束符的编辑器(例如 Notepad++)保存的。您必须从脚本中删除这些内容。
为此,请使用dos2unix
脚本文件,或者
$ tr -d '\r' <script >script.new && mv script.new script
(这将删除所有回车符任何地方在脚本中)
至于脚本中的代码:
:
iter=1
if [ -f iter.txt ]
then rm ./iter.txt
fi
这可能看起来像
iter=1
if [ -f "./$iter.txt" ]; then
rm "./$iter.txt"
fi
这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
或者,如果我们感到偷偷摸摸/懒惰,
rm -f {1..10}.txt
在理解大括号扩展的 shell 中。
答案3
您的脚本的行结尾错误。 Windows 使用 CR+LF (\r\n),Unix 使用 LF (\n),Classic MacOS 使用 CR (\r)。您需要使用文本编辑器或独立工具(例如dos2unix
.
FTP 和版本控制系统(例如 SVN)往往能够适当地转换行结尾,因此您将来可能需要研究这些用于传输文件的选项。
如果这些文件不是正在传输,但仅在单台计算机上使用,那么您将需要在首选文本编辑器中找到行结尾的设置。大多数标榜为“针对程序员”的产品都会有这样的选择。
答案4
如果不是dos2unix,也有'flip'
$ Flip -u 你的文件名.txt
将其翻转为使用 UNIX 行结尾。