全部博文(184)
分类: LINUX
2008-07-11 16:49:01
sssh - 快速 ssh 登陆脚本
2008-07-11 Toy Posted in Apps, ScriptsRSSTrackback
此脚本对于那些需要经常 ssh 登陆远程服务器的朋友应该有点用处。尤其是需要中转服务器 ssh 2 次以上的。脚本功能包括:将服务器 IP 和密码保存于文本文件中 (明文保存,安全性要自己保证),方便登陆,支持多次 ssh 中转,支持服务器编码自动转换,支持某个用户名的通用密码。
使用方法:
最好将脚本保存在 PATH 变量包含的路径下,建议保存于 ~/bin 并确保此目录在 PATH 中。
编写 ~/.pass 文件,并执行 chmod 600 ~/.pass
安装 expect 包。
.pass 文件的写法:
最简单的,可以在文件中写下如下一行:
name=hostA passwordA
就可以使用 sssh hostA 登陆此服务器了。
中转登陆:
name=hostA passwordA
name-hostA=hostB passwordB
执行 sssh hostA hostB 就相对于先登陆 hostA,然后在 hostA 上登陆 hostB。同理,理论上可以中转 N 次,hostA->hostB->hostC->hostD……,嘿嘿……
使用通用用户名的密码:
这是用于这样的例子:有 N 个服务器,都开通了一个通用用户名 (例如:view 用户,只有很低的权限),这些 view 用户的密码都是同一个,而且会定期同步修改。这种情况下,如果修改了 view 密码的话,.pass 文件就要修改 N 个密码了,为了避免这样的麻烦,可以使用通用用户名和密码功能:
usualName view
usualPSW password-of-view
name=hostA
name=hostB
name=hostC
这样就可以直接用 sssh hostA,sssh hostB 登陆了。可以看到,这里省略了第 3 列的密码字段。此法同样适用于多级登陆的服务器。
指定服务器使用的编码:
usualName view
usualPSW password-of-view
name=hostA passwordA gbk
name=hostB | gbk
在某行服务器的后面 (第 4 列),加上 gbk,就可以指明该服务器使用的是 gbk,登陆了以后不会出现乱码了。如果某行使用了通用用户名和密码的话,为了不致引起混乱,密码那列需要加个 | (竖线) 占位。
使用通用编码:
usualCODING gbk
加上此行,对于没有指定编码的服务器,将默认使用 gbk 编码。
PASSFILE="$HOME/.pass"
if [[ x`which expect` = x"" ]];then
echo "么装expect啊...先给装上吧..."
exit 1
fi
if [[ x`which luit` = x"" ]];then
echo "么装luit啊...先给装上吧..."
exit 2
fi
if [[ ! -f $PASSFILE || ! -r $PASSFILE ]];then
echo "密码文件不存在或不可读"
exit 3
fi
PASSFILEAccess=`stat "$PASSFILE" | grep Access | head -1 | awk -F "[\(/]+" '{print $2}'`
if [[ $PASSFILEAccess -gt 0600 ]];then
echo "密码文件($PASSFILEAccess)权限太大了,为了安全起见,请设置为600"
exit 4
fi
if [[ $# -eq 0 ]];then
echo "Usage: $0 [-l]|[-e]|hostname1 hostname2 ..."
exit 5
fi
if [[ $1 = "-l" ]];then
cat $PASSFILE
exit 0
fi
if [[ $1 = "-e" ]];then
gedit $PASSFILE &
exit 0
fi
HOSTS=""
EXP=""
LINEPREFIX="name"
NL="
"
USUALNAME=`grep usualName $PASSFILE | awk '{print $2}'`
USUALNAMEPSW=`grep usualPSW $PASSFILE | awk '{print $2}'`
until [[ -z "$1" ]]
do
THENAMEANDHOST=`grep "${LINEPREFIX}=$1" $PASSFILE | awk '{print $2}'`
if [[ "x$THENAMEANDHOST" = "x" ]];then
echo "没有找到名称为 $1 的服务器..."
exit 10
fi
TMP=`echo "$THENAMEANDHOST" | wc -l`
if [[ $TMP -gt 1 ]];then
echo "找到多个名称匹配 $1 的服务器..."
echo "`grep "${LINEPREFIX}=$1" $PASSFILE`"
exit 11
fi
THENAME=`grep "${LINEPREFIX}=$1" $PASSFILE | awk '{print $2}' | awk -F "@" '{print $1}'`
THEPSW=`grep "${LINEPREFIX}=$1" $PASSFILE | awk '{print $3}'`
CODING=`grep "${LINEPREFIX}=$1" $PASSFILE | awk '{print $4}'`
HOSTS+=" ssh -t "$THENAMEANDHOST
if [[ "x$THEPSW" = "x" || "$THEPSW" = "|" && "$THENAME" = "$USUALNAME" ]] ; then
EXP+="expect password:"$NL"send \""$USUALNAMEPSW"\n\""$NL
else
EXP+="expect password:"$NL"send \""$THEPSW"\n\""$NL
fi
LINEPREFIX+="-$1"
shift
done
if [[ "x$CODING" = "x" ]];then
CODING=`grep usualCODING $PASSFILE | awk '{print $2}'`
fi
if [[ "x$CODING" = "x" ]];then
echo "$PASSFILE 中没有配置 usualCODING,使用utf8."
CODING="utf8"
fi
CMD="set timeout 30"$NL"spawn luit -encoding ""$CODING""$HOSTS"$NL"$EXP""interact""$NL"
echo "$CMD"
echo "======================"
expect -c "$CMD"