如何并行运行bash函数并将所有输出按顺序合并到一个字符串?

时间:2019-06-22 22:50:06

标签: string bash parallel-processing

我正在以oh-my-git的样式编写多个bash提示函数,并且希望它们并行运行并按顺序合并其输出。速度至关重要,我想避免写入任何文件系统,无论是在内存中还是在硬盘驱动器上。

我的想法是尝试并行设置变量,但在同一范围内不可行。 GNU Parallel和parset不能接缝使用bash函数。

.bashrc的结尾:


: "${ORIGINAL_PS1:=$PS1}"

PROMPT() {

    git="$(GIT_PROMPT)"
    pamac="$(PAMAC_PROMPT)"
    busich="$(BUSICH_PROMPT)"

    PS1="$git$pamac$busich$ORIGINAL_PS1"

}

PROMPT_COMMAND="PROMPT; $PROMPT_COMMAND"

(源bash函数的是GIT_PROMPT,PAMAC_PROMPT和BUSICH_PROMPT)

2 个答案:

答案 0 :(得分:1)

要狭义地回答这个问题,产生三个流程替换并将它们的结果串联起来将使工作并行进行,同时以已知顺序生成输出:

PS1=$(cat <(GIT_PROMPT) <(PAMAC_PROMPT) <(BUSICH_PROMPT))

类似地,在bash 4.1或更高版本中,您可以显式启动外部进程,并附加一个自动分配的文件描述符以用于读取其输出:

# start GIT_PROMPT function in the background
exec {git_prompt_fd}< <(GIT_PROMPT)

# ...do other stuff...

# now, later, read its output
git_prompt=$(</dev/fd/$git_prompt_fd)

...请记住,在完成函数内部的艰苦工作之前,您要避免执行任何会阻塞写入stdout的操作。


但是,我实际上并不建议,特别是在代码中尤其是对性能敏感的提示。更好的办法是检查您的功能,并阻止它们执行任何派生操作,任何对外部命令的使用等;而不是以并行化的名义添加更多分支。

答案 1 :(得分:0)

解决方案1:使用env_parallel

env_parallel --session
GIT_PROMPT() { echo stdoutgit; echo stderrgit >&2; sleep 2; }
PAMAC_PROMPT() { echo stdoutpamac; echo stderrpamac >&2; sleep 2; }
BUSICH_PROMPT() { echo stdoutbusich; echo stderrbusic >&2; sleep 2; }
PS1=`env_parallel -k ::: GIT_PROMPT PAMAC_PROMPT BUSICH_PROMPT`
env_parallel --endsession

解决方案2:导出功能

GIT_PROMPT() { echo stdoutgit; echo stderrgit >&2; sleep 2; }
export -f GIT_PROMPT
PAMAC_PROMPT() { echo stdoutpamac; echo stderrpamac >&2; sleep 2; }
export -f PAMAC_PROMPT
BUSICH_PROMPT() { echo stdoutbusich; echo stderrbusic >&2; sleep 2; }
export -f BUSICH_PROMPT
PS1=`parallel -k ::: GIT_PROMPT PAMAC_PROMPT BUSICH_PROMPT`

仅捕获stdout,因此您需要自己处理stderr(可能只是将其重定向到stdout)。

(GNU Parallel在/tmp中使用了临时文件,但是非常努力地清理它们-通常在创建文件后不到1毫秒。文件保持打开状态,因此通常会发生文件活动之后将其删除)。