为啥正确的 shell 脚本会给出包装/截断/损坏的错误消息? [复制]

Posted

技术标签:

【中文标题】为啥正确的 shell 脚本会给出包装/截断/损坏的错误消息? [复制]【英文标题】:Why would a correct shell script give a wrapped/truncated/corrupted error message? [duplicate]为什么正确的 shell 脚本会给出包装/截断/损坏的错误消息? [复制] 【发布时间】:2015-10-31 08:26:34 【问题描述】:

我有一个带有命令的 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

为什么会发生这种情况,我该如何解决?

【问题讨论】:

我想知道是否值得交叉引用您的其他行尾问题。 (到目前为止,我已经看过这个和另一个;你还有更多吗?) 或者甚至关闭一个作为另一个的副本:) @chepner 这是一个选择:A. 令人困惑地关闭为看似不相关的问题的副本,因为修复恰好解决了这两个问题,B. 笨拙地将多个问题添加到一个帖子中,或者 C. 只是发布两个。我选择了 C,将两者都添加到了 bash 标签 wiki,并将它们标记为社区答案,以明确表示这不是骗局:P 【参考方案1】:

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 yourscriptcat yourscript | tr -d '\r' > fixedscript 从命令行删除它们。

如果在您的数据中找到,您可以通过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

【讨论】:

在 vi 中打开文件并输入 :set ff=unix 很好的修复,非常感谢!

以上是关于为啥正确的 shell 脚本会给出包装/截断/损坏的错误消息? [复制]的主要内容,如果未能解决你的问题,请参考以下文章

截断所有 MySql 表的 shell 脚本

为啥shell脚本exit后,当前进程没有终止?

%00截断的猜测

LIST_ENTRY 已损坏(即双重删除)。不知道为啥

在shell脚本里使用cd命令为啥没有效果

当它的目标应该被删除时,为啥这个智能指针会给出正确的结果?