I was looking through the /etc/profile file and I noticed a strange if statement. Can someone let me know what this means?
I'm referring to the second if statement if [ "${-#*i}" != "$-"] .
for i in /etc/profile.d/*.sh /etc/profile.d/sh.local ; do
if [ -r "$i" ]; then
if [ "${-#*i}" != "$-" ]; then
. "$i"
else
. "$i" >/dev/null
fi
fi
done
CodePudding user response:
$- outputs the list of options the shell is running with. i in the output of $- means that the shell is interactive.
${var#expr} removes from the value of var the part from the left that matches the expr. expr is a glob. In the case expr is not matched, the original string is just outputted.
So ${-#*i} gets the value of $- and removes the part from the left that matches *i.
For example: $- is himBHs. The part that matches *i from the left is hi. So hi from the left will be removed. So ${-#*i} will be mBHs.
https://www.gnu.org/software/bash/manual/html_node/Shell-Parameter-Expansion.html https://www.gnu.org/software/bash/manual/html_node/The-Set-Builtin.html
Can someone let me know what this means?
I believe it's an odd way of checking if the session is interactive.
I would very much prefer and recommend case "$-" in *i*) for readability and portability. Also https://www.gnu.org/software/bash/manual/html_node/Is-this-Shell-Interactive_003f.html .
CodePudding user response:
It's a hack comparison that seems intended to work with shells not having the == operator and the pattern matching feature. It relies on checking if $- remains the same after i and everything that comes before it are attempted to be stripped from the beginning of its value. Unfortunately it might still not work as intended because even the != operator is not common. The ! operator along with = should be used instead.
