试图弄清楚如何让 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