使用python远程操作另一台主机

paramiko
使用python的Paramiko模块,可以在程序内部创建一个连接到远程主机的SSH通道,通过这个连接,你可以向远程主机发送指令。

使用pip安装paramiko

pip install paramiko

1. 远程执行指令

想要远程执行指令,需要远程主机开放端口22,并且知道ssh登录所用的用户名和密码

import paramiko


host = 'ip'
username = 'username'
password = 'password'

# 连接到服务器
coon = paramiko.SSHClient()
coon.set_missing_host_key_policy(paramiko.AutoAddPolicy())
coon.load_system_host_keys()
coon.connect(host, username=username, password=password)

stdin, stdout, stderr = coon.exec_command('ls')

if stderr.read() == b'':        # 没有发生错误
    for line in stdout.readlines():
        print(line.strip())
else:
    print(stderr.read())

set_missing_host_key_policy方法是制定连接远程主机没有本地密钥或HostKeys对象时的策略,有3种:

  1. AutoAddPolicy,自动添加主机名及主机密钥到本地HostKeys对象,并保存,不依赖load_system_host_keys()的配置,即使~/.ssh/known_hosts不存在也不产生影响
  2. WarningPolicy,用于记录一个未知的主机密钥的python警告,并接受它,功能上与AutoAddPolicy相似,但未知主机会有告警
  3. RejectPolicy,自动拒绝不知的主机名和密钥,依赖 load_system_host_keys()的配置

远程执行的命令的输出结果,都会返回到本地,如果stderr读取不到内容,就说明命令正常执行。

2. 从本地上传文件到远程主机

如果想将本地的文件上传到远程主机上,需要安装scp模块

pip install scp

下面的代码演示如何从本地上传文件

import paramiko
from scp import SCPClient

host = 'ip'
username = 'username'
password = 'password'

# 连接到服务器
coon = paramiko.SSHClient()
coon.set_missing_host_key_policy(paramiko.AutoAddPolicy())
coon.load_system_host_keys()
coon.connect(host, username=username, password=password)

with SCPClient(coon.get_transport()) as scp:
    scp.put('test.py', '/root')     # 将test.py文件上传到远程主机的/root目录下

2. 执行远程主机上的程序

执行远程主机上的程序,不过是执行一条命令而已,所需要考虑的是,是否需要等待程序结束。

如果希望立即返回,将程序输出重定向即可,反之,和执行普通命令一样。如果想启动后台进程,可以用一个小技巧,在命令后面加$!,可以获得进程的pid,如此,可以监控远程主机上进程是否存在。

在远程主机/root目录里新建一个work.py文件

import time

time.sleep(20)

这个脚本会执行20秒的时间,在本地远程执行它并监控进程。

import time
import paramiko

host = 'ip'
username = 'username'
password = 'password'

# 连接到服务器
coon = paramiko.SSHClient()
coon.set_missing_host_key_policy(paramiko.AutoAddPolicy())
coon.load_system_host_keys()
coon.connect(host, username=username, password=password)

stdin, stdout, stderr = coon.exec_command("nohup python /root/work.py >/tmp/work.log 2>&1 & echo $!;")
pid = stdout.read().decode().strip()

while True:
    stdin, stdout, stderr = coon.exec_command('ps -p ' + pid)
    if len(stdout.readlines()) < 2:
        break
    time.sleep(1)

print("进程结束")

本文对paramiko进行了简单的介绍,所实现的功能都非常简单,想对远程主机进行更便捷的操作,推荐使用fabric库,它封装提供了更为强大和完善的功能。

扫描关注, 与我技术互动

QQ交流群: 211426309

加入知识星球, 每天收获更多精彩内容

分享日常研究的python技术和遇到的问题及解决方案