To the shell. An executable file that starts with a #! line will cause the executing shell to start up the program indicated in that line. That way, you can use #!/bin/sh to create a shell script, #!/usr/bin/perl to create a perl script etc. At least on unixish systems, there is always a shell involved in this process (but for instance windows doesn't work like that)
(Possibly) to the interpreter indicated in the #! line.
For instance, perl reads the additional arguments on the #! line as a sort of "setup parameters". Example:
#!/usr/bin/perl -wT will run perl with global warnings enabled and in taint mode.
To the shell. [...] At least on unixish systems, there is always a shell involved in this process
The #! line, also called shebang, tells nothing to any shell. It's the kernel who interprets it. When the first two bytes of an executable file are #!, the kernel runs the command that follows them, with the parameters specified, and feeds it the whole file on its standard input:
I'm trying to figure out where you get the idea that the contents are passed to tail's stdin. It's not. The full path to the file (as given by the shell - full path if searched via PATH, relative path if PATH not used) is passed in.
Compare the output of "strace ./a" and "strace /usr/bin/tail -n2 < a". The former has a call to "open" and all reading is done from filehandle 3. The latter doesn't call open, and all reading is done from filehandle 0.