使用ruby解析xml的简单例子

在使用hudson持续集成的工作中,我们会在构建完成后运行一个自动部署脚本。
自动部署脚本需要知道构建的模块信息,用ruby解析pom.xml是比较合适的选择。

pom.xml:

<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
        xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
        <modelVersion>4.0.0</modelVersion>
        <artifactId>sample</artifactId>
        <version>0.1.9-SNAPSHOT</version>
...
</project>

ruby脚本片段如下:

#!/usr/bin/env ruby

require "rexml/document"
doc = REXML::Document.new(File.open('pom.xml'))

artifactId = doc.elements["project/artifactId"].text
version = doc.elements["project/version"].text

上面的脚本,使用rexml模块解析xml。
注意:如果版本号是通过继承得来(或是在profile里指定的),先使用maven生成实际生效的pom.xml才能获得正确的结果。
Tips:使用mvn help:effective-pom生成实际生效的pom。

在bash里使用PID文件

实践中,我们把一些任务放到后台运行,停止/重启任务时需要找到任务的PID(process Id)。
我们可以采用下面的方式:

$ ./task.sh &
$ ps -ef|grep task.sh
hao      18635 18496  0 22:20 pts/0    00:00:00 /bin/bash ./task.sh
hao      18673 18496  0 22:20 pts/0    00:00:00 grep task.sh

这种方式的不便之处在于不适合编写脚本。
更好的的方式是使用一个PID文件,记录下任务的PID,如下:

$ ./task.sh & echo $! > pid
$ cat pid
19219

需要杀死进程时,如下:

$ PID=`cat pid` && pkill -P $PID && kill $PID

下面是一个启动任务,然后关闭的例子:

#! /bin/bash

# 后台启动任务,把PID保存在文件pid里
# "1>/dev/null 2>&1"丢弃了标准输出和错误输出
nohup ./task.sh 1>/dev/null 2>&1 & echo $!>pid

# 打印服务状态
if ps -p `cat pid` >&-; then echo UP; else echo DOWN; fi

# 杀死任务的子进程及任务进程
PID=`cat pid` && pkill -P $PID && kill $PID

参考资料:
Write a PID file in bash
Best way to kill all child processes