Open mhemery opened 1 year ago
Invalid syntax. What else to expect?
Sometimes languages will add an exception to allow shebang syntax on the first line. Mechanically, this would mean ignoring the first line of the file if it starts with #!
, treating it as a comment. With this feature, users on the terminal could mark the file as executable with chmod +x program.pl
and execute it directly like ./program.pl
without having to name the interpreter explicitly every time. Shells that execute a file that starts with a shebang will start the identified interpreter with the filename as the first argument instead.
This can be nice for integrating into unix-y systems. While it works out of the box with the many scripting languages that use #
as a comment symbol (python, perl, ruby) some languages that use different comment symbols will allow shebang on the first line as a specific exception. RosettaCode.org lists a number of examples of this: https://rosettacode.org/wiki/Native_shebang
This may or may not be a good fit for scryer-prolog, but it would certainly be useful for interacting with scryer-prolog in a shell environment.
I played around with it and actually found a very hacky way to do this with scryer-prolog in bash today:
$ cat test.pl
/*usr/bin/env scryer-prolog "$0" "$@" ; exit #*/
run :- write(hello),nl,halt.
:- initialization(run).
$ chmod +x test.pl
$ ./test.pl
hello
The way this works is that this test.pl
is both a valid shell file and prolog file. So when executing as a shell file the first line finds and executes /usr/bin/env
after searching for the glob pattern /*usr/bin/env
. env
then executes scryer-prolog "test.pl"
which runs the prolog file as a module and halts; of course it ignores the first line as a comment /* ... */
. Then the shell continues and executes the next command after ;
, which is exit
which stops execution so the rest of the file (which is not valid shell) is ignored. The #
makes the shell evaluator ignore the */
that closes the comment for prolog. (Thanks to the comment from johannesloetzsch for this last tweak!)
I don't know what to think about this.
As far as I can tell, that's ingenious!
It remains valid Prolog syntax, and can also be used as a shell file.
Great summary, @infogulch. I would much prefer a non-hacky solution, like having scryer-prolog ignore the shebang, similar to what SWI-Prolog does.
@infogulch, one minor improvement: Instead of /*/bin/env
rather use /*usr/bin/env
which should reduce the search overhead.
... and avoids exploits with /tmp/bin/env
...
/usr/bin/env scryer-prolog "$0" "$@" ; exit /
Nice polyglot hack :+1:
When I run it, it works, but also shows an error at the end:
./test.pl
hello
./test.pl: line 1: exit: */: numeric argument required
It can be simply fixed, by adding an additional #
behind the exit
to prevent sh
from evaluating the */
. The fixed shebang line than looks like this:
/*usr/bin/env scryer-prolog "$0" "$@" ; exit #*/
The rather typical shebang kills scryer prolog.
my minimal example is a file with just :
#! prolog