web-dev-qa-db-ja.com

この「while」ループが最後の行を認識しないのはなぜですか?

次のスクリプトを使用します。

more test.sh
#!/bin/bash

while read -r line
do

echo $line

done < /tmp/file

これはファイルです:

kafka-broker,log.retention.hours,12
kafka-broker,default.replication.factor,2
fefolp-defaults,fefolp.history.fs.cleaner.interval,1d
fefolp-defaults,fefolp.history.fs.cleaner.maxAge,2d
fefolp-env,fefolp_daemon_memory,10000
blo-site,blo.nodemanager.localizer.cache.target-size-mb,10240
blo-site,blo.nodemanager.localizer.cache.cleanup.interval-ms,300000
ams-env,metrics_collector_heapsize,512
fefolp,hbase_master_heapsize,1408
fefolp,hbase_regionserver_heapsize,512
fefolp,hbase_master_xmn_size,192
core-site,blolp.proxyuser.ambari.hosts,*
core-site,Hadoop.proxyuser.root.groups,*
core-site,Hadoop.proxyuser.root.hosts,*
blo-site,blo.scheduler.minimum-allocation-mb,1024
blolp-env,fefolp_heapsize,4096

備考-最終行の後-スペースはありません!

ただし、スクリプトは次の行のみを出力します(最後の行を除く)。

./test.sh
kafka-broker,log.retention.hours,12
kafka-broker,default.replication.factor,2
fefolp-defaults,fefolp.history.fs.cleaner.interval,1d
fefolp-defaults,fefolp.history.fs.cleaner.maxAge,2d
fefolp-env,fefolp_daemon_memory,10000
blo-site,blo.nodemanager.localizer.cache.target-size-mb,140
blo-site,blo.nodemanager.localizer.cache.cleanup.interval-ms,300
ams-env,metrics_collector_heapsize,51
fefolp,hbase_master_heapsize,1408
fefolp,hbase_regionserver_heapsize,542
fefolp,hbase_master_xmn_size,19
core-site,blolp.proxyuser.ambari.hosts,*
core-site,Hadoop.proxyuser.root.groups,*
core-site,Hadoop.proxyuser.root.hosts,*
blo-site,blo.scheduler.minimum-allocation-mb,1024

なぜこれが起こるのですか?

2
yael

入力テキストの最後の行に不完全な行が含まれています。最後の行は改行で終了しません。

while IFS= read -r line || [ -n "$line" ]; do
    printf '%s\n' "$line"
done <file

上記のループは、fileというファイルから(空白を削除したり、バックスラッシュされた制御シーケンスを解釈したりせずに)変更されていない行を読み取り、標準出力に出力します。

incomplete行が読み取られると、readは失敗しますが、$lineは引き続きデータを含みます。余分な-n testはこれを検出して、ループ本体が不完全な行を出力できるようにします。その後の反復では、readは再び失敗し、$lineは空の文字列になるため、ループが終了します。

7
Kusalananda