77

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.

Gilles 'SO- stop being evil'
  • 807,993
  • 194
  • 1,674
  • 2,175
Tim
  • 98,580
  • 191
  • 570
  • 977

3 Answers3

80

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.

alexwlchan
  • 901
  • 5
  • 7
45

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

Eric Renouf
  • 18,141
  • 4
  • 49
  • 65
11

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.

Luke Yeager
  • 219
  • 2
  • 6
  • 2
    Ah. yet another reason for me to be grumpy about systemd; Just what I needed… Thanks for the heads-up. – Wyatt Ward Jan 06 '21 at 22:13
  • 4
    FWIW, I can't reproduce with systemd 245.4-4ubuntu3.6 (on Ubuntu 20.04). – Stéphane Chazelas Jun 21 '21 at 15:37
  • 3
    The only reference to `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
  • 2
    I'm not sure why systemd would want to parse shebangs by itself. Also, I'd expect a "no such file or directory" error if systemd tried to execute `" /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
  • I just see the obvious system call too, `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