【问题标题】:GNU Parallel: Run bash code that reads (seq number) from pipe?GNU Parallel:运行从管道读取(序列号)的 bash 代码?
【发布时间】:2022-01-03 18:55:33
【问题描述】:

我想并行读取(seq numbers)管道,所以我想运行类似的东西:

seq 2000 | parallel --max-args 0 --jobs 10 "{ read test; echo $test; }"

相当于运行:

echo 1
echo 2
echo 3
echo 4
...
echo 2000

但不幸的是,管道没有被并行读取,这意味着它是这样运行的:

echo
echo
echo
...
echo

而且输出是空的。

有谁知道如何制作并行读取(序列号)管道?谢谢。

【问题讨论】:

  • 旁白:parallel 不是 bash 的一部分;这是一个用 perl 编写的完全独立的项目。 (它的作者在这里也很活跃;适当地修改了标签,他们很可能会出现)
  • 另外,您可能需要 --pipe 参数来并行化,或其同义词 --spreadstdin,以使内容位于儿童的标准输入上,以便 read 可以访问它们。 (更常见的是使用 argv 而不是 stdin;我不清楚你为什么不想在这里这样做)。
  • 恰恰相反,parallel确实从管道中读取,它自己,所以read 没有什么可以读取的了。此外,使用双引号,$testparallel 运行之前扩展,因此即使 read 成功,您在每个子进程中执行 echo,而不是 echo $test
  • @CharlesDuffy 你能给我看一个并行使用 argv 的例子吗?
  • 如果您暂时忘记了 parallel 并且只显示了前 3-4 个实际命令,我想您会得到更接近您想要做的事情的答案> 你真的很想跑。 echo 是一个特例,因为 a) 它是内置的,b) 它是 parallel 的默认命令,这意味着您得到的答案不会对您有太大帮助。实际上,您问题的实际答案是seq 2000 | parallel 或者seq 2000 | parallel echo

标签: bash curl gnu-parallel


【解决方案1】:

GNU xargs 的替代方案,不需要 GNU parallel

seq 2000 | xargs -P 10 -I {} "echo" "hello world {}"

输出:

你好世界1 你好世界2 你好世界3 你好世界4 你好世界5 . . .

来自man xargs

-P max-procs:一次最多运行max-procs 个进程;默认值为 1。如果 max-procs 为 0,xargs 将一次运行尽可能多的进程。

-I replace-str:将初始参数中出现的replace-str 替换为从标准输入读取的名称。

【讨论】:

  • 值得注意的是,这会产生大量 /bin/echo 的副本,而不是使用 bash 的内置 echo
  • @CharlesDuffy:我同意你的看法。我怀疑echo 只是user12345432109890 代码中用于调用程序的占位符。
  • 点头。真正的问题是是否有空间减少单独调用的数量,例如通过将多个文件名传递给它们启动的程序的每个调用。
【解决方案2】:

您希望将输入通过管道传输到您运行的命令中,因此请使用--pipe

seq 2000 |
   parallel --pipe -N1 --jobs 10 'read test; echo $test;'

但如果你真的只需要它作为变量,我会做以下其中之一:

seq 2000 | parallel --jobs 10 echo
seq 2000 | parallel --jobs 10 echo {}
seq 2000 | parallel --jobs 10 'test={}; echo $test'

我会鼓励你花 20 分钟阅读https://doi.org/10.5281/zenodo.1146014 的第 1+2 章,你的命令行会因此而爱上你。

【讨论】:

    【解决方案3】:

    使用xargs 而不是并行同时仍然使用shell(而不是在每行运行/bin/echo 可执行文件的新副本)看起来像:

    seq 2000 | xargs -P 10 \
      sh -c 'for arg in "$@"; do echo "hello world $arg"; done' _
    

    这可能比 Cyrus 的现有答案更快,因为启动可执行文件需要时间;即使启动 /bin/sh 的新副本比启动 /bin/echo 的副本花费更长的时间,因为这不使用 -I {},它能够将许多参数传递给/bin/sh 的每个副本,从而将时间成本摊销到更多数字上;这样我们就可以使用echo 内置在sh 中的副本,而不是单独的echo 可执行文件。

    【讨论】:

      猜你喜欢
      • 2015-11-12
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2017-09-09
      • 2014-07-19
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多