在持续集成任务中,有时候需要在不同的平台上进行自动化测试,完成后获取测试结果。这时就需要先将测试包发送到目标平台,然后传输一些测试命令到目标平台完成测试任务。本文主要总结一些远程执行命令的方式。
paramiko是一个基于SSH用于连接远程服务器并执行相关操作的库。
安装
$ sudo pip3 install paramiko
#!/usr/bin/env python3
# -*- coding:utf-8 -*-
import paramiko
def connect(ip, username, passwd):
try:
# 创建SSHClient对象
client = paramiko.SSHClient()
# 允许连接不在know_hosts文件中的主机
client.set_missing_host_key_policy(paramiko.AutoAddPolicy())
# 连接目标机器
client.connect(ip, 22, username, passwd, timeout=10)
return client
except:
print('connect %s error\n', ip)
def send_command(client, cmd):
try:
# 执行命令并获取输出
stdin, stdout, stderr = client.exec_command(cmd)
return stdout
except :
print('send command error\n')
ip='192.168.0.102'
username='username'
password='PASSWORD'
client=connect(ip, username, password)
cmd='ls'
print(send_command(client, cmd).readlines())
通过SSHClient可以传输指令,而想要传输文件的话,可以使用SFTPCLient,它可以根据ssh传输协议的传输文件。
t = paramiko.Transport(ip, 22)
t.connect(username='username', password='password')
sftp = paramiko.SFTPClient.from_transport(t)
# 传输文件到目标机器
file = 'test.py'
sftp.put(file, '/home/user/test.py')
# 下载目标机器上的文件
sftp.get('/home/user/test.py', './test.py')
t.close()
使用ssh应该是最简单的方式,需要先配置ssh免密登录
$ssh-keygen -t rsa
$ssh-copy-id [email protected]
/usr/bin/ssh-copy-id: INFO: attempting to log in with the new key(s), to filter out any that are already installed
/usr/bin/ssh-copy-id: INFO: 1 key(s) remain to be installed -- if you are prompted now it is to install the new keys
Password:
Number of key(s) added: 1
Now try logging into the machine, with: "ssh '[email protected]'"
and check to make sure that only the key(s) you wanted were added.
传输文件
$scp test_packget.tar.gz [email protected]:/workspace
test_packget.tar.gz 100% 2222 2.2KB/s 00:00
执行命令
$ssh [email protected] "echo test"
test
sshpass用于非交互的ssh密码验证
安装
$sudo apt-get install sshpass
传输文件
$sshpass -p PASSWORD scp test_packget.tar.gz [email protected]:/workspace
执行命令
$sshpass -p PASSWORD ssh [email protected] "echo test"
test
如果需要执行的命令比较多,可以通过下面脚本的形式实现:
#!/bin/bash
sshpass -p PASSWORD ssh [email protected] << remotessh
cd workspace
ls
echo yes
remotessh
“<< remotessh”与“remotessh”之间是需要远程的指令,remotessh可以换成其他的形式。
使用上面这种形式可能会报如下警告:
Pseudo-terminal will not be allocated because stdin is not a terminal.
意思是伪终端将无法分配,因为标准输入不是终端。可以增加-tt参数来强制伪终端分配:
#!/bin/bash
sshpass -p PASSWORD ssh tt [email protected] << remotessh
cd workspace
ls
echo yes
remotessh
输出:
usernamedeiMac:~ username$ cd workspace
usernamedeiMac:workspace username$ ls
test_packget.tar.gz
usernamedeiMac:workspace username$ echo yes
yes
也可以使用-Tq参数
输出:
test_packget.tar.gz
yes
可以明显看到区别
另外还可以通过环境变量传递密码
$export SSHPASS="user_password"
$sshpass -e ssh [email protected] "echo test"
test
如果没有安装ssh可以考虑使用nc进行文件传输。nc是netcat的简写,
首先在目标机上启动接受监听:
$nc -lv 8888 > test.py
然后在本地执行下面命令发送文件到目标机器:
$nc -v 192.168.0.102 8888 < test.py
Connection to 192.168.0.102 8888 port [tcp/*] succeeded!