paramiko是基于Python实现的SSH2远程安全链接,支持认证及密钥方法。能够实现远程命令执行,文件传输,中间SSH代理等功能,相对于Pexpect,封装层次更高。html
pip install Paramikopython
http://www.paramiko.org/
demo:https://github.com/paramiko/p...mysql
若是在linux环境,还需安装依赖:crypto,ecdsa,python3-devel。linux
paramiko包含两个核心组件:SSHClient类,SFTPClient类nginx
import paramiko, base64,getpass paramiko.util.log_to_file('syslogin.log') #日志记录 try: key=paramiko.RSAKey.from_private_key_file('pk_path') except paramiko.PasswordRequiredException: password = getpass.getpass('RSA key password: ') key = paramiko.RSAKey.from_private_key_file('pk_path', password) # 须要口令的私钥 #key = paramiko.RSAKey(data=base64.decodestring('AAA...')) client = paramiko.SSHClient() # client.get_host_keys().add('ssh.example.com', 'ssh-rsa', key) client.load_system_host_keys()#~/.ssh/known_hosts client.connect('ssh.example.com', 22,username='strongbad', password='thecheat',pkey=key) stdin, stdout, stderr = client.exec_command('ls') # stdin, stdout, stderr=ssh.exec_command('sudo su') # stdin.write('123456') for line in stdout: print('... ' + line.strip('\n')) #使用send # cmds=['sudo su\n', 'cd /var/log\n', 'ls\n'] #利用send函数发送cmd到SSH server,添加'\n'作回车来执行shell命令。注意不一样的状况,若是执行完telnet命令后,telnet的换行符是\r\n # ssh=s.invoke_shell() #在SSH server端建立一个交互式的shell,且能够按本身的需求配置伪终端,能够在invoke_shell()函数中添加参数配置。 # for cmd in cmds: # time.sleep(1) # ssh.send(cmd) #利用send函数发送cmd到SSH server, # out = ssh.recv(1024) #.recv(bufsize)经过recv函数获取回显。 # print out client.close()
##################################################################################### import paramiko paramiko.util.log_to_file('syslogin.log') #日志记录 client = paramiko.SSHClient() client.set_missing_host_key_policy(paramiko.AutoAddPolicy()) client.connect('192.168.8.248', 22, username='root', password='password', timeout=4) stdin, stdout, stderr = client.exec_command('ls -l') #print(stdout.read()) for line in stdout.readlines(): print(line) client.close()
SSHClient方法参数说明
connect(hostname, port=22, username=None, password=None, pkey=None, key_filename=None, timeout=None, allow_agent=True, look_for_keys=True, compress=False, sock=None, gss_auth=False, gss_kex=False, gss_deleg_creds=True, gss_host=None, banner_timeout=None)git
pkey-私钥类型
key_filename-str or list(str) 私钥文件或其列表
timeout-以秒为单位
allow_agent-为False时禁用链接到SSH代理
look_for_keys-为False时禁用在~/.ssh中搜索私钥文件
exec_command(command, bufsize=-1, timeout=None, get_pty=False)
command-字符串github
load_system_host_keys(filename=None)指定公钥文件,默认为~/.ssh/known_hostsweb
set_missing_host_key_policy(policy):设置链接的远程主机没有本地主机密钥时的策略。目前支持三种: RejectPolicy (the default), AutoAddPolicy, WarningPolicysql
#上传批量文件到远程主机 import paramiko import os import datetime hostname = '74.63.229.*' username = 'root' password = 'abc123' port = 22 local_dir = '/tmp/' remote_dir = '/tmp/test/' if __name__ == "__main__": # try: t = paramiko.Transport((hostname, port)) t.connect(username=username, password=password) sftp = paramiko.SFTPClient.from_transport(t) # files=sftp.listdir(dir_path) files = os.listdir(local_dir) for f in files: '#########################################' 'Beginning to upload file %s ' % datetime.datetime.now() 'Uploading file:', os.path.join(local_dir, f) # sftp.get(os.path.join(dir_path,f),os.path.join(local_path,f)) sftp.put(os.path.join(local_dir, f), os.path.join(remote_dir, f)) 'Upload file success %s ' % datetime.datetime.now() t.close()
参考http://www.cnblogs.com/yangsh...shell
Fabric是基于paramiko的基础上作了一层更高的封装,操做起来更加方便。
官网:http://www.fabfile.org/index....
github:https://github.com/fabric/fab...
依赖crypto,paramiko.注意:fabric目前不支持Python3.不过github上有个支持py3的版本https://github.com/mathiasert...
在windows上的安装:
一、安装pycrypto.
有几种方式安装:
A.win7下安装 MSVC2010,而后经过pip install pycrypto编译安装.
B.选择别人编译好的。
pycrypto-for-python-3-2及如下
pycrypto-for-python-3-4
二、支持Python3的版本安装:pip install Fabric3
fabfile.py from fabric.api import run def host_type(): run('uname -s')
经过fab命令执行。-f指定文件,-H指定主机列表.
$ fab -f fabfile.py -H localhost,linuxbox host_type
fab参数说明:
-f 指定入口3文件
-g 指定网关设备(中转,堡垒机)IP
-H 指定目标主机,多个用“,”分割
-P 异步运行多主机任务
-R 指定角色,以角色来区分机组
-t 设备链接超时时间,秒
-T 远程主机命令执行超时时间,秒
-w 当命令执行失败,发出警告,而不是终止任务。
固然咱们彻底能够在代码中设定这些选项值,而无需在命令行指定。以下:全局属性设定
env对象的做用是定义fabfile的全局设定,支持多个属性及自定义属性。
env.hosts,定义目标主机,列表
env.exclude_hosts,排除主机,列表
env.user,定义用户名,str
env.port , 定义端口,str
env.password,定义密码,str
env.passwords,字典,可是形式以下:env.passwords={ 'root@192.168.1.21:22':'123456','root@192.168.2.21:22':'1234'}
env.key_filename=None 指定SSH密钥文件,str or list
env.gateway指定网关设备(中转,堡垒机)IP,str
env.roledefs定义角色分组,字典:env.roledefs={ 'web':['192.168.1.21','192.168.1.23'],'db':['192.168.1.22','192.168.1.24']}
env.parallel=False是否并发执行任务
env.path=' ' 定义在run/sudo/local使用的$PATH环境变量
env.command_timeout=None
env.timeout=10
env.shell=“/bin/bash -l -c”
env.ssh_config_path=“$HOME/.ssh/config”
env.sudo_password=None
env.sudo_passwords={}
env.use_ssh_config=False
env.warn_only=False,若是为True,当操做遇到错误时,发出警告并继续执行,而不是终止
env.变量名 自定义变量
例如:
@roles('web') def webtask(): run('/etc/init.d/nginx start') @roles('db') def dbtask(): run('/etc/init.d/mysql start') @roles('web','db') def publicstask(): run('uptime') def deploy(): execute(webtask) execute(dbtask) execute(publictask)
而后终端执行命令就能够了
$ fab deploy
命令行传参:
def hello(name="world"): print("Hello %s!" % name) $ fab hello:name=Jeff Hello Jeff! Done.
fabric.api模块:
local,执行本地命令,如local('uname -s')
lcd,切换本地目录,如lcd('/home')
cd,切换远程目录
run,执行远程命令
sudo,sudo方式执行远程命令
put,上传文件到远程主机 put('/home/aaa','/home/xby/aaa')
get,从远程主机下载文件到本地 get('/opt/bbb','/home/bbb')
prompt,获取用户输入
confirm,得到提示信息确认,如confirm('Continue[Y/N]?')
reboot,重启远程主机,如reboot()
@task函数装饰器,标识函数为fab可调用的,不然对fab不可见
@runs_once,标识函数只会执行一次,不受多台主机影响。
@roles,表示函数执行时的主机角色
@parallel(pool_size=)
@with_settings()
fabric.contrib.console.confirm(question, default=True) 用户输入Y/n,返回True/False
from fabric.api import * env.user='root' env.hosts=['192.168.1.2','192.168.1.3'] env.password='123' @runs_once #即便有多台主机,但它只会执行一次 def local_task(): local('uname -a') def remote_task(): with cd("/data/logs"): #这个with的做用是让后面的表达式语句继承当前的状态,实现"cd /data/logs && ls -l"的效果。 run("ls -l") $ fab -f sample.py local_task $ fab -f sample.py remote_task
from fabric.api import * from fabric.contrib.console import confirm env.user='root' env.hosts=['192.168.1.2','192.168.1.3'] env.password='123' @runs_once def input_raw(): return prompt("please input dir name:",default='/home') def worktask(dirname): run("ls -l "+dirname) @task def go(): dirname=input_raw() worktask(dirname)
其实只要定义好env.gateway的ip就好了。相比paramiko确实简化了很多。
from fabric.api import * from fabric.contrib.console import confirm from fabric.context_managers import * env.user='root' env.hosts=['192.168.1.2','192.168.1.3'] env.password='123' env.gateway='192.168.22.2' lpath='/home/install/lnmp.tar.gz' rpath='/tmp/install' @task def put_task(): run("mkdir -p /tmp/install") with settings(warn_only=True): #put出现异常时,发出警告,继续执行,不要终止。 result=put(lpath,rpath) #上传 if result.failed and not confirm("put failed,continue[Y/N]?"): abort("Aborting") @task def run_task(): with cd("/tmp/install"): run("tar -zxvf lnmp.tar.gz") with cd("lnmp"): run("./install.sh") @task go(): put_task() run_task()
fabric.colors.blue(text, bold=False)
fabric.colors.cyan(text, bold=False)
fabric.colors.green(text, bold=False)
fabric.colors.magenta(text, bold=False)
fabric.colors.red(text, bold=False)
fabric.colors.white(text, bold=False)
fabric.colors.yellow(text, bold=False)
from fabric.colors import red, green print(red("This sentence is red, except for " + green("these words, which are green") + "."))
示例1:它能够把当前的源代码上传至服务器,并安装到一个预先存在 的 virtual 环境:
from fabric.api import * # 使用远程命令的用户名 env.user = 'appuser' # 执行命令的服务器 env.hosts = ['server1.example.com', 'server2.example.com'] def pack(): # 建立一个新的分发源,格式为 tar 压缩包 local('python setup.py sdist --formats=gztar', capture=False) def deploy(): # 定义分发版本的名称和版本号 dist = local('python setup.py --fullname', capture=True).strip() # 把 tar 压缩包格式的源代码上传到服务器的临时文件夹 put('dist/%s.tar.gz' % dist, '/tmp/yourapplication.tar.gz') # 建立一个用于解压缩的文件夹,并进入该文件夹 run('mkdir /tmp/yourapplication') with cd('/tmp/yourapplication'): run('tar xzf /tmp/yourapplication.tar.gz') # 如今使用 virtual 环境的 Python 解释器来安装包 run('/var/www/yourapplication/env/bin/python setup.py install') # 安装完成,删除文件夹 run('rm -rf /tmp/yourapplication /tmp/yourapplication.tar.gz') # 最后 touch .wsgi 文件,让 mod_wsgi 触发应用重载 run('touch /var/www/yourapplication.wsgi')
参考:<<Python自动化运维>>