Парамико процесс заканчивается рано

Я пытаюсь запустить команду на нескольких компьютерах, но команда запускается и почти сразу завершается. Запуск занимает некоторое время, поэтому я просто хочу начать, а затем перейти к следующему компьютеру.

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)

Кто-нибудь знает, как запустить процесс, а затем завершить сеанс без завершения процесса?


person SirParselot    schedule 08.04.2017    source источник
comment
Команда завершается немедленно или запускается через некоторое время?   -  person Stephen Rauch    schedule 09.04.2017
comment
Вы представляете себе что-то, что потоки не решат?   -  person Stephen Rauch    schedule 09.04.2017
comment
@StephenRauch Выполнение команды должно занять некоторое время, но она преждевременно прерывается   -  person SirParselot    schedule 09.04.2017


Ответы (1)


Вы можете запустить команду с nohup, чтобы отключить сигнал зависания, и закончить ее с & для работы в фоновом режиме. Теперь ваш ssh может выйти, и он будет продолжать работу. При создании каталогов вам следует дождаться завершения exec_command, на всякий случай, если система на мгновение замедлится. Я объединил обе марки в одну, так что ждать осталось только одно. Кроме этого, я добавил только nohup и & в команду net.

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
person tdelaney    schedule 09.04.2017
comment
Это не решает проблемы. Я заметил, что если я запускаю команду вручную, она печатает PID, но не тогда, когда я выполняю ее через скрипт. - person SirParselot; 09.04.2017
comment
Я просто хочу начать, а затем перейти к следующему компьютеру - nohup отсоединяет stdout / err, а затем команда выполняется в фоновом режиме. Если вы хотите двигаться дальше, вы не увидите вывода программы. Если вы хотите получить результат, другой способ - запустить их все в потоках. - person tdelaney; 09.04.2017
comment
Независимо от того, использую ли я nohup или нет, я получаю тот же результат и результат. Я также пробовал это решение, и оно тоже не сработало. - person SirParselot; 09.04.2017
comment
Вы не увидите вывода, если закроете соединение. В моих тестах это сработало. Выложу рабочий пример. - person tdelaney; 09.04.2017
comment
Я добавил рабочий пример, чтобы у нас было что-то общее для сравнения. - person tdelaney; 09.04.2017