酷壳博主发过一条微博
要如何识别一个公司的运维能力高还是低。在我看来,其实很简单。就看你ssh到机器上的频率有多高,ssh上去的次数越多,就说明你的运维能力越Low。如果你还在ssh到机器上用vim改配置,那么你的运维能力基本上还处于“原始社会”。
以这个标准,我的工作就相当的low了。公司统一的配置管理程序是cfengine,但改sudo配置这种事情,从来都是扔给我们组手动操作。当没有批量功能的时候,脚本似乎成了唯一的救命稻草。然而,大量机器一起改的需求并不是很常见,很多时候就那么几台,跑个脚本还真是不值得。
需求
只有十多台机器的时候,单纯从时间来计算,调试脚本的时间或许已经手动做完了。但是调试脚本的过程可比重复敲命令好受的多。其实,这种需求应该是通过程序全程完成的。
提案申请 --> 提案审批完成 --> push或者pull 到配置管理工具 --> 配置管理工具下发变更
进入正题。今天需要给15台机器加2个用户的sudo权限。首先,这15台机器不一定都有免密码登录权限,没有登录权限的时候会提示输入密码,脚本就卡住了,因此,需要忽略密码提示。
ssh -o NumberOfPasswordPrompts=0 $id "pwd" &>/dev/null
然后,登录成功后需要在那台机器上执行命令,当然直接像上面那样在ssh命令后面直接加命令。但是当命令较多时,可读性较差。所以将一个区块重定向至ssh命令。
ssh -tt $id << EOF rsync 10.217.1.22::root/sudo/* . echo "$USER">dat sed -i "s/\ /\n/g" dat sudo ./addsudo.sh > $id.log rsync $id.log 10.217.1.22::root/sudo/log/ exit EOF
ssh -tt选项的作用
-t Force pseudo-tty allocation. This can be used to execute arbitrary screen-based programs on a remote machine, which can be very useful, e.g., when implementing menu services. Multiple -t options force tty allocation, even if ssh has no local tty.
while代码块中的“吃行”问题
一开始从文件中读ip,却总是只能执行第一行的ip,代码结构如下:
#/bin/bash while read id;do ssh -tt $id if [ $? != 0 ];then echo "$id : No Permission" continue else echo "$id : ok" fi done <ip.list
执行结果:
bash0-3.2$ ./bat.sh tcgetattr: Inappropriate ioctl for device Last login: Tue Feb 3 16:47:28 2015 from 10.2.6.4 [root@localhost ~]$ -bash: 10.210.231.26: command not found [root@localhost ~]$ -bash: 10.210.137.11: command not found [root@localhost ~]$ ls Killed by signal 2. 10.210.231.25 : No Permission
可以看到,ip.list中的内容除第一行外都定向到登录上的那台服务器上去了。
这里用文件描述符可以解决
#/bin/bash exec 3<ip.list while read id<&3;do ssh -tt $id "pwd" &>/dev/null if [ $? != 0 ];then echo "$id : No Permission" continue else echo "$id : ok" fi done exec 3<&-
执行结果
bash0-3.2$ ./bat.sh 10.210.231.25 : ok 10.210.231.26 : ok 10.210.137.11 : ok
参考网上资料,是这么解释的:
因为重定向是针对整个while循环块的,而不只是read命令,read从输入读取了一行内容后,
其它的程序(比如 rsh或sed)从同样的地方把其它的输入读走了,read当然读不到其它内容了,
while也就结束了
完整代码
#/bin/bash exec 3<ip.list while read id<&3;do ssh -o NumberOfPasswordPrompts=0 $id "pwd" &>/dev/null if [ $? != 0 ];then echo "$id : No Permission" continue else echo "$id : ok" fi ssh -tt $id << EOF rsync 10.217.1.22::root/sudo/* . echo "$USER">dat sed -i "s/\ /\n/g" dat sudo ./addsudo.sh > $id.log rsync $id.log 10.217.1.22::root/sudo/log/ exit EOF done exec 3<&-
参考资料
1. Chinauxix论坛. http://bbs.chinaunix.net/thread-4130474-1-1.html 2. http://blog.csdn.net/ace_fei/article/details/6653503
不还是用ssh登上去的么~