So, I thought I had a good understanding of this, but just ran a test (in response to a conversation where I disagreed with someone) and found that my understanding is flawed...
In as much detail as possible what exactly happens when I execute a file in my shell? What I mean is, if I type: ./somefile some arguments
into my shell and press return (and somefile
exists in the cwd, and I have read+execute permissions on somefile
) then what happens under the hood?
I thought the answer was:
- The shell make a syscall to
exec
, passing the path tosomefile
- The kernel examines
somefile
and looks at the magic number of the file to determine if it is a format the processor can handle - If the magic number indicates that the file is in a format the processor can execute, then
- a new process is created (with an entry in the process table)
somefile
is read/mapped to memory. A stack is created and execution jumps to the entry point of the code ofsomefile
, withARGV
initialized to an array of the parameters (achar**
,["some","arguments"]
)
- If the magic number is a shebang then
exec()
spawns a new process as above, but the executable used is the interpreter referenced by the shebang (e.g./bin/bash
or/bin/perl
) andsomefile
is passed toSTDIN
- If the file doesn't have a valid magic number, then an error like "invalid file (bad magic number): Exec format error" occurs
However someone told me that if the file is plain text, then the shell tries to execute the commands (as if I had typed bash somefile
). I didn't believe this, but I just tried it, and it was correct. So I clearly have some misconceptions about what actually happens here, and would like to understand the mechanics.
What exactly happens when I execute a file in my shell? (in as much detail is reasonable...)
source somefile
is very different from a new process being forked off by./somefile
, though../somefile
would cause bash to execute the commands insomefile
if the file didn't have a magic number. I thought it would just display an error, and instead it appears to effectivelysource somefile
somefile
is a text file, then a new shell is spawned if I try to execute it. A fileecho $$
behaves differently if I execute vs source it.