http://qs321.pair.com?node_id=140474

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

We package a version of perl with our commercial software product. (yes, yes boo on me for selling closed source; i don't like it either but one has to pay the bills.) Of course, there's no way to know in advance exactly where a client will install our software - as in what directory structure they will use. So I have to write scripts all the time that need to first find perl, and then run the main body of the code. Since I can depend on sh just about everywhere, for Unix I have a sh script which finds perl for me based on some ENV variables that our software always sets and the runs perl using the old  exec $PERL -x $0 $* trick, $PERL having been set by the sh portion of the code (I'll include full code below for the curious). What I need is a win32 batch script equivalent of this and I don't even know where to begin. Any win32 peeps out there think they can help? I hope this question is clear enough.... =]

We speak the way we breathe. --Fugazi

#!/bin/ksh # -*- perl -*- # these are the varibles you change ####################################### IGNORE_NO_USER=N # 'Y' or 'N' ####################################### # DONT CHANGE STUFF AFTER THIS ARCH=$(uname -s)$(uname -r) if [[ $ARCH = "SunOS5.5.1" ]]; then ARCH=SunOS5.5 elif [[ $(echo $ARCH|grep -c "HP-UXB.10") -gt 0 ]]; then ARCH=HP-UXB.10 elif [[ $(echo $ARCH|grep -c "HP-UXB.11") -gt 0 ]]; then ARCH=HP-UXB.11 elif [[ $(echo $ARCH|grep -c "Linux2.2") -gt 0 ]]; then ARCH=Linux2.2 fi BIN=$HOME/bin/$ARCH if [[ ! -d $BIN ]]; then echo "ERROR: \$BIN not found ($BIN)" exit 1 fi LD_LIBRARY_PATH=$HOME/lib/$ARCH if [[ $(echo $ARCH|grep -c "HP-UXB") -gt 0 ]]; then export SHLIB_PATH=$HOME/lib/$ARCH:$SHLIB_PATH fi PLAT=$(uname -s) PERL=$HOME/tools/bin/$PLAT/perl if [[ ! -x $PERL ]]; then echo "ERROR: \$PERL not found ($PERL)" exit 1 fi export HOME ARCH BIN PLAT LD_LIBRARY_PATH IGNORE_NO_USER exec $PERL -x $0 $* #--------------------------------------------------------------------- +---------- #!/bin/perl # # perl code starts after this

Replies are listed 'Best First'.
Re: win32 perl script when you don't know where perl is
by Corion (Patriarch) on Jan 22, 2002 at 00:42 UTC

    On Win32, "both" (that is, IndigoPerl and ActiveState Perl) Perl distributions install themselves in the path during the setup, and both come with the perl2bat.bat batch file, that (tries to) convert(s) any Perl program to a batch file.

    The bootstrap code looks like this :

    @rem = '--*-Perl-*-- @echo off if "%OS%" == "Windows_NT" goto WinNT perl -x -S "%0" %1 %2 %3 %4 %5 %6 %7 %8 %9 goto endofperl :WinNT perl -x -S "%0" %* if NOT "%COMSPEC%" == "%SystemRoot%\system32\cmd.exe" goto endofperl if %errorlevel% == 9009 echo You do not have Perl in your PATH. goto endofperl @rem '; #!perl #line 14 eval 'exec perl -x -S "$0" ${1+"$@"}' if 0; # In case running under some shell require 5; ... Perl program begins ...

    You could either simply use this, as any installed Perl is supposedly also in the path, or you could start from there with something crude like :

    set DRIVES=c d e f g h echo Scanning for perl.exe for %%d in %DRIVES% dir %%d:\ /s /b perl.exe |find /i "Perl.exe"
    and then let the user choose the version of Perl she wants to use. Note that people (or at least I) can have multiple versions of Perl installed, but most versions of Perl should be at least Perl 5 - so if your install script is self-reliant, you should be in the green.
    perl -MHTTP::Daemon -MHTTP::Response -MLWP::Simple -e ' ; # The $d = new HTTP::Daemon and fork and getprint $d->url and exit;#spider ($c = $d->accept())->get_request(); $c->send_response( new #in the HTTP::Response(200,$_,$_,qq(Just another Perl hacker\n))); ' # web
      I'm starting to see how this can be done. A few points and questions.

      - I will have an ENV var with the path where Perl will be
      - I can use %HOME%\perl to get the right perl I think (trying now)
      - I can also know what win32 I'm on in advance, or, at least, make a select the right vresion of a script

      Questions:

      what does the line perl -x -S "%0" %1 %2 %3 %4 %5 %6 %7 %8 %9 mean? Specifically all the numbered variables at the end...look like lines, but I don't know.

      what do you mean by "In case running under some shell"?

      I'm sorry if the questions are dumb. I literally know nothing about windows you can't see on the desktop...

      We speak the way we breathe. --Fugazi

        I'm going to offer some different advice.

        Personally, I wouldn't count on perl.exe being in the path. I don't know about IndigoPerl, but the ActivePerl installation gives you the option of adding the perl/bin folder to the path, but it's not mandatory.

        I don't let setup programs add things to %PATH% (apart from a few special exceptions), because I want a bit more control over what gets executed, and where. So I generally add things to PATH manually, or write a quick wrapper to the executable that I want frequent access to. I'm not saying that it's a good or bad thing to do, but I don't think I am alone in guarding my environment variables.

        This is my suggestion: install your own copy of perl along with your commercial application. The Perl licenses (Perl Artistic License) allow for this. You should simply be able to compile your own version of perl, add the modules needed (check their licenses too.) and include those compiled files in the setup distribution of the commercial application. This has several benefits.

        • You know WHERE Perl is installed
        • You know THAT Perl is installed
        • You know what version of Perl is installed

        The downside is of course, that you increase the size of your distribution by several MB. If you need a reason convince the bosses, tell them that you will be able to provide better support for your software and clients. If your clients run Perl already, it won't break your application if they upgrade it or add modules, or uninstall it, etc.

        Just make sure you've covered all the licensing issues before you do this.

        Update: I've just re-read your original post, and you package Perl with the application already. So perhaps it's not too far fetched to just bundle a compiled version with only the bits you need. It may even reduce the overall size, and you won't clobber a perl installation that may already exist.

        Simon Flack ($code or die)
        $,=reverse'"ro_';s,$,\$,;s,$,lc ref sub{},e;$,
        =~y'_"' ';eval"die";print $_,lc substr$@,0,3;
Re: win32 perl script when you don't know where perl is
by screamingeagle (Curate) on Jan 22, 2002 at 00:23 UTC
Re: win32 perl script when you don't know where perl is
by johannz (Hermit) on Jan 22, 2002 at 03:22 UTC

    Using the Perl Power Tools: Unix Reconstruction Project, there is a perl-only version of 'which' that might help.

    You might be able to take this, and build off of it to run your code. Of course, if you have '.pl' in your PATHEXT environment variable on windows, you can just run perl scripts without the '.pl' extension, assuming that perl is in your path, which the installer normally sets.

(jptxs)Re: win32 perl script when you don't know where perl is - my solution
by jptxs (Curate) on Jan 22, 2002 at 02:45 UTC
    with a little help from my friends here and abroad:
    @echo off rem Have echo follow the ECHO environment variable. Used for debugging +. if not {%ECHO%} == {} echo %ECHO% rem Make sure this is Windows NT. if not {%OS%} == {Windows_NT} goto :NOT_NT rem Set path for Windows commands. set WINEXE="%windir%\system32" rem Save the current environment and directory. setlocal pushd . if defined PERL goto :RUNPERL if not defined HOME ( for /f "tokens=*" %%i in ('cd') do set home=%%i ) if not defined HOME ( set HOME=%home:\tools\script=% ) if not exist "%HOME%\World" ( echo ERROR: Cannot determine HOME ^(please set it manually^) goto :DONE ) set OLDHOME=%HOME% if exist "%OLDHOME%\bin\Windows2000" set OLDARCH=Windows2000 if exist "%OLDHOME%\bin\WinNT4.0" set OLDARCH=WinNT4.0 set ARCH=%OLDARCH% set BIN=%HOME%\bin\%ARCH% if not exist "%BIN%" ( echo ERROR: BIN not found ^(BIN^) goto :DONE ) set LD_LIBRARY_PATH=%HOME%\lib\%ARCH% set PLAT=%ARCH% set PERL=%HOME%\tools\bin\%PLAT%\perl if not exist "%PERL%.exe" ( echo ERROR: perl not found ^(%PERL%.exe^) goto :DONE ) for /f "tokens=*" %%i in ('hostname') do set HOSTNAME=%%i :RUNPERL rem echo running PERL rem CMD /c %PERL%.exe %0 rem goto :DONE if exist "%HOME%\tools\script\%1.pl" ( call "%PERL%.exe" "%HOME%\tools\script\%1.pl" %2 ) else ( echo ERROR: %HOME%\tools\script\%1.pl doesn't exist ) goto :DONE :DONE popd & endlocal goto :EOF :NOT_NT rem ////////////////////////////////////////////////////////////////// +/////// rem This is not Windows NT. rem This procedure must fall through to the end of the file, for compa +tibility. echo This script requires Windows NT. rem ////////////////////////////////////////////////////////////////// +///////

    We speak the way we breathe. --Fugazi