Beefy Boxes and Bandwidth Generously Provided by pair Networks
"be consistent"
 
PerlMonks  

script running on linux but not windows

by thadc (Novice)
on Dec 19, 2017 at 19:56 UTC ( [id://1205868]=perlquestion: print w/replies, xml ) Need Help??

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

Hello,

I am new to perl. I am using a script, squirrel.pl for running database scripts automatically. It works fine on my linux box, but does not run on windows, and I need it to. I saw some general guidelines for making portable scripts, but this one is over 800 lines long. I am assuming that file paths with back slashes should be converted to forward slashes, but I cannot always tell where backslashes should remain as backslashes. For instance:

I assume all of these need to be converted

$sqlLog = "/opt/devOps/tools/squirrel/logs/squirrel-sql-" . $creationTime . ".log";. ,

but not sure about these:

if($chosenRealm=~/^prd$/ && !@ARGV)

or these:

elsif($connectionNames[$i]=~/4b/)

or these:

elsif($output=~/ORA-01031/ || $output=~/ORA-00942/ || $output=~/ORA-01749/)

Any insights are greatly appreciated. Thank you

Replies are listed 'Best First'.
Re: script running on linux but not windows
by stevieb (Canon) on Dec 19, 2017 at 20:11 UTC

    You can use forward slashes on Windows within Perl, so realistically the only thing that needs to change is the path itself (ie. Windows certainly does not have a /opt/devOps/... directory, more like c:/opt/.... You can however convert them to backslashes if you wish, but I wouldn't bother.

    The other slashes are for regexes and should most definitely not be changed. Only the file paths if you want to.

    However, there may be more that we don't know of, so you'll have to deal with each error as it comes up. It doesn't look like you're using use strict; or use warnings;, so the process may be a bit tedious, but 800 lines shouldn't be very bad at all to convert.

Re: script running on linux but not windows
by toolic (Bishop) on Dec 19, 2017 at 20:08 UTC
    Your first line of code probably needs to change. It specifies a path to a file. The file is likely going to be in a different location anyway. You'd be better off using single quotes for that line.

    You should not change the slashes in the remaining 3 lines of code because they delimit regular expressions.

    but does not run on windows
    You should be able to start to debug where things go wrong. Then you can narrow down your problem and post other, more specific questions: Basic debugging checklist
Re: script running on linux but not windows -- File::Spec
by Discipulus (Canon) on Dec 19, 2017 at 21:05 UTC
    Hello thadc and welcome to the monastery and to the wonderful world of Perl!

    you already got good replies: yes you may need to adjust paths in the form (but as stevieb said c:/path/to is ok within windows) and for their content ( /opt does not exists at all on windows).

    To make the program more portable I suggest you to use the core module File::Spec and all it's utilities: it'sa bit machinery to put in but very good choice in the long term.

    Basically you must abstract the filling of every absolute path you intend to use, in the beginning of the program, then use them freely and safely. Using your example:

    use strict; use warnings; use File::Spec; .. my @prog_dirs; # directory to find the program, still empty if ($^O eq 'MSWin32'){ @prog_dirs = qw(c: Programs devOps tools logs) } elsif $^O eq 'Linux'){ @prog_dirs = qw( opt devOps tools logs) } else{...} my $sqlLog = File::Spec->catfile( @prog_dirs, 'squirrel-sql-'.$creatio +nTime.'.log');

    PS from the same module File::Spec->file_name_is_absolute File::Spec->rel2abs methods are very useful: everytime transform your paths into absolute ones!

    L*

    There are no rules, there are no thumbs..
    Reinvent the wheel, then learn The Wheel; may be one day you reinvent one of THE WHEELS.

      Hello again and thank you for useful feedback. I am making very preliminary progress. I absolutely had to change some file paths up front for:

      #set the log files

      my $creationTime = strftime "%F-%R:%S", localtime;

      $sqlLog = "C:/Users/thclotworthy/squirrel/logs/squirrel-sql-" . $creationTime . ".log";

      $scriptLog = "C:/Users/thclotworthy/squirrel/logs/squirrel-" . $creationTime . ".log";

      However, I am immediately getting error on the following line:

      #Setup filehandlers for the mysql output log and the squirrel log

      open($sqlFh, ">", $sqlLog) or exitOnError("Could not open $sqlLog for writing. Exiting......\n");

      open($scriptFh, ">", $scriptLog) or exitOnError("Could not open $scriptLog for writing. Exiting......\n");

      , where the exit on error is generated. Here is the exit on error subroutine:

      sub exitOnError

      {

          my $errorString = $_[0];

          print $sqlFh "$errorString\n";

          print $scriptFh "$errorString\n";

          print "$errorString\n";

          exit(9);

      }

      , and here is the actual failure message on the terminal:

      print() on closed filehandle $sqlFh at squirrelBAK.pl line 855. Can't use an undefined value as a symbol reference at squirrelBAK.pl line 856.

      , So I am guessing that sqlFh perhaps needs to be initialized and I am not doing that?. The only instance of it before the code above is at the beginning of the script with other parameters:

      my $dbHost; my $dbPort; my $serviceName; my @connectionNames; my %usernames; my %passwords; my $chosenRealm; my $release; my $releasePath; my $sqlLog; my $sqlFh; my $scriptLog; my $scriptFh;

      , So perhaps I supposed to be passing it as a command line argument or something? Grateful for any ideas. Thank you!

        You might be interested in the original error string ($! and $^E) which might tell you more about the problem. Don't use the filehandle to report errors related to the filehandle itself.
        open $sqlFh, '>', $sqlLog or die "Could not open $sqlLog for writing.\ +n$!\n$^E\nExiting...\n";

        BTW, do you know that double quotes interpolate variables?

        $scriptLog = "C:/Users/thclotworthy/squirrel/logs/squirrel-$creationTi +me.log";

        Also, declaring all the variables in one place usually makes their scope too wide. It's better to declare them only for the scope where they're really needed.

        ($q=q:Sq=~/;[c](.)(.)/;chr(-||-|5+lengthSq)`"S|oS2"`map{chr |+ord }map{substrSq`S_+|`|}3E|-|`7**2-3:)=~y+S|`+$1,++print+eval$q,q,a,

        Check that folder C:/Users/thclotworthy/squirrel/logs exists and is writeable to.

        poj
        As debugging 101, I ran the first part of your code (below). Making a simple example for us is good, but in the future please make it a "runnable as is" example.

        An obvious problem is that colon ":" is not valid in a Windows file name. Also regardless of that issue, the complete path does look a bit suspicious to me - that path does not exist on the Windows machine I'm writing this post upon using to write this post.

        #!/usr/bin/perl use strict; use warnings; use POSIX qw(strftime); my $creationTime = strftime "%F-%R:%S", localtime; my $sqlLog = "C:/Users/thclotworthy/squirrel/logs/squirrel-sql-" . $cr +eationTime . ".log"; my $scriptLog = "C:/Users/thclotworthy/squirrel/logs/squirrel-" . $cre +ationTime . ".log"; print "$sqlLog\n$scriptLog\n"; __END__ prints: C:/Users/thclotworthy/squirrel/logs/squirrel-sql--:23.log C:/Users/thclotworthy/squirrel/logs/squirrel--:23.log
        As an extra updated note: I use Windows as my development platform and often move programs to a Unix environment. I try to only use file names that are compatible with both Windows and Unix. For example Windows allows a "space" in the name but Unix does not.(see post by choroba - my recollection of this is was evidently wrong). So I use underscore "_" instead of that (where possible). Of course there are situations on Windows where a space is need, e.g. "My Documents". Always use "/" instead of "\" for path names. That even works from the Windows command line (which BTW is NOT DOS). There are some weird situations where the backslash is needed, but I encounter this so rarely that I can't think of such an example right now. Perl is amazingly good at being multi-platform.

Log In?
Username:
Password:

What's my password?
Create A New User
Domain Nodelet?
Node Status?
node history
Node Type: perlquestion [id://1205868]
Approved by toolic
help
Chatterbox?
and the web crawler heard nothing...

How do I use this?Last hourOther CB clients
Other Users?
Others about the Monastery: (6)
As of 2024-03-29 00:37 GMT
Sections?
Information?
Find Nodes?
Leftovers?
    Voting Booth?

    No recent polls found