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

Hello fellow Monks,

The scripts that I write on Win32 often call out to external programs, rkill and tail being two common ones. I could rewrite some of these in pure-perl, but I'm lazy, low on time, and some of these scripts are inherited and not easily changed.

Anyways, my question is, how can I check for the existence of a command I'll be calling before I'm in too deep?

As an example, I have code which runs like so:
foreach my $k (%serverlist) { system("tail \\\\$k\\logfiles\\$serverlist{$k}\\logfile.log --lin +es=$lines > temp"); }
and I'd like to verify 'tail' is somewhere in my path before I call it.

Thanks all!!

ibanix

$ echo '$0 & $0 &' > foo; chmod a+x foo; foo;

Replies are listed 'Best First'.
Re: Verifiying an external program exists
by Paladin (Vicar) on Jan 24, 2003 at 05:22 UTC
    I don't run Win myself, so I can't test this, but perhaps something like:
    sub isExe { my $exe = shift; my @paths = split /;/, $ENV{PATH}; foreach my $path (@paths) { return 1 if -x $path/$exe; } return 0; }
    Call it like:
    if (isExe("tail.exe")) { print "tail.exe is in my PATH.\n" }

      I was just about to start writing something like this myself, when I saw this comment. Unfortunately, I realized it wasn't that easy just after. There are two major reasons.

      The first is that windows will often allow you to run programs that aren't on your path, if they're registered properly in the Registry. Specifically, if HKEY_(LOCAL_MACHINE|CURRENT_USER)\Software\Microsoft\Windows\CurrentVersion\App Paths\$exe exists, and has it's default value set to an existing file... I think. There seem to be some cases on my machine that would indicate a more complex pattern.

      The second is that there are other executable extensions, beyond the common .exe. There's .com and .pif, .bat, and on NT, .cmd. In fact, CMD (the shell under NT) allows you to set whatever you want to be considered as executables; echo %PATHEXT% at a prompt (or perl -e 'print $ENV{PATHEXT}', if you prefer).

      Update: Fixed spelling errors.


      Warning: Unless otherwise stated, code is untested. Do not use without understanding. Code is posted in the hopes it is useful, but without warranty. All copyrights are relinquished into the public domain unless otherwise stated. I am not an angel. I am capable of error, and err on a fairly regular basis. If I made a mistake, please let me know (such as by replying to this node).

Re: Verifiying an external program exists
by mojotoad (Monsignor) on Jan 24, 2003 at 07:35 UTC
Re: Verifiying an external program exists
by zengargoyle (Deacon) on Jan 24, 2003 at 06:31 UTC

    sorta ugly but it's ugly week ... you could try running the program with a choice of options that should produce known results. have you checked CPAN?

    ... my $last_line = `tail $0 --lines=1`; $last_line =~ /^the last line/ or die "non-functional tail"; ... __END__ the last line

    or maybe '--version'.

Re: Verifiying an external program exists
by Aristotle (Chancellor) on Jan 24, 2003 at 16:40 UTC
    Try File::Tail. I don't know just what rkill does, but chances are there's a module for it. As a bonus, the script will (be easy to get to) work wherever these modules are installed, if that's a concern. (I always keep it in mind, if only fleetingly.)

    Makeshifts last the longest.

      I can be sure that my coworkers all have 'tail' installed, but I can't ask them all to install File::Tail. But thanks for the idea.

      Cheers,
      ibanix

      $ echo '$0 & $0 &' > foo; chmod a+x foo; foo;