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

Hey Monks

I've got a system I'm working on consisting of several listings that I've been working on to solve certain parts of the problem. The general format is as follows:

#! /usr/bin/perl package diskman::runner; use strict; use warnings; use XML::Simple; # Accept arguments from the config.xml file my $args = XMLin('config/config.xml') or die "Can not read config.xml\ +n"; # Run the HP utility on every server in the config file foreach my $server (@{$args->{server}}) { system(qq[wine "/home/nathan/.wine/drive_c/Program\ Files/HP\ Remo +te\ System\ Management/"hprsmcli.exe -s $server -u $args->{user} -p $ +args->{pass} -f $args->{fmt} -o $args->{winepath}.$server -t $args->{ +options}]); } # Script is done print "Runner Done\n";

I've got 4 listings like this that I need to tie together in one script. This question is about my options for achieving such a package

Firstly, I know of system, exec, and backticks. If I run it using one of those, how do I know the script was successful and didn't die? Do warnings come back to my "main script"?. Secondly, what is the advantage of the package system? I'm thinking that I didn't design the listings as "modules" in a way that I can interface with them with use. I would just like to run them and return to the main script with some indication of failure or success. Do I need to use any package/use syntax?

Ransom

Replies are listed 'Best First'.
Re: Running script from script
by blue_cowdawg (Monsignor) on Jul 11, 2012 at 15:12 UTC

    Fellow Monk,
    I'm not sure in this context why you are using package in this case at all. Package is normally used when you are creating a module. Given this example of what I'm talking about:

    package myFoo; sub new { return {},"myFoo"; } sub stuff { } 1;
    and in another file:
    use myFoo; my $f = new myFoo(); $f->stuff;

    Of course the example I give is a total NOOP but that's besides the point.

    You formed electrons and spake thusly:

        I would just like to run them and return to the main script with some indication of failure or success.

    That's a rather open ended statement. Without understanding the underlying mechanics of your system invocation with respect to the behavior of the program you are executing with it in my opinion all I can do is give you a speculative answer.

    In my own experience if I am spawning a child process and I want to know if the process is still running I may use one of the following schemes:

    • If there is a socket to the child process I can open and jiggle, write a function to do that.
    • If the child process is running locally check the process table and make sure it is still consuming resources
    • Again if the process if running locally check any resultant log files for signs of life
    • If it is running remotely use a variation of the above.

    Some research you could do is look at Nagios plugin sources and see how they determine if a process is up or not.

    Another observation is that since you are using system are you really kicking off multiple instances of the code you are trying to execute? I've never personally executed Wine from within a Perl script but I'd think that until it finishes execution it is going to block further execution of your script. A way around that is to use fork() and execute your system command within the child process. That way you can check to see if the child PID is still active and if you capture SIGCHLD you can be notified in the parent process when the child dies.

    Hope this helps...


    Peter L. Berghold -- Unix Professional
    Peter -at- Berghold -dot- Net; AOL IM redcowdawg Yahoo IM: blue_cowdawg

      OK confimed my suspicions of my misuse of paskages. The example you gave makes much more sense.

      In an effort to clarify myself, the sentence you quoted is DWIM. This isn't an asynchronous operation, doesn't involve sockets or actual data passage. Think of the listings as a sub that's just in another file. This is a single run operation that will be set up with cron to run a few times a day.

      You're right that running Wine (I imagine any system command running a program?) does block further execution, but thankfully this is exactly what I want to happen.

      Sorry this isn't such an advanced project ;) Thanks for your help

      Ransom
            You're right that running Wine (I imagine any system command running a program?) does block further execution, but thankfully this is exactly what I want to happen.

        Then one of your requirements is solved. That means if the child process dies (if you use fork/exec like I suggest) then you know the process has died.

            Sorry this isn't such an advanced project ;) Thanks for your help
        No project is too basic if it is important to you.


        Peter L. Berghold -- Unix Professional
        Peter -at- Berghold -dot- Net; AOL IM redcowdawg Yahoo IM: blue_cowdawg
Re: Running script from script
by aitap (Curate) on Jul 11, 2012 at 15:03 UTC

    You can check $? after running system(...). Basically, it should be zero if all was successful and >0 otherwise (also -1 if the command failed to run, check $!).

    Wrapping everything in packages is a matter of choice. I don't think it's nessecary to do it in such a small script, other people may disagree with me.

    Sorry if my advice was wrong.

      Ok cool thanks. Found this after looking at your post

      $? = The status returned by the last pipe close, backtick(``) command or system operator. Note that this is the status word returned by the wait() system call, so the exit value of the subprocess is actually ($? >>*). $? & 255 gives which signal, if any, the process died from, and whether there was a core dump.

      Tested it and it seems to work as expected and allows me to handle the errors.

      Ransom
Re: Running script from script
by RedElk (Hermit) on Jul 11, 2012 at 15:26 UTC

    The package system would allow you to separate your "processing" from your "process". Requires a bit more effort, naturally. It could be just as well to wire up your scripts as subroutines within the main. Can't really tell what would be better for you.

    I can only point you to the references for the specifics you need...exec, system, backticks.