美文网首页
Cygwin自动登录ssh

Cygwin自动登录ssh

作者: 掖莯圷 | 来源:发表于2019-04-12 10:22 被阅读0次

    autossh

    #!/bin/bash
    #Filename:      loginssh.sh
    #Revision:      0.2
    #Date:          2019/04/17
    #Author:        taoyz
    #Description:   自动登录ssh
    #send:用于向进程发送字符串
    #expect:从进程接收字符串
    #spawn:启动新的进程
    #interact:允许用户交互
    
    #sed用法,参考:https://blog.51cto.com/xficc/1621403
    
    #dirname $0,取得当前执行的脚本文件的父目录 
    #$0 使用一个文件调用bash,那$0的值,是那个文件的名字
    #使用-c选项启动bash的话,真正执行的命令会从一个字符串中读取,字符串后面如果还有别的参数的话,使用从$0开始的特殊变量引用
    #除此以外,$0会被设置成调用bash的那个文件的名字
    basepath=$(cd `dirname $0`; pwd)
    v_pass_dir=$basepath"/sshlogin.config"
    v_sn=0
    v_ip="127.0.0.1"
    v_port="22"
    v_user="root"
    v_password="123456"
    v_desc=""
    v_fs="b8d9ae71a737464795a0a3754b905b8a"
    v_title="序号${v_fs}主机$v_fs端口$v_fs用户名$v_fs密码$v_fs说明"
    v_init=0
    Green_font_prefix="\033[32m" && Red_font_prefix="\033[31m" && Green_background_prefix="\033[42;37m" && Red_background_prefix="\033[41;37m" && Font_color_suffix="\033[0m"
    v_serch_index=
    v_console=""
    v_salt=DAA482697BECAB46
    v_key="B19607C21B91022063367901BE2F936109CD67BADA327C80DCF020C43B9C42A9"
    v_iv="849BDEF6D991CAF429EF04C8E5791A1C"
    #获取总行数
    function get_serch_index(){
       v_serch_index=$(awk -v num=$1 'BEGIN {FS="'$v_fs'"} {if($1 == num) {print NR}}' $v_pass_dir)
       
    }
    function show_text(){
        awk  \
        'function drawLine(v_part,v_length,v_cols_len,v_splilt,v_line_style){
            v_resulte = ""
            v_index = 0
            v_cols_len_index = 0
            #遍历总长度
            for(i=0;i < v_length;i++){
                #添加列分隔符
                if(i == v_cols_len_index){
                    if(v_part == "top" && i!=0){
                        v_resulte= v_resulte""v_line_style
                    }else{
                        v_resulte= v_resulte""v_splilt
                    }
                    v_cols_len_index += (v_cols_len[v_index]+3)
                     v_index++
                }else{
                      v_resulte = v_resulte""v_line_style
                }
            }
            
            v_resulte = v_resulte""v_splilt
            return v_resulte
          }
          function get_str(v_str){
                v_length = length(v_str)
               # printf("%s-->设置前长度:%s\n",v_str,v_length);
               # v_cout = 0
                v_size = v_length
                for(x=0;x<v_length;x++){
                     if (substr(v_str, x, 1) > "\177") {
                        v_size++
                      #  v_cout++
                     }
                }
               # printf("%s-->设置后长度:%s,中文数量:%s\n",v_str,v_size,v_cout);
                return v_size
    
          
          }
          function copyright(line_len_sum,cols_len){
                  start_line = drawLine("start",line_len_sum,cols_len,"#","#");
                   print start_line
                   v_welcome="Auto Login SSH Platform"
                   v_space=""
                   v_space_size = (line_len_sum - length(v_welcome))/2;
                   for(k=0;k<v_space_size;k++){
                            v_space=v_space" "
                   }
                   print  v_space""v_welcome""v_space
                   print start_line
          
          }
            BEGIN {FS="'$v_fs'"} 
            {   
                #遍历设置每列最大长度 
                v_index=0
                for(i=0;i<=NF;i++){ 
                    if(i==0){
                        if(NR==1){
                         v_value="行数"
                        }else{
                         v_value=NR-1
                        }    
                    }else{
                        v_value=$i
                    }
                    if(NR==1){
                       cols_len[v_index]=3
                    }
                    v_length=get_str(v_value)
                    #获取每列最大长度 
                    if(v_length > cols_len[v_index]){
                        cols_len[v_index]=v_length 
                    }  
                    #讲每行的值临时存储到二维数组 
                    rows_list[NR-1][v_index]=v_value
                    v_index=v_index+1
                    #移除密码
                    if(i == 4){
                        i=i+1
                    }
                } 
            } END{ 
                #开始输出n数据 
                # 行最大总长度
                line_len_sum=length(cols_len)
                for(i=0;i<length(cols_len);i++){
                    line_len_sum=line_len_sum + cols_len[i] + 2
                }
                #for(i=0;i<length(cols_len);i++){
                #    printf("列 %s,长度:%s\n",i,cols_len[i]);
                #    
                #}
                #printf("******************\n")
                # 上边框
                top_line = drawLine("top",line_len_sum,cols_len,"+","-")
                # 分隔
                mid_line = drawLine("mid",line_len_sum,cols_len,"+","-")
                if("'$1'" == 1){
                    copyright(line_len_sum,cols_len)
                   
                }
                if("'$2'" == 1){
                    for(i = 0 ; i < length(rows_list); i++){
                        if(i==0){
                            print top_line
                        } 
                        #绘制一行
                        row_str="|"
                        for(j = 0 ; j < length(cols_len); j++){ 
                            v_space=""
                            for(k=0;k<cols_len[j]-get_str(rows_list[i][j]);k++){
                                v_space=v_space" "
                            }
                            row_str=row_str""rows_list[i][j]""v_space"  |"
    
                        }
                        print row_str
                        print mid_line
    
                    }
                }
            } ' $v_pass_dir
    }
    function reset_context(){
        echo -e $v_title > $v_pass_dir
    }
    function inset_context(){
        
        while read -p '[*] 请输入主机: ' v_console ;do
            if  [ ! -n "$v_console" ] ;then
                echo -e "${Red_font_prefix}请输入内容${Font_color_suffix}"
            else
               v_ip=$v_console
               break
            fi
        done
        
        read -p '[*] 请输入端口(默认为22): ' v_console
        if  [ ! -n "$v_console" ] ;then
           v_port="22"
        else
           v_port=$v_console
        fi
        read -p '[*] 请输入用户名(默认为root): ' v_console
        if  [ ! -n "$v_console" ] ;then
           v_user="root"
        else
           v_user=$v_console
        fi    
         while read -s -p '[*] 请输入密码: ' v_console ;do
            if  [ ! -n "$v_console" ] ;then
                echo
                echo -e "${Red_font_prefix}请输入内容${Font_color_suffix}"
            else
               #v_password=$(echo  $v_console | openssl aes-128-cbc -k 123 -base64)
               #https://blog.51cto.com/shjia/1427138
               v_password=$(echo  $v_console | openssl enc -e -aes-256-cbc -a -K ${v_key} -iv ${v_iv} -salt)
               break
            fi
        done
        echo
        read -p '[*] 请输入描述: ' v_console
        v_desc=$v_console
        #获取自增序号
        last_row=`sed -n '$=' $v_pass_dir`
        v_sn=$(awk -v num=$last_row 'BEGIN {FS="'$v_fs'"} {if(NR == num) {print $1}}' $v_pass_dir)
        if [ ! -n "$(echo $v_sn| sed -n "/^[0-9]\+$/p")" ];then  
            v_sn=0
        fi
        v_sn=`expr $v_sn + 1`
        read -p '[*] 是否确定新增(y/n): ' v_console
        if [ $v_console = "y" ] || [ $v_console = "Y" ]; then
            echo -e "${Green_font_prefix}自增序号:$v_sn${Font_color_suffix}"
            echo -e $v_sn$v_fs$v_ip$v_fs$v_port$v_fs$v_user$v_fs$v_password$v_fs$v_desc >> $v_pass_dir
            echo -e "${Green_font_prefix}新增成功${Font_color_suffix}"
            show_text 0 1
        fi
    }
    
    function read_number(){
        while read -p "$1: " v_console ;do
            if  [ ! -n "$v_console" ] ;then
                echo -e "${Red_font_prefix}请输入内容${Font_color_suffix}"
            else
    
                if [ ! -n "$(echo $v_console| sed -n "/^[0-9]\+$/p")" ];then  
                  echo -e "${Red_font_prefix}错误,请输入数字!${Font_color_suffix}"
                else
                  
                  break 
                fi
            fi
        done
    }
    function edit_context(){
        read_number "[*] 请选择要修改的序号" 
        get_serch_index $v_console
        if [ -z "$v_serch_index" ];then
           echo -e "${Red_font_prefix}未匹配到数据${Font_color_suffix}"
        else
            v_row=`expr $v_serch_index - 1`
            v_sn=$v_console
            echo -e "${Green_font_prefix}匹配到行数:${v_row}${Font_color_suffix}"
            v_ip_o=$(awk -v num=$v_console 'BEGIN {FS="'$v_fs'"}  {if($1 == num) {print $2}}' $v_pass_dir)
            v_port_o=$(awk -v num=$v_console 'BEGIN {FS="'$v_fs'"}  {if($1 == num) {print $3}}' $v_pass_dir)
            v_user_o=$(awk -v num=$v_console 'BEGIN {FS="'$v_fs'"}  {if($1 == num) {print $4}}' $v_pass_dir)
            v_password_o=$(awk -v num=$v_console 'BEGIN {FS="'$v_fs'"}  {if($1 == num) {print $5}}' $v_pass_dir)
                    
            read -p '[*] 请输入主机(为空时不修改): ' v_console 
                if  [ ! -n "$v_console" ] ;then
                   v_ip=$v_ip_o
                else
                   v_ip=$v_console
                fi
            read -p '[*] 请输入端口(为空时不修改): ' v_console
            if  [ ! -n "$v_console" ] ;then
               v_port=$v_port_o
            else
               v_port=$v_console
            fi
            read -p '[*] 请输入用户名(为空时不修改): ' v_console
            if  [ ! -n "$v_console" ] ;then
               v_user=$v_user_o
            else
               v_user=$v_console
            fi  
            read -s -p '[*] 请输入密码(为空时不修改): ' v_console
            if  [ ! -n "$v_console" ] ;then
               v_password=$v_password_o
            else
               v_password=$(echo  $v_console | openssl enc -e -aes-256-cbc -a -K ${v_key} -iv ${v_iv} -salt)
            fi     
            echo
            read -p '[*] 请输入描述: ' v_console
            v_desc=$v_console          
            read -p '[*] 是否确定修改(y/n): ' v_console
            if [ $v_console = "y" ] || [ $v_console = "Y" ]; then
                sed -i "${v_serch_index}c $v_sn$v_fs$v_ip$v_fs$v_port$v_fs$v_user$v_fs$v_password$v_fs$v_desc" $v_pass_dir
                echo -e "${Green_font_prefix}编辑成功${Font_color_suffix}"
                show_text 0 1
            fi
        fi
    }
    function del_index(){
        read_number "[*] 请输入序号:" 
        get_serch_index $v_console
        if [ -z "$v_serch_index" ];then
           echo -e "${Red_font_prefix}未匹配到数据${Font_color_suffix}"
        else
            v_row=`expr $v_serch_index - 1`
            echo -e "${Green_font_prefix}匹配到行数:$v_row${Font_color_suffix}"
            read -p '[*] 是否确定删除(y/n): ' v_console
            if [ $v_console = "y" ] || [ $v_console = "Y" ]; then
                sed -i "${v_serch_index}d" $v_pass_dir
                echo -e "${Green_font_prefix}删除成功${Font_color_suffix}"
                show_text 0 1
            fi
        fi
    
    }
    function del_row(){
        read_number "[*] 请输入行号:" 
        v_row=`expr $v_console + 1`
        last_row=`sed -n '$=' $v_pass_dir`
        if [ `echo ${v_row} | awk -v tem=$last_row '{print($1>tem)? "1":"0"}'` -eq "1" ];then
            echo -e "${Red_font_prefix}输入行数越界${Font_color_suffix}"
        else
            read -p '[*] 是否确定删除(y/n): ' v_console
            if [ $v_console = "y" ] || [ $v_console = "Y" ]; then
                sed -i "${v_row}d" $v_pass_dir
                echo -e "${Green_font_prefix}删除成功${Font_color_suffix}"
                show_text 0 1
            fi
        fi
    
    }
    function start_linkssh(){
     #   while [ True ];do
        read_number "[*] 请输入序号" 
        get_serch_index $v_console
        if [ -z "$v_serch_index" ];then
           echo -e "${Red_font_prefix}未匹配到数据${Font_color_suffix}"
        else
            v_row=`expr $v_serch_index - 1`
            echo -e "${Green_font_prefix}匹配到行数:$v_row,正在连接...${Font_color_suffix}"
            v_ip=$(awk -v num=$v_console 'BEGIN {FS="'$v_fs'"}  {if($1 == num) {print $2}}' $v_pass_dir)
            v_port=$(awk -v num=$v_console 'BEGIN {FS="'$v_fs'"}  {if($1 == num) {print $3}}' $v_pass_dir)
            v_user=$(awk -v num=$v_console 'BEGIN {FS="'$v_fs'"}  {if($1 == num) {print $4}}' $v_pass_dir)
            v_password=$(awk -v num=$v_console 'BEGIN {FS="'$v_fs'"}  {if($1 == num) {print $5}}' $v_pass_dir)
            v_password=$(echo  $v_password | openssl enc -d -aes-256-cbc -a -K ${v_key} -iv ${v_iv} -salt)
            # expect -f $basepath/ssh_login.exp $v_ip $v_user $v_password $v_port
            # -o stricthostkeychecking=no  首次登陆免输yes登录 即每隔30秒,向服务器发出一次心跳。若超过300次请求,都没有发送成功,则会主动断开与服务器端的连接
            sshpass -p $v_password ssh $v_user@$v_ip -p $v_port -o stricthostkeychecking=no -o ServerAliveInterval=30 -o ServerAliveCountMax=300
            echo $? #捕获上一条命令的输出 (if 0 正常 else 错误)
    #       freq=0
    #       echo "连接信息:$v_info"
    #       v_status=$?
    #       echo "连接状态:$v_status"
    #       while [ True ];do
    #           if [[$freq -gt 3]];then
    #               echo "${Red_font_prefix}尝试连接失败${Font_color_suffix}"
    #               break
    #           fi
    #           while read -s -p '[*] 授权失败,请输入密码重试: ' v_console ;do
    #               if  [ ! -n "$v_console" ] ;then
    #                   echo
    #                   echo -e "${Red_font_prefix}请输入内容${Font_color_suffix}"
    #               else
    #                  v_password=$v_console
    #                  break
    #               fi
    #           done
    #           freq=freq+1
    #           sshpass -p $v_password ssh $v_user@$v_ip -p $v_port
    #           read -s -p '[*] 成功: ' v_console
    #       done
    #   break;
        fi
     #   done
    
    }
    function start_link_sftp(){
        read_number "[*] 请输入序号" 
        get_serch_index $v_console
        if [ -z "$v_serch_index" ];then
           echo -e "${Red_font_prefix}未匹配到数据${Font_color_suffix}"
        else
            v_row=`expr $v_serch_index - 1`
            echo -e "${Green_font_prefix}匹配到行数:$v_row,正在连接SFTP...${Font_color_suffix}"
            v_ip=$(awk -v num=$v_console 'BEGIN {FS="'$v_fs'"}  {if($1 == num) {print $2}}' $v_pass_dir)
            v_port=$(awk -v num=$v_console 'BEGIN {FS="'$v_fs'"}  {if($1 == num) {print $3}}' $v_pass_dir)
            v_user=$(awk -v num=$v_console 'BEGIN {FS="'$v_fs'"}  {if($1 == num) {print $4}}' $v_pass_dir)
            v_password=$(awk -v num=$v_console 'BEGIN {FS="'$v_fs'"}  {if($1 == num) {print $5}}' $v_pass_dir)
            v_password=$(echo  $v_password | openssl enc -d -aes-256-cbc -a -K ${v_key} -iv ${v_iv} -salt)
            # expect -f $basepath/ssh_login.exp $v_ip $v_user $v_password $v_port
            lftp -u ${v_user},${v_password} sftp://${v_ip}:$v_port
            if [ "$?" != "0" ]; then
                echo -e "${Red_font_prefix}连接失败,请查看是否安装lftp或尝试手动执行:sftp -oPort=$v_port ${v_user}@${v_ip}${Font_color_suffix}"
            fi
    
        fi
    
    }
    
    function show_pass(){
        read_number "[*] 请输入序号" 
        get_serch_index $v_console
        if [ -z "$v_serch_index" ];then
           echo -e "${Red_font_prefix}未匹配到数据${Font_color_suffix}"
        else
            v_password=$(awk -v num=$v_console 'BEGIN {FS="'$v_fs'"}  {if($1 == num) {print $5}}' $v_pass_dir)
            v_password=$(echo  $v_password | openssl enc -d -aes-256-cbc -a -K ${v_key} -iv ${v_iv} -salt)
            echo "密码:$v_password"
        fi
    
    }
    function main_menu(){
        echo -e "
    ${Green_font_prefix}--${Font_color_suffix}主菜单
      ${Green_font_prefix}-1.${Font_color_suffix} 显示站点列表
      ${Green_font_prefix}-2.${Font_color_suffix} 选择站点连接SSH
      ${Green_font_prefix}-3.${Font_color_suffix} 选择站点连接SFTP
      ${Green_font_prefix}-4.${Font_color_suffix} 新增站点
      ${Green_font_prefix}-5.${Font_color_suffix} 编辑站点
      ${Green_font_prefix}-6.${Font_color_suffix} 删除站点(根据序号)
      ${Green_font_prefix}-7.${Font_color_suffix} 删除站点(根据行数)
      ${Green_font_prefix}-8.${Font_color_suffix} 重置配置文件
    ${Red_font_prefix}按q退出${Font_color_suffix} 
          "
    input_info="[1-8]"
    echo && read -e -p "请输入数字 $input_info:" num
    case "$num" in
        1)
        show_text 0 1
        main_menu
        ;;
        2)
        start_linkssh
        ;;
        3)
        start_link_sftp
        ;;
        4)
        inset_context
        ;;
        5)
        edit_context
        ;;
        6)
        del_index
        ;;
        7)
        del_row
        ;;
        8)
        reset_context
        ;;
        9999)
        show_pass
        ;;
        "q")
        exit;
        ;;
        *)
        echo -e "${Red_font_prefix}请输入正确的数字 $input_info${Font_color_suffix}"
        
        ;;
    esac
    }
    function init_file(){
        if [ ! -f $v_pass_dir ];then
            echo "未检测到配置文件,正在初始化..."
            reset_context 
            echo "初始化成功"
            echo
        fi
        #空文本初始化
        if [[ ! -s $v_pass_dir ]] 
        then
            reset_context
        fi 
    }
    function main(){
        v_first=0
        while [ True ];do
            init_file
            if [[ $v_first == 0 ]];then
                show_text 1 1
                echo -e "${Red_font_prefix}ssh需安装sshpass、sftp需安装lftp${Font_color_suffix}"
            fi
            v_first=v_first+1
            main_menu
        done
    }
    
    main
    
    

    window自动运行脚本,放置同一目录即可

    @echo off
    set v_cur_path=%cd:\=/%
    pushd "%~dp0"
    E:\tyz\soft\cygwin64\bin\mintty.exe  -e /bin/bash --login -i -c "cd \"%v_cur_path%\"; ./loginssh.sh exec bash"
    
    

    相关文章

      网友评论

          本文标题:Cygwin自动登录ssh

          本文链接:https://www.haomeiwen.com/subject/yypqwqtx.html