├── CheungSSH使用手册.docx ├── 功能升级记录.txt ├── README.md ├── Format_Char_Show.py ├── LogCollect.py ├── install-CheungSSH.sh └── cheungSSH_Manager_Stand_V96_ISSUE.py /CheungSSH使用手册.docx: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/4021019/CheungSSH/HEAD/CheungSSH使用手册.docx -------------------------------------------------------------------------------- /功能升级记录.txt: -------------------------------------------------------------------------------- 1 | 版本升级记录: 2 | V94: 3 | 1 升级了cd功能,可以使用cd切换目录 4 | V95: 5 | 1 升级了使用方向键的功能 6 | V96: 7 | 1 升级了原始日志记录 8 | 9 | 10 | 简单的用法请到我的博客: 11 | http://blog.chinaunix.net/uid-29295703-id-4663051.html 12 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # CheungSSH 2 | 比Ansibel更好用的自动化工具 3 | 这是我(张其川 Cheung Kei-Chuen) 自主开发的基于 SSH协议的自动操作工具,比Ansible更轻量!操作更简单! 4 | 如果您觉得本软件还不错,有需要的话,请与我联系,包括有任何的使用疑问 5 | 我的QQ 741345015 6 | 7 | 详细的用法介绍请: http://blog.chinaunix.net/uid-29295703-id-4663051.html 8 | 如果有任何试用疑问,请联系我!! 9 | -------------------------------------------------------------------------------- /Format_Char_Show.py: -------------------------------------------------------------------------------- 1 | #!/usr/bin/python 2 | VERSION=1.3 3 | import os,sys,commands 4 | def Get_Char(Char,i): 5 | Char=Char 6 | New_Char=[] 7 | for m in Char.split('\n'): 8 | New_Char.append('|' + m ) 9 | b=Char.split('\n') 10 | Char_Len=[] 11 | for t in b: 12 | Char_Len.append(len(t)) 13 | Max_Char_Len=sorted(Char_Len)[-1] 14 | return Max_Char_Len,New_Char 15 | 16 | def Show_Line(Max_Char_Len,i=0,Flag='end'): 17 | T='' 18 | while i<=Max_Char_Len+2: 19 | if i<=5 and Flag=='start': 20 | #sys.stdout.write('+') 21 | T+='+' 22 | i+=1 23 | continue 24 | 25 | #sys.stdout.write('-') 26 | T+='-' 27 | i+=1 28 | return T 29 | def Show_Char(New_Char,Color_Status): 30 | AllChar='' 31 | if Color_Status==0: 32 | Color_Start="\033[1;32m" 33 | Color_End="\033[0m" 34 | else: 35 | Color_Start="\033[1;31m" 36 | Color_End="\033[0m" 37 | New_Char=New_Char 38 | AllChar+='\n\n' 39 | Len_and_Char=Get_Char(New_Char,i=0) 40 | AllChar+=Color_Start 41 | AllChar+=Show_Line(Len_and_Char[0],i=0,Flag='start') + '\n' 42 | for t in Len_and_Char[1]: 43 | AllChar=AllChar + t + '\n' 44 | AllChar+=Show_Line(Len_and_Char[0],i=0) + Color_End +'\n' 45 | #print AllChar 46 | return AllChar 47 | 48 | if __name__=='__main__': 49 | Show_Char(sys.argv[1],0) 50 | 51 | -------------------------------------------------------------------------------- /LogCollect.py: -------------------------------------------------------------------------------- 1 | #!/usr/bin/python 2 | #coding:utf-8 3 | import os,sys,random,paramiko,time 4 | def LogCollect(ip,port,username,password,cmd,ListenTime,UseKey): 5 | try: 6 | outchar='' 7 | errchar='' 8 | ssh=paramiko.SSHClient() 9 | if UseKey=='y': 10 | KeyPath=os.path.expanduser('~/.ssh/id_rsa') 11 | key=paramiko.RSAKey.from_private_key_file(KeyPath) 12 | ssh.load_system_host_keys() 13 | ssh.set_missing_host_key_policy(paramiko.AutoAddPolicy()) #使用这个,如果是第一次连接,就不会不会弹出(yes/no) 提示 14 | ssh.connect(ip,port,username,pkey=key) #paramiko用法 http://docs.paramiko.org/en/latest/api/client.html 15 | else: 16 | ssh.set_missing_host_key_policy(paramiko.AutoAddPolicy()) 17 | ssh.connect(ip,port,username,password) 18 | 19 | Timeout_i=1 20 | while Timeout_i<=int(ListenTime): 21 | stdin,stdout,stderr=ssh.exec_command(cmd) 22 | out=stdout.readlines() 23 | error_out=stderr.readlines() 24 | for o in out: 25 | outchar+=o 26 | for err in error_out: 27 | errchar+=err 28 | if errchar: 29 | print "\033[1;31m-ERR %s Deployment Faild , Check deployment FlagFile error (%s)\033[0m\a" %(ip,errchar) 30 | return False 31 | if outchar=='DoneSucc': #shell的终端输出应该是 echo -n 'DoneSucc' 32 | print "\033[1;32m+OK %s Deployment \033[0m" % (ip) 33 | return True 34 | #print "Wating %s (%d Sec) Deploeymenting..." %(ip,Timeout_i), 35 | Timeout_i+=1 36 | time.sleep(1) 37 | stdin,stdout,stderr=ssh.exec_command("""killall -9 tail 2&>/dev/null""") 38 | 39 | except Exception,e: 40 | print "\033[1;31m-ERR %s\033[0m\a" % e 41 | return False 42 | 43 | 44 | if __name__ =='__main__': 45 | #LogCollect(ip,port,username,passwd,cmd,Timeout) 46 | LogCollect('127.0.0.1',22,'sshd','zaq1ZAQ!',"""grep 'a' /tmp/a -q && echo -n 'DoneSucc'""",10,'n') 47 | 48 | -------------------------------------------------------------------------------- /install-CheungSSH.sh: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | #Author=Cheung Kei-Chuen 张其川 3 | #QQ=741345015 4 | #如果您在使用过程中,遇到了一点点的问题,我都真诚希望您能告诉我!为了改善这个软件, 方便您的工作! 5 | export LANG=zh_CN.UTF-8 6 | if [ `id -u` -ne 0 ] 7 | then 8 | echo "Must be as root install!" 9 | exit 1 10 | fi 11 | echo "Installing..." 12 | rpm -qa|grep gcc -q 13 | if [ $? -ne 0 ] 14 | then 15 | echo "您的系统当前没有gcc环境!" 16 | echo "现在为您安装GCC..." 17 | yum install -y gcc >/dev/null 2>/dev/null 18 | if [ $? -ne 0 ] 19 | then 20 | echo "安装GCC失败了,请手动安装gcc。" 21 | exit 1 22 | else 23 | echo "GCC安装成功!" 24 | fi 25 | 26 | fi 27 | rpm -qa|grep python-devel -q 28 | if [ $? -ne 0 ] 29 | then 30 | echo "您的系统没有python-devle包,现在需要安装..." 31 | yum install -y python-devel >/dev/null 2>/dev/null 32 | if [ $? -ne 0 ] 33 | then 34 | echo "无法安装python-devel,请手动安装python-devel" 35 | exit 1 36 | else 37 | echo "安装python-devel成功!" 38 | fi 39 | fi 40 | 41 | 42 | 43 | 44 | which pip 2>/dev/null 45 | if [ $? -ne 0 ] 46 | then 47 | easy_install pip 48 | if [ $? -ne 0 ] 49 | then 50 | echo "安装pip失败,请手动安装pip" 51 | exit 1 52 | else 53 | echo "安装pip成功" 54 | fi 55 | fi 56 | 57 | pip install pycrypto 58 | if [ $? -ne 0 ] 59 | then 60 | echo "安装pycrypto失败,请手动下载安装:https://pypi.python.org/packages/source/p/pycrypto/pycrypto-2.6.1.tar.gz" 61 | exit 1 62 | else 63 | echo "安装pycrypto成功" 64 | fi 65 | 66 | pip install paramiko 67 | if [ $? -ne 0 ] 68 | then 69 | echo "安装paramiko失败,请手动下载后安装 https://pypi.python.org/packages/source/p/paramiko/paramiko-1.9.0.tar.gz" 70 | exit 1 71 | else 72 | echo "安装paramiko成功" 73 | fi 74 | ######### 75 | chmod -R a+x CheungSSH* 2>/dev/null 76 | chmod a+x *.py 2>/dev/null 77 | cat <>>") 456 | d_file=raw_input("Remote Destination Full-Path>>>") 457 | Global_start_time=time.time() 458 | for s in Servers.split(","): 459 | try: 460 | t_password=All_pass["%s_Password" % (s)] 461 | except: 462 | t_password=Password 463 | try: 464 | t_username=All_user["%s_Username" % (s)] 465 | except: 466 | t_username=Username 467 | try: 468 | t_port=All_port["%s_Port" % (s)] 469 | except: 470 | t_port=Port 471 | if RunMode.upper()=='M': 472 | a=threading.Thread(target=Upload_file,args=(s,t_port,t_username,t_password)) 473 | a.start() 474 | else: 475 | Upload_file(s,t_port,t_username,t_password) 476 | elif option.excute_type == "download": 477 | if option.source_file and option.destination_file: 478 | s_file=option.source_file 479 | d_file=option.destination_file 480 | else: 481 | print "Download File" 482 | s_file=raw_input("Remote Source Full-Path>>>") 483 | d_file=raw_input("Local Destination Path>>>") 484 | if not os.path.isdir(d_file): 485 | print 'Recv location must be a directory' 486 | sys.exit(1) 487 | Global_start_time=time.time() 488 | for s in Servers.split(","): 489 | 490 | try: 491 | t_password=All_pass["%s_Password" % (s)] 492 | except: 493 | t_password=Password 494 | try: 495 | t_username=All_user["%s_Username" % (s)] 496 | except: 497 | t_username=Username 498 | try: 499 | t_port=All_port["%s_Port" % (s)] 500 | except: 501 | t_port=Port 502 | 503 | if option.regex: 504 | a=threading.Thread(target=Download_file,args=(s,t_port,t_username,t_password)) 505 | else: 506 | a=threading.Thread(target=Download_file_regex,args=(s,t_port,t_username,t_password)) 507 | a.start() 508 | elif not option.excute_type: 509 | Excute_cmd() 510 | sys.exit(0) 511 | else: 512 | print "Parameter does not currently support\t(%s)\a" % (option.excute_type) 513 | Excute_cmd() 514 | except KeyboardInterrupt: 515 | print "exit" 516 | except EOFError: 517 | print "exit" 518 | 519 | def Excute_cmd_root(s,Port,Username,Password,Passwordroot,cmd,UseLocalScript,OPTime): 520 | global All_Servers_num_all,All_Servers_num,All_Servers_num_Succ,Done_Status,bufflog 521 | Done_Status='start' 522 | bufflog='' 523 | start_time=time.time() 524 | ResultSum='' 525 | Result_status=False 526 | try: 527 | t=paramiko.SSHClient() 528 | if UseKey=='y': 529 | KeyPath=os.path.expanduser('~/.ssh/id_rsa') 530 | key=paramiko.RSAKey.from_private_key_file(KeyPath) 531 | t.load_system_host_keys() 532 | t.set_missing_host_key_policy(paramiko.AutoAddPolicy()) 533 | t.connect(s,Port,Username,pkey=key) 534 | else: 535 | t.set_missing_host_key_policy(paramiko.AutoAddPolicy()) 536 | t.connect(s,Port,Username,Password) 537 | ssh=t.invoke_shell() 538 | ssh.send("LANG=zh_CN.UTF-8\n") 539 | ssh.send("export LANG\n") 540 | ssh.send("su - root\n") 541 | buff='' 542 | while not re.search("Password:",buff) and not re.search(":", buff): 543 | resp=ssh.recv(9999) 544 | buff += resp 545 | #print buff #show su result 546 | ssh.send("%s\n" % (Passwordroot)) 547 | buff1='' 548 | while True: 549 | resp=ssh.recv(500) 550 | buff1 += resp 551 | if re.search('su:',buff1): 552 | #print "\033[1;31m-ERR su Failed %s\033[0m" % (s) 553 | break 554 | else: 555 | if re.search('# *$',buff1): 556 | Result_status=True 557 | All_Servers_num_Succ+=1 558 | break 559 | if Result_status: 560 | ssh.send(PWD) 561 | ssh.send("%s\n" % (cmd)) 562 | buff="" 563 | bufflog='' 564 | while not buff.endswith("# "): 565 | resp=ssh.recv(9999) 566 | buff += resp 567 | bufflog += resp.strip('\r\n') + '\\n' 568 | t.close() 569 | All_Servers_num += 1 570 | ResultSum=buff + "\n\033[1m\033[1;32m+OK %s (%0.2f Sec All %d Done %d)\033[1m\033[0m\n" % (s,float(time.time() - start_time),All_Servers_num_all,All_Servers_num) 571 | 572 | bufflog_new='' 573 | for t in bufflog.split(): 574 | if t==cmd: 575 | continue 576 | bufflog_new+=t 577 | bufflog=bufflog_new 578 | else: 579 | All_Servers_num += 1 580 | ResultSum=buff + "\n\033[1m\033[1;31m-ERR Su Failed %s (%0.2f Sec All %d Done %d)\033[1m\033[0m\n" % (s,float(time.time() - start_time),All_Servers_num_all,All_Servers_num) 581 | 582 | except Exception,e: 583 | All_Servers_num += 1 584 | Result_status=False 585 | ResultSum="\n\033[1m\033[1;31m-ERR %s %s (%0.2f Sec All %d Done %d)\033[1m\033[0m\a" % (e,s,float(time.time() - start_time),All_Servers_num_all,All_Servers_num) 586 | bufflog=str(e) 587 | if Result_status: 588 | Write_Log(s,'NULL',bufflog.strip('\\n') + '\n',cmd,LogFile,'Y',Username,UseLocalScript,'N','N') 589 | TmpShow=Format_Char_Show.Show_Char(Show_Result+"Time:"+OPTime,0) 590 | WriteSourceLog(TmpShow) 591 | print TmpShow 592 | #Format_Char_Show.Show_Char(ResultSum+"Time:"+OPTime,0) 593 | else: 594 | Write_Log(s,bufflog.strip('\\n'),'NULL\n',cmd,LogFile,'Y',Username,UseLocalScript,'N','N') 595 | TmpShow=Format_Char_Show.Show_Char(Show_Result+"Time:"+OPTime,0) 596 | WriteSourceLog(TmpShow) 597 | print TmpShow 598 | #Format_Char_Show.Show_Char(ResultSum+"Time:"+OPTime,1) 599 | if All_Servers_num_all == All_Servers_num: 600 | print "+Done (Succ:%d,Fail:%d, %0.2fSec GUN/Linux Cheung Kei-Chuen All Right Reserved)" % (All_Servers_num_Succ,All_Servers_num_all-All_Servers_num_Succ,time.time()-Global_start_time) 601 | All_Servers_num =0 602 | All_Servers_num_Succ=0 603 | Done_Status='end' 604 | 605 | def Excute_cmd(): 606 | global All_Servers_num_all,All_Servers_num,All_Servers_num_Succ,Done_Status,Logcmd,ListenLog,Global_start_time,PWD 607 | Done_Status='end' 608 | All_Servers_num_all=len(Servers.split(',')) 609 | All_Servers_num =0 610 | All_Servers_num_Succ=0 611 | UseLocalScript='N' # 612 | PWD='' 613 | IS_PWD=False 614 | while True: 615 | OPTime=time.strftime('%Y%m%d%H%M%S',time.localtime()) 616 | if Done_Status=='end': 617 | if Useroot == "y": 618 | cmd=raw_input("CheungSSH root>>>>") 619 | else: 620 | cmd=raw_input("CheungSSH>>>>") 621 | 622 | else: 623 | time.sleep(0.05) 624 | continue 625 | 626 | try: 627 | if not IS_PWD: 628 | PWD=re.search("^ *cd.*",cmd).group() +";" 629 | Done_Status='end' 630 | IS_PWD=True 631 | continue 632 | else: 633 | try: 634 | PWD=re.search("^ *cd.*",cmd).group() +";" 635 | Done_Status='end' 636 | IS_PWD=True 637 | continue 638 | except: 639 | pass 640 | except Exception,e: 641 | PWD='' 642 | 643 | if re.search("^ *[Ee][Xx][Ii][Tt] *",cmd): 644 | sys.exit(0) 645 | if re.search("^ *[Cc][Ll][Ee][Aa][Rr] *",cmd): 646 | print "请使用ctrl + L 清屏" 647 | continue 648 | if re.search('^ *[Ff][Ll][Uu][Ss][Hh] *[Ll][Oo][Gg][Ss] *$',cmd): 649 | try: 650 | Log_Flag=time.strftime('%Y%m%d%H%M%S',time.localtime()) 651 | shutil.move('/cheung/logs/cheungssh.log','/cheung/logs/cheungssh%s.log' % Log_Flag) 652 | print "+OK" 653 | continue 654 | except Exception,e: 655 | print "Waring : %s Failed (%s)" % (cmd,e) 656 | continue 657 | if cmd=="reload": 658 | Read_config() 659 | print "+OK" 660 | continue 661 | 662 | 663 | if not cmd : 664 | continue 665 | Global_start_time=time.time() 666 | for s in Servers.split(","): 667 | 668 | try: 669 | t_password=All_pass["%s_Password" % (s)] 670 | except: 671 | t_password=Password 672 | try: 673 | if UseKey=="y": 674 | t_username=Username 675 | else: 676 | t_username=All_user["%s_Username" % (s)] 677 | except: 678 | t_username=Username 679 | try: 680 | t_port=All_port["%s_Port" % (s)] 681 | except: 682 | t_port=Port 683 | if LocalScript.lower() == 'y': 684 | if not os.path.isfile(cmd): 685 | print "Eroor: %s ScriptFile is not fond " % cmd 686 | #continue 687 | break 688 | else: 689 | ScriptFlag=str(random.randint(999999999,999999999999)) 690 | d_file='/tmp/' + os.path.basename(cmd) + ScriptFlag 691 | LocalScriptUpload(s,t_port,t_username,t_password,cmd,d_file) 692 | Newcmd="""chmod a+x %s;%s;rm -f %s""" % (d_file,d_file,d_file) 693 | Logcmd=cmd 694 | UseLocalScript='Y' 695 | else: 696 | Newcmd=cmd 697 | Logcmd=cmd 698 | 699 | Done_Status='start' 700 | if RunMode.upper()=='M': 701 | if Useroot=='y': 702 | a=threading.Thread(target=Excute_cmd_root,args=(s,t_port,t_username,t_password,Passwordroot,Newcmd,UseLocalScript,OPTime)) 703 | a.start() 704 | else: 705 | 706 | a=threading.Thread(target=SSH_cmd,args=(s,t_username,t_password,t_port,Newcmd,UseLocalScript,OPTime)) 707 | a.start() 708 | 709 | else: 710 | if Useroot=='y': 711 | Excute_cmd_root(s,Port,t_username,t_password,Passwordroot,Newcmd,UseLocalScript,OPTime) 712 | else: 713 | if Deployment=='y': 714 | ListenLog="""if [ ! -r %s ] ; then echo -e '\033[1m\033[1;31m-ERR ListenFile %s not exists,so do not excute commands !\033[1m\033[0m\a ' 1>&2 ;exit;else nohup tail -n 0 -f %s 2&>%s & fi;""" % (ListenFile,ListenFile,ListenFile,DeploymentFlag) 715 | SSH_cmd(s,t_username,t_password,t_port,Newcmd,UseLocalScript,OPTime) 716 | else: 717 | SSH_cmd(s,t_username,t_password,t_port,Newcmd,UseLocalScript,OPTime) 718 | 719 | ############################################################################################ 720 | if __name__=='__main__': 721 | InitInstall() 722 | Read_config() 723 | Main_p(Servers,Port,Username,Password) 724 | --------------------------------------------------------------------------------