2013-11-01 31 views
0

我已閱讀了有關此主題的許多線索,並嘗試了我遇到的所有內容:> /dev/null,qx,system,exec,fork,cmd with | (在win32下工作,但現在我正在移植到使用prefork MPM的CentOS),echo |現在還有Proc :: Daemon,但我還沒有嘗試過Apache2 :: Subprocess,因爲它看起來正是我不想要的東西,這是一個與父代綁定的線程。如何從mod_perl2中釋放一個殺死父項的進程

也許我的情況有所不同。在長時間運行的數據庫恢復過程結束時,我想重新啓動腳本運行的httpd服務。拋開這種設計的智慧問題,我該怎麼做?我試過的每種方法都會在執行的一半時立即停止腳本,因此它不會再次自行啓動。

一個例外是回聲|現在看起來很有希望,但是如果我複製一些在命令行上執行並在mod_perl腳本中執行的東西時,我會得到一個不錯的成功聲音行,例如job 1 at 2013-10-31 19:20,但沒有任何反應。沒有帶有now -m的shell郵件,沒有帶2>&1和/或> /path/with/all/777/perms的錯誤消息,沒有來自我自己的模塊的電子郵件,通常在任何die上執行此操作,沒有自動記錄所有內容的日誌文件。儘管成功,但只是沉默失敗。

萬一有幫助,這裏就是service httpd stop運行:

stop() { 
     echo -n $"Stopping $prog: " 
     kill -TERM `cat ${pidfile}` 
     RETVAL=$? 
     if [ $RETVAL = 0 ] && rm -f ${lockfile} ${pidfile} 
     then success 
     else failure 
     fi 
     echo 
} 

這似乎之前很簡單,有這麼多建議的解決方案,但他們都不做。還有什麼要檢查或嘗試?

+1

雙分叉和/或開始一個新的會話和/或開始一個新的進程組。檢出Daemon :: Daemonize,如果不使用它,則使用它的代碼。 – ikegami

+0

@ikegami,我安裝了Daemon :: Daemonize,沒有選項,它不起作用,並且'close =>'std',它也不起作用。在這兩種情況下,該進程都會與其父進程一起死掉,並且無法成功重新啓動httpd。我不確定雙叉應該如何幫助,如果兩個新進程在父進程時仍然死機。 – Kev

+0

也就是說,我將我的'system()'調用放在Daemonize的'run'子目錄中。 – Kev

回答

0

終於成功的是從Apache2 :: SubProcess的文檔中竊取提示。

在mod_perl腳本中,我只是做qx($command 2>&1),雖然其他方法也可能工作。

然後在腳本中調用在$命令,我只是把這些線的httpd重新啓動之前:

use POSIX 'setsid'; 
setsid or die "Can't start a new session: $!"; 

它不會永遠返回mod_perl的腳本,這是很好的,因爲我重定向到一個反正日誌顯示頁面。

與此同時,包含重新啓動的腳本通過舊的STDOUT重定向生成日誌,然後通過電子郵件發送給我,如果有的話die s。

此外,包含重新啓動的腳本通常可以從命令行運行,因爲它也是用來執行的。