使用Fabric和nohup无法真正将SSH隧道放到后台运行

3

我似乎无法让Fabric与我已经使用nohup的进程背景运行良好。. . .鉴于各种信息,包括这里这里,这应该是可能的。

def test():
h = 'xxxxx.compute-1.amazonaws.com'    
ports = [16646, 9090, 6666]

with settings(host_string = h):
    tun_s = "ssh  -o StrictHostKeyChecking=no -i ~/.ssh/kp.pem %s@%s " % (env.user, h)      

    for port in ports:
        p_forward = "-L %d:localhost:%d" % (port, port)
        tun_s = "%s %s" % (tun_s, p_forward)

    tun_s = "%s -N" % tun_s
    # create the tunnel. . .
    print "creating tunnel %s" % tun_s
    run("nohup '%s' >& /dev/null < /dev/null &" % tun_s)
    print "fin"

缩略输出:

ubuntu@domU-xxx:~/deploy$ fab test
executing on tunnel ssh  -o StrictHostKeyChecking=no -i ~/.ssh/kp.pem ubuntu@xxx  -L 16646:localhost:16646 -L 9090:localhost:9090 -L 6666:localhost:6666 -N
[xxx.compute-1.amazonaws.com] run: nohup 'ssh  -o StrictHostKeyChecking=no -i ~/.ssh/kp.pem ubuntu@xxx.compute-1.amazonaws.com  -L 16646:localhost:16646 -L 9090:localhost:9090 -L 6666:localhost:6666 -N' >& /dev/null < /dev/null &
fin

Done.
Disconnecting from xxxx

我知道隧道命令本身没有问题,因为如果我去掉nohup的部分,它可以正常工作(但显然Fabric会挂起)。我相当确定它没有正确地分离,当运行函数返回时,隧道进程立即死亡。

但是为什么呢?

我的代码另一部分中也出现了这种情况。


你为什么要使用nohup?如果你问我,这是多余的。 - sehe
你尝试过使用-T禁用ssh的tty分配,以及使用pty=False禁用任务的tty分配吗? - favoretti
@sehe,为什么这是多余的?我应该如何分离进程,以便Fabric可以返回而不会导致隧道死亡? - Edwardr
@Edwardr 我不熟悉 Fabric,但 ssh 在 -N 上后台运行就足够让我能够退出 shell、注销、终止 XServer 而不影响以这种方式启动的隧道。 - sehe
@favoretti 我尝试了这两个方法,但都不行。谢谢。 - Edwardr
显示剩余3条评论
1个回答

0

所以,经过多番争执,似乎我的设置(默认的Ubuntu在EC2实例上安装)不可能实现这个功能。我不知道为什么,因为根据各种来源似乎是可能的。

我通过使用Paramiko替换Fabric,解决了我的特定问题,用于需要在后台持续运行的调用。以下是实现此目的的方法:

import paramiko
ssh = paramiko.SSHClient()
ssh.set_missing_host_key_policy(paramiko.AutoAddPolicy())
privkey = paramiko.RSAKey.from_private_key_file('xxx.pem')
ssh.connect('xxx.compute-1.amazonaws.com', username='ubuntu', pkey=privkey)
stdin, stdout, stderr = ssh.exec_command("nohup ssh  -f -o StrictHostKeyChecking=no -i     ~/.ssh/xxx.pem ubuntu@xxx.compute-1.amazonaws.com -L 16646:localhost:16646 -L -N >& /dev/null < /dev/null &")
ssh.close()

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接