了解bash脚本开头的PATH变量导出

时间:2014-08-07 11:03:26

标签: bash

我经常看到在脚本开头导出PATH变量。例如,在Debian Wheezy的/etc/init.d/rc脚本中:

PATH=/sbin:/usr/sbin:/bin:/usr/bin
export PATH

虽然我知道这可以确保脚本中使用的可执行文件是从正确的目录启动的,但我并不完全了解哪些shell受此export语句的影响。例如,我在rc(PID 3987)中启动名为bash的脚本(PID 6582;命令为" / bin / sh /etc/init.d/rc"):

init(1)-+-acpid(1926)
        |-sshd(2139)-+-sshd(2375)---bash(2448)---screen(3393)---screen(3394)-+-bash(3395)---vim(3974)
        |            |                                                       |-bash(3397)---pstree(6584)
        |            |                                                       `-bash(3987)---rc(6582)---sleep(6583)

我是否正确rc脚本中的此PATH导出语句仅影响带有PID 6582的/ bin / sh,因为父shell(在我的示例中使用PID 3987的bash)不会从子节点继承变量?另外,我是否更正了脚本rc中执行的所有命令都是在带有PID 6582的/ bin / sh下启动的,因此使用这个PATH=/sbin:/usr/sbin:/bin:/usr/bin变量?如果是,那么简单的PATH = / sbin:/ usr / sbin:/ bin:/ usr / bin是不够的?

2 个答案:

答案 0 :(得分:2)

环境变量由从脚本运行的所有进程继承。 PATH特别影响C函数execlp()execvp()的行为,因此启动init.d的{​​{1}}脚本及其后代启动的所有进程都是受影响,但直到其中一个后代改变并导出它。

特别是,sshd很可能会更改它,因为它是一个登录shell,以匹配系统和用户的配置,因此所有后代都会受到此更改的影响。

然后,当您手动手动运行bash(2448)脚本时,/etc/init.d/rc命令会继承更改(但该命令永远不会尝试运行。)

  

如果是,那么是不是简单的PATH = / sbin:/ usr / sbin:/ bin:/ usr / bin已经足够了?

如果您只是设置变量而不是导出变量,则取决于sleep脚本运行的内容。如果它启动了任何试图用任何这些函数运行命令的东西,那么不,只有在导出rc之后它才会影响孩子。

答案 1 :(得分:1)

当脚本运行时,父shell应该已经导出

PATH,所以确实没有必要。

我可以想象在运行脚本的shell可能无法正确初始化的情况下,例如在启动过程中很早就运行的启动脚本,但是对于常规用户空间脚本,应该按照您想要的方式设置他们已经。