我想根据其他函数输出的完成来执行一些函数。
要求:
同时调用 func1 和 func2 等待 funct1 完成 一旦 funct1 完成,调用 func3
请找到相同的代码。
l_var='N';
func1()
{
l_var='C'
# do some logic which will take time
echo "$l_var"
}
func2()
{
l_var2='C'
# do some logic which will take time
echo "$l_var2"
}
func3()
{
l_var3='C'
# do some logic which will take time
echo "$l_var3"
}
# call function1 and function2 parallaly
func1 & func2
echo "$l_var"
# wait until funct1 complete
while [$l_var != "C"]
do
sleep 30
done
# once function1 one completed, then call function3
if [$l_var = "C"]
then
func3
fi
我面临的问题是 func1 内的 $l_var 值打印为 C,但在 while 条件和 if 条件下打印为 null(空值 - 函数外部)。
答案1
您的条件命令不正确:这[
不仅仅是语法,它实际上是一个命令。与每个命令一样,它需要一个空格来将其与其参数分开。
不是
if [$l_var = "C"]
但
if [ "$l_var" = "C" ]
# ..^........^.^...^ mandatory whitespace
请注意左侧变量周围添加的引号。很重要。
问题是您试图在子 shell 中设置全局变量。你不能这样做:子 shell(通过在后台运行该函数创建)无法更改父 shell 的环境。
最直接的技术是将新值写入文件中,当后台进程完成时(该wait
命令在此处有所帮助),您可以从文件中读取该值
#!/bin/bash
tmpfile=$(mktemp)
l_var='N';
func1() {
l_var='C'
# do some logic which will take time
sleep 5
echo "$l_var" > "$tmpfile"
echo "$FUNCNAME complete"
}
func2() {
l_var2='C'
# do some logic which will take time
sleep 1
echo "$FUNCNAME: l_var2=$l_var2"
}
func3() {
l_var3='C'
# do some logic which will take time
echo "$FUNCNAME: l_var3=$l_var3"
}
echo "start: l_var=$l_var"
# call function1 and function2 parallaly
func1 &
func2
# wait for func1, then read the new value from the file
wait
l_var=$(< "$tmpfile")
echo "after func1, l_var=$l_var"
# once function1 one completed, then call function3
if [[ "$l_var" == "C" ]]; then
func3
fi
输出
start: l_var=N
func2: l_var2=C
func1 complete
after func1, l_var=C
func3: l_var3=C
答案2
ksh coprocess 对此很方便
#!/usr/bin/ksh
func1() {
sleep $1
echo "X${1}X"
}
func2() {
sleep $1
echo "Y${1}Y"
}
func3() {
sleep $1
echo "Z${1}Z"
}
func1 10 |&
exec 5>&p # assign fd 5 to stdout
exec 6<&p # and fd 6 to stdin
func2 7 &
func3 5 |&
read -u6 F1A
read -p F3A
echo $F1A
echo $F3A
echo "wait until all is done"
wait