我有几个与非交互式、非登录 shell 和 cron 作业相关的问题。
Q1.我读过非交互式、非登录 shell 只能“加载” $BASH_ENV
。这究竟意味着什么?这是否意味着我可以指向$BASH_ENV
一个文件,并且该文件将被获取?
Q2:假设我有一个条目cron
指向带有 Bash shebang 的 Bash 脚本,我可以假设我的 Bash 脚本加载了哪些环境变量和定义?
第三季度:如果我添加SHELL=/bin/bash
到我的顶部crontab
,这到底有什么作用?这是否意味着:
cron
本身在 Bash 中运行?- 命令指定的in
crontab
是在 Bash 中解释的吗? - 执行以下操作的脚本不是其中有
shebangs
,在下面运行$SHELL
还有别的东西吗?
第四季度: 如何设置BASH_ENV
cron 作业?
答案1
对于 Q1 和 Q2,请参阅这里。 Q3 在下面对您的其他三个问题的讨论中得到了回答。
WRT $BASH_ENV
,来自man bash
:
当 bash 以非交互方式启动时,要运行 shell 脚本,例如,它会在环境中查找变量 BASH_ENV,如果出现该变量,则扩展其值,并使用扩展后的值作为要读取和执行的文件名。
所以这可能是一个.profile
打字脚本。至于在哪里或谁设置它,这取决于上下文——通常它不会被设置,但它可能是由当前进程的任何祖先设置的。 cron
似乎没有对此进行任何特殊用途,并且 AFAIK 也没有使用 init.
这是否意味着 cron 本身在 Bash 中运行?
如果您所说的“in”是指从 shell 启动,那么这取决于 init 系统——例如,SysV 为服务执行 shell 脚本,因此这些服务始终通过 shell 启动。
但是,如果您所说的“in”是指“它是 shell 进程的子进程吗?”,不。 与其他守护进程一样,它作为自己进程组的领导者运行,其父进程是 init 进程(pid 1)。
cron
然而,对环境的影响可能并不重要。有关初创服务环境的更多信息,请参阅上面链接的有关 Q1 和 Q2 的答案。 WRT专门针对cron,根据man 5 crontab
它也套由它启动的任何进程继承的一些环境变量($LOGNAME
、$HOME
和$SHELL
)。
crontab 中指定的命令在 Bash 中解释吗?
它们用sh
or来解释$SHELL
;再次来自man 5 crontab
:
该行的整个命令部分,直到换行符或“%”字符,将由 /bin/sh 或由 cronfile 的 SHELL 变量中指定的 shell 执行。 命令中的“%”字符,除非用反斜杠()转义,否则将被更改为换行符,并且第一个 % 之后的所有数据都将作为标准输入发送到命令。
强调部分回答了Q3。
没有 shebangs 的脚本使用 $SHELL 运行
$SHELL
带有或不带有 shebang 的可执行脚本由( 或)打开sh
。不同之处在于,那些带有 shebang 的将被交给适当的解释器(#!/bin/sh
作为 shell 的另一个实例),而可执行文件没有 shebang 的脚本(具有作为可执行文件引用的可执行位集的脚本)将会失败,就像从命令行运行时一样(除非您运行它们sh script.sh
)。