Skip site navigation (1)Skip section navigation (2)
Date:      Wed, 9 Apr 2014 22:21:28 +0200
From:      Polytropon <freebsd@edvax.de>
To:        Gary Aitken <garya@dreamchaser.org>
Cc:        FreeBSD Mailing List <freebsd-questions@freebsd.org>
Subject:   Re: blindly passing on shell flags ($- )?
Message-ID:  <20140409222128.9a323764.freebsd@edvax.de>
In-Reply-To: <53459F47.6080407@dreamchaser.org>
References:  <53459F47.6080407@dreamchaser.org>

next in thread | previous in thread | raw e-mail | index | archive | help
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:

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

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


As you can see, I have manually "set -P" in sh-opt-test.sh
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 sh-opt-test.sh 
#!/bin/sh

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



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



Want to link to this message? Use this URL: <https://mail-archive.FreeBSD.org/cgi/mid.cgi?20140409222128.9a323764.freebsd>