【发布时间】:2017-06-15 23:14:52
【问题描述】:
我有一个 bash 函数,我像这样使用 xargs -P 并行调用它
echo ${list} | xargs -n 1 -P 24 -I@ bash -l -c 'myAwesomeShellFunction @'
一切正常,但输出因明显原因而混乱(无缓冲)
试图找出一种有效缓冲输出的方法。我在想我可以使用 awk,但我还不足以编写这样的脚本,而且我在 google 上找不到任何有价值的东西?有人可以帮我在 sed 或 awk 中编写这个“输出缓冲区”吗?没什么特别的,只是累积输出并在进程终止后将其吐出。我不在乎 shell 函数的执行顺序,只需要缓冲它们的输出......就像:
echo ${list} | xargs -n 1 -P 24 -I@ bash -l -c 'myAwesomeShellFunction @ | sed -u ""'
附:我尝试按照标准使用 stdbuf https://unix.stackexchange.com/questions/25372/turn-off-buffering-in-pipe 但没用,我在 o 和 e 上指定了缓冲但输出仍然没有缓冲:
echo ${list} | xargs -n 1 -P 24 -I@ stdbuf -i0 -oL -eL bash -l -c 'myAwesomeShellFunction @'
这是我的第一次尝试,这只捕获第一行输出:
$ bash -c "echo stuff;sleep 3; echo more stuff" | awk '{while (( getline line) > 0 )print "got ",$line;}'
$ got stuff
【问题讨论】:
-
不要告诉我使用 GNU 并行,我没有安装它,安装它是有问题的,因为我在 RHEL6 上运行
-
为什么不将输出重定向到文件,使用
-I@为每个任务生成唯一的文件名?然后您可以cat所有文件。你甚至可以使用mktemp -
不想乱搞文件
-
顺便说一句,如果您不信任您的数据,
-I@被替换为bash -c是有问题的。如果您的列表条目之一包含$(/tmp/evil-prog),那么您只是注入了代码。从代码带外传递数据要安全得多。 -
@BenjaminW.,打开行缓冲告诉单个实例不要尝试执行短于单行的写入(假设您没有超过缓冲区大小的单行),但是它不会阻止您的线路在多个实例中交错。即使是大于行的缓冲区也不能防止缓冲区的边界(以及写入的边界)处于不希望的截止点。