$ { - #*i}在shell脚本中的含义是什么?

Ren*_*Ren 18 linux shell centos6

/etc/profileCentOS 6上的文件中有一个for循环:

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
Run Code Online (Sandbox Code Playgroud)

${-#*i}上面的循环意味着什么?
谢谢你的帮助.

And*_*rey 12

$- 壳标志.

${-#*i}表示shell标志减去第一个匹配*i.

如果这两个不相等,那么shell被认为是交互式的(标志i存在).


Ren*_*Ren 11

上面的回答什么是"$ { - #*I}" ="$ - !"是什么意思?的Unix和Linuxcuonglm:

$-是shell本身,调用或使用setbuiltin命令设置的当前选项标志:

$ echo $-
himBH
$ set -a
$ echo $-
ahimBH
Run Code Online (Sandbox Code Playgroud)

"${-#*i}"是删除字符串的语法:(来自POSIX文档)

$ { 参数#[ word ]}

删除最小的前缀模式.该词应扩展为产生一种模式.然后参数扩展将产生参数,前缀的最小部分与删除的模式匹配.

如果存在,则单词不得以不带引号的' #' 开头.

$ { 参数 ## [ word ]}

删除最大的前缀模式.该词应扩展为产生一种模式.然后参数扩展将产生参数,前缀的最大部分与删除的模式匹配.

所以${-#*i}删除最短的字符串直到第一个i字符:

enter code here
$ echo "${-#*i}"
mBH
Run Code Online (Sandbox Code Playgroud)

在您的情况下,if [ "${-#*i}" != "$-" ]检查您的shell是否是交互式的.

  • 我已经编辑了你的答案,正确引用并归因于原作者.查看帮助中心的[Referencing](http://stackoverflow.com/help/referencing); 建议是"仅引用相关部分",而不是完整答案. (3认同)

mkl*_*nt0 7

TL;博士:

如果当前shell是交互式的[ "${-#*i}" != "$-" ],条件求值为逻辑true,在这种情况下,退出代码设置为0,信号为true,这将导致封闭if语句的then分支被执行.

有条件和整体故意只使用问题的代码兼容POSIX的shell语言语法和命令,以便携带(与所有POSIX-工作兼容可作为行动炮弹/bin/sh).

请注意,如果bash可以假设为shell,则相同的条件可以更可读地表示为
[[ $- == *i* ]]


说明

  • ${-#*i}是一个参数扩展,#它从名称参数的值中删除匹配模式 的最短前缀()(命名参数通常称为变量).*i$-

  • $-是一个特殊的参数,(链接和重点添加):

    扩展为调用时指定的当前选项标志(单字母选项名称连接成字符串),由set special内置命令扩展,或由shell隐式扩展.

  • 一个交互式的外壳隐含增加了选项标志i,它的值$- ; 换句话说:字母的存在i在的值$-意味着在手壳是互动,并且,相反地,不存在i暗示壳是非交互.

  • 因此,在参数扩展${-#*i},图案*i将只匹配的值内$-如果i存在,并且,如果是这样,凭借除去什么*i匹配时,返回一个子串的(后缀,在这种情况下)$-.
    换句话说:只在交互式 shell中${-#*i} 相等$-,因为在非交互式 shell中 - 由于缺少i- 参数扩展没有效果,并且两个操作数相等.


问题中的代码作为一个整体什么:

简而言之:代码使用它找到的shell脚本/etc/profile.d来初始化当前的shell; 进一步来说:

  • *.sh位于目录/etc/profile.d中的当前用户(-r)可读的脚本(名为文件)将按字母顺序逐个传递给.(点)实用程序.点实用程序执行当前 shell中每个文件的命令,通常用于定义别名,函数和环境变量.这通常称为采购文件.

  • 每个源脚本生成的输出的处理方式不同,具体取决于当前shell是否具有交互性:

    • 交互式 shell:输出传递(将在交互式shell中可见).

    • 非交互式 shell:输出被抑制(>/dev/null 2>&1符合POSIX标准的方式使stdout和stderr静音).