从管道增量读取

从管道增量读取

试图弄清楚如何让 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被多个命令使用吗?

答案1

你可以用 阅读所有内容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

答案2

实际问题的答案是肯定的,您可以从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

相关内容