如何使用 paramiko 启动后台作业?

发布于 2024-08-21 00:34:56 字数 544 浏览 14 评论 0原文

这是我的场景:我正在尝试使用 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 仍然阻塞到进程结束。

在屏幕情况下,输出重定向效果不太好(实际上,我所能想到的根本不起作用)。

因此,在所有这些解释之后,我的问题是:是否有一种简单优雅的方法来分离进程并捕获输出,从而结束 paramiko 的 exec_cmd 阻塞?

更新

dtach 命令非常适合此操作!

Here is my scenario: I am trying to automate some tasks using Paramiko. The tasks need to be started in this order (using the notation (host, task)): (A, 1), (B, 2), (C, 2), (A,3), (B,3) -- essentially starting servers and clients for some testing in the correct order. Further, because in the tests networking may get mucked up, and because I need some of the output from the tests, I would like to just redirect output to a file.

In similar scenarios the common response is to use 'screen -m -d' or to use 'nohup'. However with paramiko's exec_cmd, nohup doesn't actually exit. Using:

bash -c -l nohup test_cmd & 

doesnt work either, exec_cmd still blocks to process end.

In the screen case, output redirection doesn't work very well, (actually, doesnt work at all the best I can figure out).

So, after all that explanation, my question is: is there an easy elegant way to detach processes and capture output in such a way as to end paramiko's exec_cmd blocking?

Update

The dtach command works nicely for this!

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(3

久随 2024-08-28 00:34:56

不使用 nohup 或 screen。

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

这表示“将 STDOUT 从 cmd 重定向到 dev/null,然后将 STDERR 重定向回 STDOUT,后者进入 /dev/null。然后将其推入后台。”

exec_command 不会挂起任何输出(不会出现),因此它会返回。

without using nohup or screen.

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

this says "Redirect STDOUT from cmd into dev/null, then redirect STDERR back into STDOUT, which goes into /dev/null. Then push it into the background."

exec_command wont get hung up on any output (thats not coming), thus it'll return.

扮仙女 2024-08-28 00:34:56

我对 paramiko 一无所知,它是 exec_cmd,但也许 bash 的 disown 可以提供帮助。

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

I don't know anything about paramiko and it's exec_cmd, but maybe bash's disown could help.

#!/bin/bash -l
test_cmd &
disown test_cmd
橘香 2024-08-28 00:34:56

为此,我编写了一个在远程端执行的小 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

它的作用:执行给定的任务,将 stdout、stderr 的输出通过管道传输到两个不同的文件,并创建一个日志文件,该日志文件在任务启动时保存,它完成并返回任务的值。

然后我首先将脚本复制到远程主机并使用 exec_command 执行它:

command = './runcommand.sh "{execpath}" "{taskname}" > /dev/null 2>&1 &'
ssh.exec_command(command.format(execpath=anexecpath, taskname=ataskname)

For this purpose I wrote a small shell script which I execute on the remote side:

#!/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

What it does: executes a given task, pipes the output of stdout, stderr to two different files and creates a logfile which saves when the task was started, when it finished and the return value of the task.

Then I first copy the script to the remote host and execute it there with exec_command:

command = './runcommand.sh "{execpath}" "{taskname}" > /dev/null 2>&1 &'
ssh.exec_command(command.format(execpath=anexecpath, taskname=ataskname)
~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文