scryer-prolog
scryer-prolog copied to clipboard
#! prolog
The rather typical shebang kills scryer prolog.
my minimal example is a file with just : #! prolog
hemery@portablepret:prolog$ ~/scryer-prolog shebang.pl
error(syntax_error(incomplete_reduction),read_term/3:1).
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.
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 ...