Paramiko流程提前结束

时间:2017-04-08 23:14:17

标签: python paramiko

我正在尝试在多台计算机上运行命令,但命令启动然后几乎立即结束。运行需要一段时间,所以我只想启动然后移动到下一台计算机上。

import paramiko

client = paramiko.SSHClient()
client.set_missing_host_key_policy(paramiko.AutoAddPolicy())
un = 'username'
pw = 'password'
version = None
count = 0

for i in xrange(1):
    host = 'hydra' + str(i) + '.eecs.utk.edu'

    try:
        conn = client.connect(host, username=un, password=pw)
    except:
        continue
    count += 1
    stdin, stdout, stderr = client.exec_command('ls ./neuro/networks/anets/')

    #gets highest numbered folder to compute next version
    if version == None:
        version = max(map(int, stdout.read().split())) + 1

    anew = 'mkdir ~/neuro/networks/anets/{}'.format(version)
    bnew = 'mkdir ~/neuro/networks/bnets/{}'.format(version)

    #this is the command that ends too early
    net = 'nice -n 19 ~/neuro/apps/polebalance/bin/PBEO > ~/neuro/networks/anets/{v}/net{pc:02d}_{v}.txt'.format(v=version, pc=i)
    print '.../anets/{v}/net{pc:02d}_{v}.txt'.format(v=version, pc=i)

    stdin, stdout, stderr = client.exec_command(anew)
    stdin, stdout, stderr = client.exec_command(bnew)
    stdin, stdout, stderr = client.exec_command(net)

    client.close()
print 'making {} nets'.format(count)

有没有人知道如何启动进程然后在没有进程终止的情况下终止会话?

1 个答案:

答案 0 :(得分:0)

您可以使用nohup运行命令以禁用挂断信号,并使用&结束该命令以在后台运行。现在你的ssh可以退出,它会继续下去。在制作目录时,您应该等待exec_command完成,以防万一系统运行缓慢。我将两个制作合二为一,所以只有一个等待。除此之外,我只在网络命令中添加了nohup&

import paramiko

client = paramiko.SSHClient()
client.set_missing_host_key_policy(paramiko.AutoAddPolicy())
un = 'username'
pw = 'password'
version = None
count = 0

for i in xrange(1):
    host = 'hydra' + str(i) + '.eecs.utk.edu'

    try:
        conn = client.connect(host, username=un, password=pw)
    except:
        continue
    count += 1
    stdin, stdout, stderr = client.exec_command('ls ./neuro/networks/anets/')

    #gets highest numbered folder to compute next version
    if version == None:
        version = max(map(int, stdout.read().split())) + 1

    anew = 'mkdir ~/neuro/networks/anets/{}'.format(version)
    bnew = 'mkdir ~/neuro/networks/bnets/{}'.format(version)

    #this is the command that ends too early
    net = 'nohup nice -n 19 ~/neuro/apps/polebalance/bin/PBEO > ~/neuro/networks/anets/{v}/net{pc:02d}_{v}.txt &'.format(v=version, pc=i)
    print '.../anets/{v}/net{pc:02d}_{v}.txt'.format(v=version, pc=i)

    stdin, stdout, stderr = client.exec_command(';'.join((anew, bnew)))
    # wait directory creation done
    stdout.read()
    # cmd in background with nohup so won't exit on ssh exit
    client.exec_command(net)
    client.close()

print 'making {} nets'.format(count)

<强>更新

此测试程序通过ssh在本地计算机上运行。每个远程命令都写入我们读取的日志文件,以确保它有效。

from __future__ import print_function

import sys
import os
import paramiko
import getpass
import time

def remote_command(logfile):
    print("remote command", logfile)
    with open(logfile, 'w') as fp:
        pid = os.getpid()
        fp.write('{}: Proof of life, pid {}\n'.format(
            time.ctime(), pid))
        fp.flush()
        for i in range(20):
            print('remote', pid)
            time.sleep(.5)
        fp.write("{}: done\n".format(time.ctime()))

def runner():
    print("Run remote execution test via ssh on local computer")
    username = getpass.getuser()
    password = getpass.getpass()
    my_dir = os.path.abspath(os.path.dirname(__file__))
    my_prog = os.path.abspath(__file__)
    if my_prog[-1] == 'c':
        del my_prog[-1]
    life_files = []
    for i in range(3):
        # remote writes this, but since its really our machine
        # we can read it later.
        life_files.append(os.path.join(my_dir, '{}-{}.text'.format(
            os.getpid(), i)))
        client = paramiko.SSHClient()
        client.set_missing_host_key_policy(paramiko.AutoAddPolicy())
        client.connect('localhost', username=username, password=password)
        cmd = 'nohup {} {} {} &'.format(sys.executable, my_prog, 
            life_files[-1])
        print('running', cmd)
        client.exec_command(cmd)
        client.close()

    print("verify all started")
    time.sleep(2) # allow time for python to start...
    for name in life_files:
        print(open(name).readline(), end='')

    print("verify all ended")
    for i in range(10, 0, -1):
        sys.stdout.write('{}..'.format(i))
        sys.stdout.flush()
        time.sleep(1)
    print()
    for name in life_files:
        print(open(name).read(), end='')

if __name__=="__main__":
    if len(sys.argv) == 1:
        runner()
    elif len(sys.argv) == 2:
        remote_command(sys.argv[1])
    else:
        print("bad command line")
        exit(1)

在我的机器上,结果是

$ python3 test.py
Run remote execution test via ssh on local computer
Password: 
running nohup /usr/bin/python3 /home/td/tmp/test.py /home/td/tmp/27212-0.text &
running nohup /usr/bin/python3 /home/td/tmp/test.py /home/td/tmp/27212-1.text &
running nohup /usr/bin/python3 /home/td/tmp/test.py /home/td/tmp/27212-2.text &
verify all started
Sun Apr  9 13:05:30 2017: Proof of life, pid 27232
Sun Apr  9 13:05:31 2017: Proof of life, pid 27255
Sun Apr  9 13:05:31 2017: Proof of life, pid 27275
verify all ended
10..9..8..7..6..5..4..3..2..1..
Sun Apr  9 13:05:30 2017: Proof of life, pid 27232
Sun Apr  9 13:05:40 2017: done
Sun Apr  9 13:05:31 2017: Proof of life, pid 27255
Sun Apr  9 13:05:41 2017: done
Sun Apr  9 13:05:31 2017: Proof of life, pid 27275
Sun Apr  9 13:05:41 2017: done