if [“$ { - #* i}”!=“$ - ”]是什么意思?

时间:2013-10-09 04:02:25

标签: linux bash shell

在我的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语句来重定向输出? 谢谢!

4 个答案:

答案 0 :(得分: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}" != "$-" ]
如果变量$-包含选项i,则

将为true,这意味着interactive mode已启用。

这一切意味着如果您处于交互模式,输出将仅重定向到/dev/null

答案 1 :(得分:4)

检查shell是否是交互式的。当前shell的选项位于$-中,如果删除任何后跟i的内容会产生不同的结果,则表示i属于这些标记。

但这会更具可读性和惯用性:

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

此外,最好在循环外进行一次检查。

答案 2 :(得分:2)

  

$-是什么意思?

从手册:

  

-

     

(连字符。)扩展到调用时指定的当前选项标志,set builtin命令或shell设置的那些标志。   本身(例如-i选项)。

当您以交互方式运行bash 时,$-可能会出现以下情况:

himBH

当您执行脚本时,$-不会有i(除了上面的其他标志)。

  

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

${-#*i}导致*i的最短匹配从$-的扩展开始被删除。 (请参阅Shell Parameter Expansion。)

简而言之,示例中的内部if条件意味着在交互模式下执行以下操作:

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

并且在非交互模式下,以下内容:

. "$i"

答案 3 :(得分:1)

只是添加一些关于$的更多细节。如果您尝试输入终端

[root@zee ~]# echo $-
himBH

那些似乎是shell'set'值

来自info bash --index-search=set

的摘录
 '-h'

在查找时查找并记住(哈希)命令 执行。默认情况下启用此选项。

 '-m'

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

 '-B'

shell将执行大括号扩展(* note Brace 扩张::)。默认情况下,此选项处于启用状态。

'-H'

启用'!'风格历史替代(*注释历史 相互作用::)。默认情况下,此选项处于启用状态 壳。

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