我需要实现一些配置 - 如果我的系统上有人bash
以任何形式(交互式、非交互式和bash -c
表单)调用命令,我需要执行一些代码。例如,这是我想要添加到每个 bash 调用的命令:
touch /tmp/$RANDOM
我添加了该行,/bash/bash.bashrc
它对于登录 shell 和通过调用bash
命令初始化的 shell 都运行良好。
但这不适用于像这样初始化的 bash 会话:
bash -c 'echo 1'
- 不会创建新文件
从文档中我了解到,该bash.bashrc
和bash_profile
仅在登录或交互式 shell 中调用。有没有办法为非交互式 shell 创建一些类似的调用?
答案1
要使 bash 在作为非交互式 shell 调用时解析文件,您需要设置环境变量BASH_ENV
以指向该文件。来自man bash
(关于 INVOCATION 的部分):
例如,当 bash 以非交互方式启动以运行 shell 脚本时,它会在环境中查找变量 BASH_ENV,如果该变量存在,则扩展其值,并使用扩展的值作为要读取和执行的文件的名称。Bash 的行为就像执行了以下命令一样:
if [ -n "$BASH_ENV" ]; then . "$BASH_ENV"; fi
但 PATH 变量的值不用于搜索文件名。
那么在哪里设置呢BASH_ENV
?
任何一个:
如果您希望变量在整个系统环境中可用,则放置它的最佳位置是/etc/environment
。此文件专门用于系统范围的环境变量设置。它不是由 shell 解析的,而是由 PAM 模块解析的pam_env
,因此您不能在其中使用 shell 语法或变量扩展,而只能使用以下类型的简单赋值:
VARIABLE=value
或者
VARIABLE=/full/path/to/file
更改将在下次登录/身份验证时生效,因此请切换到新的 tty 控制台或注销并重新登录您的会话。
在标准桌面系统上,这应该适用于使用 PAM 的所有类型的经过身份验证的会话,包括控制台登录、ssh 和显示管理器,以及 atd 和 cron 等守护进程。如果一切按预期运行,那么您就大功告成了,无需继续阅读。
但是,某些程序/发行版的 PAM 配置文件偶尔会有一些错误,因此,如果/etc/environment
某种类型的程序无法解析,请确保在该程序的 PAM 配置文件中加载了必要的 PAM 模块/etc/pam.d
:
session required pam_env.so readenv=1
(注意:readenv
打开/关闭读取配置文件的标志实际上并不需要,因为默认情况下它被设置为开启(1) - 但确保这一点也没有什么坏处。)
或者:
如果您正在使用的系统不提供pam_env
,那么我想到最好的替代方案就是编写一个简单的 init 脚本(或 systemd 上的服务单元文件),/etc/default/environment
在启动时解析自定义配置文件(例如)。