2

问题陈述 -

我使用 Perl 向用户显示一条消息并进行输入。根据输入,我决定是否需要进行进一步处理。此处理需要很长时间(例如 5 小时),用户通过登录远程运行此过程Unix/Linux系统。因此确保网络故障不会影响进程;我想将进程切换到后台。

如何将这种正在运行的 Perl 进程切换到后台?

或者

如果进程正在运行到后台,是否可以从当前终端获取用户输入(用户运行进程作为输入的终端需要在开始时获取)?

操作系统 - Linux 变体

4

3 回答 3

4

是的,您希望在程序完成与用户的交互后将其守护。不过,我鼓励您使用类似的模块Proc::Daemon来完成这项工作:正确地完成工作有很多微妙之处。POD forProc::Daemon很好地描述了它的用法,但是一个简单的用法可以是基本的

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!
于 2013-10-04T17:47:39.383 回答
2

这是我上面评论的一个非常非常简单的例子......

#!/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);

如果你把它保存到一个名为“myself.pl”的文件中,然后运行它。命令行上没有参数,脚本会要求你输入一个数字。输入 20 并按回车键。您将看到脚本几乎立即退出。但如果你很快

tail -f /tmp/myself.txt

您会看到后台进程仍在运行,每秒向文件打印一个新行。此外,在 Linux 系统上键入“ps”命令,应该会显示在后台运行的衍生进程:

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
于 2013-10-04T21:04:52.590 回答
2

如果输入正确,则妖魔化过程:

#test input
if($inputsuccess) {
    if(fork() = 0) {
        #child
        if(fork() = 0) {
            #child
            #background processing
        }
    } else {
       wait();
    }
}
于 2013-10-04T16:45:37.763 回答