Why does a shebang need a path?
#!/usr/local/bin/ruby #!/usr/bin/env ruby
The operating system should have the information regarding the path for a registered command, and why does it still expect it to be given?
Unix & Linux Stack Exchange is a question and answer site for users of Linux, FreeBSD and other Un*x-like operating systems. It only takes a minute to sign up.Sign up to join this community
Probably to keep the kernel simpler. I don't think the kernel ever searches your path to find an executable. That's handled by the C library.
#! processing is done in the kernel, which doesn't use the standard C library.
Also, I don't think the kernel has a notion of what your path is.
$PATH is an environment variable, and only processes have an environment. The kernel doesn't. I suppose it could access the environment of the process that did the exec, but I don't think anything currently in the kernel ever accesses environment variables like that.
You can get
PATH-searching semantics using
has the semantics you would like from
The reason that depending on
PATH is not considered good practice is that the script can make no assumptions about the content of the PATH environment variable, breaking the "sequential dependency model" of binaries where
/bincontains the executables needed at boot time;
/usr/bincontains the other executables used by the OS installation;
/usr/local/bincontains executables installed by the system administrator that are not part of the base OS.
~/bincontains the user's own executables.
Each level should not assume the existence of binaries later in the sequence, which are more "application" but may rely on binaries earlier, which are more "fundament". And the PATH variable tends to run from applicationy to fundamental, which is the opposite direction to the natural dependency above.
To illustrate the problem, ask yourself what happens if a script in
~/bin invokes an script in
/usr/local/bin that invokes Ruby? Should that script depend on the OS installed version at
/usr/bin/ruby, or on the personal copy the user happens to have at
PATH searching gives the unpredictable semantics associated with the latter (maybe
~/bin/ruby is a broken symbolic link), while baking in the path to
#! gives the former.
There isn't really any other platform-independent "operating system ... information regarding the path for a registered command", so the simplest thing is to insist on the path being provided in the
From Classic Shell Scripting book:
Shell scripts typically start with
#! /bin/sh. Use the path to a POSIX-compliant shell if your
/bin/shisn't POSIX compliant. There are also some low-level "gotchas" to watch out for:
- You have to know the full pathname to the interpreter to be run. This can prevent cross-vendor portability, since different vendors put things in different places (e.g.,
There are other reasons, but from a security perspective I would never want a script to make assumptions about the correct path. What if it is wrong and it runs the wrong shell or interpreter? One that has been inserted by a malicious user? Or what if it relies on a particular shell and will crash out if the wrong shell is used?
Users may mess around with their path and break stuff - don't trust the user:-) I have conducted numerous attacks which rely on the user doing the wrong thing with their path - usually getting things in the wrong order - so I can subvert a normal script call.
Yes, I know if you've written the script yourself you can quite rightly claim that you have sorted out your own path, but an interpreter can't make those decisions.