关于变量,陷阱 EXIT 函数和“sleep n && 函数”在 bash 中究竟是如何运行的?

问题描述 投票:0回答:1

这是一个重现我的问题的脚本。该函数回显并更改变量。无论我先按下一个键还是让计时器先用完都没关系,两次调用的变量都不会改变,它只是打印“Not touched!”两次,这对我来说很奇怪。

#!/bin/bash

func(){
    echo "$globalVar"       
    globalVar="touched!"
}

globalVar="Not touched!"

trap func EXIT
(sleep 3 && func) &

read -n1 -r -p "Press any key to exit..."

我希望它回显“未触及!”第一次和“感动!”第二次。

编辑: 与使用后台进程的 (sleep 3 && func) $ 行有关。那么我的问题是如何使变量真正成为全局变量?

bash function variables sleep
1个回答
2
投票

陷阱

内置的

trap
由 posix
sh
指定,bash 受该规范约束。来自官方规范

shell 在 EXIT 上执行陷阱的环境应与在执行 EXIT 陷阱之前执行的最后一个命令之后立即相同的环境。

每次调用 trap 时,动作参数的处理方式等同于:

eval action

这应该可以回答您标题中的问题。但是,您的脚本受到另一个可能有点混乱的其他细节的影响:

子壳

在子流程中,您不能更改父流程的变量。如果你有像 ...

这样的命令,这可能看起来很明显
#! /bin/bash
x=1
bash -c 'x=2'
echo "$x"

...但是 bash 在很多地方启动所谓的子 shell,例如在管道 (

subshell1 | subshell2
)、替换
command "$(subshell)"
、后台进程
subshell &
和显式子 shell
(subshell)
.

(sleep 3 && func) &
在子 shell 中运行,因此不能改变父进程的全局变量

进程间通信

我的问题是如何使变量真正成为全局变量?

如果你想在两个进程之间共享一个变量,那么使用内置函数是不可能的。您需要某种方式来进行进程间通信。在 shell 中,最简单的解决方案是读取和写入文件/fifos。细节取决于你到底想达到什么目的。

© www.soinside.com 2019 - 2024. All rights reserved.