Too many shebang (script declaration) lines --- any way to reduce their amount?
Even though your project may now be solely consisting of 50 Bash scripts, it will sooner or later start accumulating scripts written in other languages such as Perl or Python (for the benefits that these scripting languages have that Bash does not have).
Without a proper #!
-line in each script, it would be extremely difficult to use the various scripts without also knowing what interpreter to use. It doesn't matter if every single script is executed from other scripts, this only moves the difficulty from the end users to the developers. Neither of these two groups of people should need to know what language a script was written in to be able to use it.
Shell scripts executed without a #!
-line and without an explicit interpreter are executed in different ways depending on what shell invokes them (see e.g. the question Which shell interpreter runs a script with no shebang? and especially Stéphane's answer), which is not what you want in a production environment (you want consistent behaviour, and possibly even portability).
Scripts executed with an explicit interpreter will be run by that interpreter regardless of what the #!
-line says. This will cause problems further down the line if you decide to re-implement, say, a Bash script in Python or any other language.
You should spend those extra keystrokes and always add a #!
-line to each and every script.
In some environments, there are multi-paragraph boilerplate legal texts in each script in each project. Be very happy that it's only a #!
-line that feels "redundant" in your project.
You misunderstand the point of #!
. It's actually a directive to the operating system to run this program under the defined interpreter.
So a script could being #!/usr/bin/perl
and the resulting program can be run as ./myprogram
and the perl interpreter could be used. Similar #!/usr/bin/python
would cause a program to run under python.
So the line #!/bin/bash
tells the OS to run this program under bash.
Here's a example:
$ echo $0
/bin/ksh
$ cat x
#!/bin/bash
ps -aux | grep $$
$ ./x
sweh 2148 0.0 0.0 9516 1112 pts/5 S+ 07:58 0:00 /bin/bash ./x
sweh 2150 0.0 0.0 9048 668 pts/5 S+ 07:58 0:00 grep 2148
So, despite my shell being ksh, the program "x" runs under bash because of the #!
line, and we can see that explicitly in the process listing.
On .sh
What is bad is the .sh
at the end of the file-name.
Imagine that you rewrite one of the scripts in python.
Well now you have to change the first line to #!/usr/bin/python3
this is not so bad, as you had to change every other line of code in the file as well. However you also have to change the file name from prog.sh
to prog.py
. And then you have to find everywhere in the other scripts, and all of your user scripts (the ones that you did not even know existed), and change them to use the new script. sed -e 's/.sh/.py/g'
may help for the ones you know about. But now your revision control tool is showing a change in lots of unrelated files.
Alternatively do it the Unix way and name the program prog
not prog.sh
.
On #!
If you have the correct #!
, and set the permission/mode to include execute. Then you don't need to know the interpreter. The computer will do it for you.
chmod +x prog #on gnu adds execute permission to prog.
./prog #runs the program.
For non gnu systems read the manual for chmod
(and learn octal), maybe read it anyway.