如何从zsh中的多个后台子进程获取字符串输出

问题描述 投票:0回答:1

我有一个在 zsh 中运行的脚本。调用脚本后,它会运行 main_process() 函数。 main_process 需要 ${hash_from_evaluator} 来完成其其余操作,但是计算该值需要时间。

为了加快速度,我首先在后台调用 5 个 _evaluator() 作为子进程,它们可以独立并行运行,以找出 ${hash_from_evaluator} 的 some 值。

main_process() 可以使用 $hash_from_evaluator 的任何值进行操作,只要它与给定的正则表达式匹配即可。任何首先返回该值的子进程都可以被获取,然后必须杀死剩余的子进程。

我请求您的帮助。我能够启动子进程,但是无法监视其中任何一个子进程是否返回了该值,然后使用该值并终止其余子进程。我如何在 zsh 中执行此操作?

#!/usr/bin/env zsh
zmodload zsh/system


_evaluator(){
  printf "launched subprocess $1 with PID $sysparams[pid]"
  
  while ! [[ ${hash_from_evaluator} =~ ${input_regex} ]]; do
    hash_from_evaluator="custom commands to maniuplace some data and get some hash as result"
  done
  
  return_value="subprocess $1 calculated ${hash_from_evaluator}"
  echo ${return_value}
}


main_process(){
  local input_regex="^abc123"
  local hash_from_evaluator=""

  for i in {1..5}; do
    echo "starting subprocess $i"
    _evaluator $i &
    pids[$i]=$!
  done

  # Requesting for yout kind help here please
  # wait for any one of the 5 subprocesses to give back $return_value.
  # assign this $return_value to hash_from_evaluator.
  # kill other 4 child processes.

  .... rest of the script consumes any valid ${hash_from_evaluator} in match with $input_regex
}


main_process "$@"

linux shell subprocess zsh
1个回答
0
投票

这就是我要做的。

在脚本开始时,您创建一个临时目录和一个 fifo 文件、一个锁定机制和一个用于清理所有内容的

trap

tempdir=$(mktemp -d) || exit 1
trap 'rm -rf "$tempdir"' EXIT

fifofile=$tempdir/fifo
mkfifo -m 600 "$fifofile" || exit 1
exec 3<>"$fifofile"

lockex() { ln -s _ "$tempdir/lock" 2> /dev/null; }

然后在

_evaluator
中输出如下结果:

lockex && printf '%s\0' "$return_value" >&3

并在

main_process
中,您通过读取 FD3 等待第一个子进程完成:

IFS='' read -u 3 -r -d $'\0' hash_from_evaluator

kill $(jobs -p)

顺便说一句,

pids[$i]=$!
似乎在
zsh
中不起作用,我明白了
pids=('$!' '$!' '$!' '$!' '$!')

© www.soinside.com 2019 - 2024. All rights reserved.