14

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"

  • 2
    See http://stackoverflow.com/questions/7268437/bash-script-execution-with-and-without-shebang-in-linux-and-bsd – jasonwryan Oct 10 '12 at 06:10

3 Answers3

10

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).

  • 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 03: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 05: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 'SO- stop being evil' Oct 11 '12 at 09:37
  • 3
    @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 'SO- stop being evil' Oct 11 '12 at 09:38
  • @gilles No.I think so.It will also change the shell which execute script ,if script doesnt contain magic lines. When you change your login shell from etc/passwd, it will change your login shell.And login shell in turn invoke a same type of shell for shell scripts ,if no magic line is there in the shell script.And login shell will only invoke shell scripts on its own type because here login shell is parent and shell for "script" is child.And child inherits all properties of parent except PID – user1678213 Oct 11 '12 at 12:18
  • 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 'SO- stop being evil' Oct 11 '12 at 12:22
3

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.

Guru
  • 5,905
-2

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!

bizna
  • 149
  • 3
    neither did i call it with bash nor with any extension. – user1678213 Oct 10 '12 at 06: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 06: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 'SO- stop being evil' Oct 11 '12 at 00:27