Regards,
Troy
Changing it to -x will turn on echo mode echoingg all lines executed to
stdout.
Commonly used for debigging startup scripts during the boot process.
MickG
According to posix (and assuming the "sh" in question is posix),
"The following operands shall be supported:
-
A single <hyphen> shall be treated as the first operand and then
ignored. If both '-' and "--" are given as arguments, or if other operands
precede the single <hyphen>, the results are undefined."
I can't imagine why that should be necessary though.
Just leave the #! as it is and add a shell statement set -x to the code.
>
> According to posix (and assuming the "sh" in question is posix),
>
> "The following operands shall be supported:
>
> -
> A single <hyphen> shall be treated as the first operand and then
> ignored. If both '-' and "--" are given as arguments, or if other operands
> precede the single <hyphen>, the results are undefined."
>
> I can't imagine why that should be necessary though.
The typical more or less pathological cases; shell files whose name start
with '-' in this case.
Janis
I guess there is a subtle difference between "-" and "--"? Both turn
off
further "option" processing but one ignores itself and the other
doesn't?
I wrote this little script to test passing "-" and "--" and seeing
slightly
different results:
cat /tmp/echoargs
#!/sbin/sh
echo at start:
echo '$#='$#
echo '$*='$*
while getopts a c
do
case $c in
a) echo $c;;
\?) echo "Usage: `basename $0` $USAGE" >&2;exit 2;;
esac
done
shift `expr $OPTIND - 1`
echo after getopts:
echo '$#='$#
echo '$*='$*
tc324570@triton% /tmp/echoargs -- -a
at start:
$#=2
$*=-- -a
after getopts:
$#=1
$*=-a
tc324570@triton% /tmp/echoargs - -a
at start:
$#=2
$*=- -a
after getopts:
$#=2
$*=- -a
tc324570@triton% /tmp/echoargs -a
at start:
$#=1
$*=-a
a
after getopts:
$#=0
$*=
I'm not sure how to interpret the results yet...
Troy
Slightly better script:
cat /tmp/echoargs
#!/sbin/sh
echo at start:
echo '$#='$#
echo '$*='$*
while getopts ab c
do
case $c in
a) echo "found option:"$c;;
b) echo "found option:"$c;;
\?) echo "Usage: `basename $0` $USAGE" >&2;exit 2;;
esac
done
shift `expr $OPTIND - 1`
echo after getopts:
echo '$#='$#
echo '$*='$*
tc324570@triton% /tmp/echoargs -a -- -b
at start:
$#=3
$*=-a -- -b
found option:a
after getopts:
$#=1
$*=-b
tc324570@triton% /tmp/echoargs -a - -b
at start:
$#=3
$*=-a - -b
found option:a
after getopts:
$#=2
$*=- -b
tc324570@triton% /tmp/echoargs -a -b
at start:
$#=2
$*=-a -b
found option:a
found option:b
after getopts:
$#=0
$*=
I think I understand more clearly what the difference is..."-" doesn't
"disappear" and
"--" does from the post-processed "getopts" list of arguments.
Thanks again,
Troy
See section OPERANDS in
http://www.opengroup.org/onlinepubs/9699919799/utilities/sh.html
« A single <hyphen> shall be treated as
» the first operand and then ignored. »
« The positional parameters [...] shall be
» set to arguments, if any. »
The hyphen in your example comes /after/ command_name, it is a
positional parameter.
The shell is invoked as: /bin/sh /tmp/echoargs -a - -b
The 'ignored hyphen' would be: /bin/sh - /tmp/echoargs -a - -b
(first '-' ignored, second '-' is parameter)
--
printf -v email $(echo \ 155 141 162 143 145 154 142 162 165 151 \
156 163 155 141 100 171 141 150 157 157 056 143 157 155|tr \ \\\\)
# Live every life as if it were your last! #
It makes it a login shell.
from man bash:
INVOCATION
A login shell is one whose first character of argument
zero is a -, or one started with the --login option.
Sid
Note that in "sh -", argument zero is "sh". The "-" argument is argument one,
not zero.
When - is an argument, it means the same thing as --. I.e. "the remaining
arguments, if any, are not options".
To make a shell with an argument zero which starts with "-", you use
an exec system call, e.g.:
char * const argv[] = { "-sh", 0 }: /* argv is null terminated */
execv("/bin/sh", argv);
This execs a shell with no arguments, which thinks its name is "-sh".
> On 2009-10-02, Sidney Lambe <sidne...@nospam.invalid> wrote:
>
>> troycamp...@gmail.com <troycamp...@gmail.com> wrote:
>>
>>> I have a script that has "#!/sbin/sh -" at the top and
>>> wondering what the single "-" means in particular? I
>>> understand "/sbin/sh" is the statically linked shell but
>>> want to add debug options but concerned about changing
>>> functionality if I change it to "-x" instead of just "-".
>>>
>>> Regards, Troy
>>
>> It makes it a login shell.
>>
>> from man bash:
>>
>> INVOCATION
>>
>> A login shell is one whose first character of argument zero is
>> a -, or one started with the --login option.
>
> Note that in "sh -", argument zero is "sh". The "-" argument is
> argument one, not zero.
The command name is always "argument 0" or "positional paramater
"$0".
When you call/invoke bash with a single dash for an argument
it makes it a login shell.
This is easy to test. Why don't you do so and then, armored
with real knowledge, get back to us with a report.
[delete]
Sid
That, so far, doesn't contradict anything I've written.
> When you call/invoke bash with a single dash for an argument
... then that argument is not $0. Oops! It's argument 1 to the process,
and one which does not become any positional parameter at all.
> it makes it a login shell.
Why are you writing about bash? This thread isn't specifically about the GNU
implementation.
Be that as it may, you are misinformed about bash. The following is copied
*verbatim* from the (nroff-formatted) man page for GNU bash 3.0:
-- A -- signals the end of options and disables further option
processing. Any arguments after the -- are treated as file-
names and arguments. An argument of - is equivalent to --.
The argument which makes bash a login shell is -l. Another quote
from the bash 3.0 man page:
-l Make bash act as if it had been invoked as a login shell
(see INVOCATION below).
> This is easy to test. Why don't you do so
Because I can read and understand specifications.
> to us with a report.
I doubt there is anyone here who would care to be named as a member of any
group that you call ``us''.
Earlier this week I read some admonishments in this newsgroup against
replying to one Sidney Lambe.
Now I see why!
I won't bite again.
Yeh. There are some technocratic bullies on this group who have
tried to push me around and failed.
I see that you are made in the same mold, refusing to accept
even what the bash man pages says as fact and trying to shove
your own notions down my throat.
Sorry. You are wrong.
And a dickhead.
I won't miss you a bit.
Sid
[...]
> When you call/invoke bash with a single dash for an argument
> it makes it a login shell.
$ bash
$ shopt login_shell
login_shell off
$ exit
exit
$ bash -l
$ shopt login_shell
login_shell on
$ exit
logout
$ bash -
$ shopt login_shell
login_shell off
$ exit
exit
> Evergreen <sidne...@nospam.invalid> wrote:
>
> [...]
>
>> When you call/invoke bash with a single dash for an argument it makes
>> it a login shell.
...
>
> $ bash -
> $ shopt login_shell
> login_shell off
> $ exit
> exit
How dare you! You, you, shopt puppet!
:)
What is all that bullshit about?
Man bash:
"INVOCATION A login shell is one whose first character of argument
zero is a -, or one started with the --login option."
I've been calling login shells with "-" in scripts, on the commandline,
and in configuration files, since I first started using Linux.
They are very obviously login shells because they read the user's
~/.bashrc.
There sure a lot of stupid people on this group. (or one stupid person
hiding behind a lot of different names)
Sid
> "INVOCATION A login shell is one whose first character of argument zero
> is a -, or one started with the --login option."
Sid, there is a major hint in the sentence you're quoting here,
will you try and enjoy the experiment of having a bonus
hint about that hint you were just bringing to you?
If so, just type:
$ echo $0
-bash
and then, read again, slowly, the part about "argument zero is a -".
Lessons about the rest of your hint (that part which begins with an "OR")
will take place shortly after you'll fully manage the understanding
of your previously quoted knowledge.
Have a nice year 2010, see you next turn.
The discussions about invoking the shell (not just bash(1)!) as
a login shell if $0 has an initial dash character, as well as
noting that a single dash is specifically allowed by sh(1) as
synonymous to "--", the special option recognized by
getopt(), getopts(), and AST optget(), are both true. HOWEVER,
the real reason that a dash is conventionally added to the
hash-pling line, is to prevent the kind of situation exemplied
by what would happen if a script named "-x" (for instance)
was exec'ed.
Along with the programming idioms once used to mitigate the
grievious security hole possible because sh(1) used IFS to
determine word separation in scripts, that is: "IFS=x sh -e
exit" runs command "e" with command line argument "it"!)
... these two conventions comprise a real trip down memory
lane. Modern scripters still use various programming idioms
without knowing why.
=Brian
Another quote --still from the bash(1) manpage, still from the INVOCATION
section-- might be interesting in this case:
When an interactive shell that is not a login shell is started, bash
reads and executes commands from ~/.bashrc, if that file exists.
> There sure a lot of stupid people on this group. (or one stupid person
> hiding behind a lot of different names)
Agreed. At least one. Surely.
Regards,
Kees.
--
Kees Theunissen.
>They are very obviously login shells because they read the user's
>~/.bashrc.
And there you're wrong.
Interactive bash will *always* read ~/.bashrc.
A login shell reads:
~/.bash_profile
or
~/.profile
/bin/bash -
doesn't make a login shell.
Casper
--
Expressed in this posting are my opinions. They are in no way related
to opinions held by my employer, Sun Microsystems.
Statements on Sun products included here are not gospel and may
be fiction rather than truth.
Well, it's worst than that login shells don't read ~/.bashrc at all
(that's why you often source .bashrc from the .bash_profile)
From man bash:
"When an interactive shell that is not a login shell
is started, bash reads and executes commands from ~/.bashrc, if that file exists."
--
pgas @ SDF Public Access UNIX System - http://sdf.lonestar.org
Deliberately so, I suspect. Stupidity like this can only be contrived.
The '$' represents a user prompt, the other lines are shell output.
The three examples are invocations of bash which demonstrate the
differences in the shell's login status when provided with, in order
of appearance: no arguments, the -l option and a single dash.
In each example the shopt builtin is used to examine the login_shell
variable which is set by bash to reflect its login/non-login state.
This variable is not user-modifiable.
The first two examples show the expected output from a non-login and
a login shell respectively.
The third example disproves your claim that running bash as "bash -"
produces a login shell.
D 21:[Sidney Lambe] +->
9! D 200 34:[Kaz Kylheku ] | `->
10! D 100 40:[Evergreen ] | `->
11! D 200 70:[Kaz Kylheku ] | +->
12! D 100 89:[Sidney Lambe] | | `->
13! D 200 24:[Dave Gibson ] | `->
14! D 100 17:[Loki Harfagr] | +->
15! D 100 20:[Dave Gibson ] | | `->
16! D 100 47:[Sidney Lambe] | `->
17! D 200 19:[Loki Harfagr] | +->
18! D 200 61:[Kees Theunis] | +->
19! D 200 26:[Casper H.S ] | +->
20! D 100 20:[pgas ] | | +->
21! D 100 9:[Kaz Kylheku ] | | `->
22! D 200 45:[Dave Gibson ] | `->
23 D 26:[bsh ] `->
What a bunch of petty and ego-swollen jerkoffs.
Any idiot can determine in two seconds what the truth
is here, and only one person needed to point it out.
Yet we have this whole list of people who got their knickers
all in a twist over this silly matter and some even posted
more than once and even became abusive in the process.
You just don't want petty and small-minded and mean
and ego-swollen jerkoffs working on your computers.
Computers require clear-thinking and dispassionately
rational and controlled personalities who can leave
their egos at home.
What we have here are wannabees playing the role
on the usenet...
Sid
It's a security mechanism in this case. There is a danger
that user arguments to a shell script will be interpreted as
options to the shell. Originally an argument of a single
dash was the separator between options and arguments
(please don't ask me to define the difference :-), later
"--" was chosen as a better separator (some utilities
treat a single dash as an argument meaning "standard
input). To support older shell scripts, newer shells
can correctly interpret either a single or double
dash.
Using this in the she-bang prevents accidental or
malicious false interpretation of user supplied
arguments.
(It's not a serious problem; the she-bang mechanism
adds an initial argument of the pathname of the script,
and in general, the first argument that doesn't start
with a dash means the end of options. But this isn't
universal---the whole she-bang mechanism is not
standardized anywhere---so adding a dash can't
hurt and may help. Especially if you use a
she-bang line of ``#!/bin/sh -'', since you don't
always know which shell that will be.)
As another has posted, don't change that line;
add ``set -x'' near the top of the script instead.
--
Wayne
> D 21:[Sidney Lambe] +->
> 9! D 200 34:[Kaz Kylheku ] | `->
> 10! D 100 40:[Evergreen ] | `->
> 11! D 200 70:[Kaz Kylheku ] | +->
> 12! D 100 89:[Sidney Lambe] | | `->
^^^^^^^^^^^^
[snip]
> What a bunch of petty and ego-swollen jerkoffs.
What a fucking dickhead. At least read what you're posting before hitting
"send".
Why do you keep changing your name and trying to imitate a bitchy
teen-age girl having a bad day in special class?
I mean, when are you going to get the balls to post under just
one alias and stand behind your words like a man.
If you'd like to try, I know a good surgeon.
You know that you are human scum.
Sid
> It's a security mechanism in this case. There is a danger
> that user arguments to a shell script will be interpreted as
> options to the shell. Originally an argument of a single
> dash was the separator between options and arguments
> (please don't ask me to define the difference :-), later
> "--" was chosen as a better separator [...]
Anecdote: "originally", it was even a different story...
In the following I dont' distinguish options to the shell from
those to the "set" built-in. They are identical where it makes
sense.
Version 7
- The V7 shell doesn't know "--", yet.
- But even "-" is not intended to terminate options. It turns off
especially -x and -v and is documented as such. ("+" to turn off
an option is not available until the next release on System III.)
- Traditional shells accept options only combined (set -eu) and not
separated (set -e -u). Thus you can abuse "-" to set arguments
with leading dashes:
set - -argument
But if -x or -v were active before, you would have to set them
again now.
- "#!/bin/sh -" works the same way. But you even wouldn't notice
the abuse, because it's not in the middle of a script where options
could have been set earlier.
- There's also a bug about "-": The code wrongly triggers for the
leading dash in any option, because the check for a terminating \0
is missing. Thus you have to set -x or -v again if you subsequently
set any other option.
System III
- System III introduces "--" to explicitly end options.
Thus, set now works correct, e.g., "set -eu -- -firstargument".
- The bug from above is gone (recognizing any option also as "-").
- System III also introduces + to turn off a respective option.
- The behaviour for a single "-" to turn off -x and -v is not
documented anymore. But it remains unchanged, apparently by
accident (because due to "+" it has become useless.)
- Thus "#!/bin/sh -" still works. The correct way is
"#!/bin/sh --" but this is not compatible to the V7 shell.
After all, "-" seems to be used until today.
Solaris
- Ironically, there's an error in the Solaris manual about "--"
since at least 5.8 (but not since SVR4). One dash in the description
got lost and now it tells that "-" does not change any of the flags.
As "-" still can be abused this way, this error might have slipped through.