Linux服务器的管理员经常需要在多台机器上执行相同的命令。我不是Linux管理员,可以今天就接了个活,检查线上N台机器的存储是否都正确挂载了。N台机器一个一个ssh登录上去,然后mount人肉看一下,也许30分钟就搞定了。可是我是工程师,不能用这么“土”的方式解决。网上搜索了一下,虽然有很多这种管理工具,比如:tentakel什么的。可是我要检查的这些机器,一台都没有装这种东西,我也没有相应的系统权限装。我唯一有的,就是一个guest权限的账户,怎么办?
想到了以前用过的一个网络调试利器socat,比netcat强大100倍。socat有个牛叉的功能就是……就是……啊呀,专业术语怎么讲我也不知道,类型于tty重定向吧。比如:
(sleep 1; echo sshpassword; sleep 5; echo date; sleep 1;) | \
socat - EXEC:'ssh sshusername@somebox.com',pty,setsid,ctty
安装socat之后,执行这样的命令等于自动以sshusername用户ssh登陆到somebox.com机器,然后执行date命令,然后退出。整个过程不用你人工干预了。如果这个语句外面套一个for循环,里边的一些值再做成变量,那就威力无穷了。
socat的安装和使用,详见这里http://www.dest-unreach.org/socat/和这里http://www.cyberciti.biz/faq/linux-unix-tcp-port-forwarding/。好吧,如果你不懂英文,那勉强看这里。
我最后写的检查机器存储挂载的shell脚本如下:
#!/bin/sh
for host in 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72;
do
if [ $host -gt 54 ]
then
# 网速慢的机器
s1=2
s2=8
else
# 网速快的机器
s1=1
s2=2
fi
(sleep $s1; echo "$host"; sleep $s2; echo "hostname | xargs echo GG"; sleep $s1; echo "mount"; sleep $s1; echo "ls -l /mnt/"; sleep $s1) | \
socat - EXEC:'ssh somebody@somebox.com',pty,setsid,ctty | egrep "(GG|product|repository)"
done
几点说明:
1. 由于我做了ssh共享连接,所以不需要输入ssh密码了。
2. 由于我要先登陆跳板机,然后再输入机器号来跳转,然后再执行命令。所以host变量其实就是机器号。
3. 为了知道输出的mount信息是哪台机器的,我先执行了hostname(加了个GG前缀方便grep),然后再执行mount。
4. 最后通过grep来过滤出来我关注的信息。
执行结果如下:
$GG box1
192.168.1.100:/vol/product on /mnt/product type nfs (ro,remount,bg,nfsvers=3,tcp,rsize=32768,wsize=32768,hard,intr,addr=192.168.1.100)
drwxr-xr-x 3 admin systems 4096 Feb 14 17:29 product
lrwxrwxrwx 1 root root 15 Feb 15 02:36 repository -> /mnt/product
Shared connection to somebox.com closed.
$GG box2
192.168.1.100:/vol/product on /mnt/product type nfs (rw,remount,bg,nfsvers=3,tcp,rsize=32768,wsize=32768,hard,intr,addr=192.168.1.100)
drwxr-xr-x 3 admin systems 4096 Feb 14 17:29 product
lrwxrwxrwx 1 root root 15 Feb 15 02:36 repository -> /mnt/product
Shared connection to somebox.com closed.