Search code examples
linuxexecexecvpexecvexecve

what function in Linux API implements execution of a script file with a shebang?


From https://unix.stackexchange.com/a/2910/674

... the way shebang (#!) is typically implemented:

  1. The kernel opens the executable, and finds that it starts with #!.
  2. The kernel closes the executable and opens the interpreter instead.
  3. The kernel inserts the path to the script to the argument list (as argv[1]), and executes the interpreter.

I was wondering what function in Linux API implements the above steps for execution of a script file with a shebang?

I have considered the following possibilities, but none of them seems a match:

  • execve() will fail to execute a script.
  • Either execlp() or execvp() seems to be just for executing a script without any shebang, default to be /bin/sh, according to APUE:

    If either execlp() or execvp() finds an executable file using one of the path prefixes, but the file isn’t a machine executable that was generated by the link editor, the function assumes that the file is a shell script and tries to invoke /bin/sh with the filename as input to the shell.

    Can either execlp() or execvp() execute a script with a shebang for any language's interpreter (Python, Perl, Bash, ...).

Thanks.


Solution

  • It should be implemented by execve(). All the other functions in the exec family are just wrappers around this (the ones ending with p perform the $PATH search to find the executable argument, the ones with l build the argv array by iterating through the variadic argument list).

    It works the same for any language's interpreter -- the mechanism doesn't really care what the program in the shebang line does, it just executes it with the script pathname as an argument. You can even do:

    #!/bin/cat
    

    to create a file that just prints itself when you execute it.