Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/python/304.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Python 使用Paramiko通过SSH执行reboot命令_Python_Linux_Ssh_Paramiko - Fatal编程技术网

Python 使用Paramiko通过SSH执行reboot命令

Python 使用Paramiko通过SSH执行reboot命令,python,linux,ssh,paramiko,Python,Linux,Ssh,Paramiko,我用于建立与某个目标设备的SSH连接,我想执行reboot命令 ssh = paramiko.SSHClient() ssh.set_missing_host_key_policy(paramiko.AutoAddPolicy()) ssh.connect(zip_hostname, username=username, password=password, timeout=1) try: stdin, stdout, stderr = ssh.exec_command("/sbin/r

我用于建立与某个目标设备的SSH连接,我想执行
reboot
命令

ssh = paramiko.SSHClient()
ssh.set_missing_host_key_policy(paramiko.AutoAddPolicy())
ssh.connect(zip_hostname, username=username, password=password, timeout=1)
try:
    stdin, stdout, stderr = ssh.exec_command("/sbin/reboot -f")
    # .........
    # some code
    # .........
except AuthenticationException, e:
    print ''
finally:
    ssh.close()

但在执行
ssh.exec_命令(“/sbin/reboot-f”)
后,“某些代码”不会执行,因为程序卡在
exec_命令中(重新启动会导致断开连接)。我应该如何解决我的问题?

从ssh获取传输并使用以下命令设置keepalive:

transport = ssh.get_transport()
transport.set_keepalive(5)
这将持续
5
秒;请注意,我本以为
超时=1
也会达到同样的效果。

试试这个:

ssh.exec_command("/sbin/reboot -f > /dev/null 2>&1 &")

重新启动的所有输出被重定向到/dev/null,使其不产生任何输出,并且由于最后的“&”符号,它在后台启动。希望程序不会以这种方式挂起,因为远程shell会返回提示。

您需要做的就是调用
channel.exec\u command()
,而不是调用高级接口
client.exec\u command()


我遇到了这个问题,并通过切换到以下命令来避免它:

/sbin/shutdown -r now
注意此命令不会产生任何
STDOUT
STDERR
输出


如果您或其他任何人无法使用转发代理(ssh密钥)或我的情况(yubikey)尝试使用sudo重新启动主机

如果将其视为bash,则会像下面这样以非root用户的身份重新启动主机

ssh -t -A user@hostname sudo /sbin/reboot
对于-A标志,来自ssh手册页

启用身份验证代理连接的转发。这也可以在中按每台主机指定 配置文件。 应谨慎地启用代理转发。能够绕过上的文件权限的用户 远程主机(用于代理的Unix域套接字)可以通过转发连接访问本地代理。 攻击者无法从代理获取密钥材料,但可以对该密钥执行操作 使他们能够使用加载到代理中的标识进行身份验证*

对于-t标志,来自ssh手册页

强制伪tty分配。这可用于在远程机器上执行任意基于屏幕的程序, 这可能非常有用,例如在实施菜单服务时。多个-t选项强制tty分配,甚至 如果ssh没有本地tty*

因此,让我们将其分解为您在帕拉米科的工作方式

ssh = paramiko.SSHClient()
ssh.set_missing_host_key_policy(paramiko.AutoAddPolicy())
ssh.connect(hostname=host, username=username)
s = ssh.get_transport().open_session()
paramiko.agent.AgentRequestHandler(s)

ssh.exec_command("sudo /sbin/reboot", get_pty=True)
ssh.exec_command("sudo /sbin/reboot", get_pty=True)
用于paramiko的身份验证转发(-bash ssh命令中的标志)

ssh = paramiko.SSHClient() #'ssh' is client variable 
s = ssh.get_transport().open_session() #get 'ssh' transport and open sessions assigned to 's' variable
paramiko.agent.AgentRequestHandler(s) #call in 's' to the forwarding agent for current ssh session
现在为paramiko强制伪tty分配(-bash ssh命令中的t标志)

ssh = paramiko.SSHClient()
ssh.set_missing_host_key_policy(paramiko.AutoAddPolicy())
ssh.connect(hostname=host, username=username)
s = ssh.get_transport().open_session()
paramiko.agent.AgentRequestHandler(s)

ssh.exec_command("sudo /sbin/reboot", get_pty=True)
ssh.exec_command("sudo /sbin/reboot", get_pty=True)
将“get_pty=True”添加到exec_命令将允许您执行sudo/sbin/reboot


希望这能有所帮助,每个人的环境都不同,但它的工作原理应该与作为bash运行时完全相同。

只要持续生成输出,就不会触发keepalive和timeout,因为它们正在测量数据线的连续空闲时间。情况是发出重新启动命令,这将突然终止ssh连接的另一端。keepalive的目的是快速检测这种情况。不完全是这样。令人惊讶的是,当系统向sshd发送一个术语信号时,reboot最终会优雅地终止ssh通道,从而使其正常工作。据我所知,这是OP不想等待的事情。关键是最终。使用
reboot-f
跳过标准关机过程,在这种情况下没有信号发送给sshd;您依赖于TCP超时。不过,我并没有看到与OP相同的问题,所以我认为这一系列评论是没有意义的。