Reputation: 4199
Problem Statement --
I display a message to user using Perl and takes an input.On the basis of input I decide whether I need to do further processing or not.This processing takes a long time ( say 5 hour) and user run this process by logging into remote Unix/Linux system.Hence to make sure that network malfunctioning will not affect the process; I want to switch the process to background.
How can I switch such running Perl process to background?
or
Is it possible to take user input from current terminal( the terminal from where user run process as input need to be taken at very starting) if process is running into background?
OS - Linux variants
Upvotes: 2
Views: 852
Reputation: 1482
Here is a very, very simple example for my comment above...
#!/usr/bin/perl
use strict;
use warnings;
my $lcnt = 0;
if( !$ARGV[0] ) { # If no ARGS on the command line, get user input
print "How many lines do you want to print?";
chomp( $lcnt = <STDIN> );
if( $lcnt > 0 ) {
# when we are sure we have what we need
# call myself.pl and put it in the background with '&'
my $cmd = "./myself.pl ".$lcnt.' &';
system($cmd);
exit(0);
} else { die "Invalid input!\n"; }
} else { # Otherwise, lets do the processing
$lcnt = $ARGV[0];
for( my $x = 0; $x <= $lcnt; $x++ ) {
my $cmd = "echo 'Printing line: $lcnt' >> /tmp/myself.txt";
system($cmd);
sleep(1);
}
}
exit(0);
If you save this to a file called 'myself.pl' then run it. With no arguments on the command line, the script will ask you to input a number. Type in 20 and press enter. You'll see the script exit almost instantly. But if you quickly
tail -f /tmp/myself.txt
you'll see that the background process is still running, printing a new line to the file every second. Also, typing the 'ps' command on Linux systems, should show the spawned process running in the background:
jlb@linux-f7r2:~/test> ps
PID TTY TIME CMD
1243 pts/1 00:00:00 bash
4171 pts/1 00:00:00 myself.pl
4176 pts/1 00:00:00 ps
Upvotes: 2
Reputation: 1360
Yup, you want to daemonize your program after it finishes its interaction with the user. I would encourage you to use a module like Proc::Daemon
to do the work, though: there are a bunch of subtleties in doing it correctly. The POD for Proc::Daemon
gives a good description of its usage, but a simple usage can be as basic as
use Proc::Daemon;
# ... finished the interactive stuff
my $pid = Proc::Daemon::Init( { work_dir => '/var/run/my_program' })
exit 0 if ($pid == 0);
die "Error daemonizing, cannot continue: $!\n" if ($! != 0);
# ... now do the background processing
# note that STDOUT and STDERR are no longer connected to the user's terminal!
Upvotes: 4
Reputation: 5348
Demonise the process if the correct input:
#test input
if($inputsuccess) {
if(fork() = 0) {
#child
if(fork() = 0) {
#child
#background processing
}
} else {
wait();
}
}
Upvotes: 2