2013-10-09 428 views
2

在我的Oracle Linux中,我发现脚本块在/etc/profile是很难搞清楚:

for i in /etc/profile.d/*.sh ; do 
    if [ -r "$i" ]; then 
     if [ "${-#*i}" != "$-" ]; then 
      . "$i" 
     else 
      . "$i" >/dev/null 2>&1 
     fi 
    fi 
done 

我的问题是在if语句${-#*i}$-的变量。 这是什么意思?为什么要添加一个else语句来重定向输出? 谢谢!

回答

8

$-variable which stores the current options set by the shell

${-#*i}正在使用子串删除从变量的开始处移除与模式*i的最短匹配。因此,如果$-具有值abcifOO,则${-#*i}将是fOO(You can read more about bash substrings here.)

这意味着如果该变量$-包含选项i,这意味着interactive mode接通测试

[ "${-#*i}" != "$-" ] 

将为真。

所有这一切意味着如果处于交互模式,输出将只会被重定向到/dev/null

2

$-是什么意思?

从手册:

-

(连字符)扩展到在调用时所指定,由所述一组内建命令,或者那些由壳 设置当前选项标志本身(如-i选项)。

当你运行bash交互,然后$-可能exapnd喜欢的东西:当你执行一个脚本

himBH 

$-不会有i(除了一些其他上面的标志)。

${-#*i}是什么意思?

话说${-#*i}引起*i$-膨胀开始时的最短匹配被删除。 (参考Shell Parameter Expansion

总之,内if条件在实施例意味着,当在交互模式中执行以下操作:

. "$i" >/dev/null 2>&1 

和在非交互模式下,执行以下操作:

. "$i" 
4

它检查shell是否是交互式的。当前shell的选项在$-中,如果删除任何内容后跟i产生不同的结果,则表示i是标志之一。

这将是一个很大更具可读性和地道,但:

case $- in *i*) ... ;; esac 

而且,这将是更好地做检查一次,外循环。

1

只是加起来多一点关于$ - 的细节。如果您尝试输入您的终端

[[email protected] ~]# echo $- 
himBH 

那些似乎是壳“设置”值

片段从info bash --index-search=set

'-h' 

找到并记住(散),因为他们抬头命令执行 。该选项默认启用。

'-m' 

作业控制已启用(* note Job Control :)。

'-B' 

外壳将执行花括号扩展(*注括号 扩展::)。该选项默认开启。

'-H' 

启用'!'风格历史替代(*注意历史 交互:)。对于交互式 炮弹,此选项默认为打开。

使用+' rather than - '导致这些选项被关闭。 这些选项也可以在调用shell时使用。

相关问题