我有一个在 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 "$@"
这就是我要做的。
在脚本开始时,您创建一个临时目录和一个 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=('$!' '$!' '$!' '$!' '$!')