In my Oracle Linux box, I found a block of script in /etc/profile
that is hard to figure out:
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
My question is the variables in the if statement ${-#*i}
and $-
. What does that mean? And why should add an else statement to redirect output? Thanks!
$-
is a variable which stores the current options set by the shell .
${-#*i}
is using substring removal to remove the shortest match to the pattern *i
from the beginning of the variable. So if $-
has the value abcifOO
then ${-#*i}
would be fOO
. (You can read more about bash substrings here.)
This means that the test
[ "${-#*i}" != "$-" ]
will be true if the variable $-
contains the option i
, which means interactive mode is switched on.
All together this means that the output will only be redirected to /dev/null
if you are in interactive mode.
It's checking whether the shell is interactive. The current shell's options are in $-
and if removing anything followed by i
yields a different result, it means that i
was among the flags.
This would be a lot more readable and idiomatic, though:
case $- in *i* ) ... ;; esac
Also, it would be better to do the check once, outside the loop.
What does
$-
mean?
From the manual:
-
(A hyphen.) Expands to the current option flags as specified upon invocation, by the set builtin command, or those set by the shell itself (such as the
-i
option).
When you're running bash
interactively , then $-
might exapnd to something like:
himBH
When you're executing a script, $-
wouldn't have i
(apart from some other flags above).
What does
${-#*i}
mean?
Saying ${-#*i}
causes the shortest match of *i
from the beginning of the expansion of $-
to be deleted. (Refer to Shell Parameter Expansion .)
In short, the inner if
conditional in the example implies that while in the interactive mode the following is executed:
. "$i" >/dev/null 2>&1
and in the non-interactive mode, the following:
. "$i"
Just to add up a little more detail about $-. if you try to type in your terminal
[root@zee ~]# echo $-
himBH
Those appear to be shell 'set' values
Snippets from info bash --index-search=set
'-h'
Locate and remember (hash) commands as they are looked up for execution. This option is enabled by default.
'-m'
Job control is enabled (*note Job Control::).
'-B'
The shell will perform brace expansion (*note Brace Expansion::). This option is on by default.
'-H'
Enable '!' style history substitution (*note History Interaction::). This option is on by default for interactive shells.
Using +' rather than
-' causes these options to be turned off. The options can also be used upon invocation of the shell.
The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.