Zeroth Argument Inconsistency
Back when #! behavior was first implemented in UNIX, they probably should have done argument pass-through 100% transparently, including the zeroth argument in the list of arguments that the shell script interpreter gets. No, not the resolved file path of that script. I mean the actual zeroth argument, the exact string at index zero of the `argv` argument to the `execve` system call.
It would've been nice if there was some standard way to pass the actual zeroth argument, as specified by the caller of the script, to the interpreter, and then for the interpreter to pass it through to the script.
The second part of that is easy: it's already normal for interpreters to expose a zeroth argument to script code - it's just the resolved script file path instead of the program name as invoked or whatever else the caller put in the zeroth argument. Could've just put that in, and exposed the script name in a separate non-argument way.
The first part is the harder part. If you just require that all script interpreter calls look like
foo script.foo arg0 arg1 arg2 ...
then that's bad for the common case. In many situations a default zeroth argument can be reasonably inferred. Human users typing commands do not normally think of zeroth arguments as a thing at all, let alone as a thing distinct from what it normally contains (the invoked program name). So ideally the system would pass the zeroth argument to the interpreter in some other way. Perhaps with an optional flag like `--arg0`, or in an environment variable like `ARG0`, or maybe someone can think of an even better way.
Meanwhile, compiled executables have the opposite problem: on many systems, they literally cannot know the actual resolved file path to themselves - they can only know their zeroth argument. At best they can hope that the zeroth argument will let them infer their file name. They can pray that the zeroth argument, and maybe an environment variable like PATH, will let them infer their location on disk. But the zeroth argument can "lie", because it can be set to anything.
It would have been nice if there was some standard way for compiled executables to learn the actual file path with which they were invoked - the same and only information that scripts inevitably get in their zeroth argument.
Instead we live in a world where scripts and compiled executables have fundamentally different behaviors, on at least some systems. Scripts can only receive the file path to themselves as the zeroth argument. Compiled executables receive the invoked program name or any other useful information like an error prefix which the zeroth argument has been used for.
















