我创建了一个 bash 脚本来运行一些具有自定义环境变量的其他程序。这是我的第一个脚本,run-hello.sh
名为/home/user
#!/bin/bash
export PATH=$PATH":/home/user/cool/path"
hello.sh
exit 0
我/home/user/cool/path
有hello.sh
脚本:
#\!/bin/bash
echo Hello from $(pwd)
运行第一个脚本 (run-hello.sh) 会产生:
Hello from /home/user
我的问题:
第一个脚本中的调用
export
仅在脚本处于活动状态期间有效?如果运行脚本后我echo $PATH
将看不到脚本添加的路径...这是预期的行为吗?我怎样才能让它至少在终端的持续时间内存在?为什么打印结果
/home/user
而不是/home/user/cool/path
?
答案1
首先,您需要考虑,当您在 shell 下启动某个 shell 脚本时,您的 shell 将派生一个新的 shell(我们称之为子 shell)来执行该脚本的命令。
然后 man bash 告诉:
环境
当程序被调用时,它会被赋予一个称为环境的字符串数组。这是名称-值对的列表,其形式为name=value
。shell 提供了多种操作环境的方法。在调用时,shell 会扫描自己的环境,并为找到的每个名称创建一个参数,自动将其标记为导出到子进程。执行的命令继承环境。和
export
命令declare -x
允许在环境中添加和删除参数和函数。如果环境中的参数值被修改,新值将成为环境的一部分,替换旧值。任何执行的命令继承的环境由 shell 的初始环境组成,其值可以在 shell 中修改,减去命令删除的任何对unset
,加上通过export
和declare -x
命令添加的任何内容。
因此,当您第一次导出 时PATH
,它的新值将成为您的子 shell 环境的一部分,并且可供它将触发的任何子进程使用。 (例如hello.sh)
因此,如果您echo $PATH
在运行hello.sh后立即运行,则应该显示更新后的值。
但是,您退出 shell! (执行 run-hello.sh 的子 shell 终止)它的某些祖先(很可能是您启动 run-hello.sh 的 shell)收回了控制权,但完全不知道 run-hello.sh 环境的干扰。
所以,是的,这确实是预期的行为。
现在,任务启动时的当前工作目录是从其父级继承的。它不会自动更改为程序所在的目录。
所以我必须怀疑您的调用run-hello.sh
是从该/home/user
目录进行的。
总而言之:任何导出变量的生命周期都等于负责导出的任务的生命周期,并且任务本身及其所有子项(在其启动时)的有效性得到保证。