Can anybody explain to me what the shell does in the two examples A) and B) below?
It obviously behaves differently, but I can't find out why the output is different.
Example:
Let's have a script in our current directory named bla.sh
with only one command:
echo ${0##/*} hello
A)
Started as: ./bla.sh
gives: ./bla.sh hello
B)
Started as: . bla.sh
gives: -bash hello
Since I use this in a script, the second output (because of the "-" in front of the -bash) kills the command. Of course, a simple --
before the ${...}
helped, but I would love to understand what causes the output in the first place.
I love bash. And vi[m]. But I digress…
Best Answer
Here, the command is
./bla.sh
. This makes the shell look for an executable namedbla.sh
in the current directory, then ask the kernel to run it as a normal program, in a separate process from the shell. (It doesn't matter ifbla.sh
is abash
script, aperl
orpython
one, or a compiled binary.)Here, the command is
.
(akasource
), a built-in command of your shell. It makes the shell look for a file namedbla.sh
in the system path ($PATH) and interpret the contents as if they were typed by you; all this is done in the same process as the shell itself (and therefore can affect the shell's internal state).This of course only works when
bla.sh
contains commands for thebash
shell (if that's the one you are currently using), it won't work forperl
scripts or anything else.(This is explained in
help .
andhelp source
too.)As
.
and./
are completely different things (a command vs part of a path), they can be combined, of course – using. ./bla.sh
would "source" a filebla.sh
in the current directory.Usually it is best to use the
./bla.sh
method. Only~/.bashrc
,~/.profile
and such files are usually sourced, because they are supposed to modify the current environment.