pythonssh交互
A. python 通过ssh协议批量跑哪个最快
局域网内有一百多台电脑,全部都是linux操作系统,所有电脑配置相同,系统完全相同(包括用户名和密码),ip地址是自动分配的。现在有个任务是在这些电脑上执行某些命令,者说进行某些操作,比如安装某些软件,拷贝某些文件,批量关机等。如果一台一台得手工去操作,费时又费力,如果要进行多个操作就更麻烦啦。
或许你会想到网络同传, 网络同传是什么?就是在一台电脑上把电脑装好,配置好,然后利用某些软件,如“联想网络同传”把系统原样拷贝过去,在装系统时很有用,只要在一台电脑上装好,同传以后所有的电脑都装好操作系统了,很方便。同传要求所有电脑硬件完全相同,在联想的电脑上装的系统传到方正电脑上肯定会出问题的。传系统也是很费时间的,根据硬盘大小,如果30G硬盘,100多台电脑大约要传2个多小时,反正比一台一台地安装快!但是如果系统都传完了,发现忘了装一个软件,或者还需要做些小修改,再同传一次可以,但是太慢,传两次半天时间就没了。这时候我们可以利用ssh去控制每台电脑去执行某些命令。
先让我们回忆一下ssh远程登录的过程:首先执行命令 ssh [email protected] ,第一次登录的时候系统会提示我们是否要继续连接,我们要输入“yes”,然后等一段时间后系统提示我们输入密码,正确地输入密码之后我们就能登录到远程计算机,然后我们就能执行命令了。我们注意到这里面有两次人机交互,一次是输入‘yes’,另一次是输入密码。就是因为有两次交互我们不能简单的用某些命令去完成我们的任务。我们可以考虑把人机交互变成自动交互,python的pexpect模块可以帮我们实现自动交互。下面这段代码是用pexpect实现自动交互登录并执行命令的函数:
#!/usr/bin/env python
# -*- coding: utf-8 -*-
import pexpect
def ssh_cmd(ip, passwd, cmd):
ret = -1
ssh = pexpect.spawn('ssh root@%s "%s"' % (ip, cmd))
try:
i = ssh.expect(['password:', 'continue connecting (yes/no)?'], timeout=5)
if i == 0 :
ssh.sendline(passwd)
elif i == 1:
ssh.sendline('yes\n')
ssh.expect('password: ')
ssh.sendline(passwd)
B. 怎么用Python对一个交互式的命令行程序进行交互
在cmd里运行这个交互式程序
然后其他就和python和cmd下的程序打交道一样了
比如:
开本机telnet或ssh服务
通过python telnet或ssh到本机,荣国write启动这个交互式程序,开始write and receive就好
C. 请教下python3 上如何实现级联ssh
首先,我的windows系统上有python2和python3。使用下面命令切换到python3:
activate py3
1
接着使用下面命令下载相关模块:
pip install ecdsa
pip install Crypto
pip install paramiko
1
2
3
连接服务器操作:
# -*- coding: utf-8 -*-
import paramiko
# 服务器相关信息,下面输入你个人的用户名、密码、ip等信息
ip = ""
port = 22
user = ""
password = ""
ssh = paramiko.SSHClient()
ssh.set_missing_host_key_policy(paramiko.AutoAddPolicy())
# 建立连接
ssh.connect(ip,port,user,password,timeout = 10)
#输入linux命令
stdin,stdout,stderr = ssh.exec_command("pwd")
# 输出命令执行结果
result = stdout.read()
print(result)
#关闭连接
ssh.close()
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
如下,运行该程序,可以看到控制台输出的结果:
D. 如何Python3.4使用pexpect来实现SSH登陆
Pexpect 是 Don Libes 的 Expect 语言的一个 Python
实现,是一个用来启动子程序,并使用正则表达式对程序输出做出特定响应,以此实现与其自动交互的 Python 模块。 Pexpect
的使用范围很广,可以用来实现与 ssh、ftp 、telnet
等程序的自动交互;可以用来自动复制软件安装包并在不同机器自动安装;还可以用来实现软件测试中与命令行交互的自动化。
在shell里面用过pexpect的人,相信都会很熟悉这种工具,pexpect是expect的python的一个实现,利用python来操作某些交互式的自动化任务是非常方便的。
如何在linux下安装?
1,使用wget https://pypi.python.org/pypi?:action=show_md5&digest= 下载
2,使用tar -zxvf pexpect-3.3.tar.gz解压
3,使用python setup.py install进行安装
ok,上面的步骤,执行完成之后,我们就可以来写个demo测试一下了,另外注意兼容问题,散仙的python是3.4,所以要下载支持python3.4的pexpect,如果你的python版本是2.x那么就要下载2.x的pexpect来使用。
下面是散仙模拟SSH登陆一台机器并打印磁盘情况,然后退出的例子:
#!/usr/local/python3.4/bin/python3.4
import pexpect
ip="192.168.46.22"
name="root"
pwd="abc"
#发送命令执行交互
child=pexpect.spawn('ssh %s@%s' % ("root",ip) )
#
child.expect ('password:')
child.sendline(pwd)
child.expect('$')
child.sendline('df -h')
#发送命令
child.sendline("exit")
child.interact()
#关闭pexpect
child.close()
执行结果如下:
Last login: Wed Oct 22 18:35:08 2014 from 192.168.46.31
exit[root@ganglia ~]# df -h
Filesystem Size Used Avail Use% Mounted on
/dev/mapper/vg_ganglia-lv_root 30G 3.6G 25G 13% /
tmpfs 495M 0 495M 0% /dev/shm
/dev/sda1 485M 32M 428M 7% /boot
[root@ganglia ~]# exit
logout
Connection to 192.168.46.22 closed.
[root@master 2012]#
本文只是一个简单的例子,可能觉得没有必要使用python来完成,但当系统管理规模一旦大起来的话,使用python来自动化管理是非常轻松的一件事。
E. python如何通过串口SSH登录服务器
需要写一个基于串口通信协议的ssh服务器和客户端,服务器部署到linux上,客户端在windows上;
其次,客户端要提供sdk for python;
最后,你就可以用python通过ssh登录linux了。
F. python 实现ssh的执行远端命令和scp的不同机器文件传输功能
#!/usr/bin/env python
# -*- coding: utf-8 -*-
import pexpect
def ssh_cmd(ip, passwd, cmd):
ret = -1
ssh = pexpect.spawn('ssh root@%s "%s"' % (ip, cmd))
try:
i = ssh.expect(['password:', 'continue connecting (yes/no)?'], timeout=5)
if i == 0 :
ssh.sendline(passwd)
elif i == 1:
ssh.sendline('yes\n')
ssh.expect('password: ')
ssh.sendline(passwd)
ssh.sendline(cmd)
r = ssh.read()
print r
ret = 0
except pexpect.EOF:
print "EOF"
ssh.close()
ret = -1
except pexpect.TIMEOUT:
print "TIMEOUT"
ssh.close()
ret = -2
return ret
利用pexpect模块我们可以做很多事情,由于他提供了自动交互功能,因此我们可以实现ftp,telnet,ssh,scp等的自动登录,还是比较实用的。根据上面的代码相信读者已经知道怎么实现了(python就是那么简单!)。
用
上面的代码去完成任务还是比较费时间的,因为程序要等待自动交互出现,另外ubuntu用ssh连接就是比较慢,要进行一系列的验证,这样才体现出ssh
的安全。我们要提高效率,在最短的时间内完成。后来我发现了python里面的paramiko模块,用这个实现ssh登录更加简单。看下面的代码:
复制代码 代码如下:
#-*- coding: utf-8 -*-
#!/usr/bin/python
import paramiko
import threading
def ssh2(ip,username,passwd,cmd):
try:
ssh = paramiko.SSHClient()
ssh.set_missing_host_key_policy(paramiko.AutoAddPolicy())
ssh.connect(ip,22,username,passwd,timeout=5)
for m in cmd:
stdin, stdout, stderr = ssh.exec_command(m)
# stdin.write("Y") #简单交互,输入 ‘Y'
out = stdout.readlines()
#屏幕输出
for o in out:
print o,
print '%s\tOK\n'%(ip)
ssh.close()
except :
print '%s\tError\n'%(ip)
if __name__=='__main__':
cmd = ['cal','echo hello!']#你要执行的命令列表
username = "" #用户名
passwd = "" #密码
threads = [] #多线程
print "Begin......"
for i in range(1,254):
ip = '192.168.1.'+str(i)
a=threading.Thread(target=ssh2,args=(ip,username,passwd,cmd))
a.start()
上面的程序还是有些技巧的:
1.
利用多线程,同时发出登录请求,同时去连接电脑,这样速度快很多,我试了一下,如果不用多线程,直接一个一个挨着执行的话,大约5~10秒钟才能对一台电
脑操作完,具体时间要根据命令的来决定,如果是软件安装或者卸载时间要更长一些。这样下来怎么也要一二十分钟,用多线程后就快多了,所有的命令执行完用了
不到2分钟!
2.最好用root用户登录,因为安装或者卸载软件的时候如果用普通用户又会提示输入密码,这样又多了一次交互,处理起来就比较麻
烦!安装软件时apt-get install xxx
最好加上“-y”参数,因为有时安装或删除软件时提示是否继续安装或卸载,这又是一次自动交互!加上那个参数后就没有人机交互了。
3. 循环时循环所有ip,因为计算机的ip是路由器自动分配的,保险起见,最好全部都执行,保证没有遗漏的主机
4.远端执行命令时如果有交互,可以这样用 stdin.write("Y")来完成交互,“Y”就是输入“Y”。
5.把所有的命令放到一个列表里面,遍历列表可以依次执行列表里面的命令
6.为了更好的进行控制,最好在电脑上提前把root用户打开,装好ssh服务器并让其开机自动执行。
G. 怎么运行python的交互解释器
使用ssh的协议进行管理,使用python的paramiko来进行管理
可以使用python的paramiko模块来进行管理名下服务器,前提是能够ssh到各个服务器上。
H. 如何利用Python的paramiko模块实现ssh互信
import os
import paramiko
def check(output):
# output=os.popen('service ntpd status')
for file in output:
if 'stopped' in file:
print "ntpd is stopped"
else:
print "ntpd is running"
if __name__ == 'main':
for ip in ('10.0.0.1','10.0.0.2'):
ssh = paramiko.SSHClient()
ssh.set_missing_host_key_policy(paramiko.AutoAddPolicy())
ssh.connect(ip)
# check()
stdin, stdout, stderr = ssh.exec_command("service ntpd status")
check(stdout.readlines())
ssh.close()
I. 求教关于python实现ssh证书登陆交互的问题
可以使用 paramiko 编程完成登录与SSH操作。
具体请查阅 paramiko 文档
J. python 获取ssh响应吗
最近在做一个项目,需要在客户端集成一个交互式ssh功能,大概就是客户端跟服务器申请个可用的机器,服务端返回个ip,端口,密码, 然后客户端就可以直接登录到机器上操做了。该程序基于paramiko模块。
经查找,从paramiko的源码包demos目录下,可以看到交互式shell的实现,就是那个demo.py。但是用起来有些bug,于是我给修改了一下interactive.py(我把windows的代码删掉了,剩下的只能在linux下用)。代码如下:
[python]view plain
#coding=utf-8
importsocket
importsys
importos
importtermios
importtty
importfcntl
importsignal
importstruct
importselect
now_channel=None
definteractive_shell(chan):
posix_shell(chan)
defioctl_GWINSZ(fd):
try:
cr=struct.unpack('hh',fcntl.ioctl(fd,termios.TIOCGWINSZ,'aaaa'))
except:
return
returncr
defgetTerminalSize():
cr=ioctl_GWINSZ(0)orioctl_GWINSZ(1)orioctl_GWINSZ(2)
returnint(cr[1]),int(cr[0])
defresize_pty(signum=0,frame=0):
width,height=getTerminalSize()
ifnow_channelisnotNone:
now_channel.resize_pty(width=width,height=height)
defposix_shell(chan):
globalnow_channel
now_channel=chan
resize_pty()
signal.signal(signal.SIGWINCH,resize_pty)#终端大小改变时,修改pty终端大小
stdin=os.fdopen(sys.stdin.fileno(),'r',0)#stdinbuff置为空,否则粘贴多字节或者按方向键的时候显示不正确
fd=stdin.fileno()
oldtty=termios.tcgetattr(fd)
newtty=termios.tcgetattr(fd)
newtty[3]=newtty[3]|termios.ICANON
try:
termios.tcsetattr(fd,termios.TCSANOW,newtty)
tty.setraw(fd)
tty.setcbreak(fd)
chan.settimeout(0.0)
whileTrue:
try:
r,w,e=select.select([chan,stdin],[],[])
except:
#解决SIGWINCH信号将休眠的select系统调用唤醒引发的系统中断,忽略中断重新调用解决。
continue
ifchaninr:
try:
x=chan.recv(1024)
iflen(x)==0:
print'rn***EOFrn',
break
sys.stdout.write(x)
sys.stdout.flush()
exceptsocket.timeout:
pass
ifstdininr:
x=stdin.read(1)
iflen(x)==0:
break
chan.send(x)
finally:
termios.tcsetattr(sys.stdin,termios.TCSADRAIN,oldtty)
#coding=utf8
importparamiko
importinteractive
#记录日志
paramiko.util.log_to_file('/tmp/aaa')
#建立ssh连接
ssh=paramiko.SSHClient()
ssh.load_system_host_keys()
ssh.set_missing_host_key_policy(paramiko.AutoAddPolicy())
ssh.connect('192.168.1.11',port=22,username='hahaha',password='********',compress=True)
#建立交互式shell连接
channel=ssh.invoke_shell()
#建立交互式管道
interactive.interactive_shell(channel)
#关闭连接
channel.close()
ssh.close()
使用示例:
[python]view plain
interactive.py代码中主要修复了几个问题:
1、当读取键盘输入时,方向键会有问题,因为按一次方向键会产生3个字节数据,我的理解是按键一次会被select捕捉一次标准输入有变化,但是我每次只处理1个字节的数据,其他的数据会存放在输入缓冲区中,等待下次按键的时候一起发过去。这就导致了本来3个字节才能完整定义一个方向键的行为,但是我只发过去一个字节,所以终端并不知道我要干什么。所以没有变化,当下次触发按键,才会把上一次的信息完整发过去,看起来就是按一下方向键有延迟。多字节的粘贴也是一个原理。解决办法是将输入缓冲区置为0,这样就没有缓冲,有多少发过去多少,这样就不会有那种显示的延迟问题了。
2、终端大小适应。paramiko.channel会创建一个pty(伪终端),有个默认的大小(width=80, height=24),所以登录过去会发现能显示的区域很小,并且是固定的。编辑vim的时候尤其痛苦。channel中有resize_pty方法,但是需要获取到当前终端的大小。经查找,当终端窗口发生变化时,系统会给前台进程组发送SIGWINCH信号,也就是当进程收到该信号时,获取一下当前size,然后再同步到pty中,那pty中的进程等于也感受到了窗口变化,也会收到SIGWINCH信号。
3、读写‘慢’设备(包括pipe,终端设备,网络连接等)。读时,数据不存在,需要等待;写时,缓冲区满或其他原因,需要等待。ssh通道属于这一类的。本来进程因为网络没有通信,select调用为阻塞中的状态,但是当终端窗口大小变化,接收到SIGWINCH信号被唤醒。此时select会出现异常,触发系统中断(4, 'Interrupted system call'),但是这种情况只会出现一次,当重新调用select方法又会恢复正常。所以捕获到select异常后重新进行select可以解决该问题。