私は非常に単純な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
プログラムを使用して出力行を読み取ることは、潜在的な引用の問題のために問題があり、エレガントではなく、多くのメモリを占有する可能性があります(すべての出力をシェルに保存する必要があるため)。