Hudson, Jenkins, Gulp, Grunt 这些都是用来写自动化的工具,网路已经有很多相关的教学,使用这些工具的公司更是不胜枚举,而就算没有这些工具,我们仍然可以用 Linux Command 来做自动化的工作,用起来也不会输给那些工具,反而省去了复杂的设定,还更简单维护。
检查多台机器的 Log
在写自动化程式前,我先来说明如果远端呼叫 Linux 机器做事。
如果我有个线上机器 hostname 是 www.puritys.me,当线上机器发生问题时,我会需要检查 /var/log/messages 档案内的 Log 讯息,但是我不用真的登入线上机器,我只要使用 ssh host "command" 这个指令,就可以远端呼叫线上机器把 log 印出来看。
- [www]$ ssh www.puritys.me "tail -n 5 /var/log/messages"
- May 23 12:30:01 localhost systemd: Starting Session 5094 of user root.
- May 23 12:30:01 localhost systemd: Started Session 5094 of user root.
- May 23 12:38:04 localhost systemd: Starting Session 5095 of user www.
- May 23 12:38:04 localhost systemd: Started Session 5095 of user www.
- May 23 12:38:04 localhost systemd-logind: New session 5095 of user www.
上面这个范例是当线上机器只有一台的时候,但若我们线上机器不只一台,例如 www1.puritys.me ~ www4.puritys.me 共四台机器,那么单单靠上面这个指令,就得执行四次 。
这里我要用 shell script 的 forloop 语法,一次执行呼叫四台机器印出我要的 Log 。
- [www]$ for i in $(seq 1 4); do ssh www$i.puritys.me "tail -n 1 /var/log/messages"; done;
为了更清楚呈现 每一台机器的 Log ,我们可以在 shell script 中加入 echo "in $host" ,先印出机器名称。
- [www]$ for i in $(seq 1 4); do host=www$i.puritys.me ; echo "In $host:"; ssh $host "tail -n 1 /var/log/messages"; done;
- In www1.puritys.me:
- Warning: Permanently added 'www1.puritys.me' (RSA) to the list of known hosts.
- May 29 20:01:55 website systemd-logind: New session 30270 of user www.
- In www2.puritys.me:
- Warning: Permanently added 'www2.puritys.me' (RSA) to the list of known hosts.
- May 29 20:01:55 website systemd-logind: New session 30270 of user www.
- In www3.puritys.me:
- Warning: Permanently added 'www3.puritys.me' (RSA) to the list of known hosts.
- May 29 20:01:55 website systemd-logind: New session 30270 of user www.
- In www4.puritys.me:
- Warning: Permanently added 'www4.puritys.me' (RSA) to the list of known hosts.
- May 29 20:01:55 website systemd-logind: New session 30270 of user www.
如何使用 Makefile
刚刚的指令太长了,如果每次都要手动输入的话就太累了,我们可以用 Linux 内建的 Gnu Make ,将指令写在 Makefile 里面,然后再用简短的 command 来呼叫。
我建一个档案档名为 Makefile ,然后写入我们要的指令:
- 注意每一行前面的空白必须是一个 tab
- Makefile 中如果要在使用有 $ 字串的指令,必须使用两个 $ ,因为一个 $ 代表读取某一个变数 。
- log:
- for i in $$(seq 1 4); do host=www$$i.puritys.me ; echo "In $$host:"; ssh $$host "tail -n 1 /var/log/messages"; done;
这个档案建好之后,我就可以输入 make log
,执行我刚写入的指令。
另外有可能我们的机器名称没有一定的规则,那么我们可以先把机器名称写入一个档案:
- www1.puritys.me
- www2.puritys.me
- kkk.jjjj.com.tw
再使用 `cat hosts` 跟 forloop ,来对每一台机器传送指令。
- log:
- for host in `cat hosts`; do echo "In $$host:"; ssh $$host "tail -n 1 /var/log/messages"; done;
线上机器 Release
如何快速的将新版程式,安装到线上的所有机器呢? 这里用 rpm package 来示范,首先用上面教的方式,读取 hosts 内的所有机器 hostname ,再用 scp 指令,将 rpm 档传送到线上机器,最后再用 rpm -ivh 来安装。
- release:
- for host in `cat hosts`; \
- do \
- scp test-1.0-1.x86_64.rpm $$host:~/ \
- && ssh $$host "sudo rpm -ivh test-1.0-1.x86_64.rpm"; \
- done
写好指令后,以后我只要输入 make release 就可以快速的将程式 release 出去。
- [www]$ make release
- for host in `cat hosts`; \
- do \
- scp test-1.0-1.x86_64.rpm $host:~/ \
- && ssh $host "sudo rpm -ivh test-1.0-1.x86_64.rpm"; \
- done
- test-1.0-1.x86_64.rpm 100% 1508 1.5KB/s 00:00
- Preparing... ########################################
- Updating / installing...
- test-1.0-1 ########################################