在 Python 中创建和维护多个 ssh 会话

发布于 2025-01-06 01:30:55 字数 274 浏览 0 评论 0原文

一旦我的程序启动,它就会打开任意数量的 ssh 会话(用户定义)并无限期地在服务器上运行特定命令(当真正循环时)或直到用户退出。出于效率原因,我只想创建每个会话一次,然后能够运行命令直到用户退出。

我怎样才能在Python中做到这一点?我在另一篇文章中遇到了一个很酷的方法,它使用 subprocess 来运行命令并捕获其 STDOUT。如何首先启动会话,然后运行循环命令?

任何指向 Python 中类似流程的内容的链接也将不胜感激。这是我的第一个 python 应用程序。

Once my program has been launched, it opens any number of ssh sessions (user defined) and runs specific commands on the servers indefinitely (while true loop) or until the user quits. For efficiency reasons I want to create each session only once, then be able to run the commands until the user quits.

How can I do this in python? I ran across a cool method in another post which used subprocess to run a command and capture its STDOUT. How can I first initiate the session, then run looped commands?

Any links to process-like stuff in Python would also be appreciated. This is my first python application.

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

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

发布评论

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

评论(4

阳光的暖冬 2025-01-13 01:30:55

暂时忽略 Python,您可以通过将其添加

ControlMaster auto
ControlPath /tmp/ssh_mux_%h_%p_%r
ControlPersist 1h

~/.ssh/config 文件来复用 ssh 会话。连接到计算机一次后,与该计算机的 ssh 会话将保持打开状态,随后的命令将在该计算机上几乎立即执行。然后,您可以使用 Python 子进程调用 ssh 并根据需要在该机器上执行命令,并且会话将被重用,而无需执行任何特殊操作。

如果您不想使会话多路复用成为默认行为(或者您正在部署对于可能没有将其作为默认值的其他用户)。

Ignoring Python for the moment, you can multiplex ssh sessions by adding this

ControlMaster auto
ControlPath /tmp/ssh_mux_%h_%p_%r
ControlPersist 1h

to your ~/.ssh/config file. After connecting to a machine once, the ssh session to this machine will stay open, and subsequent commands will execute on this machine near-instantaneously thereafter. You could then use Python subprocess to call ssh and execute commands on that machine as-needed, and the session will be reused without having to do anything special.

You could also call ssh with the -F flag pointing to an alternate config file, if you'd rather not make the session multiplexing the default behavior (or you're deploying for other users who might not have it as their default).

久夏青 2025-01-13 01:30:55

选项 1:
您可以通过使用 PIPE 重定向输入来重新使用 ssh 进程。

这是一个基本示例:

[(Z) </tmp> ]% touch input_file
[(Z) </tmp> ]% tailf input_file | ssh <remote_host>

现在尝试在文件中写入一些内容

[(Z) </tmp> ]% echo "date" >> /tmp/input_file

这是在 Python 中使用 subprocess 模块使用此功能的方法。

import subprocess
SSH_CMD = "cat -| /usr/bin/ssh -o PasswordAuthentication=no -T -x %s "
HOSTNAME = "127.0.0.1"
s = subprocess.Popen(SSH_CMD%HOSTNAME , shell=True, close_fds=True, 
stdin=subprocess.PIPE, stderr=subprocess.PIPE, stdout=subprocess.PIPE)

这将启动一个可以重复使用的子进程。请注意,由于已知错误 (http://bugs. python.org/issue2320)。

>>> REMOTE_CMD = "date"
>>> s.stdin.write( REMOTE_CMD +
... "\necho 'remote command completed with exit code = '$?\n")
>>> s.stdout.readline()
'Thu Feb 16 20:01:36 PST 2012\n'
>>> s.stdout.readline()
'remote command completed with exit code = 0\n'

echo 'remote command Completed with exit code = '$?\n 行用于了解远程命令已完成并且已完成对 s.stdout 的写入。这对于了解远程命令的退出代码也很有用。

使用同一个子进程执行另一个远程命令:

>>> REMOTE_CMD = "uptime"
>>> s.stdin.write( REMOTE_CMD +
... "\necho 'remote command completed with exit code = '$?\n")
>>> s.stdout.readline()
' 20:02:17 up 28 days,  9:15, 48 users,  load average: 0.01, 0.02, 0.05\n'
>>> s.stdout.readline()
'remote command completed with exit code = 0\n'

回到你的问题,一旦创建了 ssh 子进程,你就可以继续发送远程命令。一旦用户退出,您可以终止子进程。

>>> s.kill()

选项 2:我从未使用过此选项,但 ssh 有一个用于重新使用 ssh 的 ControlMaster 选项。检查 ssh_config(5) 的手册页

OPTION 1:
You can re-use a ssh process by redirecting input using a PIPE.

Here is a basic example:

[(Z) </tmp> ]% touch input_file
[(Z) </tmp> ]% tailf input_file | ssh <remote_host>

Now try writing something into the file

[(Z) </tmp> ]% echo "date" >> /tmp/input_file

Here is a way to make use of this in Python using subprocess module.

import subprocess
SSH_CMD = "cat -| /usr/bin/ssh -o PasswordAuthentication=no -T -x %s "
HOSTNAME = "127.0.0.1"
s = subprocess.Popen(SSH_CMD%HOSTNAME , shell=True, close_fds=True, 
stdin=subprocess.PIPE, stderr=subprocess.PIPE, stdout=subprocess.PIPE)

This starts a subprocess which can be re-used. Please note that close_fds=True is required because of a known bug (http://bugs.python.org/issue2320).

>>> REMOTE_CMD = "date"
>>> s.stdin.write( REMOTE_CMD +
... "\necho 'remote command completed with exit code = '$?\n")
>>> s.stdout.readline()
'Thu Feb 16 20:01:36 PST 2012\n'
>>> s.stdout.readline()
'remote command completed with exit code = 0\n'

echo 'remote command completed with exit code = '$?\n line is used to know that the remote command finished and it is done writing to s.stdout. This is also useful to know the exit code of the remote command.

To use the same subprocess for executing another remote command:

>>> REMOTE_CMD = "uptime"
>>> s.stdin.write( REMOTE_CMD +
... "\necho 'remote command completed with exit code = '$?\n")
>>> s.stdout.readline()
' 20:02:17 up 28 days,  9:15, 48 users,  load average: 0.01, 0.02, 0.05\n'
>>> s.stdout.readline()
'remote command completed with exit code = 0\n'

Coming back to your question, once you create a ssh subprocess, you can keep sending the remote commands. Once the user is quits, you can kill the subprocess.

>>> s.kill()

OPTION 2: I have never used this, but ssh has a ControlMaster option for re-using ssh. Check man page for ssh_config(5)

一页 2025-01-13 01:30:55

尝试使用 pexpect 模块。它允许打开和维护 ssh 会话,您可以重复使用这些会话来发送多个命令。您可以发送任何命令并期望特定的输出,您可以根据这些输出执行其他逻辑操作。

Try using pexpect module. It allows opening and maintaining ssh sessions, which you can reuse to send in multiple commands. You can send in any commands and expect particular outputs based on which you can perform other logical operations.

秋千易 2025-01-13 01:30:55

尝试将其与多线程混合吗?

Tried mixing it up with multithreading?

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文