Chinaunix首页 | 论坛 | 博客
  • 博客访问: 703481
  • 博文数量: 696
  • 博客积分: 15910
  • 博客等级: 上将
  • 技术积分: 7345
  • 用 户 组: 普通用户
  • 注册时间: 2010-03-03 14:34
文章分类

全部博文(696)

文章存档

2012年(263)

2011年(394)

2010年(39)

分类: Python/Ruby

2012-11-17 22:18:03

import signal
signal.signal(signal.SIGINT, signal.SIG_DFL)

from pexpect import *
import os, sys, commands
from optparse import OptionParser

##exit codes

SPAWNED_BASE_CODE = 100     #exit codes by spawned ssh will be added to 100 
MAIN_ERROR = 1              #main program error
TIME_OUT_ERROR = 2          #ssh timeout
SSH_CON_ERROR = 3           #ssh conn error
PASS_ERROR = 4              #ssh pass error
UNKNOWN_ERROR = 5           #ssh unknwon error


#parse options
usage = "pscp [user@]host:srcpath [...] dstpath password\n       pscp srcpath [...] [user@]host:destpath password"
parser = OptionParser(usage)
parser.add_option("-t", "--timeout",
                 type="int", dest="timeout",
                 help="When execute time exceeds TIMEOUT, force to exit, default value is infinite.")

parser.add_option("-e", "--encrypt-password", action="store_true", dest="encrypt",
                  help="Use this command with a encrypted password, for DMS only."
                  )
 
options, args = parser.parse_args()
if len(args) < 3:
   print parser.format_help()
   sys.exit(MAIN_ERROR)  
scparg = ""
for arg in args[0:-1]:
    scparg += " " + arg 
timeout = None 
if options.timeout:
   timeout = options.timeout
password = args[-1]
#find out host
host = ""
for x in args:
   splits = x.split(':')
   if len(splits) > 1:
      host = splits[0]
      break

encrypt = False
if options.encrypt:
   encrypt = options.encrypt
   
password = password

#expect keys
keys = [ 'authenticity', 
   'assword:', 
   TIMEOUT, 
   EOF,
   'pssh_exit',#a little chance, ssh don't echo EOF, while remote cmd exiting.
   '@@@@@@@@@@@@@@@@@@@@' #key failed
         ]

def clear_ssh_key():
   hostname = host.split('@')[-1]
   keyfile = os.environ['HOME'] + "/.ssh/known_hosts"
   tmpfile = os.environ['HOME'] + "/.ssh/known_hosts.tmp"
   cmd = "sed '/%s/d' %s > %s; mv %s %s" % (hostname, keyfile, tmpfile, tmpfile, keyfile)
   os.system(cmd)     

clear_ssh_key()

#build command to spawn
#when build command as scp -r %s; echo $?pssh_exit, 
#it doesn't work, so create a wrapper script. 
#a litte dirty but work. 
scp_wrapper = '/root/scp_echo'
command = "%s -r %s"  % (scp_wrapper, scparg)
#spawn it
try:
  child = spawn(command, [], timeout)
except Exception, inst:
  print inst
  sys.exit(MAIN_ERROR)

index = child.expect(keys)
##ssh key failed
if index == 5 or index == 3 :
   clear_ssh_key()
   child.close()
   #respawn it
   try:
     child = spawn(command, [], timeout)
   except Exception, inst:
     print inst
     sys.exit(MAIN_ERROR)
   index = child.expect(keys)
   
#ssh connect failed
if index == 5 or index == 3:
   print child.before.strip()
   sys.exit(SSH_CON_ERROR)  

#new connection need authenticity
if index == 0:
   child.sendline('yes')
   index = child.expect(keys)

#got 'assword:', and send it.   
if index == 1:
   child.sendline(password)
   index = child.expect(keys)
   
#got 'TIMEOUT'
if index == 2:
   print 'run command timeout.' 
   child.close()
   sys.exit(TIME_OUT_ERROR) 

#got 'assword'
elif index == 1:
   print 'wrong password.'
   sys.exit(PASS_ERROR)  

#complete 
elif index == 4:
   output = child.before.strip() 
   output = output.replace('\r','')
   exitval = output.split('\n')[-1]
   s = output.split('\n')[0:-1]
   for line in s:
       print line   
   sys.exit(int(exitval) + SPAWNED_BASE_CODE) #exit value what command exit

#Unknown
print 'unknown error'

sys.exit(UNKNOWN_ERROR) 

阅读(1015) | 评论(0) | 转发(0) |
0

上一篇:vim 列模式

下一篇:pssh over

给主人留下些什么吧!~~