一個(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」。






























