[sf-lug] 'source' works but 'shebang' doesn't

Alex Kleider akleider at sonic.net
Fri Aug 26 14:11:34 PDT 2016


On 2016-08-26 11:44, Akkana Peck wrote:
> Alex Kleider writes:
>> Mystery:
>> 
>> alex at X301n3:~/Py/Backup/Backup$ cat ./path.sh
>> #!/bin/bash
>> # Add current working directory to the PYTHONPATH.
>> export PYTHONPATH="${PYTHONPATH:+$PYTHONPATH:}$(pwd)"
> [ ... ]
>> I don't understand how
>> source ./path.sh
>> does the job but
>> ./path.sh
>> does not!
>> 
>> Can anyone explain?
> 
> It is working -- just not the way you expect.
> 
> When you run ./path.sh, it looks at the shebang and runs the shell
> you specify there -- as a subshell of the one you're typing in. That
> subshell reads the lines of the script and exports PYTHONPATH in
> that subshell, and when it's done reading the script, it exits,
> leaving you in your original shell, which still has its original
> environment.
> 
> When you source ./path.sh, "source" explicitly tells your current
> shell to run the commands in the script *in the current shell*.
> So this time, export modifies your current shell rather than
> executing a subshell.

Of course!  I should have known that.  Thanks for taking the time to 
explain.
It's much appreciated.

> 
> Source also ignores the shebang line, since you've explicitly told
> it you want your current shell to execute it, not some other
> program. Even if you have a shebang line that says something like
> #!/usr/bin/env python, with source your shell will try to execute it
> as a shell script. Try it! It's especially amusing if your python
> program starts with import lines: I'll leave the question of what
> it's doing in that case as a fun exercise for the reader.

Exercise completed- ... and understood:-)

My tentative conclusions:

source myscript # use existing shell to interpret code in file myscript 
ignoring lines after '#' including '#!'.  Changes to environment will 
persist in the existing shell.

./myscript # another shell is spawned to open the file as if it were a 
command- if it finds a shebang, the appropriate program is commissioned 
to take over, otherwise, the spawned shell continues to read and 
execute.  Changes to environment will pertain to the spawned shell only 
and so will be lost when the script is finished.

As I write the above, another thought comes to mind: in the latter case-
If the spawned shell finds a shebang referring to bash, does the spawned 
shell then spawn another instance of bash to run the script?




More information about the sf-lug mailing list