Reputation: 8487
I recently saw the following line:
curl -fsSL https://deb.nodesource.com/setup_17.x | bash -
What is the difference between bash
and bash -
? I tried running both variants, and they seem to do the same thing.
man bash
didn't supply an answer either.
Upvotes: 1
Views: 152
Reputation: 16819
The commands are identical.
The author probably believes that passing -
as an argument will make bash read commands from stdin but bash will do that anyway.
In fact, the bash man-page explains that -
is equivalent to --
and terminates option processing:
-- 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 --.
Note that if there was something after the -
, then behaviour might be different. For example:
$ echo "echo foo" > ./-c
$ chmod +x ./-c
$ export PATH=.:"$PATH"
$ bash -c "echo bar"
bar
$ bash - -c "echo bar"
foo
$
Note also, it is not the case that using bash -
makes it a login shell. This can be demonstrated by adding something printable to ~/.bash_profile
:
$ export HOME=$(mktemp -d)
$ cd
$ echo "echo login shell" > .bash_profile
$ echo "echo hello" | bash
hello
$ echo "echo hello" | bash -
hello
$ echo "echo hello" | bash -l
login shell
hello
$
The meaning in the manpage of "A login shell is one whose first character of argument zero is a -" is that the command name starts with a hyphen:
$ cat .bash_profile
echo login shell
$ ln -s /bin/bash ./notLoginShell
$ ln -s /bin/bash ./-isLoginShell
$ export PATH=~:"$PATH"
$ echo "echo hello" | notLoginShell
hello
$ echo "echo hello" | -isLoginShell
login shell
hello
$
Addendum
Using bash -
may be a cargo-culted carry-over from a technique used historically to prevent a particular type of security exploit.
POSIX comments:
On systems that support set-user-ID scripts, a historical trapdoor has been to link a script to the name
-i
. When it is called by a sequence such as:sh -
or by:
#! usr/bin/sh -
the historical systems have assumed that no option letters follow. Thus, this volume of POSIX.1-2017 allows the single <hyphen-minus> to mark the end of the options, in addition to the use of the regular "
--
" argument, because it was considered that the older practice was so pervasive.
unix-faq explains:
suppose the script is called
/etc/setuid_script
, starting with:#!/bin/sh
Now let us see what happens if we issue the following commands:
$ cd /tmp $ ln /etc/setuid_script -i $ PATH=. $ -i
We know the last command will be rearranged to:
/bin/sh -i
But this command will give us an interactive shell, setuid to the owner of the script!
Fortunately this security hole can easily be closed by making the first line:
#!/bin/sh -
The
-
signals the end of the option list: the next argument-i
will be taken as the name of the file to read commands from, just like it should!
Upvotes: 4