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

I thought I was submitting a program to run on Unix (solaris) in background mode ("&") by using the following syntax.

@command = ("/bin/nohup /mevs/$version/bin/mevs", "/mevs/$version/data +/config_data/mevs2.cfg", "online"); system(join " ", @command, "&"); # restart pgm in background

However, when I issue the "ps -ef" command the "&" shows up as part of the command line display. I'm wondering now if the "&" is being considered as another $ARGV instead of requesting the program be run in the background. I use the above syntax instead the following:

@command = ("/bin/nohup /mevs/$version/bin/mevs", "/mevs/$version/data +/config_data/mevs2.cfg", "online", "&"); system(@command);

Is the first approach the correct way to submit a job to run in the background?

I am just a little confused and any help you can provide is greatly appreciated. Thanks.

Replies are listed 'Best First'.
Re: Submitting program to background from perl
by Zaxo (Archbishop) on Mar 02, 2005 at 20:02 UTC

    Here's how to do that in perl without any interference from the shell:

    $SIG{CHLD} = 'IGNORE'; { my $cpid = fork; defined $cpid or warn 'Could not fork: ', $! and last; $cpid and last; # child open STDERR, '>>', $errorfile || '/dev/null' or die $!; open STDOUT, '>', $outputfile || '/dev/null' or die $!; open STDIN, '<', $inputfile || '/dev/null' or die $!; $SIG{HUP} = sub {}; exec "/mevs/$version/bin/mevs", "/mevs/$version/data/config_data/mevs2.cfg", 'online'; die $!; } # parent

    That does about what nohup does. That can be further refined by imitating how a daemon starts with POSIX::setsid() to declare the child a session leader and remove itself from a controlling terminal.

    Shell-like access to a background process is neither necessary or desirable in perl. We have finer weapons than that.

    After Compline,
    Zaxo

Re: Submitting program to background from perl
by Fletch (Bishop) on Mar 02, 2005 at 19:38 UTC

    If you pass a single string value to system which has shell metacharacters (such as & in this case) it will use /bin/sh -c to run the command. What you're probably seeing is this shell instance's command line with the ampersand. The alternative is to use fork/exec yourself; see perldoc perlipc.

Re: Submitting program to background from perl
by phaylon (Curate) on Mar 02, 2005 at 20:06 UTC
    The & is interpreted by your shell (probably bash), but you are calling nohup directly. Try calling /bin/sh and nohup as argument.

    hth,phay

    Ordinary morality is for ordinary people. -- Aleister Crowley
exec, not system
by jhourcle (Prior) on Mar 03, 2005 at 00:38 UTC

    You may want to use exec in place of system, to get the backgrounding, without needing to fork and all that other work.

    Update: There are times when you'd want to fork (if you needed to get the final status from when the program finished), and I have no idea what the program is that you're kicking off. But the example given doesn't attempt to capture the return value from system(), and as you're attempting to run it through nohup, in the background, I can only assume that it's not needed.

      I think that I need to fork when using an exec so my perl process doesn't die. Doesn't an exec replace the current process? My perl module must run 24/7 to monitor the remote server program that also must run 24/7 and if the server program hangs, dies, or is unable to access it's database...my perl module must restart it in the background. That's the reason I was using the system call in the first place. Anyway, I am going to play around and see fi I can restruct it using a fork and exec. Thanks.
Re: Submitting program to background from perl
by Anonymous Monk on Mar 02, 2005 at 21:52 UTC
    Thank you for all you suggestions. I will now try to look into utilizing the fork/exec process to restart the program.