一个Shell工具:jsondiff.sh

系统 Linux
我最近忙着重构一个历史项目,不过由于客观条件所限,没有测试用例可用,以至于我不得不通过人肉对比新旧服务器的结果集是否一致来判断对错。既然说懒惰是程序员的美德,所以我想还是写一个工具吧,加之结果集为JSON,于是便有了jsondiff.sh。

我最近忙着重构一个历史项目,不过由于客观条件所限,没有测试用例可用,以至于我不得不通过人肉对比新旧服务器的结果集是否一致来判断对错。既然说懒惰是程序员的美德,所以我想还是写一个工具吧,加之结果集为JSON,于是便有了jsondiff.sh。

逻辑很简单,无非就是通过curl在不同的服务器上取得结果集,然后diff即可,不过这里有几点需要注意的地方:首先,JSON就一行,直接diff会失去意义;其次,JSON中汉字会被编码,不利于查看;另外,JSON中字段顺序是无所谓的,所以diff前***排序。说明一下,在格式化JSON数据的时候,我没有用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 
  • 1.
  • 2.
  • 3.
  • 4.
  • 5.
  • 6.
  • 7.
  • 8.
  • 9.
  • 10.
  • 11.
  • 12.
  • 13.
  • 14.
  • 15.
  • 16.
  • 17.
  • 18.
  • 19.
  • 20.
  • 21.
  • 22.
  • 23.
  • 24.
  • 25.
  • 26.
  • 27.
  • 28.
  • 29.
  • 30.
  • 31.
  • 32.
  • 33.
  • 34.
  • 35.
  • 36.
  • 37.
  • 38.
  • 39.
  • 40.
  • 41.
  • 42.
  • 43.
  • 44.
  • 45.
  • 46.
  • 47.
  • 48.
  • 49.
  • 50.
  • 51.
  • 52.
  • 53.
  • 54.
  • 55.
  • 56.
  • 57.
  • 58.
  • 59.
  • 60.
  • 61.
  • 62.
  • 63.
  • 64.
  • 65.
  • 66.
  • 67.
  • 68.

其中「getopt」的用法值得注意一下,相关参考资料如下:

Getopt in Bash 
Bash: Preserving Whitespace Using set and eval 
  • 1.
  • 2.

虽然我的Shell水平有限,但是我尽可能写得易用:在diff的时候,允许使用多种工具,缺省情况下会优先使用「colordiff」,需要的话还可以激活「vimdiff」。

责任编辑:黄丹 来源: 火丁笔记
相关推荐

2025-01-08 11:00:00

AIshell开源

2013-06-13 11:07:52

2022-05-23 08:05:14

benchstat工具Go

2020-04-06 20:47:42

FishShellLinux

2012-07-17 17:05:55

JavaScript

2023-12-11 08:16:51

工具命令行参数

2022-12-28 12:29:45

duf命令

2017-07-25 14:20:13

戴尔配置功耗

2020-11-04 07:56:19

工具Linux 翻译

2021-02-15 17:29:46

LinuxShell脚本

2015-09-09 13:29:17

FISHShellLinux

2013-12-18 09:51:02

2021-10-08 19:00:28

NMState网络配置工具系统运维

2017-06-23 13:51:38

ShutItPythonshell

2022-11-03 08:13:52

echo 命令Linux

2011-06-17 16:49:05

Cocoa苹果

2009-07-07 11:38:54

jsp oracle

2020-07-20 10:00:52

Python翻译工具命令行

2017-09-07 19:21:20

Java语言Iodine

2025-01-08 08:00:00

点赞
收藏

51CTO技术栈公众号