如何使用paramiko启动后台任务?
这是我的情况:我想用Paramiko来自动化一些任务。这些任务需要按照特定的顺序启动(用(主机,任务)表示):(A,1),(B,2),(C,2),(A,3),(B,3)——基本上是为了测试而按正确的顺序启动服务器和客户端。此外,由于在测试中网络可能会出现问题,而且我需要一些测试的输出,所以我想把输出直接重定向到一个文件里。
在类似的情况下,常见的解决办法是使用'screen -m -d'或者'nohup'。但是使用Paramiko的exec_cmd时,nohup并不能真正退出。使用:
bash -c -l nohup test_cmd &
也不行,exec_cmd仍然会阻塞,直到进程结束。
在使用screen的情况下,输出重定向效果也不好(实际上,按照我所能理解的,根本就不行)。
所以,经过这些解释,我的问题是:有没有简单优雅的方法来分离进程并捕获输出,以便结束Paramiko的exec_cmd阻塞?
更新
dtach命令对此非常有效!
3 个回答
0
为此,我写了一个小的shell脚本,在远程机器上执行:
#!/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
这个脚本的作用是:执行一个指定的任务,把标准输出和错误输出分别保存到两个不同的文件中,并创建一个日志文件,记录任务开始的时间、结束的时间和任务的返回值。
接着,我先把这个脚本复制到远程主机上,然后用exec_command在那边执行它:
command = './runcommand.sh "{execpath}" "{taskname}" > /dev/null 2>&1 &'
ssh.exec_command(command.format(execpath=anexecpath, taskname=ataskname)
0
我对paramiko和它的exec_cmd一点都不了解,不过也许可以试试bash
里的disown
命令。
#!/bin/bash -l
test_cmd &
disown test_cmd
4
不使用nohup或screen。
def command(channel, cmd):
channel.exec_command(cmd + ' > /dev/null 2>&1 &')
这段话的意思是:“把命令的正常输出(STDOUT)发送到一个叫做dev/null的地方,然后把错误输出(STDERR)重新发送到正常输出,这样它们也就去了/dev/null。最后,把这个过程放到后台运行。”
这样做的话,exec_command就不会因为没有输出而卡住,所以它会正常返回。