有些时候,在面对开发机的时候,不断的telnet和不断的command自己的命令确实非常麻烦,需要一些自动测试或者自动部署的需求。然而面对telnet很多同学都跟我一样一开始觉得无法通过管道等传用户名和密码给telnet进行自动化执行。但其实还是有解决办法的,目前解决办法大致分一共有两种,一种是用第三方的expect这个命令,它可以交互式的根据终端返回的信息可以在你事先设定好的游戏规则之下进行命令,比如expect "Hello", send "Hello, too",表示当终端返回Hello的时候我就返回Hello,too,不然就用其中的set timeout进行超时等待。具体的用法同学可以参考相关细节,总之,expect绝对是服务器管理员的利器,如果你有空,确实可以抽空好好学习一下这个命令。但麻烦的就是它不是系统标配的,需要后期安装。
第二种方法比较简单,有些同学可能会跟我一样,想着兼容性方面,比如我这个脚本有可能会给我团队的队友一起使用,难道要求他们都去装expect吗?有没有简单的办法可以让shell来帮我们进行telnet并自动执行一些简单的命令呢?答案是有的,那就是利用管道,echo,telnet的三者结合,先看以下demo.
#!/bin/bash
#==============================================
# Author: Ricky.K
# Description: Auto telnet and run command
#==============================================
echo "My own command..." &&
(sleep 1; echo "user"; \
sleep 1; echo "password"; \
sleep 1; echo "cd /usr/local"; \
sleep 1; echo "./test.sh"; \
while [[ true ]]; do \
sleep 1; \
done;) | telnet 192.168.1.1
可以看到,在输入完自己命令之后,可以通过小括号(用大括号需要注意左边第一个括号和第一个命令有一个空格)将命令包起来,这样整个的管道就是对其中各个命令的全部起作用,利用echo,将用户名,密码,以及你要输入的命令通过管道传给telnet,即实现了自动化的telnet脚本命令实现。同时需要注意,在最后一个命令(非sleep)之前,如果直接传给telnent,你会发现命令根本就没有执行完或者压根就没执行就被你断开链接了,这个时候你需要用while循环或者sleep一个比较大的值来让它有时间进行命令响应,这也是需要考虑的。
telnet自动化并没有我们想的这么复杂,用用简单命令一样可以实现这些功能,也反应了UNIX经典的设计哲学,通过管道和命令组装,你就拥有了世界上最好的武器。
送几条常用命令:
判断通或不通
echo q|telnet -e 'q' $ip $port && echo "$ip:port 通"||echo "$ip:port 不通"
登录
//test.txt
set timeout 120
spawn telnet 192.168.1.1
expect "Username:"
send "test\r"
expect "Password:"
send "test\r"
expect "$"
send "ls -l\r"
redis
#!/bin/bash
#redirect input
rm -f tmp_in
mknod tmp_in p
exec 8<> tmp_in
address=`kubectl get pods -n dw -o wide|grep redis|grep sentinel-1|awk '{print $6}'`
port=26379
echo "address==$address"
#process custom command
telnet $address $port <&8 &
echo "info" >> tmp_in
sleep 1
#quit: escape character ^] ascii is \035
echo -e "\035quit" >> tmp_in
最后命令参考交互式进程(如telnet)的自动处理脚本【转】写的。