Today I ran into the fact that shebangs with multiple arguments do not get parsed as I would expect…
In order to prevent multiple copies of a long-running cronjob from running simultaneously I wanted to use flock. So I changed the first line of my script.
My standard above, to something that I would expect to work.
#!/usr/bin/flock --nonblock /tmp/mylockfile /bin/bash
Running it gave me:
/usr/bin/flock: unrecognized option '--nonblock /tmp/mylockfile /bin/bash'
Followed by flock’s usage information…
- The shebang is used by the kernel to call the correct interpreter if the leading magic bits of the file are “!#”
- Most historic kernels used to only pass the first 32 bytes of the line, Linux uses 127. So watch that character count!
- Only the first space is used to separate the command from the argument, all trailing spaces are ignored and passed as a single argument, essentially an
exec('prog', 'arg1 arg2 arg3')
- Perl parses its arguments as it pleases, and doesn’t let the exec string tell it what to do.
I ended up with the following, which while it works was a bit too ugly for me to commit for others to review:
#!/usr/bin/perl -e exec "/usr/bin/flock", "--nonblock", "/tmp/mylockfile", "/bin/bash", @ARGV
I also have a simple program as a perl gist, simply because I haven’t touched perl in years, so if I need to in the future my shebangs can be a bit simpler.
#!/bin/spacexec /usr/bin/flock --nonblock /tmp/mylockfile /bin/bash