Как запустить фоновые задания с paramiko? - PullRequest
6 голосов
/ 04 февраля 2010

Вот мой сценарий: я пытаюсь автоматизировать некоторые задачи с помощью Paramiko. Задачи нужно запускать в следующем порядке (используя обозначения (хост, задача)): (A, 1), (B, 2), (C, 2), (A, 3), (B, 3) - - по сути, запуск серверов и клиентов для некоторого тестирования в правильном порядке. Кроме того, поскольку в тестах работа сети может быть испорчена, а поскольку мне нужны некоторые результаты тестов, я бы хотел просто перенаправить вывод в файл.

В аналогичных сценариях общий ответ - использовать screen -m -d или nohup. Однако с exec_cmd от Paramiko nohup фактически не завершается. Использование:

bash -c -l nohup test_cmd & 

тоже не работает, exec_cmd все еще блокирует до конца процесса.

В случае экрана перенаправление вывода работает не очень хорошо, (на самом деле, работает не во всем лучшем, что я могу выяснить).

Итак, после всего этого объяснения у меня возникает вопрос: есть ли простой элегантный способ отсоединить процессы и захватить вывод таким образом, чтобы положить конец блокировке exec_cmd в Paramiko?

Обновление

Команда dtach прекрасно работает для этого!

Ответы [ 3 ]

4 голосов
/ 16 ноября 2011

без использования nohup или screen.

def command(channel, cmd):
    channel.exec_command(cmd + ' > /dev/null 2>&1 &')

здесь написано: «Перенаправить STDOUT из cmd в dev / null, затем перенаправить STDERR обратно в STDOUT, который переходит в / dev / null. Затем перенести его в фоновый режим».

exec_command не будет зависать на любом выходе (он не приходит), поэтому он вернется.

0 голосов
/ 14 июля 2011

Для этого я написал небольшой скрипт оболочки, который выполняю на удаленной стороне:

#!/bin/bash

# check for command line arguments
if [ $# -lt 2 ]; then
        echo "usage: runcommand.sh EXECUTIONSTRING TASKNAME"
        exit -1
fi

taskname=$2
execstr=$1
logfile=$taskname.log

echo START $taskname > $logfile
echo OWNPID $BASHPID >> $logfile
stime=`date -u +"%Y-%m-%d_%H-%M-%S"`
stimes=`date -u +"%s"`
echo STARTTIME $stime >> $logfile
echo STARTTIMES $stimes >> $logfile
# execute program
$execstr 1>$taskname.stdout 2>$taskname.stderr 
echo RETVAL $? >> $logfile

stime=`date -u +"%Y-%m-%d_%H-%m-%S"`
stimes=`date -u +"%s"`
echo STOPTIME $stime >> $logfile
echo STOPTIMES $stimes >> $logfile
echo STOP $taskname >> $logfile

Что он делает: выполняет заданную задачу, перенаправляет вывод stdout, stderr в два разных файла и создает файл журнала, который сохраняет время запуска задачи, ее завершение и возвращаемое значение задачи.

Затем я сначала копирую скрипт на удаленный хост и выполняю его там с помощью exec_command:

command = './runcommand.sh "{execpath}" "{taskname}" > /dev/null 2>&1 &'
ssh.exec_command(command.format(execpath=anexecpath, taskname=ataskname)
0 голосов
/ 04 февраля 2010

Я ничего не знаю о paramiko, и это exec_cmd, но, возможно, bash s disown может помочь.

#!/bin/bash -l
test_cmd &
disown test_cmd
...