Python学习总结 06 paramiko 远程执行命令
有时会需要在远程的机器上执行一个命令,并获得其返回结果。对于这种情况,python 可以很容易的实现。
1 工具
Python paramiko
- Paramiko模块安装
在Linux的Terminal中,直接输入pip install paramiko 命令安装。
2)确定paramiko安装成功
在python命令行输入import paramiko,确认是否安装成功,没报错就没问题。
2 步骤
1 导入 paramiko 模块
#!/usr/bin/python
import paramiko
2 创建 ssh 连接函数
def ssh_connect( _host, _username, _password ):
try:
_ssh_fd = paramiko.SSHClient()
_ssh_fd.set_missing_host_key_policy( paramiko.AutoAddPolicy() )
_ssh_fd.connect( _host, username = _username, password = _password )
except Exception, e:
print( 'ssh %s@%s: %s' % (_username, _host, e) )
exit()
return _ssh_fd
3 创建命令执行函数
def ssh_exec_cmd( _ssh_fd, _cmd ):
return _ssh_fd.exec_command( _cmd )
4 创建关闭 ssh 函数
def ssh_close( _ssh_fd ):
_ssh_fd.close()
5 使用示例
hostname = '192.168.55.243'
port = 22
username = 'root'
password = 'P@ssw0rd'
cmd = "ps -ef|grep java"
sshd = ssh_connect( hostname , username , password )
stdin, stdout, stderr = ssh_exec_cmd( sshd, cmd )
err_list = stderr.readlines()
if len( err_list ) > 0:
print 'ERROR:' + err_list[0]
exit()
for item in stdout.readlines():
print item,
ssh_close( sshd )
if __name__ == "__main__":
main()
如果执行脚本成功,会成功返回以下结果。
root 2540 2536 2 14:13 pts/4 00:01:21 java -Ddefault.client.encoding=UTF-8 -Dfile.encoding=UTF-8 -Duser.language=Zh -Duser.region=CN -Duser.timezone=GMT+08 cn.com.ctsi.csdp.resource.App
root 3442 3387 0 2016 ? 01:09:00 java -Ddefault.client.encoding=UTF-8 -Dfile.encoding=UTF-8 -Duser.language=Zh -Duser.region=CN -Duser.timezone=GMT+08 cn.com.ctsi.csdp.product.App
root 3451 3390 0 2016 ? 01:04:54 java -Ddefault.client.encoding=UTF-8 -Dfile.encoding=UTF-8 -Duser.language=Zh -Duser.region=CN -Duser.timezone=GMT+08 cn.com.ctsi.csdp.report.App
root 3452 3388 0 2016 ? 00:51:00 java -Ddefault.client.encoding=UTF-8 -Dfile.encoding=UTF-8 -Duser.language=Zh -Duser.region=CN -Duser.timezone=GMT+08 cn.com.ctsi.csdp.workflow.launcher.App
root 3892 3886 0 2016 ? 00:29:59 java -Ddefault.client.encoding=UTF-8 -Dfile.encoding=UTF-8 -Duser.language=Zh -Duser.region=CN -Duser.timezone=GMT+08 cn.com.ctsi.csdp.charge.App
root 4509 4507 0 15:09 ? 00:00:00 bash -c ps -ef|grep java
root 4519 4509 0 15:09 ? 00:00:00 grep java
root 12861 12857 0 Jan06 ? 00:09:06 java -Ddefault.client.encoding=UTF-8 -Dfile.encoding=UTF-8 -Duser.language=Zh -Duser.region=CN -Duser.timezone=GMT+08 cn.com.ctsi.csdp.workorder.App
root 16484 16480 0 2016 ? 00:45:27 java -Ddefault.client.encoding=UTF-8 -Dfile.encoding=UTF-8 -Duser.language=Zh -Duser.region=CN -Duser.timezone=GMT+08 cn.com.ctsi.csdp.billing.App
root 18699 18694 0 Jan06 ? 00:09:30 java -Ddefault.client.encoding=UTF-8 -Dfile.encoding=UTF-8 -Duser.language=Zh -Duser.region=CN -Duser.timezone=GMT+08 cn.com.ctsi.csdp.order.App
root 21902 21898 0 Jan05 ? 00:18:46 java -Ddefault.client.encoding=UTF-8 -Dfile.encoding=UTF-8 -Duser.language=Zh -Duser.region=CN -Duser.timezone=GMT+08 cn.com.ctsi.csdp.user.launcher.App
在实际的开发中,每次更新模块的jar包时,都需要使用 ps -ef | grep java, 查看模块的进程号,然后使用使用命令 kill -9 进程号,处理掉进程,然后重新启动 模块。
下面尝试使用python脚本来代替手工输入代码。
3 实例
1) 启动模块
# -*- coding: utf-8 -*-
import paramiko
ssh = paramiko.SSHClient()
ssh.set_missing_host_key_policy(paramiko.AutoAddPolicy())
ssh.connect('192.168.55.243', username = 'root', password = 'P@ssw0rd', timeout = 5)
cmd = 'nohup /csdp/charge_launcher-1.0-release/bin/run.sh > /csdp/charge_launcher-1.0-release/bin/nohup.out 2>&1 & \r\n'
password= 'P@ssw0rd'
stdin, stdout, stderr = ssh.exec_command( cmd )
##stdin, stdout, stderr = ssh.exec_command('sudo -S %s\n' % cmd )
##stdin.write('%s\r\n' % password)
##stdin.flush()
print "------------------------"
##print stdout.readlines()
##print stderr.read()
print "------------------------"
cmd = 'pwd'
stdin, stdout, stderr = ssh.exec_command(cmd )
print stdout.readlines()
ssh.close()
2) 远程上传文件
# -*- coding: utf-8 -*-
import paramiko
serverIp = '192.168.55.243'
serverUser = 'root'
serverPwd = 'P@ssw0rd'
localFile = 'user-1.0-release.jar'
localpath = r'D:\workspace\csdp201512041\csdp-ningxia\csdp_user\user\target' + os.sep + localFile
remotepath = '/csdp/user_launcher-1.0-dev/lib/' + localFile
def ftpModuleFile():
t = paramiko.Transport(( serverIp ,22))
t.connect(username = serverUser , password = serverPwd)
sftp = paramiko.SFTPClient.from_transport(t)
# remotepath='/csdp/user_launcher-1.0-dev/user-1.0-release.jar'
# localpath= r'D:\workspace\csdp201512041\csdp-ningxia\csdp_user\user\target\user-1.0-release.jar'
sftp.put(localpath,remotepath)
t.close()
print(":) 成功上传%s文件。" % remotepath)
if __name__ == '__main__':
ftpModuleFile()
- 执行远程linux命令
# -*- coding: utf-8 -*-
import paramiko
if __name__ == "__main__":
hostname = '192.168.55.243'
port = 22
username = 'root'
password = 'P@ssw0rd'
cmd = "ps -ef|grep java"
ssh = paramiko.SSHClient()
ssh.set_missing_host_key_policy(paramiko.AutoAddPolicy())
#ssh.connect( hostname ,22, username , password )
ssh.connect(hostname,username=username,password=password,allow_agent=False,look_for_keys=False)
stdin, stdout, stderr = ssh.exec_command(cmd )
list = stdout.readlines()
print( list )
ssh.close()