web-dev-qa-db-ja.com

同じ行のcurlコマンドの後にテキストをエコーする

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

戻り値:

abcer: gws

およびbash -xは以下を示します。

++ grep Server
++ curl -s -I https://google.com
' abco 'Server: gws
 abcer: gws

だが

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

戻り値

abc Server: gws

つまり、curlコマンドの後にテキストを追加すると文字化けしますが、curlコマンドの前に追加しても問題ありません。
何が起こっている?私はそれを把握することはできません。

4
w00t
echo $(curl -s -I https://google.com|grep Server)|cat -A

curlが返す値に^ M(キャリッジリターン)があることを示しています。 curlの出力を出力すると、キャリッジリターンによって「カーソル」が行頭に戻り、「abc」が出力されて「Serv」が上書きされます。

2回目の試行では、キャリッジリターンは明らかな影響を与えません。

2
Craig Miskell

HTTP標準では、すべてのヘッダー行と、ヘッダーの終わりを示す空の行で、CRLF(復帰、改行)の末尾を使用する必要があると規定されています。多くのクライアントは自由で、LFを単独で受け入れますが、Googleを含むほとんどのサーバーは標準を尊重します。

_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
_

__文字は、カーソルを行の先頭に移動するように端末に指示するため、文字abcは行の最初の3文字を上書きします。

これは、_bash -x_からのトレースが不明瞭になる理由も説明します。

コマンドecho abc "$(curl -s -I https://google.com|grep Server)"は、次を含む行を表示します

_Server: gwsabc␍
_

␍文字はカーソルを行の先頭に移動し、改行はカーソルを次の行の先頭に移動するため、theは目に見える影響を与えません。

CRによる複雑化を回避するには、入力からそれらを取り除きます。

_echo "$(curl -s -I https://google.com | tr -d '\r' | grep Server)" abc
_

キャリッジリターンを削除するには、次のことを試してください。

 echo "$(curl -s -I https://google.com|grep Server)" abc | tr -d "\r"

出力:

サーバー:GFE/2.0 abc 
1
Cyrus