Relative shebang: How to write an executable script running portable interpreter which comes with it
The relative path written directly in a shebang is treated relative to the current working directory, so something like #!../bin/python2.7
will not work for any other working directory except few.
Since OS does not support it, why not to use external program like using env
for PATH
lookup. But I know no specialized program which computes the relative paths from arguments and executes the resulting command.. except the shell itself and other scripting engines.
But trying to compute the path in a shell script like
#!/bin/sh -c '`dirname $0`/python2.7 $0'
does not work because on Linux shebang is limited by one argument only. And that suggested me to look for scripting engines which accept a script as the first argument on the command line and are able to execute new process:
Using AWK
#!/usr/bin/awk BEGIN{a=ARGV[1];sub(/[a-z_.]+$/,"python2.7",a);system(a"\t"ARGV[1])}
Using Perl
#!/usr/bin/perl -e$_=$ARGV[0];exec(s/\w+$/python2.7/r,$_)
update from 11Jan21:
Using updated env
utility:
$ env --version | grep envenv (GNU coreutils) 8.30$ env --helpUsage: env [OPTION]... [-] [NAME=VALUE]... [COMMAND [ARG]...]Set each NAME to VALUE in the environment and run COMMAND.Mandatory arguments to long options are mandatory for short options too. -i, --ignore-environment start with an empty environment -0, --null end each output line with NUL, not newline -u, --unset=NAME remove variable from the environment -C, --chdir=DIR change working directory to DIR -S, --split-string=S process and split S into separate arguments; used to pass multiple arguments on shebang lines
So, passing -S
to env will do the job