Bash

從管道增量讀取

  • January 23, 2022

試圖弄清楚如何讓 shell 腳本只從stdin. 我原以為這樣的事情會奏效,但它沒有:

#!/bin/bash
value=0
while [ "$value" != "-1" ]; do
 read -r -d '' -n 20 value
 if [ "$value" != "-1" ]; then
   dd conv=notrunc status=none of=/path/bigfile.bin bs=1M count=1 seek=$value
 fi
done

簡而言之,我試圖將特定塊從大文件複製到遠端位置的同一個文件。從發送腳本發送的數據有一個塊位置(20 個字節),後跟要寫入該位置的 1 MiB 數據。當位置為-1時完成。

如果執行已編譯的 C 程序,我有一個可以正常工作的設置,但我想避免這種情況並使用本機 shell 命令執行。問題是,它似乎沒有dd消耗任何數據,所有這些都由read命令處理。

可以stdin被多個命令消費嗎?

實際問題的答案是肯定的,您可以從stdin管道開始逐步閱讀。

腳本問題的解決方案是該dd命令沒有消耗 1 MiB 的數據。寫入dd時將讀取 65516 字節,即 65536 (64 KiB) 減去塊大小的 20 字節。在讀取了這個有限數量的數據後,dd就會退出。解決方案是使用 flag iflag=fullblock。此外,對 -1 的檢查並不能像所寫的那樣工作。完整的功能解決方案是:

value=0
while [ $value != -1 ]; do
 read -r -d '' -n 20 value
 value=$((value))
 if [ $value != -1 ]; then
   dd iflag=fullblock conv=notrunc status=none \
     of=/path/bigfile.bin bs=1M count=1 seek=$value
 fi
done

你可以用dd.

這應該有效(read ... value變成value=$(dd bs=20 count=1 status=none)):

#!/bin/bash
value=0
while [ "$value" != "-1" ]; do
 value=$(dd bs=20 count=1 status=none)
 if [ "$value" != "-1" ]; then
   dd conv=notrunc status=none of=/path/bigfile.bin bs=1M count=1 seek=$value
 fi
done

引用自:https://unix.stackexchange.com/questions/687142