自写 Shell 脚本快捷登陆服务器

开始的时候把个人的、公司的服务器登陆信息保存在了记事本当中,在每天需要频繁切换的情况下,实在是有些烦躁了,就想用 Shell 来写一个登陆脚本,知道有的 SSH 工具可以自带,写这样一个脚本原因就是个人兴趣。话说前阵子还出了个事情,某知名 SSH 工具带后门。

此脚本包括的 Shell 知识点:数组、自定义函数、if、while、printf、expect、read,等等,有基础知识点遗忘的时候也可以回头看看。

使用过程当中也出现了 Bug,都一一进行了修复,也存在还需要优化的地方,以后有空还会进行完善,目前我个人已经使用了一段时间,还算方便快捷。

脚本内容

#!/bin/bash

# 登陆信息配置
# 每个登陆信息为一个数组
# 第一个登陆信息的变量名称必须是「LOGIN_USER_1」,多条登陆信息时需要是 1 的连续整数 
LOGIN_USER_1=(
    'root' # 用户名
    '192.168.171.128' # 主机
    '8686' # 端口
    '' # 密码
    '/Users/admin/.ssh/id_rsa' # 密钥文件的绝对路径
    'key' # 登陆方式。key:密钥方式;pwd:密码方式
    '公司开发服务器' # 备注信息
)

LOGIN_USER_2=(
    'root'
    '192.168.171.120'
    '22'
    '123456'
    ''
    'pwd'
    '本地虚拟机 公司环境'
)

LOGIN_USER_3=(
    'root'
    '192.168.171.129'
    '22'
    '123456'
    ''
    'pwd'
    '本地虚拟机 个人环境'
)

LOGIN_TAG_START=1

login_user_configure_check() {

local LOCAL_LOGIN_TAG_START=${LOGIN_TAG_START}

# 第一个登陆配置数组不存在
if [ ! $(eval echo \${LOGIN_USER_${LOCAL_LOGIN_TAG_START}}) ]
then
    echo '错误!登陆数组:LOGIN_USER_'${LOCAL_LOGIN_TAG_START}' 不存在'
    exit 1
fi

while [ $(eval echo \${LOGIN_USER_${LOCAL_LOGIN_TAG_START}}) ]
do

    # 获得配置数组的元素总数
    local length=$(eval echo "\${#LOGIN_USER_${LOCAL_LOGIN_TAG_START}[*]}")

    if [ 7 -ne ${length} ]
    then
        echo 'LOGIN_USER_'${LOCAL_LOGIN_TAG_START}' 配置项必须是 7 项。脚本停止检查、终止执行、退出!'
        exit 1
    fi

    if [[ 'pwd' != "$(eval echo \${LOGIN_USER_${LOCAL_LOGIN_TAG_START}[5]})" ]] && [[ 'key' != "$(eval echo \${LOGIN_USER_${LOCAL_LOGIN_TAG_START}[5]})" ]]
    then
        echo 'LOGIN_USER_'${LOCAL_LOGIN_TAG_START}' 配置登陆方式错误,脚本停止检查、终止执行、退出!'
        exit 1
    fi

    if [[ 'key' == "$(eval echo \${LOGIN_USER_${LOCAL_LOGIN_TAG_START}[5]})" ]] && [[ ! "$(eval echo \${LOGIN_USER_${LOCAL_LOGIN_TAG_START}[4]})" ]]
    then
        echo 'LOGIN_USER_'${LOCAL_LOGIN_TAG_START}' 配置为密钥登陆,但是没有配置密钥文件,脚本停止检查、终止执行、退出!'
        exit 1
    fi

    for i in ` seq 0 "$((length-1))" `
    do
        if [ 3 -eq "${i}" ] || [ 4 -eq "${i}" ]
        then
            continue
        fi

        if [ ! "$(eval echo \${LOGIN_USER_${LOCAL_LOGIN_TAG_START}[${i}]})" ]
        then
            local LOGIN_USER_CONFIGURE_NUM=$((i+1))
            echo 'LOGIN_USER_'${LOCAL_LOGIN_TAG_START}' 第 '${LOGIN_USER_CONFIGURE_NUM}' 项配置不能为空'
            exit 1
        fi

    done

    ((LOCAL_LOGIN_TAG_START++))

done

}

# 调用登陆用户配置数组的检查
login_user_configure_check

screen_echo() {

printf "%-7s | " '序号'
printf "%-30s\n" '说明'

local LOCAL_LOGIN_TAG_START=${LOGIN_TAG_START}

while [ $(eval echo \${LOGIN_USER_${LOCAL_LOGIN_TAG_START}})  ]
do

    printf "\e[31m %-5s\e[0m| " "${LOCAL_LOGIN_TAG_START}" # 颜色为红色
    printf "%-30s\n" "$(eval echo \${LOGIN_USER_${LOCAL_LOGIN_TAG_START}[6]})"

    # 服务器总数 
    USER_SUM=${LOCAL_LOGIN_TAG_START}

    ((LOCAL_LOGIN_TAG_START++))

done

}

# 调用屏幕输出信息函数
screen_echo

while true
do

    # 让使用者选择所需要登陆服务器的所属序号
    read -p '请输入要登陆的服务器所属序号: ' LOGIN_NUM

    if [[ "${LOGIN_NUM}" =~ [^0-9]+ ]]
    then
        echo '序号是数字'
        continue
    fi

    if [ ! ${LOGIN_NUM} ]
    then
        echo '请输入序号'
        continue
    fi

    if [[ "${LOGIN_NUM}" =~ ^0 ]]
    then
        echo '序号不能以 0 开头'
        continue
    fi

    # 用户选择的序号 > 服务器总数、用户选择的序号 < 服务器总数。则提示错误并且重新循环
    if [ ${LOGIN_NUM} -gt ${USER_SUM} ] || [ ${LOGIN_NUM} -lt ${LOGIN_TAG_START} ]
    then
        echo '请输入存在的序号'
        continue
    fi

    break

done

# 登陆的函数

login_exec () {

# 当登陆方式是密码时
if [ 'pwd' == "$(eval echo \${LOGIN_USER_${LOGIN_NUM}[5]})" ]
then
    local mima=$(eval echo \${LOGIN_USER_${LOGIN_NUM}[3]})

    # 密码长度非 0 时
    if [ -n ${mima} ]
    then

        # 对 } 转义
        local mima=${mima//\}/\\\}}

        # 对 ; 转义
        local mima=${mima//\;/\\;}

    fi
fi

# spawn -noecho 不显示登陆信息
# 当登陆后出现「*yes/no*」是,回应「yes」
# ConnectTimeout 连接时超时时间;ConnectionAttempts 连接失败时的重试次数;StrictHostKeyChecking 不提示认证;ServerAliveInterval 客户端每多少秒向服务器发送请求;ServerAliveCountMax 客户端向服务器发送请求失败时的重试次数
# 「exp_continue」继续执行下面的匹配
# 「interact」留在远程终端上面。如果不写此语句,自动退出服务器
expect -c "
switch $(eval echo \${LOGIN_USER_${LOGIN_NUM}[5]}) {
    "pwd" { 
        spawn -noecho ssh -o ConnectTimeout=15 -o ConnectionAttempts=3 -o StrictHostKeyChecking=no -o ServerAliveInterval=15 -o ServerAliveCountMax=3 $(eval echo \${LOGIN_USER_${LOGIN_NUM}[0]})@$(eval echo \${LOGIN_USER_${LOGIN_NUM}[1]}) -p $(eval echo \${LOGIN_USER_${LOGIN_NUM}[2]})
        expect { 
            *yes/no* {
                send yes\r
                exp_continue
            }
            *denied* {
                exit
            }
            *password* {
                send ${mima}\r
            }
        }
        interact
    }
    "key" { 
        spawn -noecho ssh -o ConnectTimeout=15 -o ConnectionAttempts=3 -o StrictHostKeyChecking=no -o ServerAliveInterval=15 -o ServerAliveCountMax=3 -i $(eval echo \${LOGIN_USER_${LOGIN_NUM}[4]}) $(eval echo \${LOGIN_USER_${LOGIN_NUM}[0]})@$(eval echo \${LOGIN_USER_${LOGIN_NUM}[1]}) -p $(eval echo \${LOGIN_USER_${LOGIN_NUM}[2]})
        interact
    }
    default {
        puts "error"
    }
}
";

return 0;

}

# 调用登陆执行函数
login_exec

脚本不要忘了加上可执行权限

你需要的配置

脚本的开始就说了,第一个登陆信息数组名字必须是 LOGIN_USER_1,后面的服务器信息必须数组只需要 1 连续递增就好了。每个数组中的 7 个元素都不能少。脚本注释写的很清楚了。

GitHub 地址

Shell 登陆服务器脚本 GitHub 地址

知识共享许可协议
本作品采用知识共享署名-非商业性使用-禁止演绎 4.0 国际许可协议进行许可。
随喜
支付宝随喜
微信随喜

我喜欢在.bash_profile加alias aliyun="ssh abc@xxx.xxx.xxx.xxx", 然后直接输入aliyun就可以了

后三排

我喜欢在.bash_profile加alias aliyun="ssh abc@xxx.xxx.xxx.xxx", 然后直接输入aliyun就可以了

引用

简单粗暴有效。哈哈

喜欢简单粗暴的但是你这个最后一直需要输入密码,怎么回事

Several key Cavaliers players have already declared for the NBA draft, including De’Andre Hunter, Ty Jerome and Kyle Guy. Yeezy Boost 700 http://www.yeezy700.org.uk/

With several players either pursuing pro opportunities or moving on from UVA, it would be difficult, if not impossible to get everyone back together, Bennett said. We would have to respectfully decline an invitation. Steelers Jerseys http://www.pittsburghsteelers-jerseys.us/

yonlliuixv,Hi there, just wanted to say, I liked this article. It was helpful. Keep on posting! Jordan 12 Gym Red 2018 http://www.jordan12gymred.us.com/

qeuyyloqjjb,Thanks for sharing such an amazing blog. I am so happy found this informative blog. Jordan 12 Gym Red 2018 http://www.jordan12gymred.us/

Zithromax For Sale isotretinoin 10mg skin health Cats Amoxil <a href=http://lowpricecial.com>cheapest cialis 20mg</a> Comprar Cialis 20 Mg

vjppppAdidas Yeezy,Definitely believe that which you said. Your favourite justification appeared to be on the net the simplest thing to remember of. [url=http://www.travisscottjordan1.us.com/]Travis Scott Jordan 1[/url]

nkgwvs,Your blog was informative and valuable to me. Thanks for sharing. Pandora Jewelry Official Site http://www.pandora-officialsite.us/

Viagra Cialis Eu <a href=http://ausgsm.com></a>; Avodart In Singapore

Kamagra Ajanta Mumbai Cipla Cialis Review <a href=http://etrobax.com>cheapest cialis 20mg</a> Lowest Prices On Viagra