1. pexpect
安装好pexpect模块后,按照demo sshls.py改造了自己的lib封装,虽然很挫,也算是新增了一个可用的工具。
run脚本:
run bb2008 'ps -ef | grep drct'
使用pexpect执行ssh -l,在bb-testing-oped2008.vm机器上执行命令ps -ef | grep drct,显示执行结果,退出状态与远程退出状态相同
run
#!/bin/sh
if [ $# -lt 2 ]; then
echo ': run $host $cmd'
echo ": run bb2008 'ps -ef | grep drct'"
echo "please use 'run' with user 'work'"
exit 1
fi
python /usr/bin/Expect.py $@
Expect.py
#!/usr/bin/env python
import pexpect
import sys
import getpass, os
class Expect:
'''
run remote command with pexpect
'''
def __init__(self, host='', usr='', pwd=''):
self.host = host
self.usr = usr
self.pwd = pwd
self.res = None
def _ssh_command (self, host, user, password, command):
ssh_newkey = 'Are you sure you want to continue connecting'
child = pexpect.spawn('ssh -l %s %s %s'%(user, host, command))
i = child.expect([pexpect.TIMEOUT, ssh_newkey, 'password: '])
if i == 0: # Timeout
print 'ERROR!'
print 'SSH could not login. Here is what SSH said:'
print child.before, child.after
return None
if i == 1: # SSH does not have the public key. Just accept it.
child.sendline ('yes')
child.expect ('password: ')
i = child.expect([pexpect.TIMEOUT, 'password: '])
if i == 0: # Timeout
print 'ERROR!'
print 'SSH could not login. Here is what SSH said:'
print child.before, child.after
return None
child.sendline(password)
return child
def run_remote_command(self, cmd=''):
'''
run remote command $cmd
users should set remote host/user/password by explicitly
'''
if self.host == '' or \
self.usr == '' or \
self.pwd == '':
print '[Expect]: host/usr/pwd hasnot been set, please set correct values!'
return None
if cmd == '':
print '[Expect]: parameter $cmd is empty, do nothing!'
return None
print '[Expect]: trying to ssh to %s@%s, and executes <%s>...'%(self.usr, self.host, cmd)
cmd += ';echo $?'
child = self._ssh_command(self.host, self.usr, self.pwd, cmd)
child.expect(pexpect.EOF)
self.res = child.before
return eval(child.before.split('\n')[-2].strip())
def interactive_run_remote_command(self, cmd=''):
'''
run remote command $cmd interactively
users should input remote host/user/password while running
'''
print '[Expect]: trying to remote run <%s>, please input remote host information:'%(cmd)
cmd += ';echo $?'
_host = raw_input('Hostname: ')
_usr = raw_input('User: ')
_pwd = getpass.getpass('Password: ')
child = self._ssh_command(_host, _usr, _pwd, cmd)
child.expect(pexpect.EOF)
self.res = child.before
return eval(child.before.split('\n')[-2].strip())
if __name__ == '__main__':
try:
host = sys.argv[1][0:2] + '-xxxxxxx-' + sys.argv[1][2:] + '.vm'
cmd = ''
for part in sys.argv[2:]:
cmd += (part+' ')
remote = Expect()
remote.host = 'xxxxx'
remote.usr = 'xxxxx'
remote.pwd = 'xxxxxxxxx'
status = remote.run_remote_command(cmd)
print remote.res
exit(status)
except Exception, e:
print str(e)
2. ssh信任关系建立
欲建立机器A到机器B的信任:
机器A
$ ssh-keygen -t rsa
$ scp ~/.ssh/id_rsa.pub user@hostB:~/.ssh/
机器B
$ cd ~/.ssh/
$ mv id_rsa.pub authorized_keys
OK,机器A ssh到机器B不用输密码...
机器A在机器B远程执行命令: ssh -l user hostB ls
------------------------------------------------
好吧。。。好shability
-------------------------------------------------
纯姐对于ssh双方建立信任关系失败的建议:
ssh密钥的权限很严格,每个目录和文件的权限都得对才OK:对于work账号的,要:
/home/work 755
.ssh 700
.ssh/* 600