一個(gè)Shell工具:jsondiff.sh
我最近忙著重構(gòu)一個(gè)歷史項(xiàng)目,不過(guò)由于客觀條件所限,沒(méi)有測(cè)試用例可用,以至于我不得不通過(guò)人肉對(duì)比新舊服務(wù)器的結(jié)果集是否一致來(lái)判斷對(duì)錯(cuò)。既然說(shuō)懶惰是程序員的美德,所以我想還是寫(xiě)一個(gè)工具吧,加之結(jié)果集為JSON,于是便有了jsondiff.sh。
邏輯很簡(jiǎn)單,無(wú)非就是通過(guò)curl在不同的服務(wù)器上取得結(jié)果集,然后diff即可,不過(guò)這里有幾點(diǎn)需要注意的地方:首先,JSON就一行,直接diff會(huì)失去意義;其次,JSON中漢字會(huì)被編碼,不利于查看;另外,JSON中字段順序是無(wú)所謂的,所以diff前***排序。說(shuō)明一下,在格式化JSON數(shù)據(jù)的時(shí)候,我沒(méi)有用Bash,而是用的PHP:
- #!/bin/bash
 - RM=/bin/rm
 - PHP=/usr/bin/php
 - CURL=/usr/bin/curl
 - DIFF=/usr/bin/diff
 - VIMDIFF=/usr/bin/vimdiff
 - COLORDIFF=/usr/bin/colordiff
 - usage() {
 - echo "Usage: $0 --uri=<URI> --old=<IP> --new=<IP>"
 - }
 - format() {
 - $PHP -R '
 - function ksort_recursive(&$array) {
 - if (!is_array($array)) {
 - return;
 - }
 - ksort($array);
 - foreach (array_keys($array) as $key) {
 - ksort_recursive($array[$key]);
 - }
 - }
 - $options = JSON_PRETTY_PRINT | JSON_UNESCAPED_UNICODE;
 - $array = json_decode($argn, true);
 - ksort_recursive($array);
 - echo json_encode($array, $options);
 - '
 - }
 - request() {
 - $CURL -s -H "Host: $1" "http://$2$3"
 - }
 - eval set -- $(
 - getopt -q -o "h" -l "host:,uri:,old:,new:,vim,help" -- "$@"
 - )
 - while true; do
 - case "$1" in
 - --host) HOST=$2; shift 2;;
 - --uri) URI=$2; shift 2;;
 - --old) OLD=$2; shift 2;;
 - --new) NEW=$2; shift 2;;
 - --vim) VIM="Y"; shift 1;;
 - -h|--help) usage; exit 0;;
 - --) break;;
 - esac
 - done
 - if [[ -z "$URI" || -z "$OLD" || -z "$NEW" ]]; then
 - usage
 - exit 1
 - fi
 - if [[ -z "$HOST" ]]; then
 - HOST="www.foobar.com"
 - fi
 - OLD_FILE=$(mktemp)
 - NEW_FILE=$(mktemp)
 - request "$HOST" "$OLD" "$URI" | format > $OLD_FILE
 - request "$HOST" "$NEW" "$URI" | format > $NEW_FILE
 - if [[ "$VIM" == "Y" ]]; then
 - $VIMDIFF $OLD_FILE $NEW_FILE
 - elif [[ -x "$COLORDIFF" ]]; then
 - $COLORDIFF -u $OLD_FILE $NEW_FILE
 - else
 - $DIFF -u $OLD_FILE $NEW_FILE
 - fi
 - $RM -f $OLD_FILE
 - $RM -f $NEW_FILE
 
其中「getopt」的用法值得注意一下,相關(guān)參考資料如下:
- Getopt in Bash
 - Bash: Preserving Whitespace Using set and eval
 
雖然我的Shell水平有限,但是我盡可能寫(xiě)得易用:在diff的時(shí)候,允許使用多種工具,缺省情況下會(huì)優(yōu)先使用「colordiff」,需要的話還可以激活「vimdiff」。















 
 
 











 
 
 
 