linux并行运行两个命令,关于git:Linux-运行多个并行命令,打印顺序输出

我对bash有点陌生,我需要并行运行数百条简短命令,但要顺序打印输出。 该命令将相当短的输出输出到stdout,这是我不想使其松散或与另一个线程的输出混为一谈。 Linux中是否有一种方法可以运行多个命令(例如,并行运行的线程数不超过N个),以便按顺序打印所有命令输出(只要它们不重叠即可)。

当前的bash脚本(此处有完整代码)

declare -a UPDATE_ERRORS

UPDATE_ERRORS=( )

function pull {

git pull  # Assumes current dir is set

if [[ $? -ne 0 ]]; then

UPDATE_ERRORS+=("error message")

fi

for f in extensions/*; do

if [[ -d $f ]]; then

########## This code should run in parallel, but output of each thread

########## should be cached and printed sequentially one after another

########## pull function also updates a global var that will be used later

pushd $f > /dev/null

pull

popd > /dev/null

fi

done

if [[ ${#UPDATE_ERRORS[@]} -ne 0 ]]; then

# print errors again

fi

看看gnu.org/software/parallel

谢谢,看起来很有希望,但是如果发生故障,我如何使每个线程向全局数组添加错误消息?

要点1)将-k添加到GNU Parallel的调用中,以保持输出顺序。 要点2)定义一个函数,并确保将其导出,并将该函数传递给GNU Parallel执行-在函数内部,将错误消息附加到数组中。 gnu.org/software/parallel/

您可以为此使用flock。我已经模拟了类似的情况进行测试。 do_the_things proc产生时间重叠输出。在for循环中,文本生成同时调用了几次。输出应该混乱,但是输出将馈送到过程locked_print,该过程等待直到释放锁,然后将接收到的输入输出到stdout。需要导出以从管道内部调用过程。

#!/bin/bash

do_the_things()

{

rand="$((RANDOM % 10))"

sleep $rand

for i in `seq 1 10`; do sleep 1; echo"${rand}-$i"; done

}

locked_print()

{

echo Started

flock -e testlock cat

}

export -f do_the_things

export -f locked_print

for f in a b c d; do

(do_the_things | locked_print) &

done

wait

@ user313294如果有很多事情要做,比如说500,它只会把它们全部扔到CPU上一次完成,不是吗? 有时,当任务竞争CPU /网络/磁盘带宽时,这实际上会使速度变慢。 +1是一个很好,整洁的解决方案。

@MarkSetchell我认为其中的499个将填充其管道缓冲区,并在io上被阻塞,直到释放锁为止,而1将管道输出。

尝试这样的事情。我没有/使用git,所以我做了一个虚拟命令以在我的版本中对其进行仿真。

#!/bin/bash

declare -a ERRORS

ERRORS=( )

function pull {

cd"$1"

echo Starting pull in $1

for i in {0..9}; do echo"$1 Output line $i";done

sleep 5

echo"GITERROR: Dummy error in directory $1"

}

export -f pull

for f in extensions/*; do

if [[ -d $f ]]; then

########## This code should run in parallel, but output of each thread

########## should be cached and printed sequentially one after another

########## pull function also updates a global var that will be used later

echo $f

fi

done | parallel -k pull | tee errors.tmp

IFS=$'

' ERRORS=($(grep"^GITERROR:" errors.tmp))

rm errors.tmp

for i in"${ERRORS[@]}"; do

echo $i

done

您将看到,即使要拉4个目录,整个脚本也只需要5秒钟-尽管执行了4个sleep 5。

最好使用find extensions -type d | parallel -k pull | tee errors.tmp

@ user3132194我只是在可能的情况下重用了OPs代码以演示该技术。 我认为find命令还将找到extensions父目录,而OPs命令则找不到。 实际上,我认为bash4在for d in exrensions*上效果最好,但是我在OSX上没有bash4,正如我所说,我正在集中精力展示GNU Parallel的乐趣:-)

通过添加/列出目录。并行生成一个cd到目录的外壳。如果git pull失败,则会输出魔术字符串。所有输出也作为副本保存在out / 1 / *中。完成所有拉取后,检查魔术字符串出现在哪些文件中,并打印出这些命令的STDOUT / STDERR。清理。

parallel --results out 'cd {} && (git pull || echo e_R_r_O_r)' :::  extensions/*/

grep -l e_R_r_O_r out/*/stdout | parallel 'grep -v e_R_r_O_r {//}/stdout; cat {//}/stderr >&2'

rm -r out

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值