In a shebang, is a space or more allowed between #!
and the interpreter?
For example, #! /bin/bash
. It seems work, but some said that it is incorrect.
In a shebang, is a space or more allowed between #!
and the interpreter?
For example, #! /bin/bash
. It seems work, but some said that it is incorrect.
Yes, this is allowed.
The Wikipedia article about the shebang includes a 1980 email from Dennis Ritchie, when he was introducing kernel support for the shebang (as part of a wider package called interpreter directives) into Version 8 Unix (emphasis mine):
The system has been changed so that if a file being executed begins with the magic characters
#!
, the rest of the line is understood to be the name of an interpreter for the executed file. […]To take advantage of this wonderful opportunity, put
#! /bin/sh
at the left margin of the first line of your shell scripts. Blanks after
!
are OK.
So spaces after the shebang have been around for quite a while, and indeed, Dennis Ritchie’s example is using them.
Note that early versions of Unix had a limit of 16 characters in this interpreter line, so you couldn’t have an arbitrary amount of whitespace there. This restriction no longer applies in modern kernels.
Yes, blanks are allowed after the #!
. There was even a (mistaken) thought that some systems might require it, but it has always just been optional.
For further reading try here
FYI, some versions of systemd fail to parse shebangs with a space. With a service like this:
[Service]
Type=oneshot
ExecStart=/root/foo.sh
... and a shebang like this:
#! /bin/bash
... you may get an error like this:
systemd[32834]: foo.service: Failed at step EXEC spawning /root/foo.sh: Exec format error
Removing the space from the shebang fixes the error. So look out for that one.
shebang
I find in the source code of systemd is in ./test/test-functions
about a _shebang_regex='(#! *)(/[^ ]+).*'
(from someone who doesn't know that bash regexps are not anchored apparently) which explicitly allows those spaces (but is not otherwise related to executing services).
– Stéphane Chazelas
Jun 21 '21 at 15:54
" /bin/bash"
instead of "/bin/bash"
. It all suggests systemd is fine but your issue was elsewhere. Maybe you had a UTF-8 BOM at the start of your #! /bin/bash
script?
– Stéphane Chazelas
Jun 21 '21 at 15:56
execve("/root/test.sh", ["/root/test.sh"], [/* 6 vars */]) = 0
So, no, this doesn't seem to be true. (tested on a way older systemd, though)
– ilkkachu
Jun 21 '21 at 20:34