ProgrammingThis forum is for all programming questions.
The question does not have to be directly related to Linux and any language is fair game.
Notices
Welcome to LinuxQuestions.org, a friendly and active Linux Community.
You are currently viewing LQ as a guest. By joining our community you will have the ability to post topics, receive our newsletter, use the advanced search, subscribe to threads and access many other special features. Registration is quick, simple and absolutely free. Join our community today!
Note that registered members see fewer ads, and ContentLink is completely disabled once you log in.
If you have any problems with the registration process or your account login, please contact us. If you need to reset your password, click here.
Having a problem logging in? Please visit this page to clear all LQ-related cookies.
Get a virtual cloud desktop with the Linux distro that you want in less than five minutes with Shells! With over 10 pre-installed distros to choose from, the worry-free installation life is here! Whether you are a digital nomad or just looking for flexibility, Shells can put your Linux machine on the device that you want to use.
Exclusive for LQ members, get up to 45% off per month. Click here for more info.
Hi:
A script may be written without the header '#!/bin/sh' or the equivalent path if it only contains internal commands. But I've run scripts containing external ones and without a header (which has a name for it).
Location: Northeastern Michigan, where Carhartt is a Designer Label
Distribution: Slackware 32- & 64-bit Stable
Posts: 3,541
Rep:
You insert the #!/whatever if your shell program is written for a specific shell; i.e., it incorporates functions unique to BASH, KornShell, C-Shell (does anyone actually use C-Shell anymore?) or whatever else and you want that program to run properly when you suspect or know that some other shell "flavor" is going to be used. For example, if you write a shell program to be used by cron, it will be executed by the Bourne shell by default unless you tell it differently (with, say, #!/bin/ksh).
As it happens though, /bin/sh on many systems is a symbolic link to /bin/bash:
Code:
whence -v sh
sh is a tracked alias for /bin/sh
ls -l /bin/sh
lrwxrwxrwx 1 root root 4 May 12 2011 /bin/sh -> bash*
what /bin/sh
/bin/sh:
Bash version 4.1.10(2) release GNU
Now I am not a BASH user (I prefer KornShell), so shell programs I write will always include
Code:
#!/bin/ksh
If your system looks the same as mine does (where /bin/sh is, in fact, /bin/bash), then "pound-bang" is not necessary as long as you stick with BASH grammar and syntax. Toss in a little C-Shell or KornShell grammar... oops!
Fact is, most of the Bourne-based shells (BASH, KornShell are two) are fully compatible with Bourne Shell grammar and syntax (BASH, after all, is an acronym for Bourne Again SHell) so, unless the default shell on the system you're working on or targeting is, say, C-Shell, there's usually no problem leaving out the "pound-bang" directive. It's good practice to include the "pound-bang" in any event just to cover your hiney (and not get telephone calls at three in the morning).
Going off on a little tangent, consider for a moment the vi text editor.
Back in the day, there was no such thing as visual anything. You edited files with ed or, later, ex (extended ed) on a text-based device of some sort (lots of those were TeleType "terminals"); on paper. As video terminals came into vogue (at a couple of thousand dollar each in some cases), Bill Joy, a smart guy, at Berkeley came up with a visual mode for ex -- thus the name, vi. vi was (and still is at least on Solaris) a symbolic link to ex and, when you typed vi and hit the carriage return, ex would start up in visual mode and there you went (the program would determine how it was started and set flags to operate in the proper mode).
That was BSD (Berkeley Software Distribution) and AT&T System 3 (and later System V) and all was well with the world. GNU went a different route (GNU is Gnu's Not Unix) and
Code:
ls -al /usr/bin/vi
lrwxrwxrwx 1 root root 5 May 12 2011 /usr/bin/vi -> elvis*
And what is elvis? Why it's "elvis - a clone of the ex/vi text editor," that's what.
And what's ex?
Code:
ls -al /usr/bin/ex
lrwxrwxrwx 1 root root 3 May 12 2011 /usr/bin/ex -> vim*
Why, it's vim running in text mode! Well, sorta; it's "vim - Vi IMproved, a programmers text editor."
I think that it's a good idea regardless to insert the "shebang" line at the top of a script. (The env command is very good for making "generic" shebangs.)
One good reason for doing this is that it will remind you that you really don't have to use shell scripting for much of anything. There are probably half-a-dozen "real" programming languages installed on your computer right now, with many more available as optional packages. By "'real' programming language," I am referring to systems which are specifically designed for building small- or large-scale programs, which shell-scripting (with the exception of the Korn shell) really is not.
"Tools For The Job" is a mantra for any sort of work that you might do, and Unix/Linux is awash with good tools, all of which (thanks to "shebang") can be used to build a command and the user will be none the wiser. When you are developing a new program, it's always a good idea to map it out and then consider, among the available languages that you know (or would like to learn ...), which system is most likely to give you "the most bang for the buck." You might find that nearly all of what you're doing can be done in just a few lines of original code, by heavily leveraging the prior work of others. ("A fully functional web-browser in one line of original code," for instance, done e.g. in Perl by specifying one use statement that magically incorporates thousands of lines of bulletproof pre-tested library material written by many others. Now, that's efficiency!)
Last edited by sundialsvcs; 08-02-2012 at 08:35 AM.
ls -al /usr/bin/ex
lrwxrwxrwx 1 root root 3 May 12 2011 /usr/bin/ex -> vim*
Why, it's vim running in text mode! Well, sorta; it's "vim - Vi IMproved, a programmers text editor."
We've come full circle.
I had kernel 2.2.16 and GNU, and did not understand why Elvis was not only in every movie a saw but in linux as well. I made an alias an got rid of Elvis. I have seen the old teletypes running a program of mine in an IBM mainframe. Later on, MS-DOS console text editor, edlin was the tool I used as a programmer, until somebody brought dbEdit, a visual editor. Very interesting post and my doubts completely vanished. Regards.
Hi:
A script may be written without the header '#!/bin/sh' or the equivalent path if it only contains internal commands.
This is both wrong and makes not sense (what 'internal commands'?). The default shell is used by the kernel ie /bin/sh.
Edit: well this is wrong: the kernel won't execute it (in modern unixes), but the execl* functions of c-runtime-library might still execute the script with the default /bin/sh shell.
Last edited by NevemTeve; 08-07-2012 at 08:03 AM.
Reason: Wrong information corrected.
The short answer is that if you don't have a shebang at the top of your script, it will be executed by whatever shell the user who's executing it is running. So if you don't have a #!/bin/bash at the top of the script, for example, any users running a bash shell will run your script with bash, any users running a tcsh shell will run your script with tcsh, etc. The shebang forces the system to process your script by what you set, regardless of what shell the user who's running it is using.
If you include any shell-specific commands in your script, you need to put a shebang at the top to tell whoever runs it what shell should be used, otherwise it will execute it with whatever shell the user is running, which may result in errors.
I can write a BASH script on a system without a shebang at the top, and as long as EVERYBODY who runs that script uses BASH, there won't be a problem. As soon as a ksh user tries to run it though, bad juju...
Last edited by suicidaleggroll; 08-06-2012 at 04:30 PM.
Note: in some unix'es (eg linux, AIX etc), the kernel won't execute a script without hash-bang (execve(2)), but if you use libc-functions (execl(3) and family), they will call '/bin/sh' if execve returns ENOEXEC error.
The short answer is that if you don't have a shebang at the top of your script, it will be executed by whatever shell the user who's executing it is running. So if you don't have a #!/bin/bash at the top of the script, for example, any users running a bash shell will run your script with bash, any users running a tcsh shell will run your script with tcsh, etc. The shebang forces the system to process your script by what you set, regardless of what shell the user who's running it is using.
If you include any shell-specific commands in your script, you need to put a shebang at the top to tell whoever runs it what shell should be used, otherwise it will execute it with whatever shell the user is running, which may result in errors.
I can write a BASH script on a system without a shebang at the top, and as long as EVERYBODY who runs that script uses BASH, there won't be a problem. As soon as a ksh user tries to run it though, bad juju...
For me on Mac OS X and Linux it’s always /bin/sh what is used as interpreter if the shebang ist left out. Even if I start it from inside a tcsh session.
LinuxQuestions.org is looking for people interested in writing
Editorials, Articles, Reviews, and more. If you'd like to contribute
content, let us know.