hashbang line

Hi All,

I am new to this forum. I would really appreciate if some one from you expert team could answer my qns:

1) whats the difference between the below commands. what events occur in the background when I fire each of the three commands.

 
>./script.ksh
>sh script.ksh
>script.ksh

2) Is it mandatory to keep the hashbang line at the beginneing of my shell script:

#!/usr/bin/ksh

or for perl

#!/usr/bin/perl

I have heard that shell script mentioning #!/usr/bin/ksh is not mandatory, is that true??

Guys please clear my doubts.

Thanks a lot in advance.

1)
./script.ksh runs the (if any) script.ksh in the current directory
sh script.ksh runs the first script.ksh in your PATH using sh (which, for example on Linux would be Bash, on AIX ksh and on Solaris is sh), ignoring the "shebang" line in your script
script.ksh would run the first script.ksh in your PATH using either your default shell (as specified in /etc/passwd, or elsewhere) or whatever you specified in the "shebang"

The interpreter used has nothing to do with the .ksh extension of your filename script.ksh.

2) Yes and yes

there's no real requirement, although it's mostly best practices...and sensible to someone who wants to stay sane.

The governing shell may take hold of your script and run things incorrectly if the shebang is not present. Certain shells (and programs, like perl) have similar logical patterns and syntax, which may try to execute and provide unexpected results...or just errors. For example, if you're running a ksh script under your bash shell, or vice versa, things are just close enough to seem right, but report errors.

Sanity is the key here. You could log into a system as root where the login shell is /bin/csh. If you don't want your scripts to run in that shell you must specify the "hashbang" at the beginning of your script.

One thing I've always done is to put #!/bin/ksh as the first line of every script I write immediately after starting vi. This is one of my BEST PRACTICES rules.

HTH

1000% :b:

Thank you guys for the prompt response.:slight_smile:

Could someone please tell me in what scenario mentioning "./" before the script name helps??

eg ./script.ksh

Hi.

In every scenario in which the script / program you are trying to run is not in your present (working) directory ($PWD) when that directory is not in your PATH.

$ cat "echo Hello" > MyScript
$ chmod u+x MyScript
$ MyScript
-ksh: MyScript: not found
$ PATH=.:$PATH
$ MyScript
Hello

(. is another way to reference PWD)

Having . in your PATH is generally not a good idea.

(extreme...)

$ echo "rm -rf /etc" > MyScript
...
$ PATH=.:$PATH
$ MyScipt

So Scott, you are saying that if "." is not mentioned in my PATH variable then ./MyScript give me the desired results?

else simply executing MyScript will do. Is it?

./MyScript

... will explicitly execute MyScript in the current directory

MyScript

... will execute the first executable program (or script) called MyScript in your PATH.

$ mkdir T1 T2

$ echo "echo T1_script" > T1/Script

$ echo "echo T2_script" > T2/Script

$ PATH=T1

$ chmod u+x T1/Script T2/Script
-ksh: chmod: not found        chmod is not in my path any more

$ /bin/chmod u+x T1/Script T2/Script

$ Script
T1_Script

$ PATH=T2

$ Script
T2_Script

Also, "." should never be in your PATH anyway.

This prevents a situation where someone can put a file named, for example, "ls" in their own home directory, which contains commands only root can execute, and have you unknowingly execute it as root (by simply typing "ls").

So, you should always be referencing your scripts with either ./ or full path.

Don't necessarily agree with that! For example, if you create a script called test.ksh in your current directory, having '.' as the very first element of $PATH means that invoking test.ksh will use that instead of any other one that may be lying around elsewhere in your PATH, so for me, it's useful.
Depending on your operating system and shell, you can invoke these commands to determine which one will actually run...

> whence test.ksh
/home/jerry/test.ksh
>type test.ksh
test.ksh is /home/jerry/test.ksh
>which test.ksh
./test.ksh

sh script.ksh runs the script even if it is not in executable mode