Sponsored Content
Top Forums UNIX for Beginners Questions & Answers Answers to Frequently Asked Questions Tips and Tutorials The Whole Story on #! /usr/bin/ksh Post 302112877 by Perderabo on Saturday 31st of March 2007 07:42:51 PM
Old 03-31-2007
The Whole Story on #! /usr/bin/ksh

Introduction

Originally, we only had one shell on unix. When ran a command, the shell would attempt to invoke one of the exec() system calls on it. It the command was an executable, the exec would succeed and the command would run. If the exec() failed, the shell would not give up, instead it would try to interpret the command file as if it were a shell script. This works fine as long as there is only one shell on the system. But what if you are using one shell as your interactive and want to run a script written in another shell's language?

This is where the #! trick comes in. The idea of using # to represent a comment originated with csh and was quickly added to the bourne shell. Now all shells know to ignore stuff after a #. So we can add a leading line something like "#! /usr/bin/ksh". To the shell this line is just a comment. But if the kernel tries to execute a file with this line, it will exec the specified interpreter and pass the script to it. So shell scripts become executable pretty much like real executables are. Now when a shell tries to exec a shell script, it succeeds.

What if you leave off the #! line? Well, the kernel exec will fail. Your average shell will then try to run the script itself. A few shells will try to inspect the script to try to guess the language. This is not good. You may be running ksh as your interactive shell and writing ksh scripts. If you later switch to bash as an interactive shell, some of your scripts may continue to run while others may fail. Also the line is a comment that provides an important clue to a programmer who looks at the script to understand it. Knowing which language the author is attempting to use is a big help.

While I have used the term "shell", actually this technique can be used with many programs that are not shells. Here is a "script" to display a multiline message:
Code:
#! /usr/bin/cat
Line 1
Line 2 
Line 3

This will display that "#! /usr/bin/cat" line, but other than that, it works fairly well.

Passing an Argument

You can pass a single argument like this:
#! /usr/local/bin/perl -w
But, in general, you are limited to one argument. On most systems, a line like: "#! /some/interpreter -a -b" will result in "-a -b" being passed as a single argument. However, the single argument is not limited to starting with a hyphen. We can improve on our message script:
Code:
#! /usr/bin/sed 1d
Line 1
Line 2 
Line 3

Example

Let's put all of this together with an example. Here is a perl script that I will call perlargs:
Code:
#! /usr/local/bin/perl -w

#! /usr/local/bin/perl -w
print "script name is ", $0, "\n";
while (@ARGV) {
        $ARGV = shift @ARGV;
        print "argument ", $i++,  " is ", $ARGV, "\n";
}

system "ps -f -ww";


The -w asks perl issue warning messages. The script simply displays its arguments, then runs the ps command. When I run it, I get:
Code:
$ ./perlargs one two three
Name "main::i" used only once: possible typo at ./perlargs line 10.
script name is ./perlargs
argument 0 is one
argument 1 is two
argument 2 is three
                 UID        PID   PPID    STIME TTY     TIME CMD
                 perderabo   69      1 17:47:28 n01  0:00.24 /bin/ksh -l
                 perderabo  201     69 18:28:22 n01  0:00.03 /usr/local/bin/perl -w ./perlargs one two three
                 perderabo 2055    201 18:28:22 n01  0:00.01 ps -f -ww
$

Notice that the perl process was called with 5 arguments. The 2nd argument is the name of the script. It is up to the perl process to to present the final 3 arguments as the argument list seen by the script. Also realize the kernel started the perl process. After that, it is up to perl to open the script and read it and execute each line. This is why scripts need to be readable. You cannot execute a non-readable script.

Conclusion

This should be enough information to understand what is happening with those #! lines. In the following posts, I will add details on various aspects of the process.
These 4 Users Gave Thanks to Perderabo For This Post:
 

8 More Discussions You Might Find Interesting

1. Shell Programming and Scripting

#!/usr/bin/ksh Command Interpreter in a sh script

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)
Discussion started by: ckeith79
3 Replies

2. UNIX for Dummies Questions & Answers

ksh: /usr/bin/ls: arg list too long

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)
Discussion started by: jitindrabappa
2 Replies

3. Solaris

How do I link ld in /usr/ucb/ to /usr/ccs/bin?

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)
Discussion started by: SmartAntz
6 Replies

4. Shell Programming and Scripting

!/usr/bin/ksh error

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)
Discussion started by: dr46014
4 Replies

5. AIX

aix:ksh: /usr/bin/rm: 0403-027 The parameter list is too long.

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)
Discussion started by: nokiae63
3 Replies

6. OS X (Apple)

When to use /Users/m/bin instead of /usr/local/bin (& whats the diff?)?

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)
Discussion started by: michellepace
1 Replies

7. Shell Programming and Scripting

/usr/bin/ksh -E

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)
Discussion started by: reldb
1 Replies

8. BSD

FreeBSD: /usr/bin/ld not looking in /usr/local/lib

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)
Discussion started by: AntumDeluge
2 Replies
All times are GMT -4. The time now is 03:34 AM.
Unix & Linux Forums Content Copyright 1993-2022. All Rights Reserved.
Privacy Policy