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
设置,它可以采用值dos
或unix
。在加载文件后显式更改它
设置文件格式=unix或在写出文件时显式强制文件格式
:w +文件格式=unix
有关更多信息,请参阅此处涵盖该主题的许多问题和答案,包括:
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)
在理解大括号扩展的壳中。
您的脚本有错误的行尾。Windows 使用 CR+LF (\r\n),Unix 使用 LF (\n),而 Classic MacOS 使用 CR (\r)。您需要使用文本编辑器或独立工具(如dos2unix
.
FTP 和 SVN 等版本控制系统往往能够适当地转换行尾,因此您可能希望在将来研究这些选项以传输文件。
如果这些文件没有被传输,而只是在一台机器上使用,那么您将需要在首选文本编辑器中找到行尾的设置。大多数标榜为“程序员”的人都会有这样的选择。