我有一个带有命令的 shell 脚本,它似乎应该可以工作,但它却失败了,并显示了一条奇怪的包装/截断/损坏的错误消息。示例:
$ ls -l myfile
-rw-r----- 1 me me 0 Aug 7 12:36 myfile
$ cat myscript
ls -l myfile
$ bash myscript
: No such file or directory
文件显然存在,但即使我不存在,这也是我通常会收到的错误消息:
$ ls -l idontexist
ls: cannot access idontexist: No such file or directory
注意它如何包含工具名称 ls
、消息字符串和文件名,而我的没有。
以下是我尝试使用 mysql
时得到的结果。错误消息看起来像是被包装了,现在以引号开头:
Command: mysql -h myhost.example.com
Expected: ERROR 2005 (HY000): Unknown MySQL server host 'myhost.example.com' (0)
Actual: ' (0) 2005 (HY000): Unknown MySQL server host 'myhost.example.com
这里是我的简单 ssh 命令,它应该可以工作,或者至少给出一个正常的错误消息,但它被包装成以冒号开头并以奇怪的破坏结束:
Command: ssh myhost
Expected: ssh: Could not resolve hostname myhost: Name or service not known
Actual: : Name or service not knownname myhost
为什么会发生这种情况,我该如何解决?
TL;DR:您的脚本或数据具有 Windows 样式的 CRLF 行结尾。
通过删除回车转换为 Unix 风格。
如何检查我的脚本或数据是否有回车?
它们在 cat -v yourscript
的输出中被检测为 ^M
:
$ cat -v myscript
ls -l myfile^M
如果您的脚本没有它们,您的数据可能——特别是如果从 ini/csv 文件或 curl
读取:
hostname=$(curl https://example.com/loginhost.txt)
ssh "$hostname" # Shows strange error
echo "$hostname" | cat -v # Shows myhost^M
如何删除它们?
将您的编辑器设置为使用 Unix 行结尾(也称为“行终止符”或“行尾字符”)保存文件,然后重新保存。
您还可以使用 dos2unix yourscript
或 cat yourscript | 从命令行中删除它们tr -d '\r' > 固定脚本
。
如果在您的数据中找到,您可以通过 tr -d '\r'
管道传输您的来源:
hostname=$(curl https://example.com/loginhost.txt | tr -d '\r')
为什么回车会导致出现奇怪的错误信息?
“回车”字符,又名 CR 或 \r
,使光标移动到行的开头,并从那里继续打印。换句话说,它从头开始覆盖该行。这就是它们奇怪地包裹的原因:
Intended: ssh: Could not resolve hostname myhost\r: Name or service not known
Written: ssh: Could not resolve hostname myhost\r
Overwritten: : Name or service not known
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
Result: : Name or service not knownname myhost