szabgab has asked for the wisdom of the Perl Monks concerning the following question:

I'd like to write a perl script (an interpreter for a simple language) that by itself can be used as in the sh-bang of scripts written in simple language. Eg. my simple language interpreter (sli.pl) would look like this:
#!/usr/bin/perl print "Welcome to Simple Language\n"; print "$ARGV[0]\n"; # the name of the real file ? # process the code written in simple language
and the code written in the simple language would look like this:
#!/home/gabor/bin/sli.pl do something in simple language

Replies are listed 'Best First'.
Re: perl script used as sh-bang
by merlyn (Sage) on Jan 22, 2005 at 14:17 UTC
    The sh-bang notation was introduced in one of the early BSD releases (I think it was either 2.8BSD or maybe one of the 4.x series), some 15 or so years ago. At that time, the text after the sh-bang was limited to about 32 characters, and a single argument, and the path had to point at a "real" executable, all to keep this feature simple in the kernel.

    I'm not aware of any current release of a unix-like thing that has taken the trouble to change that behavior.

    You can use PAR to compile your Perl-script into a real executable, which can then be used on a sh-bang line. However, unless you're using libperl.so, you'll then have a completely separate Perl interpreter running for every instance of your application as well, meaning that you lose the benefit of the normally-common read-only pages of all existing Perl scripts. This has performance implications, although it won't affect the possibility of running the script.

    -- Randal L. Schwartz, Perl hacker
    Be sure to read my standard disclaimer if this is a reply.

Re: perl script used as sh-bang
by hv (Prior) on Jan 22, 2005 at 14:48 UTC

    I'd have thought you could write a simple C wrapper that execs perl with the interpreter and the 'simple language' script as its arguments, much as we recommend for suid perl scripts.

    All the script needs to do is create a copy of its arguments with the interpreter script inserted at the right place; I'm a bit rusty on this, but I think it should look something like:

    #include <unistd.h> #include <stdlib.h> char* perl = "/usr/bin/perl"; char* target = "/home/gabor/bin/sli.pl"; int main(int argc, char* argv[]) { char** argv2 = (char**)malloc(sizeof(char*) * (argc + 2)); int i; argv2[0] = argv[0]; argv2[1] = target; for (i = 1; i < argc; ++i) { argv2[i + 1] = argv[i]; } argv2[argc + 1] = (char*)NULL; return execv(perl, argv2); }

    Hugo

Re: perl script used as sh-bang
by BUU (Prior) on Jan 22, 2005 at 19:11 UTC
    As to your first question, theres a very nifty module named HashBang that:
    This CPAN distribution will install a binary program on your system called 'hashbang'. You can use this program to write your own hashbang style interpreters in Perl. Let's say you've implemented a language called foo in a file called foo.pl. Put the file in the same directory as the hashbang executable. And then create a symbolic link from foo to hashbang. Like this:
    cd /usr/bin cp ~/foo.pl . ln -fs hashbang foo
    As for the rest, I wrote a simple perl language interpreter in a perl script, it's really fairly simple to do, if you're interested let me know and I get it uploaded someplace.
Re: perl script used as sh-bang
by gaal (Parson) on Jan 22, 2005 at 15:25 UTC
    Minor note, you probably mean $0 up there, not $ARGV[0]. This is not a pip^H^H^Hc program :)
      Pardon my stupidity, but in the above example, since the print "$ARGV[0]\n"; # the name of the real file ? is in the script 'sli.pl' wouldn't replacing it with $0 actually return 'sli.pl'?
        You are correct; I was under the impression that was what the OP wanted. Now I'm not sure :)

        The shebang mechanism does put the interpreted script in argv[1] (to use the common c name), so yes, if what's mean by "real file" is the file in the target language, $ARGV[0] should be used in the interpreter.