Take the 2-minute tour ×
Unix & Linux Stack Exchange is a question and answer site for users of Linux, FreeBSD and other Un*x-like operating systems.. It's 100% free, no registration required.

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 ${-.

share|improve this question
6  
Short for a random swearword ;-) –  vonbrand May 13 at 19:30
add comment

2 Answers 2

up vote 29 down vote accepted

$- 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 GNU bash manual)

${parameter#word}
${parameter##word}

The word is expanded to produce a pattern just as in filename expansion (see     
Filename Expansion). If the pattern matches the beginning of the expanded 
value of parameter, then the result of the expansion is the expanded value 
of parameter with the shortest matching pattern (the ‘#’ case) or the
longest matching pattern (the ‘##’ case) deleted. If parameter is ‘@’ or 
‘*’, the pattern removal operation is applied to each positional parameter 
in turn, and the expansion is the resultant list. If parameter is an array 
variable subscripted with ‘@’ or ‘*’, the pattern removal operation is 
applied to each member of the array in turn, and the expansion is the
resultant list.

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.

share|improve this answer
2  
Because I wildly misread the check. Deleting my comment. –  Etan Reisner May 13 at 17:58
    
Thanks for the clear explanation. –  Pete May 15 at 11:31
add comment

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
share|improve this answer
    
It is POSIX-compatible, though. –  grawity May 14 at 12:46
add comment

Your Answer

 
discard

By posting your answer, you agree to the privacy policy and terms of service.

Not the answer you're looking for? Browse other questions tagged or ask your own question.