Beefy Boxes and Bandwidth Generously Provided by pair Networks
Just another Perl shrine
 
PerlMonks  

How to capture system return code when command launched in the background?

by ecomeau (Initiate)
on May 02, 2010 at 11:50 UTC ( [id://837986]=perlquestion: print w/replies, xml ) Need Help??

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

I am trying to launch a Java application in the background from Perl using the system command and capture the return code as a failure when the java command fails to launch the application. In the example below the bogus.jar file does not exist.
my $cmd = 'java -jar bogus.jar > bogus.log 2>&1 &'; system($cmd) == 0 or die "Failed to run command: [$cmd]\n"; if ($? == -1) { print "failed to execute: $!\n"; } elsif ($? & 127) { printf "child died with signal %d, %s coredump\n", ($? & 127), ($? & 128) ? 'with' : 'without'; } else { printf "child exited with value %d\n", $? >> 8; }
  • Comment on How to capture system return code when command launched in the background?
  • Download Code

Replies are listed 'Best First'.
Re: How to capture system return code when command launched in the background?
by moritz (Cardinal) on May 02, 2010 at 12:16 UTC
    The execution of the program (java) in the background is actually successful. It's just that later on java decides to exit with a non-successful return value.

    In general you have to wait for the external program to terminate to obtain its exit code. I'm not sure if waitpid or wait support obtaining the return value; if not you have to fork yourself, and start the program in foreground, and collect the return value, and then use some IPC to signal that back to the parent process. Sounds nasty...

    Luckily IPC::Run abstracts that away with start() and finish() - which I'd recommend to use.

Re: How to capture system return code when command launched in the background?
by ikegami (Patriarch) on May 02, 2010 at 16:38 UTC
    You're not the one launching it in the background (the shell is), so you can't find out. If you have launched it in the background yourself, wait and waitpid would set $? as system does.
Re: How to capture system return code when command launched in the background?
by samarzone (Pilgrim) on May 03, 2010 at 06:27 UTC

    Why do you want to run it in the background if you want its exit code, which will only be known after the command is finished (successfully or unsuccessfully)?

    If your concern is not to block the prompt in case the command successfully runs, run your perl script in background instead

      The Java program is a daemon process that I need to launch, runs continuously in the background listening to a JMS queue and writhing out XML messages. The Perl program scans the directory for XML files (messages from the JMS client written out) and reads them in. When the Perl program is launched, it needs to check if the JMS daemon is running and if not start it.

      I am going to implement a small sleep after the system call, then recheck if the process is running. If not exit with an error.

      Thanks Everyone for the helpful replies.

        I think that djb's daemontools could really help you here. Let daemontools handle the java process. The daemontools will take care of starting and restarting the java process, and they will also take care of reliable logging and safe log rotation. Daemontools have a reliable way to find out if a daemon is running or not (svok for programs, svstat for humans). Daemontools have a reliable way of controlling a daemon (svc). So all you need to do is to invoke svok and perhaps svc. You don't even have to check if the daemon is already running, svc -u /service/java-daemon does nothing if the java daemon is already running.

        You could also consider using the inotify / dnotify API instead of scanning for files, and have your Perl script wait for any output of the java process. Your perl script could perhaps also run as a daemon under control of daemontools. You would get automatic restarts and logging for free ...

        Alexander

        --
        Today I will gladly share my knowledge and experience, for there are no sweeter words than "I told you so". ;-)

Log In?
Username:
Password:

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

How do I use this?Last hourOther CB clients
Other Users?
Others browsing the Monastery: (1)
As of 2024-04-24 16:53 GMT
Sections?
Information?
Find Nodes?
Leftovers?
    Voting Booth?

    No recent polls found