Cygwinからの奇妙なエコー出力

Cygwinからの奇妙なエコー出力

私は非常に単純なCygwinスクリプトを作業していますが、理解することはできません。誰かが私を助けることを願っています。

スクリプトは次のとおりです。

h=www.ibm.com
for ip in $(dig $h +short); do echo "XX ${ip} XX"; done

期待される出力(Debian Buster Linuxおよびbash 5.0.3(1)リリースを使用してテスト済み:

XX www.ibm.com.cs186.net. XX
XX outer-global-dual.ibmcom-tls12.edgekey.net. XX
XX e7817.dscx.akamaiedge.net. XX
XX 37.26.112.89 XX

bash 4.4.12(3)リリースを使用してCygwinで同じスクリプトを実行すると、出力はまったく異なります。

 XXwww.ibm.com.cs186.net.
 XXouter-global-dual.ibmcom-tls12.edgekey.net.
 XXe7817.dscx.akamaiedge.net.
 XX37.26.112.89

何が起こったのか信じられません。これは明らかなことであるに違いありませんが、私はそれを見ることができません。 Cygwinのbashが最後の「XX」と先行するスペースを切り捨てるのはなぜですか?

挨拶、

答え1

このdigユーティリティはCygwinからキャリッジリターンで終わる行を出力するようです(テストできません)。その文字が出力されると、カーソルが行の先頭に戻り、奇妙な形式の出力が発生します。

この問題を解決するには、次の出力から末尾のキャリッジリターンを削除しますdig

query=www.ibm.com

dig "$query" +short | sed 's/[[:space:]]*$//' |
while IFS= read -r response; do
    printf 'XX %s XX\n' "$response"
done

これは、出力からsed一致する項目を削除するために使用されます。このパターンは、行末のキャリッジリターンが1のゼロ個以上の空白のような文字と一致します。[[:space:]]*$dig

私はwhileあなたの代わりにループを使うことにしましたfor。概念的には、whileループは、データが到着したときに長さが不確実なデータストリームから行を読み取るために使用されます。 Afor一方、ループは常に変化のない文字列セット。forこれは、シェルがすべての出力を読み取り、digそれを単語に分割するまで(そして各単語にファイル名のグロービングを適用するまで)ループを開始できないことを意味します。一般に、forプログラムを使用して出力行を読み取ることは、潜在的な引用の問題のために問題があり、エレガントではなく、多くのメモリを占有する可能性があります(すべての出力をシェルに保存する必要があるため)。

関連情報