LinuxQuestions.org

LinuxQuestions.org (/questions/)
-   Linux - Newbie (https://www.linuxquestions.org/questions/linux-newbie-8/)
-   -   Script - shebang question (https://www.linuxquestions.org/questions/linux-newbie-8/script-shebang-question-762082/)

laki47 10-15-2009 07:59 AM

Script - shebang question
 
Hi!

Can you explain me what is purpose of shebang in scripts? I have noticed that my scripts will run without shebang. i.e. When i save my crontab file it says that scripts will be executed in i.e. /bin/sh shell. So, what is the point if I put #!/bin/ksh at the start of script?

thank you

indienick 10-15-2009 09:04 AM

My thinking goes like this: You can write a script, in any language of your choice. Because 9 times out of 10 you do not want to leave a DOS-like extension on the end (.py, .rb, .lisp, .bash, etc.), the shebang line will tell the shell running your script which interpreter to use.

centosboy 10-15-2009 09:07 AM

Quote:

Originally Posted by laki47 (Post 3720239)
Hi!

Can you explain me what is purpose of shebang in scripts? I have noticed that my scripts will run without shebang. i.e. When i save my crontab file it says that scripts will be executed in i.e. /bin/sh shell. So, what is the point if I put #!/bin/ksh at the start of script?

thank you

the shebang tells the script how it should be interpreted.
of course the script could run without this, but then you would have to specify how it is interpreted on the command line.

eg

you are running a bash script from the ksh shell.
without the shebang you would have to run the script like

Code:

ksh scriptname

because the ksh shell would interpret commands differently then bash would

chrism01 10-15-2009 07:19 PM

Always a good idea in prod systems to specify the shebang line. If the shell is unavail, it won't run at all. If you don't specify and it defaults to another shell, you could get unexpected results eg deletions/corruptions etc.
Also, you may have version issues with shells or eg Perl/Python etc.

lutusp 10-15-2009 11:44 PM

Quote:

Originally Posted by laki47 (Post 3720239)
Hi!

Can you explain me what is purpose of shebang in scripts? I have noticed that my scripts will run without shebang. i.e. When i save my crontab file it says that scripts will be executed in i.e. /bin/sh shell. So, what is the point if I put #!/bin/ksh at the start of script?

thank you

Obviously, changing the shebang line changes the interpreter for the script's content.

If I have a script named "myscript.sh" that is configured to be executable, the system will try to run it, but the first thing the system does is read the shebang line, and yes, it does matter.

Some of my scripts have this line:

Code:

#!/bin/sh
Others have this line:

Code:

#!/usr/bin/ruby -W
Others have:

Code:

#!/usr/bin/perl -W
Others have:

Code:

#!/usr/bin/python
And guess what? The system chooses the interpreter solely based on the content of the shebang line, for each script.

i92guboj 10-15-2009 11:54 PM

In my opinion, the shebang should be mandatory, really :p

A script meant to be run on a given interpreter will surely fail horribly in another, and that's just an aesthetic issue. But if it runs without errors in an incompatible shell it can be potentially harmful.

Most shells are supersets of the bourne shell (sh), so most sh scripts will run on *most* modern shell, but once you start using features that are exclusive to a shell it will no longer be compatible with the rest, and csh variants will mostly be incompatible with anything but themselves :P

If there's no shebang, the running shell will probably fork a copy of itself and run the script in it, without caring if it's compatible or even if it's a script file at all. Shebangs also make easy to pass parameters to an interpreter. For example, to debug a bash script you might want to add -x to the bash shebang.

laki47 10-16-2009 01:56 AM

Thank you all to your answers.

But when I do i.e. "crontab -e" and then save crontab file, it says:

warning: commands will be executed using /usr/bin/sh

So, does it matter what shebang is specified in file, or commands will be executed in bourne shell anyway?

lutusp 10-16-2009 02:42 AM

Quote:

Originally Posted by laki47 (Post 3721304)
Thank you all to your answers.

But when I do i.e. "crontab -e" and then save crontab file, it says:

warning: commands will be executed using /usr/bin/sh

So, does it matter what shebang is specified in file, or commands will be executed in bourne shell anyway?

No, that message means the cron script will be executed by /bin/sh, but you should be calling scripts from cron, not putting executable content in the cron script file.

Each cron schedule line should call a script, not contain a command line with specific instructions -- in all but the simplest cases. That way, you will have the option of using any interpreter you care to use.

SharpyWarpy 10-16-2009 06:46 AM

Just to butt in here, thanks to all contributors to this thread -- great content. And thanks to OP for his question.

moraxu 04-08-2013 11:53 AM

The topic is quite old right now, but I have a question regarding situation when no shebang is placed in the script:

Quote:

Originally Posted by i92guboj (Post 3721190)
If there's no shebang, the running shell will probably fork a copy of itself and run the script in it, without caring if it's compatible or even if it's a script file at all.

And what if we execute the shell script from within a desktop environment (i.e., directly clicking on the file containing the script)? In my version of Ubuntu, running a file with execute permission bit set opens a window with Run in Terminal, Display, Cancel and Run options available. If the first one is chosen, I suppose that the script will be executed by the default login shell (or whatever shell the gnome-terminal starts upon its execution). But what if we choose the Run option?

Also, I've read on this website that:

Quote:

If you do not specify an interpreter line, the default is usually the /bin/sh. But, it is recommended that you set #!/bin/bash line.
Is there a way to find out which shell is the default one in case of shebang on my specific distribution? Or maybe this shell is equivalent to user's login one?

DavidMcCann 04-08-2013 12:18 PM

1. Always create a new thread, rather than restarting an old one. That way it will be shown as unanswered.

2. There are commands like
echo $SHELL
which tells you the default shell for your system
and
echo $0
which tells you what the current shell is.

Linux normally uses bash, but Arios prefers zsh. I think BSD uses sh.

moraxu 04-08-2013 12:56 PM

Quote:

Originally Posted by DavidMcCann (Post 4927669)
2. There are commands like
echo $SHELL
which tells you the default shell for your system
and
echo $0
which tells you what the current shell is.

I know that. I'd like to know if there is no shebang, will the running shell fork its child process to run commands from a script in it or use the default shebang interpreter program?

PS. Provided that this is documented somewhere and an explicit answer can be given...

chrism01 04-08-2013 06:38 PM

The default is to use the current logged in shell, because you are calling it from there, (unless you specify a shebang).

cron obviously has its own default shell, because you don't login to run cron. If it says sh, that's what you'll get.

For your Ubuntu specific qn, you'd best ask a Ubuntu forum.

As per my old post above re PROD systems and i92guboj's post I agree that specifying shebang should really be compulsory (especially on PROD).

At the cli, if you invoke as
Code:

./mysh.sh
it'll fork a new shell.
If you source it
Code:

. ./mysh.sh

#OR
 source ./mysh.sh

it will run in your current shell, not fork a new one.

Note that this is separate to what type of shell it uses eg bash, ksh etc, as this is dictated by whether or not you've specified a shebang line.

rknichols 04-08-2013 06:52 PM

When a program tries to exec() script file that does start with a shebang line:
  1. The kernel recognizes the 16-bit magic number represented by the "#!" characters and gets the path to the interpreter from the rest of the line.
  2. The kernel executes that interpreter, handing it an open file descriptor to the script file.
When a shell tries to exec() a script file that does not start with a shebang line:
  1. The kernel does not find a supported magic number at the start of the file, and the exec() call fails with ENOEXEC.
  2. The calling shell sees the failure and assumes that the file is a script in its own language.
  3. The shell invokes a subshell of itself (often by a fork() with no exec()) to interpret the script.
When a program other than a shell tries to exec() a script file that does not start with a shebang line:
  1. The exec() call fails with ENOEXEC, as above.
  2. The program sees the failure and writes an error message to stderr.
  3. The user says, "WTF is wrong? That script works fine when I run it directly from the command line."

moraxu 04-11-2013 03:53 PM

Quote:

Originally Posted by rknichols (Post 4927895)
When a program other than a shell tries to exec() a script file that does not start with a shebang line:
  1. The exec() call fails with ENOEXEC, as above.
  2. The program sees the failure and writes an error message to stderr.
  3. The user says, "WTF is wrong? That script works fine when I run it directly from the command line."

Then the following quote:

Quote:

If you do not specify an interpreter line, the default is usually the /bin/sh. But, it is recommended that you set #!/bin/bash line.
from here is erroneous, since the exec call always fails in that case?


All times are GMT -5. The time now is 09:31 PM.