bash 在bash中设置全局变量

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/29681980/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-09-18 12:48:57  来源:igfitidea点击:

setting global variable in bash

linuxbashshell

提问by eswaat

I have function where I am expecting it to hang sometime. So I am setting one global variable and then reading it, if it didn't come up after few second I give up. Below is not complete code but it's not working as I am not getting $START as value 5

我有我希望它在某个时候挂起的功能。所以我正在设置一个全局变量,然后读取它,如果几秒钟后它没有出现,我就放弃了。下面不是完整的代码,但它不起作用,因为我没有将 $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

回答by Kun Ling

You run innerfunction call in back ground, which means the STARTwill be assigned in a subshell started by current shell. And in that subshell, the STARTvalue will be 5.

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

However in your current shell, which echothe STARTvalue, it is still 0. Since the update of STARTwill only be in the subshell.

但是在您当前的 shell 中,它echoSTART值仍然是0. 由于更新START只会在子shell中。

Each time you start a shell in background, it is just like fork a new process, which will make a copy of all current shell environments, including the variable value, and the new process will be completely isolate from your current shell.

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

Since the subshell have been forked as a new process, there is no way to directly update the parent shell's STARTvalue. Some alternative ways include signals passing when the subshell which runs innerfunction exit.

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

common errors:

常见错误:

export

export

exportcould only be used to make the variable name available to any subshells forked from current shell. however, once the subshell have been forked. The subshell will have a new copy of the variable and the value, any changes to the exported variable in the shell will not effect the subshell.

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

Please take the following code for details.

详情请取以下代码。

#!/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

回答by Politank-Z

The problem is that ineer &runs the function in a subshell, which is its own scope for variables. Changes made in a subshell will not apply to the parent shell. I recommend looking into killand signal catching.

问题是ineer &在子shell中运行函数,这是它自己的变量范围。在子 shell 中所做的更改不会应用于父 shell。我建议研究杀戮和信号捕捉。

回答by gavenkoa

Save pidof inner &by:

保存pidinner &方式:

pid=$!

and use kill -0 $pid(that is zero!!) to detect if your process still alive.

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

But better redesign innerto use lock file, this is safer check!

但是更好地重新设计inner以使用锁定文件,这是更安全的检查!

UPDATEFrom KILL(2)man page:

更新KILL(2)手册页:

  #include <sys/types.h>
  #include <signal.h>

  int kill(pid_t pid, int sig);

If sig is 0, then no signal is sent, but error checking is still
performed; this can be used to check for the existence
of a process ID or process group ID.

回答by Stefano Falsetto

The answer is: in this case you can use export. This instruction allow all subprocesses to use this variable. So when you'll call the ineerfunction it will fork a process that is copying the entire environment, including the START variable taken from the parent process.

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

You have to change the first line from:

您必须将第一行更改为:

START=0

to:

到:

export START=0

You may also want to read this thread: Defining a variable with or without export

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