如何在 Shellscript 中将变量值从函数传递到调用过程

如何在 Shellscript 中将变量值从函数传递到调用过程

我想根据其他函数输出的完成来执行一些函数。

要求:

同时调用 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

相关内容