The concept originated with Dennis Ritchie:
BSD picked it up from Version 8 of Research Unix and made it popular.
What to Call the Concept
Eventually, the #! line came to be called the "sharpbang" line and sharpbang can still be found in some kernel source code. This was shortened to "shebang" somehow. I would have expected "shabang" but it seems that "shebang" is what most people use. A few people seem to use "hashpling". Apparently, SCO has a switch called "hashplingenable" which must be set at kernel build time to enable this feature. And I have been told that some folks use the term "hashbang". (Anyone for sharppling?)
Special Rules for Perl
Recall that multiple arguments on the #! line are often passed as a single argument. If perl is passed an argument like "-a -b". it will break it apart and act like "-a" and "-b" had been passed. Also perl does not ignore the #! line. Perl will inspect it and will turn on any switches it finds. This helps compensate for systems with a very short #! line limit. perl will scan a #! line until it finds the string "perl". Then it starts scanning for switches. During this scan, "-*" and "- " are ignored. If the #! line does not contain the string "perl", perl will process the #! line the way a Unix kernel would and thus invoke the proper interpreter.
Handling Different Paths
Let's say some systems have, for example, /opt/perl/bin/perl and /usr/local/bin/perl. How to write a perl script? My feeling is that it falls on the System Administrator to provide the needed commonality. I would put perl in /usr/local/bin. If the perl installation procedure puts perl in /opt/perl/bin/perl, that is fine... but then I would a symbolic link in /usr/local/bin pointing to the perl executable. Same thing with perl. So on all systems under my control "#! /usr/local/bin/python" is guaranteed to work or python is not available on that system. Same thing with perl, etc. It is rare for me to add a link to a directory like /usr/bin. But I will for do this for ksh and bash should an OS be missing either shell. And I always ensure that bash and ksh will work if stuff like /opt or /usr/local is unmounted. These shells are the only cases where I will override the installation procedure if I must. So on my systems stuff like this will work:
And until this stuff works, I do not consider the OS installation to be complete. Scripts imported from the outside world may need a tweak to run if they expect the interpreters elsewhere. But programs like "configure" will find perl if it is in /usr/local/bin. So this is my approach. But there are other ideas...
Another approach is to use a #! line that result in an intermediate program invoking the desired interpreter after a PATH search. The most frequently used example would be something like "#! /usr/bin/env perl". This assumes that env is in /usr/bin (not the case with, for example, Unicos, but my above comments apply to env and I would add the required links). It also assumes that perl is on the PATH somewhere. A more elaborate example is
And even more elaborate examples are in the book Programming Perl by Larry Wall, et al.
And the Posix Standard on this page checks in with
Quote:
Furthermore, on systems that support executable scripts (the "#!" construct), it is recommended that applications using executable scripts install them using getconf -v to determine the shell pathname and update the "#!" script appropriately as it is being installed (for example, with sed).
See the linked page for their suggested installation script.
The ksh expanded environment
Let's say that you use ksh exclusively and you have a script and you leave off the "#!". Your interactive ksh will try to exec the script and fail. So your interactive ksh with fall back to running your script as a ksh script. It does this by forking a copy of itself to create a subshell. This forked subshell can then, in effect, expand on the standard Unix concept of "environment". When a process exec's another process, the new program inherits a bunch of stuff, open files, current directory, and the ENVIRONMENT. The ENVIRONMENT is a set of strings which, by convention, take the form of variable settings, like: PATH=/usr/bin:/usr/local/bin. But the forked ksh subshell knows everything about the parent subshell. Early ksh version exploited this by having ways to export arrays, aliases, and functions. This requires avoiding the #! line and thus living with the problems this creates. Most sites strongly encourage the use of the #! line and this undermines the ksh expanded environment concept. And it confused beginners who saw stuff like exported aliases mentioned in the docs. Recent versions of ksh have retreated from the expanded environment concept. So my suggestion is to forget about ksh exported arrays, aliases, and functions and use that #! line.
These 4 Users Gave Thanks to Perderabo For This Post:
Hi,
I have a developer that is trying to start a script with sh "scriptname". In the script, he is specifying #!/usr/bin/ksh as the command interpreter. For some reason sh is ignoring the #!/usr/bin/ksh. We are running Solaris 8. Does anyone have any ideas what could be causing this? Here... (3 Replies)
I am using IBM AIX unix version 4.3.3.0.
In a directory there are many files with different patterns.
When I am trying to execute the command, ls -l with the file pattern, which have fewer files it gives the desired result. However when I am trying to execute the same command for file pattern,... (2 Replies)
Hi all,
below is the problem details:
ora10g@CNORACLE1>which ld
/usr/ucb/ld
ora10g@CNORACLE1>cd /usr/ccs/bin
ora10g@CNORACLE1>ln -s /usr/ucb/ld ld
ln: cannot create ld: File exists
ora10g@CNORACLE1>
how to link it to /usr/ccs/bin? (6 Replies)
Usually we use !/usr/bin/ksh at the start of the script.But if I am having this stuff in the scripts and calling one script from other its not working.What may be the reason behind it ?
xyz.ksh
#!/usr/bin/ksh
echo "Hi"
abc.ksh
#!/usr/bin/ksh
echo "I am fine"
ksh xyz.ksh
Its... (4 Replies)
Hi,
I am getting the below error message When i am trying to delete the files from the directory.Could you please guide me?
rm *.aud
ksh: /usr/bin/rm: 0403-027 The parameter list is too long.
and
find /oracle/admin/testP/adump/*.aud -mtime +5 -exec rm {} \;
ksh: /usr/bin/find:... (3 Replies)
Q1. I understand that /usr/local/bin means I can install/uninstall stuff in here and have any chance of messing up my original system files or effecting any other users. I created this directory myself.
But what about the directory I didn't create, namely /Users/m/bin? How is that directory... (1 Reply)
I saw one script using the first line as below
/usr/bin/ksh -E
I have used -x for debug but couldn't find what is this -E option for ?
Pls let me know what is this -E used for
Thanks
RL (1 Reply)
I'm not sure if this is the default behavior for the ld command, but it does not seem to be looking in /usr/local/lib for shared libraries.
I was trying to compile the latest version of Kanatest from svn. The autorgen.sh script seems to exit without too much trouble:
$ ./autogen.sh
checking... (2 Replies)