1

I am Run Perl CGI Script. In which i am running SCP Command. But I want that command to be run into background and exit the script. But Still Web page waiting for Finish the script. I m doing like :

system ("scp -r machinename:/path/to/file/for/copy/ /path/for/destination/directory/  &");

But it is not working fine. Still it is waiting for Finish the script. Please help me out.

And Also Tell me how to get output of SCP on webpage using Perl CGI: I am doing like this:

system ("scp -r machinename:/path/to/file/for/copy/ /path/for/ destination/directory/ 2>&1 &");
derobert
  • 49,731
  • 15
  • 94
  • 124
  • 2
    possible duplicate of [How can I spawn a long running process in a Perl CGI script?](http://stackoverflow.com/questions/3203845/how-can-i-spawn-a-long-running-process-in-a-perl-cgi-script) – Quentin Jan 12 '12 at 11:32
  • @Quentin: That isn't an exact duplicate—in that one, the person wants the web server to *wait* for all the chained processes to finish. In this question, the OP wants the web server to *not wait.* – derobert Jan 12 '12 at 16:18
  • Why do you want to shell out to `scp` instead of using the [Net::SCP](https://www.metacpan.org/module/Net::SCP)? You don't have to use the module, but I'm curious if you considered it. – brian d foy Apr 05 '12 at 02:27

2 Answers2

1

When you're running in CGI, the standard filehandles (STDIN, STDOUT, STDERR) all go back to the webserver. You need to close them in your child process:

my $pid = fork();
if (! defined $pid) {
    ...
} elsif (0 == $pid) {
    # child
    close(STDIN);
    close(STDOUT);
    chose(STDERR);
    exec { 'scp' } 'scp', 'file', 'user@host:/path/to/file';
} else {
    ...
}

Alternatively, you can reopen them somewhere more useful (e.g., STDIN from /dev/null, STDOUT and STDERR to your own log file):

open STDIN, '<', '/dev/null'
    or confess "Failed to reopen STDIN";

You can also use FD_CLOEXEC with fcntl (and that'll probably even work if you keep your existing system call instead of changing to explicit fork/exec).

Depending on web server, you may need to do other things (e.g., become session leader with POSIX::setsid.

All of this is conveniently done for you by the Proc::Daemon module.

I suggest you also look at IPC::Run3, especially for when you want to capture scp output and send it to the browser. It'll allow you to easily get that output back into a scalar, which you can then format and print easily.

derobert
  • 49,731
  • 15
  • 94
  • 124
0

This might help: scp as a background process

and for perl there is another question:

How can I run Perl system commands in the background?

Community
  • 1
  • 1
GO.exe
  • 646
  • 7
  • 13
  • Thank 4 Reply But You misunderstood the Question. I want to do via Perl CGI. Manually i know how to do but how to do via Perl CGI – Navrattan Bansal Jan 12 '12 at 11:30
  • 1
    http://stackoverflow.com/questions/2711520/how-can-i-run-perl-system-commands-in-the-background then this might help better – GO.exe Jan 12 '12 at 11:35