Could someone explain how this shebang works?
#!/usr/bin/perl -e$_=$ARGV[0];exec(s/\w+$/python3/r,$_)
I've seen it posted twice here but not coming from Perl it looks like magic to me. I ask as I would like to adjust the directory to a python environment relative to the script.
i.e #!../env/bin/python3
to (I'm just guessing here) #!/usr/bin/perl -e$_=$ARGV[0];exec(s/\w+$/env/bin/python3/r,$_)
Edit: I am trying to execute a simple ''Hello world" program.
#!/usr/bin/perl -e'$_=$ARGV[0];exec(s{\w+$}{exploit-env/bin/python3}r,$_)'
###############################
def main():
print('Hello world')
###############################
if __name__ == '__main__':
main()
Shebang handling isn't consistent across all systems[1], but your system apparently apparently executes what the following shell command would execute (assuming the file containing the shebang is /path/to/script
):
/usr/bin/perl -e'$_=$ARGV[0];exec(s/\w+$/python3/r,$_)' /path/to/script
(The path to the script might not be an absolute path —it might be relative to the current directory— but doesn't matter here.)
The script produces /path/to/python3
from /path/to/script
(by replacing the trailing "word" characters, which include letters, digits and underscore, but not /
), then evaluates
exec('/path/to/python3', '/path/to/script')
The replaces the program running in the current process with a Python interpreter, passing the path to the script as an argument.
If I read between the lines correctly, you want to to run /path/to/../env/bin/python3
instead of /path/to/python3
. In order to achieve that, use either of the following:
#!/usr/bin/perl -e$_=$ARGV[0];exec(s/\w+$/..\/env\/bin\/python3/r,$_)
or
#!/usr/bin/perl -e$_=$ARGV[0];exec(s{\w+$}{../env/bin/python3}r,$_)
/
needs to be escaped by \
when /
is used as the delimiter (first solution), but we can change the delimiter to produce a more readable result (second solution).
That shebang you presented causes the arguments to be absorbed. Replace the $_
with @ARGV
to pass them on.
#!/usr/bin/perl -e$_=$ARGV[0];exec(s{\w+$}{../env/bin/python3}r,@ARGV)
#!
as the path (i.e. no arguments allows), and some have very strict limits as to the length of the path.