39

In /etc/profile I see this:

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

What does ${-#*i} mean. I cannot find a definition of a parameter expansion starting ${-.

0

2 Answers 2

42

$- is current option flags set by the shell itself, on invocation, or using the set builtin command:

$ echo $-
himBH
$ set -a
$ echo $-
ahimBH

"${-#*i}" is syntax for string removal: (from POSIX documentation)

${parameter#[word]}

Remove Smallest Prefix Pattern. The word shall be expanded to produce a pattern. The parameter expansion shall then result in parameter, with the smallest portion of the prefix matched by the pattern deleted. If present, word shall not begin with an unquoted '#'.

${parameter##[word]}

Remove Largest Prefix Pattern. The word shall be expanded to produce a pattern. The parameter expansion shall then result in parameter, with the largest portion of the prefix matched by the pattern deleted.

So ${-#*i} remove the shortest string till the first i character:

$ echo "${-#*i}"
mBH

In your case, if [ "${-#*i}" != "$-" ] checking if your shell is interactive or not.

0
25

There is a shell parameter $-. In my case:

$ echo $-
himB

${-} is the same as $- exactly like ${foo} is the same as $foo.

#*i means: Delete (as little as possible; doesn't make a difference here) from the beginning of the variable value until (including) the first i.

$ echo "${-#*i}"
mB

In other words: [ "${-#*i}" != "$-" ] checks whether there is an i in the value of the $- variable, that is, it checks if the shell is interactive.

In other words, it's a convoluted and non-Bourne compatible way to write:

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

You must log in to answer this question.

Not the answer you're looking for? Browse other questions tagged .