我在并行模式下使用 GNU xargs(版本 4.2.2),并且在重定向到文件时似乎确实会丢失输出。当重定向到管道时,它似乎工作正常。
以下 shell 命令演示了最小、完整且可验证的示例的问题。我使用生成 2550 个数字xargs
将其分成 100 个参数的行,每行总共 26 行,其中第 26 行仅包含 50 个参数。
# generate numbers 1 to 2550 where each number is on its own line
$ seq 1 2550 > /tmp/nums
$ wc -l /tmp/nums
2550 /tmp/nums
# piping to wc is accurate: 26 lines, 2550 args
$ xargs -P20 -n 100 </tmp/nums | wc
26 2550 11643
# redirecting to a file is clearly inaccurate: 22 lines, 2150 args
$ xargs -P20 -n 100 </tmp/nums >/tmp/out; wc /tmp/out
22 2150 10043 /tmp/out
我相信问题与底层 shell 无关,因为 shell 将在命令执行之前执行重定向并等待 xargs 完成。在这种情况下,我假设 xargs 在刷新缓冲区之前完成。但是,如果我的假设是正确的,我不知道为什么在写入管道时这个问题没有显现出来。
Edit:
使用时出现>>
(创建/附加到文件)在 shell 中,问题似乎没有显现出来:
# appending to file
$ >/tmp/out
$ xargs -P20 -n 100 </tmp/nums >>/tmp/out; wc /tmp/out
26 2550 11643
# creating and appending to file
$ rm /tmp/out
$ xargs -P20 -n 100 </tmp/nums >>/tmp/out; wc /tmp/out
26 2550 11643
您的问题是由于不同进程的输出混合所致。如下所示:
parallel perl -e '\$a=\"1{}\"x10000000\;print\ \$a,\"\\n\"' '>' {} ::: a b c d e f
ls -l a b c d e f
parallel -kP4 -n1 grep 1 > out.par ::: a b c d e f
echo a b c d e f | xargs -P4 -n1 grep 1 > out.xargs-unbuf
echo a b c d e f | xargs -P4 -n1 grep --line-buffered 1 > out.xargs-linebuf
echo a b c d e f | xargs -n1 grep 1 > out.xargs-serial
ls -l out*
md5sum out*
解决方案是缓冲每个作业的输出 - 无论是在内存中还是在 tmpfiles 中(就像 GNU Parallel 所做的那样)。
本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)