2014-09-01 214 views
0

我試圖運行下面的命令作爲bash腳本的一部分,它假設打開ssh通道,在遠程機器上運行該程序,將輸出保存到文件10秒,殺死正在寫入文件的進程,然後將控制權交還給bash腳本。從bash腳本中kill ssh或和遠程進程

#!/bin/bash 
ssh hostname '/root/bin/nodes-listener > /tmp/nodesListener.out </dev/null; sshpid=!$; sleep 10; kill -9 $sshpid 2>/dev/null &' 

不幸的是,它似乎做的是在啓動程序:遠程節點監聽器,但它從來沒有得到任何進一步的,它不會把控制權交給了bash腳本。所以,停止執行的唯一方法是按Ctrl + C。

因爲ssh並沒有幫助(或者說不能執行),因爲控制器沒有使用bash腳本,因爲它等待ssh會話中的命令完成,這當然不會發生,因爲它必須是殺死停止。

回答

0

下面是你在遠程系統上運行命令行:

/root/bin/nodes-listener > /tmp/nodesListener.out </dev/null 
sshpid=!$ 
sleep 10 
kill -9 $sshpid 2>/dev/null & 

你應該把它改成這樣:

/root/bin/nodes-listener > /tmp/nodesListener.out </dev/null & <-- Ampersand goes here 
sshpid=$! 
sleep 10 
kill -9 $sshpid 2>/dev/null 

你想開始nodes-listener,然後在10秒後殺死它。爲此,需要啓動nodes-listener作爲後臺進程,以便執行此命令行的shell在啓動節點偵聽器後繼續前進到下一個命令。命令行中的&位置不正確,僅適用於kill命令。您需要將其應用於節點偵聽器命令。

我還會注意到你的sshpid=!$行不正確。你想要sshpid=$!$!是在後臺啓動的最後一個命令的進程ID。

0

您需要將與號的第一個命令後,然後把剩下的命令到下一行:

​​

順便說一句,已經執行的所有命令後SSH正在恢復。這確實意味着它也會關閉分配的pty。如果在該shell會話中仍有後臺作業正在運行,則會由SIGHUP導致死亡。這意味着,您可能可以省略明確的kill命令。 (取決於nodes-listener是否以不同方式處理SIGHUP和SIGTERM)。有了這個,你可以簡化代碼如下:

ssh hostname -- sh -c '/root/bin/nodes-listener > /tmp/nodesListener.out </dev/null & 
sleep 10' 
+0

謝謝。我的命令是bash腳本的一部分。爲什麼我需要指定它是明確的bash? – DOgl 2014-09-01 15:20:25

+0

您的命令遠程運行,由ssh觸發。正如我所說的,ssh不會啓動一個shell並在其中執行命令。它將簡單地使用'execve'(或朋友)來執行命令。但是你的命令並不是更多的shell腳本。這就是爲什麼你需要在shell中執行它 – hek2mgl 2014-09-01 15:21:58

+0

它抱怨:「sh:bash:找不到」如果我運行它 - bash -c – DOgl 2014-09-01 15:31:05

0

我已經通過將shell腳本推送到遠程機器並在那裏執行解決了這個問題。它實際上不太整潔,並且依賴於遠程計算機上可用的空間。

由於我的遠程機器是一個小型的物理設備,空間使用的問題很重要(即使是在這種情況下需要的微小空間)。

/root/bin/nodes-listener > /tmp/nodesListener.out </dev/null & 
sshpid=!$ 
sleep 20 
sync 
# killing nodes-listener process and giving control back to the base bash 
killall -9 nodes-listener 2>/dev/null && echo "nodes-listener is killed"