【问题标题】:xargs output buffering -P parallelxargs 输出缓冲 -P 并行
【发布时间】: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.,打开行缓冲告诉单个实例不要尝试执行短于单行的写入(假设您没有超过缓冲区大小的单行),但是它不会阻止您的线路在多个实例中交错。即使是大于行的缓冲区也不能防止缓冲区的边界(以及写入的边界)处于不希望的截止点。

标签: bash shell awk sed


【解决方案1】:

如果您的输出长度超过一页(通常为 4kb),这不是相当原子的,但在大多数情况下它会这样做:

xargs -P 24 bash -c 'for arg; do printf "%s\n" "$(myAwesomeShellFunction "$arg")"; done' _

这里的神奇之处在于命令替换:$(...) 创建一个子shell(您的shell 的fork()ed-off 副本),在其中运行代码...,然后将其读入以替换为外部脚本中的相关位置。

请注意,我们不需要 -n 1(如果您要处理大量参数 - 对于少量参数,它可能会提高并行性),因为我们迭代的参数数量与您的每个参数一样多通过了 24 个并行 bash 实例。


如果你想让它真正原子化,你可以使用锁文件来做到这一点:

# generate a lockfile, arrange for it to be deleted when this shell exits
lockfile=$(mktemp -t lock.XXXXXX); export lockfile
trap 'rm -f "$lockfile"' 0

xargs -P 24 bash -c '
  for arg; do
    {
      output=$(myAwesomeShellFunction "$arg")
      flock -x 99
      printf "%s\n" "$output"
    } 99>"$lockfile"
  done
' _

【讨论】:

  • 这真的很聪明,没有意识到命令替换做到了。输出只能占1页?除非发生非常不寻常的事情,否则我的文件几乎可以保证小于 4kb。参数的数量通常是
  • 可以占用多个页面,但在这种情况下更有可能被拆分为多个写入,因此如果您有多个进程同时完成(在相隔几毫秒?)结合多页输出,那么你可能会失去原子性。
猜你喜欢
  • 2015-01-28
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2011-07-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2011-07-24
相关资源
最近更新 更多