LinuxQuestions.org
Share your knowledge at the LQ Wiki.
Go Back   LinuxQuestions.org > Forums > Non-*NIX Forums > Programming
User Name
Password
Programming This forum is for all programming questions.
The question does not have to be directly related to Linux and any language is fair game.

Notices


Reply
  Search this Thread
Old 09-14-2006, 05:27 AM   #1
ananthbv
Member
 
Registered: Nov 2003
Posts: 49

Rep: Reputation: 15
what happens when a script is run using 'sh <somescript>'?


Hi,

what is the difference between running a script using
Code:
$ ./somescript
and
Code:
$ sh somescript
Because when i try to run a script which does not have executable permission using the first method, the shell shows an error. But if i run the script with the same permissions using the second method, it works.
 
Old 09-14-2006, 06:07 AM   #2
Nathanael
Member
 
Registered: May 2004
Location: Karlsruhe, Germany
Distribution: debian, gentoo, os x (darwin), ubuntu
Posts: 940

Rep: Reputation: 33
./somescritp executes the script (file needs execution perms) the intertpreter is read from the first line (shebang) e.g.: #!/bin/bash
but the first line may contain any interpreter e.g. #!/usr/bin/php4
is perfectly valid too.

sh somescript reads the file contents and executes every line (which does not start with a comment '#')
 
Old 09-14-2006, 08:11 AM   #3
ananthbv
Member
 
Registered: Nov 2003
Posts: 49

Original Poster
Rep: Reputation: 15
thanks for your reply Nathanael.

butwhat happens when there is no #!/bin/bash in the first line?

isnt the execution of the script when we do a './somescript' done by a child shell (after a fork and exec by the current shell)? how different is this from running it by 'sh somescript'? because in this case also, the current shell does a fork and exec to spawn the new 'sh'?
 
Old 09-14-2006, 09:08 AM   #4
Nathanael
Member
 
Registered: May 2004
Location: Karlsruhe, Germany
Distribution: debian, gentoo, os x (darwin), ubuntu
Posts: 940

Rep: Reputation: 33
without the shebang your current shell tries to interpret every line. so i guess there is no reald diff in running ./somefile or sh somefile
IF:
you use bash as you standard shell - though some people use zsh or i-dont-know-what-else.
so - just in case you always want (or even need) your script to run under bash you use a shebang!
you could even write a script in zsh and the you have a firstline of #!/bin/zsh so that even when you usually run bash you could execute ./somescript which will always be interpreded by zsh :-)

i think you should read through some advanced bash scripting tutorials
 
Old 09-15-2006, 11:23 AM   #5
theNbomr
LQ 5k Club
 
Registered: Aug 2005
Distribution: OpenSuse, Fedora, Redhat, Debian
Posts: 5,398
Blog Entries: 2

Rep: Reputation: 908Reputation: 908Reputation: 908Reputation: 908Reputation: 908Reputation: 908Reputation: 908Reputation: 908
Quote:
Originally Posted by Nathanael
without the shebang your current shell tries to interpret every line. so i guess there is no reald diff in running ./somefile or sh somefile
Not quite. The current shell examines the first line of the file, if it is executable, and if it finds a suitable shebang line, it launches the specified interpretter as a child process, and gives that interpretter the filename as an argument. This is exactly the same as you entering that command as a commandline, and having the shell execute it. There is a third style of invoking a shell script, called 'sourcing' the script. In that case, the specified script is read and interpetted as if you were typing the contents of the script in real time. There is no child shell launched. The beauty of this method is that environment variables can be set, and do not disappear after the child shell terminates ('cause there isn't one). Sourcing the script can be done with the 'source' command:

Code:
source somefile
or the shorthand
Code:
. somefile
No shebang line is required to 'source' a script.

--- rod.
 
Old 09-15-2006, 12:11 PM   #6
X.Cyclop
Member
 
Registered: Jun 2006
Location: Tlv
Distribution: Arch!
Posts: 120

Rep: Reputation: 21
With ./script you'll get an error (bash: ./script: Permission denied) and you'll need to add execution permissions: chmod +x script and then try again.
 
Old 09-15-2006, 02:42 PM   #7
jlliagre
Moderator
 
Registered: Feb 2004
Location: Outside Paris
Distribution: Solaris 11.4, Oracle Linux, Mint, Ubuntu/WSL
Posts: 9,783

Rep: Reputation: 492Reputation: 492Reputation: 492Reputation: 492Reputation: 492
Quote:
Originally Posted by theNbomr
Not quite. The current shell examines the first line of the file, if it is executable, and if it finds a suitable shebang line, it launches the specified interpreter as a child process, and gives that interpreter the filename as an argument. This is exactly the same as you entering that command as a commandline, and having the shell execute it.
This is not exactly what happens.
The current shell doesn't look for a shebang in the script, not does it care that much about if the file is executable.

It just forks, then pass the name of the command to the kernel, through one of the exec family system calls.
If the file has a shebang on its beginning, then the kernel launch the interpreter that follows the shebang and the forked shell is replaced by this interpreter.
If the script lack the shebang, then the exec call fails because the file hasn't a known executable format, despite the execute permission.
The control comes back to the forked shell, which either interpret itself the script if the launching is bourne shell compatible, or use a sh compatible shell to run the script if it isn't, like csh, zsh, ...
 
Old 09-15-2006, 03:54 PM   #8
theNbomr
LQ 5k Club
 
Registered: Aug 2005
Distribution: OpenSuse, Fedora, Redhat, Debian
Posts: 5,398
Blog Entries: 2

Rep: Reputation: 908Reputation: 908Reputation: 908Reputation: 908Reputation: 908Reputation: 908Reputation: 908Reputation: 908
jlliagre:

I've just spent some time studying the bash man-page; in particular, the section 'COMMAND EXECUTION'.

To my surprise, you are quite right that the shell (bash, at least) interprets a script that does not contain a leading shebang. However, the bash man-page suggests that the shell does indeed look for a shebang line, and upon finding one, launches (fork + exec, as you detailed) the specified interpretter. The man page also explains that the filesystem is searched along each directory in $PATH for 'executable files'. My assumption was that it understands a file to be 'executable' based upon the permission level of the file, and not by it's binary object format. Am I wrong about that?

At any rate, it seems to me that the shell does care about shebangs and executable status.

--- rod.
 
Old 09-15-2006, 04:21 PM   #9
jlliagre
Moderator
 
Registered: Feb 2004
Location: Outside Paris
Distribution: Solaris 11.4, Oracle Linux, Mint, Ubuntu/WSL
Posts: 9,783

Rep: Reputation: 492Reputation: 492Reputation: 492Reputation: 492Reputation: 492
Quote:
Originally Posted by theNbomr
jlliagre:

I've just spent some time studying the bash man-page; in particular, the section 'COMMAND EXECUTION'.

To my surprise, you are quite right that the shell (bash, at least) interprets a script that does not contain a leading shebang. However, the bash man-page suggests that the shell does indeed look for a shebang line, and upon finding one, launches (fork + exec, as you detailed) the specified interpretter. The man page also explains that the filesystem is searched along each directory in $PATH for 'executable files'. My assumption was that it understands a file to be 'executable' based upon the permission level of the file, and not by it's binary object format. Am I wrong about that?
The loader, not the shell, looks for the binary object format and the shebang is also a binary "magic number" that is accepted by one of the handlers (binfmt_script on Linux).
Quote:
At any rate, it seems to me that the shell does care about shebangs and executable status.
Nope, the shell doesn't even know about what a shebang is, it's just a comment for that matter.
 
Old 09-15-2006, 10:22 PM   #10
ananthbv
Member
 
Registered: Nov 2003
Posts: 49

Original Poster
Rep: Reputation: 15
i am still a bit confused . since fork+exec is done in both cases, how different is the fork+exec in the first case (when doing a ./somescript) from the fork+exec when we do a 'sh somescript'? how can the shell in the latter case execute the script even if it has no 'x' permission?
 
Old 09-15-2006, 10:32 PM   #11
randyding
Member
 
Registered: May 2004
Posts: 552

Rep: Reputation: 31
Yes the post by jlliagre is right.
When you "sh some_script", the shell only reads the script, so it doesn't matter if execute permission is there or not. So to be exact, only read permission is "necessary", execute permission is fine but it doesn't matter.
The exec() class of calls handles the shebang all on its own without the help of the shell.
 
Old 09-15-2006, 10:43 PM   #12
theNbomr
LQ 5k Club
 
Registered: Aug 2005
Distribution: OpenSuse, Fedora, Redhat, Debian
Posts: 5,398
Blog Entries: 2

Rep: Reputation: 908Reputation: 908Reputation: 908Reputation: 908Reputation: 908Reputation: 908Reputation: 908Reputation: 908
Okay, that is making it more clear. The bash man-page talks about finding executable files in $PATH, but that is only for the purpose of searching. Once found or unambiguously specified, then the execute permission is irrelevent.

--- rod.
 
Old 09-15-2006, 10:57 PM   #13
randyding
Member
 
Registered: May 2004
Posts: 552

Rep: Reputation: 31
I'm sorry, I probably wasn't very clear. I was only referring to what happens when you "sh some_script". In bash, when you type "sh some_script" the PATH is searched to find the "sh" executable only, because an absolute path wasn't specified in my example cmdline. Then the argument "some_script" is passed to that program "/bin/sh" because that's where it was found in the PATH. /bin/sh is executed via fork()/exec() by the current shell that is parsing your command line. /bin/sh in turn opens the file some_program for reading.

When you specify ./some_script doesn't involve PATH either in that case because you are specifying an absolute path (well relative actually).
bash tries to fork() and exec() it directly but only if its executable, and then the kernel examines the shebang if that is what it is.
 
Old 09-15-2006, 11:01 PM   #14
jlliagre
Moderator
 
Registered: Feb 2004
Location: Outside Paris
Distribution: Solaris 11.4, Oracle Linux, Mint, Ubuntu/WSL
Posts: 9,783

Rep: Reputation: 492Reputation: 492Reputation: 492Reputation: 492Reputation: 492
Actually, the execute permission is still required for the execve system call to succeed, my point is it isn't sufficient, a valid magic number being another requirement.
Execute permission is ignored when the script is passed as a shell argument, or read from the shell stdin.

Edit: bash doesn't care about the execute flag, and try the execve anyway, just in case ...

Last edited by jlliagre; 09-15-2006 at 11:04 PM.
 
Old 09-15-2006, 11:14 PM   #15
randyding
Member
 
Registered: May 2004
Posts: 552

Rep: Reputation: 31
Thanks jlliagre, I meant to say that.
I really wasn't completely sure if bash checked or not before passing it to exec(), in theory at least it could avoid the "for sure" error that would result from calling exec() on an argument that does not have execute permission... but again whatever it really does it will fail like you said without it.
 
  


Reply


Thread Tools Search this Thread
Search this Thread:

Advanced Search

Posting Rules
You may not post new threads
You may not post replies
You may not post attachments
You may not edit your posts

BB code is On
Smilies are On
[IMG] code is Off
HTML code is Off



Similar Threads
Thread Thread Starter Forum Replies Last Post
'cannot stat' script in /etc/rc.d/, try to run script at startup quintan Linux - Software 1 11-21-2005 02:53 AM
Shell script to run pl/sql script. colly Linux - General 1 09-09-2004 06:49 AM
Script to run script in multiple directories... seabass55 Linux - General 5 07-06-2004 12:44 AM
on Network Up Script run? On Battery power run script? v2-ncl Linux - General 0 12-08-2003 09:34 AM
can't run a script script from icon in konqueror scottsteibel Linux - Software 1 08-02-2003 07:59 PM

LinuxQuestions.org > Forums > Non-*NIX Forums > Programming

All times are GMT -5. The time now is 02:54 PM.

Main Menu
Advertisement
My LQ
Write for LQ
LinuxQuestions.org is looking for people interested in writing Editorials, Articles, Reviews, and more. If you'd like to contribute content, let us know.
Main Menu
Syndicate
RSS1  Latest Threads
RSS1  LQ News
Twitter: @linuxquestions
Open Source Consulting | Domain Registration