Take the 2-minute tour ×
Unix & Linux Stack Exchange is a question and answer site for users of Linux, FreeBSD and other Un*x-like operating systems.. It's 100% free, no registration required.

I am new to shell scripts and many books have written that use #!(sha-bang) line in starting of the script to invoke the interpreter .And this will invoke a new shell for script and do the interpretation line by line.But one of my basic script is still running without the magic line.

so my questions are:

  • from where did my basic script get the interpreter.
  • how did the script manages to locate the interpreter.

now let me tell you about my basic script it just contains the following line:

echo "basic script without the magic lines"

share|improve this question
2  
add comment

3 Answers

up vote 4 down vote accepted

If the magic line is not provided, a default shell is used to run the script. This default shell could either be Bourne shell (sh) which is the case in some flavors, however, in some other flavors, the default shell used is same as login shell to execute it. The thing is: Don't leave it to the system to decide the shell, always provide the shell which you want in the first line.

share|improve this answer
1  
yup..may be my current shell is invoking a default shell for shell script not having magic numbers. –  user1678213 Oct 10 '12 at 6:55
1  
@user1678213 Yes, it's your shell (and not the kernel) that's doing this. –  Gilles Oct 11 '12 at 0:26
    
I believe POSIX mandates that /bin/sh is used in this case. –  vonbrand Jan 30 '13 at 20:33
    
@vonbrand This is a common misconception. POSIX doesn't mandate the POSIX shell to be /bin/sh, just to be the first sh executable found while exploring a conforming PATH. –  jlliagre Jul 24 '13 at 0:03
    
That's incorrect, it's never the "login shell" that is used to execute it. What can happen though is that the calling shell (if the script is called from a shell) may have a child of itself interpreting it. –  Stephane Chazelas Jul 24 '13 at 2:08
add comment

When you execute a program, the kernel checks whether it starts by some magic byte sequence. If the executable file starts with #!, the kernel interprets the rest of the line as an interpreter name. If the executable file starts with \177ELF (where \177 is byte 127), it loads the file as an ELF executable; that's the normal kind on most unix systems nowadays.

If the kernel doesn't recognize the file format, it refuses to execute the file and returns the error ENOEXEC (Exec format error). When the shell notices that, it takes upon itself to execute the program as a shell script.

To witness this in action, add a few commands to your script:

ps l $$
ls -l /proc/$$/exe
echo hello

(This is for Linux, adjust for other unices.) Then try running that script from various shells. You'll see that some shells spawn a new instances of themselves to execute the script (bash, ksh93) while others spawn /bin/sh (dash, pdksh, zsh).

share|improve this answer
    
What do I look for with your ls -l command? This: lrwxrwxrwx 1 i 0 Oct 11 05:15 exe -> /bin/bash - ? If so, what does it say? Also, noticed I have SHELL=/bin/bash on env, but changing it didn't seem to change behaviour. Maybe it is unrelated? –  Emanuel Berg Oct 11 '12 at 3:21
    
it seems like you are changing shell variable "SHELL".if yes,then you are only chnging the value of shell variable SHELL.it wont chnge your shell.for chnaging your shell edit the /etc/passwd file. –  user1678213 Oct 11 '12 at 5:31
2  
@EmanuelBerg Yes (I should have written ls -l /proc/$$/exe, in fact). The exe links points to the shell that's executing your script. When you run your script, you'll see that it's bash that interprets the script. If you run it from e.g. pdksh, it runs /bin/sh. I don't know of any shell that uses the SHELL environment variable or the login shell in that circumstance. –  Gilles Oct 11 '12 at 9:37
2  
@user1678213 Changing the shell in /etc/passwd changes what shell is executed when you log in over SSH or on a text console. It doesn't change which shell might execute scripts. –  Gilles Oct 11 '12 at 9:38
2  
@user1678213 I verified what I wrote here by running tests. None of the shells I tested looked in /etc/passwd to decide which shell to use, they either forked an instance of themselves or executed /bin/sh. –  Gilles Oct 11 '12 at 12:22
show 1 more comment

It's probably one of the following 3 possibilities:

  1. You are calling the script directly with the interpreter, IE: bash script.sh

  2. The name of the script file has an .sh extension, which gets the system to look for the default program for this type of file

  3. The shell environment that you are using is executing the 'echo' by itself, since I can only guess that the script file is executable. If, for example, you will be using a bash shell and have a command in your file that is used only by ksh, then you will see that it will not work.

Good luck!

share|improve this answer
3  
neither did i call it with bash nor with any extension. –  user1678213 Oct 10 '12 at 6:19
1  
and shell environment is not executing it because when i invoke ps command after invoking my script. ps command shows two bash process.which means that there are two bash running. one is my login bash shell and the other one is bash for my basic_script –  user1678213 Oct 10 '12 at 6:26
1  
2: the kernel won't do anything like that. Zsh can do it, and bash can be twisted into doing it. 3: Yes, but it varies a bit between shells, see my answer. –  Gilles Oct 11 '12 at 0:27
add comment

Your Answer

 
discard

By posting your answer, you agree to the privacy policy and terms of service.

Not the answer you're looking for? Browse other questions tagged or ask your own question.