【发布时间】:2015-10-21 22:14:22
【问题描述】:
是否可以在多个阅读器之间拆分 STDIN,从而有效地成为一个作业队列?我想将每一行传递给一个读者。命名管道几乎可以工作,但同时读取会干扰:
reader.sh
#!/usr/bin/env bash
while read line
do
echo $line
done < fifo
writer.sh
#!/usr/bin/env bash
while true
do
echo "This is a test sentance"
sleep 1
done
执行:
mkfifo fifo
./reader.sh &
./reader.sh &
./writer.sh > fifo
偶尔的输出(特别是如果读取器和写入器在不同的窗口中)
This is atetsnac
Ti sats etnesats etne etsnac
isats etnes etsnac
Tisi etsnac
hi etsnac
Ti sats etn
hsi etsnac
注意事项:
- 我知道有更好的方法,只是好奇这是否可行
- 我认为这不是错误,因为我已经测试了 Linux 和 OSX 机器
- 我希望每行有一个消费者,不包括 tee
- 我想使用 STDIN,它排除了 xargs
- GNU coreutils split 可以分配循环,但不是首先可用
- GNU parallel --pipe 一直等到 STDIN 关闭;我想尽快分配
【问题讨论】:
-
我在这里复制了这个(OS X),但我不明白。
-
我想我明白了。虽然对管道的写入是原子的(只要它们小于
BUFSIZ),但消息边界不会保存在管道中。因此并发读者可以分别读取输入的不同部分。从流中读取的系统调用不提供任何方法来请求将整行作为一个单元。 -
我认为管道只是错误的机制。消息队列或数据报套接字会更好,尽管它们在
bash中没有很好的接口。 Yuo 可能需要用 Perl、PHP 或 Python 编写脚本。 -
您可以将 GNU Parallel 调用为
sem --id mymutex作为read命令的前缀,以便它们一次执行一个。