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

Alright, there may be a very simple answer to this question that I have missed, but here goes...

I'm writing a perl script that needs to provide a number of different interfaces (e-mail wrapper, CGI, and command line namely). What I need to know is how the script was run. Was it called as an e-mail wrapper, CGI script, from the command line?

I know that I can check on the existance of certain %ENV keys, but I'm not certain how portable or reliable some of those are. Is $ENV{LOGNAME} only set for e-mail wrappers running under Linux with sendmail? Will that same one exist on SunOS running Postfix? Questions like these trouble me, and I cannot answer them.

Is there a better way than checking %ENV and hoping that these are reliable on 'x' OS with 'y' mail server or 'z' web server? ;-)

(Also, before someone suggests it, I know I can just have the bulk of the code in an external module and then have small script-shells that are specific for each interface. I'm just trying to avoid that because I ultimately don't know what interfaces I will finally choose on using for this particular script)

Replies are listed 'Best First'.
Re: How was my script ran?
by jsprat (Curate) on Mar 05, 2003 at 01:26 UTC
    How about testing if STDIN is a tty - if yes, the script is run from the command line. If not, it's a CGI or the e-mail wrapper. CGI sets several HTTP_* variables, check one of these. If set, it's CGI. If not, e-mail wrapper.

    # Note - not very thoroughly tested if (-t STDIN) { # command-line } elsif (defined $ENV{SERVER_NAME}) { # CGI - I used SERVER_NAME, as it _should_ be set } else { # e-mail }

    Now I can't guarantee how portable this is, as I didn't test the e-mail part at all - and I can only test Win2K and FreeBSD. Good luck!

      That's a good idea, but if the script is being called by cron or at (or Windows Scheduled Event :o), will STDIN be a tty? I have no idea, come to think of it, as what STDIN would be identifiable in that circumstance. Or is the point moot -- will this script never be automated?

      LAI
      :eof

        Yeah, I thought of that too. Another one - if the script gets its input via a pipe, the -t will return false. I'm sure there are more scenarios that we haven't thought of yet.

        BTW, windows actually starts a shell for a perl script, so -t returns true. On FreeBSD (and other *nix, I'm sure), -t returns false for a cron job.

Re: How was my script ran?
by criswell (Initiate) on Mar 05, 2003 at 00:45 UTC

    Okay, I'm replying to my own post because I've thought of one way to do this... but it's still not 100% satisfactory for what we need right now... So I want to eliminate it from the discussion before it's suggested.

    One thing I could do is make alias links for the program:

    $ ln -s actual-script.pl mail-version
    $ ln -s actual-script.pl cgi-version
    etc.

    and then just check $0. But that's still not very portable (perhaps portability for a script like this is too much to ask ;-)

      This and the ENV methods are probably about as portable as you are going to get, if you want total, complete portability under all circumstances, you will likely have to pass the version as an argument.

        Okay, follow-up question: Is there someplace I could find out what ENV keys I should be expecting in general with these things? I mean, I would assume $ENV{"SENDER"} is probably pretty universal among MTAs/MDAs calling a perl script, but others seem pretty OS/MTA/MDA/webserver specific and I would like to avoid using those ;-)