Posted by: Anonymous
[ip: 75.211.34.89]
on July 16, 2008 10:10 PM
Specifically there's a part of the kernel that detects the executable file type of any filename/path which is passed to the execve() system call.
This characterization: ELF, a.out (obsolete), or script (starts with a #! "shebang"), or (optionally) "misc" then triggers different execution functions
binfmt_* prefixed names in the kernel sources).
If you search the sources you can read the code: <a href="http://www.tamacom.com/tour/kernel/linux/cgi-bin/global.cgi?pattern=binfmt_*&id=&type=path">http://www.tamacom.com/tour/kernel/linux/cgi-bin/global.cgi?pattern=binfmt_*&id=&type=path</a>
for starters.
#! (shebang) lines are processed by binfmt_script which attempts to execute whatever the first argument after the #! line points to, passing any arguments (usually -f for csh and awk scripts, for example) and provides it with an open file descriptor that contains the rest of the contents of the script. The "#" prefix is used as a "comment" more most scripting languages so the interpreter naturally will skip the shebang line as it would any other comment.
You can also strace an instance of the shell ... running a command like: strace -o /tmp/learnshebang.strace sh -c '~/bin/myscript.sh' ... to see how the shell handles the processing at a system call level.
Oddly there are other things that can happen. For example under some versions of csh (tcsh?) I've seen cases where a script with no #! line was still properly executed. After my initial surprise I determined that this shell would attempt to execute the command (possibly a script) and if that failed it would then open the file (in a subshell) and try to process it as the text of a csh script. I won't guarantee that this will work in any current version of csh; I'm just pointing out that I saw it once.
Re: bash scripts
Posted by: Anonymous [ip: 75.211.34.89] on July 16, 2008 10:10 PMThis characterization: ELF, a.out (obsolete), or script (starts with a #! "shebang"), or (optionally) "misc" then triggers different execution functions
binfmt_* prefixed names in the kernel sources).
If you search the sources you can read the code: <a href="http://www.tamacom.com/tour/kernel/linux/cgi-bin/global.cgi?pattern=binfmt_*&id=&type=path">http://www.tamacom.com/tour/kernel/linux/cgi-bin/global.cgi?pattern=binfmt_*&id=&type=path</a>
for starters.
#! (shebang) lines are processed by binfmt_script which attempts to execute whatever the first argument after the #! line points to, passing any arguments (usually -f for csh and awk scripts, for example) and provides it with an open file descriptor that contains the rest of the contents of the script. The "#" prefix is used as a "comment" more most scripting languages so the interpreter naturally will skip the shebang line as it would any other comment.
You can also strace an instance of the shell ... running a command like: strace -o /tmp/learnshebang.strace sh -c '~/bin/myscript.sh' ... to see how the shell handles the processing at a system call level.
Oddly there are other things that can happen. For example under some versions of csh (tcsh?) I've seen cases where a script with no #! line was still properly executed. After my initial surprise I determined that this shell would attempt to execute the command (possibly a script) and if that failed it would then open the file (in a subshell) and try to process it as the text of a csh script. I won't guarantee that this will work in any current version of csh; I'm just pointing out that I saw it once.
Jim Dennis
#