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

Pet*_*ete 38 shell shell-script

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

什么${-#*i}意思。我找不到开始的参数扩展的定义${-

cuo*_*glm 41

$-是由 shell 本身、在调用时或使用set内置命令设置的当前选项标志:

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

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

${参数#[字]}

删除最小前缀模式。这个词应该被扩展以产生一个模式。然后参数扩展将产生参数,其中与删除的模式匹配的前缀的最小部分。如果存在,单词不应以未加引号的“#”开头。

${参数##[字]}

删除最大的前缀模式。这个词应该被扩展以产生一个模式。然后参数扩展将导致参数,其中与删除的模式匹配的前缀的最大部分。

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

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

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


Hau*_*ing 23

有一个 shell 参数$-。就我而言:

$ echo $-
himB
Run Code Online (Sandbox Code Playgroud)

${-}是一样的$-完全一样${foo}是一样的$foo

#*i意味着:从变量值的开头删除(尽可能少;在这里没有区别)直到(包括)第一个i.

$ echo "${-#*i}"
mB
Run Code Online (Sandbox Code Playgroud)

换句话说:[ "${-#*i}" != "$-" ]检查变量i的值中是否有an $-,即检查shell是否是交互式的。

换句话说,这是一种复杂且与 Bourne 不兼容的编写方式:

case $- in
  *i*) ...;;
  *) ...;;
esac
Run Code Online (Sandbox Code Playgroud)

  • 不过,它 _is_ [POSIX 兼容](http://pubs.opengroup.org/onlinepubs/009695399/utilities/xcu_chap02.html)。 (4认同)