我有function,我期待它挂了一段时间。 所以我设定了一个全局variables,然后读取它,如果在几秒钟后我没有放弃,我就放弃。 下面是不完整的代码,但它不工作,因为我没有得到$ 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
你在后台运行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。 然而,一旦subhell已分叉。 子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
问题是ineer &
在一个子shell中运行函数,这是它自己的变量范围。 在子shell中所做的更改将不适用于父shell。 我建议寻找杀人和信号捕捉。
保存inner &
pid
:
pid=$!
并使用kill -0 $pid
(即零!!)来检测你的进程是否还活着。
但更好的重新设计inner
使用锁定文件,这是更安全的检查!
从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.
答案是:在这种情况下,您可以使用export
。 这个指令允许所有的子进程使用这个变量。 所以当你调用ineer
函数的时候,它会分叉一个复制整个环境的进程,包括从父进程中获取的START变量。
你必须改变第一行:
START=0
至:
export START=0
您可能还想阅读这个线程: 定义一个变量有或没有出口