2011-09-27 121 views
3

我有一堆腳本用於跨多個服務器啓動類似的進程。我想將它們壓縮成一個叫做'START'的Python腳本,但是當它通過ssh運行時會發生一些奇怪的事情。調用通過ssh創建子進程的Python腳本掛起

$ ./START APP_A按預期工作:APP_A已啓動並開始執行其操作。控制立即返回到控制檯(在APP_A終止之前)。

$ ssh localhost /path_to/START APP_A作品類型:APP_A啓動並開始做它的事情,但ssh不打印任何輸出到屏幕或返回到控制檯控制,直到APP_A終止後。

我認爲這是信號或文件句柄的問題,但我很茫然。這是Popen調用似乎造成的麻煩:

sub = subprocess.Popen(shlex.split(cmd), stdout=open(file_out, 'a+'), stderr=subprocess.STDOUT, close_fds=True) 
print 'New PID:', sub.pid 

我在RHEL上使用Python 2.4.3。

編輯: 包裝紙的Python腳本似乎工作:

DIR="$(cd "$(dirname "$0")" && pwd)" 
pushd $DIR >> /dev/null 
./START $1 & 
popd >> /dev/null 

回答

0

不要使用shlex與子一起叫。 It doesn't do what you expect。相反,給子命令的Python列表,像

subprocess.Popen(['/some/program', 'arg1', 'arg2', 'arg3']) 
+0

如何從ssh啓動腳本與直接調用腳本受此影響?該腳本直接調用時工作正常。 – dmcauslan

0

當你這樣做:

ssh some_host remote_command remote_cmd_param 

則是正常的remote_command完成之前SSH不會返回控制。如果你想,否則你需要將它發送到背景在最後添加&

ssh將remote_command的stdout重定向到其(本地)stdout。如果你沒有看到任何輸出,這可能是因爲remote_command沒有設置任何標準輸出,而是嘗試將它發送到控制檯。這就是爲什麼你不能這樣做:

ssh remote_host mC# or any other command using terminal 
+0

START腳本確實輸出一些調試信息,該信息使用打印輸出到STDOUT。當我直接調用腳本時,程序將顯示此信息並退出。當我通過ssh調用腳本時,只會在子進程終止時打印信息。子進程本身將其他數據記錄到它自己的stdout(在Popen調用中顯式設置)。 – dmcauslan

0

你應該把這個在START_APP_A

nohup /path/to/APP_A >/path/to/log 2>&1 </dev/null & 

然後它會工作,並從APP_A輸出都將進入一個日誌文件,則您可以在檢查需要。

請注意,如果您需要在APP_A運行時檢查此輸出,則需要更改APP_A,以便在打印後刷新標準輸出或將標準輸出更改爲無緩衝。

+0

不是「stdout = open(file_out,'a +'),stderr = subprocess.STDOUT」是否已經重定向IO? – dmcauslan

+0

也許它確實,也許它沒有。當你用shell腳本包裝它的時候,它可以工作,爲什麼不使用shell。另外,我不清楚哪些位在本地運行,哪些位在遠程運行。你錯過的一件事是stdin,它可能或可能不重要。在任何情況下,這一行shell腳本將與任何語言的任何應用程序一起工作,以在您使用ssh連接到的遠程服務器上運行它。閱讀nohup的手冊頁以瞭解更多信息。 –