Relative shebang: How to write an executable script running portable interpreter which comes with it Relative shebang: How to write an executable script running portable interpreter which comes with it unix unix

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