2014-09-01 219 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"