咨询/etc/profile文件中`if [ "${-#*i}" != "$-" ]`条件语句的含义
详解
if [ "${-#*i}" != "$-" ]的作用 咱们一步一步拆解这个条件语句,搞清楚它到底在做什么:
1. 先搞懂$-这个特殊变量
在Bash和大多数POSIX兼容的shell里,$-是个内置变量,存的是当前shell会话已经启用的选项标志。举个例子:
- 如果是交互模式下的shell(就是你直接在终端敲命令那种),
$-里会包含i这个标志; - 如果开启了其他选项比如
noclobber,还会有C标志,以此类推。
2. 解析参数展开${-#*i}
这是shell的参数展开语法,${变量#匹配模式}的意思是:从变量的开头开始,删掉最短的匹配模式内容。这里的模式是*i,翻译过来就是"从字符串开头到第一个i字符的所有内容"。
两种情况:
- 如果当前是交互shell(
$-里有i):比如$-的值是himBH,那${-#*i}会把开头到i的部分(也就是h)删掉,剩下mBH,这时候${-#*i}和原$-肯定不相等; - 如果是非交互shell(
$-里没i):*i这个模式匹配不到任何内容,所以${-#*i}的结果就和原$-完全一样,两者相等。
3. 整个条件的核心作用
说白了,这个条件就是在判断当前shell是不是交互模式。
结合原代码看实际用途
原代码是循环加载/etc/profile.d/下的脚本,逻辑是:
for i in /etc/profile.d/*.sh /etc/profile.d/sh.local ; do if [ -r "$i" ]; then if [ "${-#*i}" != "$-" ]; then . "$i" # 交互模式下直接执行,输出会显示给终端用户 else . "$i" >/dev/null # 非交互模式下,把所有输出丢去/dev/null,避免干扰脚本或任务的输出 fi fi done
这么做的原因很合理:
- 交互模式下,用户可能需要看到脚本输出的提示(比如环境变量设置的通知);
- 非交互模式(比如系统启动脚本、后台运行的任务),我们不希望这些脚本的输出乱飘,影响正常的程序输出或者日志,所以直接屏蔽掉。
内容的提问来源于stack exchange,提问作者rgo1991
相关产品推荐
相关产品推荐

