blindly passing on shell flags ($- )?

Polytropon freebsd at
Wed Apr 9 20:22:43 UTC 2014

On Wed, 09 Apr 2014 13:28:07 -0600, Gary Aitken wrote:
> As I read the man page for sh and bash, the variable $- is supposed to
> represent the flags passed to the script.  However, whenever I look at
> it it is empty.

No. Those "flags" (command line arguments or parameters)
are represented in $* and $@.

> Reading between the lines, it appears one may have to call getopts
> so the shell knows what the flags are, but that doesn't seem to change
> what's available in $-.

The getopts mechanism is for command line parameters, usually
in the form -[a-z0-9]. 

> Fundamentally, I want to add an arg (not a flag) and pass the whole
> shebang on to another script.  Seems like this should be trivial but I
> can't get it to work.

You just need to call the new script with $@ and append (or
prepend) your additional parameters.

> The flags seem to be treated as a normal arg.

Flags _are_ normal args (when we agree that "flag" means a
command line argument, usually called an option, that starts
with a - and in most cases is just one letter). :-)

> The only way I seem to be able to get what I want is to interpret all 
> the flags in the first script and pass them explicitly to the second,
> which is what I'm trying to avoid.

True, that doesn't sound like a good solution.

> What am I missing?

The exact wording of the manual. :-)

Allow me to quote from "man sh":

     $-      (hyphen) Expands to the current option flags (the single-letter
             option names concatenated into a string) as specified on invoca-
             tion, by the set built-in command, or implicitly by the shell.

This does _not_ refer to positional parameters (command line
parameters) which are usually represented in $* and $@ (with
the difference that $@ honors "multi word arguments" being
_one_ argument, whereas $* does not do so, as explained in
the manual as well).

Short demonstration:

% ./ "foo bar" -a baz
$@ is: foo bar -a baz
$* is: foo bar -a baz
$- is: P
$# is: 3
$0 is: ./
$1 is: "foo bar"
$2 is: "-a"
$3 is: "baz"
$4 is: ""

% bash "foo bar" -a baz
$@ is: foo bar -a baz
$* is: foo bar -a baz
$- is: hBP
$# is: 3
$0 is:
$1 is: "foo bar"
$2 is: "-a"
$3 is: "baz"
$4 is: ""

As you can see, I have manually "set -P" in
which is reflected as "P" in the $- variable. Of course it
doesn't have any effect here. When called via bash, you
can see that bash has added the flags h and B.

% cat 

set -P

echo '$@ is:' $@
echo '$* is:' $*
echo '$- is:' $-
echo '$# is:' $#
echo '$0 is:' $0
echo '$1 is: "'$1'"'
echo '$2 is: "'$2'"'
echo '$3 is: "'$3'"'
echo '$4 is: "'$4'"'

exit 0

Magdeburg, Germany
Happy FreeBSD user since 4.0
Andra moi ennepe, Mousa, ...

More information about the freebsd-questions mailing list