Shell腳本讀取最后一行丟失我有一個(gè)... bash shell腳本的奇怪問題,我希望得到一些見解。我的團(tuán)隊(duì)正在編寫一個(gè)腳本,該腳本遍歷文件中的行并檢查每個(gè)行中的內(nèi)容。我們有一個(gè)錯(cuò)誤,當(dāng)通過將不同腳本排序在一起的自動(dòng)化過程運(yùn)行時(shí),最后一行沒有被看到。使用的代碼遍歷文件中的行(名稱存儲(chǔ)在DATAFILE被cat "$DATAFILE" | while read line我們可以從命令行運(yùn)行腳本,它會(huì)看到文件中的每一行,包括最后一行,就好了。但是,當(dāng)由自動(dòng)化進(jìn)程(運(yùn)行在相關(guān)腳本之前生成DATAFILE的腳本)運(yùn)行時(shí),永遠(yuǎn)不會(huì)看到最后一行。我們更新了代碼以使用以下代碼迭代這些行,并清除了問題:for line in `cat "$DATAFILE"`注意:DATAFILE沒有在文件末尾寫入換行符。我的問題是兩部分......為什么最后一行不會(huì)被原始代碼看到,為什么這會(huì)改變有所作為呢?我只想到我能想出為什么最后一行不會(huì)被看到:前一個(gè)寫入文件的進(jìn)程依賴于進(jìn)程結(jié)束以關(guān)閉文件描述符。問題腳本正在啟動(dòng)并以足夠快的速度打開文件,而前一個(gè)進(jìn)程已“結(jié)束”,它沒有“關(guān)閉/清理”足以讓系統(tǒng)自動(dòng)關(guān)閉文件描述符。話雖這么說,似乎,如果你在shell腳本中有2個(gè)命令,那么第一個(gè)應(yīng)該在腳本運(yùn)行第二個(gè)時(shí)完全關(guān)閉。對(duì)問題的任何見解,尤其是第一個(gè),都將非常感激。
3 回答

BIG陽
TA貢獻(xiàn)1859條經(jīng)驗(yàn) 獲得超6個(gè)贊
根據(jù)read命令的POSIX規(guī)范,如果“檢測到文件結(jié)尾或發(fā)生錯(cuò)誤”,它應(yīng)返回非零狀態(tài)。由于在讀取最后一行“EOF”時(shí)檢測到EOF,因此它會(huì)設(shè)置$line
然后返回錯(cuò)誤狀態(tài),并且錯(cuò)誤狀態(tài)會(huì)阻止循環(huán)在最后一行“行”上執(zhí)行。解決方案很簡單:如果讀取命令成功或者讀入任何內(nèi)容,則執(zhí)行循環(huán)$line
。
while read line || [ -n "$line" ]; do

Qyouu
TA貢獻(xiàn)1786條經(jīng)驗(yàn) 獲得超11個(gè)贊
添加一些額外信息:
沒有必要使用
cat
while循環(huán)。while ...;do something;done<file
足夠。
使用while循環(huán)讀取行時(shí):
設(shè)置
IFS
正確(否則可能會(huì)丟失縮進(jìn))。
滿足上述要求時(shí),正確的while循環(huán)將如下所示:
while IFS= read -r line; do ...done <file
并使其在沒有換行符的情況下使用文件(從此處重新發(fā)布我的解決方案):
while IFS= read -r line || [ -n "$line" ]; do echo "$line"done <file
或者使用grep
while循環(huán):
while IFS= read -r line; do echo "$line"done < <(grep "" file)
添加回答
舉報(bào)
0/150
提交
取消