
我有一個虛擬問題要問你,我正在嘗試從文件中提取以特殊字串開頭的一些行並將它們複製到文件中。我試過 :
cat /dev/ttyACM0 | grep "something" > essai
該文件已創建,但它不包含任何內容!
答案1
為了提高效率,grep 和許多其他命令使用緩衝輸入/輸出,也就是說,它們一次讀取大塊資料(而不是一次一個字元),並且在累積到一定數量之前不輸出資料(而不是一次寫入一行或一次一個字元)
但是,當程式的輸入來自終端(例如串行埠)時,作業系統會幫助程式並一次返回一行(程式可以透過將終端放入生的或者非規範模式;大多數人沒有)。
當程式使用標準輸入輸出在庫中,到終端機(文件稱為「互動式裝置」)的標準輸出預設是行緩衝的,但到檔案或管道的輸出是完全緩衝的。
使用 stdio 函式庫的程式可以透過呼叫選擇全緩衝、行緩衝或無緩衝setvbuf
。也可以調用fflush
隨時強制寫入。
GNU grep 需要一個--line-buffered
選項,這將運行以下程式碼在輸出匹配行的函數中:
if (line_buffered)
fflush (stdout);
將所有部分放在一起:
使用此命令:
cat /dev/ttyACM0 | grep "something" > essai
cat
將從 一次讀取一行/dev/ttyACM0
。當它累積了幾千位元組的輸出後,它將寫入管道。它將重複此操作,直到讀取返回計數為零或失敗(這可能在串行端口脫機之前不會發生)。
grep
將從管道一次讀取數千字節,在累積了數千字節的輸出後,它將寫入檔案essai
。它將重複此操作,直到讀取返回計數為零或失敗,如果進程cat
退出,就會發生這種情況。
因此,在找到幾千位元組的匹配行之前,您不會看到essai
文件中出現任何內容。grep
為了更迅速地將輸出寫入文件,您可以為 GNU grep 提供該選項:
grep --line-buffered < /dev/ttyACM0 > essai
由於它是從串行埠讀取,因此它將被行緩衝,並且該--line-buffered
選項也會使輸出行緩衝。