2012-01-12 84 views
1

我正在運行Perl CGI腳本。我正在運行SCP Command。但是我想讓這個命令進入後臺並退出腳本。但仍在等待網頁完成腳本。 我這樣做:在使用Perl的背景下運行SCP CGI

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

但它不能正常工作。它仍在等待完成腳本。 請幫我一把。

,並告訴我如何獲得SCP的輸出上使用Perl CGI網頁:我做的是這樣的:

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

可能的重複[我如何在Perl CG中產生一個長時間運行的進程我腳本?](http://stackoverflow.com/questions/3203845/how-can-i-spawn-a-long-running-process-in-a-perl-cgi-script) – Quentin 2012-01-12 11:32:43

+0

@Quentin:那不是'一個精確的重複 - 在那個人中,這個人希望Web服務器*等待所有鏈接進程完成。在這個問題中,OP希望網頁服務器*不要等待。* – derobert 2012-01-12 16:18:06

+0

爲什麼你想蛻化爲'scp'而不是使用[Net :: SCP](https://www.metacpan.org/module /淨:: SCP)?你不必使用模塊,但如果你考慮它,我很好奇。 – 2012-04-05 02:27:02

回答

0

這可能幫助: scp as a background process

和perl的還有另一個問題:

How can I run Perl system commands in the background?

+0

謝謝4回覆 但你誤解了這個問題。 我想通過Perl CGI來完成。 手動我知道該怎麼做,但如何通過Perl CGI – 2012-01-12 11:30:45

+1

http://stackoverflow.com/questions/2711520/how-can-i-run-perl-system-commands-in-the-background然後這可能會幫助更好 – 2012-01-12 11:35:19

1

當你在CGI運行,標準的文件句柄(STDIN,STD OUT,STDERR)全部返回到網絡服務器。你需要關閉它們在你的孩子的過程:或者

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

,您可以(從/ dev/null的,STDOUT例如,STDIN和STDERR到自己的日誌文件)重新打開它們的地方更多有用:

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

您也可以使用FD_CLOEXECfcntl(如果您保留現有的system調用而不是更改爲顯式fork/exec,那麼這可能甚至會起作用)。

取決於Web服務器上,你可能需要做其他的事情(例如,成爲會議領導與POSIX::setsid

所有這一切都方便了您的Proc::Daemon模塊來完成。

我建議你也看看IPC::Run3,特別是當你想要捕獲scp輸出並將其發送到瀏覽器時,它可以讓你輕鬆地將輸出回到標量,然後你可以很容易地格式化和打印。