在同一行 curl 命令后回显文本

w00*_*00t 4 http curl newlines

#!/bin/bash
echo "$(curl -s -I https://google.com|grep Server)" abc
Run Code Online (Sandbox Code Playgroud)

返回:

abcer: gws
Run Code Online (Sandbox Code Playgroud)

bash -x显示:

++ grep Server
++ curl -s -I https://google.com
' abco 'Server: gws
 abcer: gws
Run Code Online (Sandbox Code Playgroud)

echo abc "$(curl -s -I https://google.com|grep Server)"` 
Run Code Online (Sandbox Code Playgroud)

返回

abc Server: gws
Run Code Online (Sandbox Code Playgroud)

换句话说,如果我在 curl 命令之后添加文本,它会被破坏,但是如果我在 curl 之前添加它就可以了。
怎么了?我想不明白。

Gil*_*il' 5

HTTP 标准指定所有标题行以及标记标题结尾的空行都必须使用 CRLF(回车,换行)结尾。许多客户端是自由的,只接受 LF,但大多数服务器,包括谷歌,都遵守该标准。

curl -I显示与服务器发送的完全相同的标头,包括 CR 字符。就 unix 系统而言,CR 字符是行的一部分,只有 LF 字符结束了该行。命令替换删除尾随的 LF 字符,但不触及 LF 字符。因此,命令 susbtitution$(curl -s -I https://google.com|grep Server)返回(在您的情况下)字符串Server: gws?(其中?是回车符),并且该命令echo "$(curl -s -I https://google.com|grep Server)" abc显示一行包含

Server: gws?abc
Run Code Online (Sandbox Code Playgroud)

?字符是给终端的指令,将光标移动到行首,所以字符abc覆盖了该行的前三个字符。

这也解释了为什么 trace frombash -x有点乱。

该命令echo abc "$(curl -s -I https://google.com|grep Server)"显示一行包含

Server: gwsabc?
Run Code Online (Sandbox Code Playgroud)

这 ?字符将光标移动到行首,然后换行将光标移动到下一行的开头,所以 ? 没有明显的效果。

为避免 CR 引起的并发症,请将它们从输入中剥离。

echo "$(curl -s -I https://google.com | tr -d '\r' | grep Server)" abc
Run Code Online (Sandbox Code Playgroud)