在bash中设置全局变量

时间:2015-04-16 17:30:07

标签: linux bash shell

我有功能,我希望它可以在某个时候挂起。所以我设置了一个全局变量然后读取它,如果它在几秒钟之后没有出现我放弃了。下面不是完整的代码,但它没有工作,因为我没有得到$ START为值5

START=0
ineer()
{
    sleep 5
    START=5
    echo "done $START"   ==> I am seeing here it return 5
    return $START
}
echo "Starting"
ineer &

while true
do
    if [ $START -eq 0 ]
    then
        echo "Not null $START"  ==> But $START here is always 0
    else
        echo "else $START"
        break;
    fi
    sleep 1;
done

4 个答案:

答案 0 :(得分:4)

您在后台运行inner函数调用,这意味着START将在当前shell启动的子shell中分配。在该子shell中,START值为5.

但是,在当前的shell echo START值中,它仍为0。由于START的更新仅在子shell中。

每次在后台启动一个shell时,它就像fork一个新进程,它将复制所有当前shell环境,包括变量值,并且新进程将完全与当前shell隔离。

由于子shell已作为新进程分叉,因此无法直接更新父shell的START值。一些替代方法包括在运行inner函数的子shell退出时传递的信号。

常见错误:

export

export只能用于使变量名可用于从当前shell派生的任何子shell。然而,一旦子壳已分叉。子shell将具有变量和值的新副本,shell中导出变量的任何更改都不会影响子shell。

请参阅以下代码了解详情。

#!/bin/bash
export START=0
ineer()
{
    sleep 3
    export START=5
    echo "done $START"  # ==> I am seeing here it return 5
    sleep 1
    echo "new value $START"
    return $START
}
echo "Starting"
ineer &

while true
do
    if [ $START -eq 0 ]
    then
        echo "Not null $START" #  ==> But $START here is always 0
        export START=10
        echo "update value to $START"
        sleep 3
    else
        echo "else $START"
        break;
    fi
    sleep 1;
done

答案 1 :(得分:1)

问题是ineer &在子shell中运行函数,子shell是变量的自身范围。子shell中所做的更改将不适用于父shell。我建议调查kill并发出信号。

答案 2 :(得分:0)

保存pid的{​​{1}}:

inner &

并使用pid=$! (即零!!)来检测您的进程是否还活着。

但最好重新设计kill -0 $pid以使用锁定文件,这是更安全的检查!

更新来自inner手册页:

KILL(2)

答案 3 :(得分:-1)

答案是:在这种情况下,您可以使用export。 该指令允许所有子进程使用此变量。 因此,当您调用ineer函数时,它将分叉复制整个环境的进程,包括从父进程获取的START变量。

您必须更改第一行:

START=0

为:

export START=0

您可能还想阅读此主题:Defining a variable with or without export