Crates.io | jsonwatch |
lib.rs | jsonwatch |
version | 0.11.0 |
created_at | 2023-07-13 10:55:11.809056+00 |
updated_at | 2025-09-22 19:09:03.094763+00 |
description | Track changes in JSON data from the command line |
homepage | https://github.com/dbohdan/jsonwatch |
repository | https://github.com/dbohdan/jsonwatch |
max_upload_size | |
id | 915224 |
size | 104,806 |
watch -d
, but for JSONjsonwatch is a command-line utility that lets you track changes in JSON data delivered by a command or a web (HTTP/HTTPS) API.
jsonwatch requests data from the source repeatedly at a set interval.
It displays the differences when the data changes.
It is similar but not identical to how watch(1) with the -d
switch works for plain text.
jsonwatch has been tested on Debian 12, Ubuntu 24.04, macOS 14, and Windows 10 and Server 2022.
The two previous versions of jsonwatch are preserved in the branch
python
and
haskell
.
Prebuilt binaries are available for Linux (x86_64) and Windows (x86). Binaries are attached to releases on the "Releases" page.
cargo install jsonwatch
Follow the instructions to build a static Linux binary of jsonwatch from the source code on recent Debian and Ubuntu.
rustup target add x86_64-unknown-linux-musl
sudo apt install build-essential expect musl-tools
cargo install just
git clone https://github.com/dbohdan/jsonwatch
cd jsonwatch
just test
just release-linux
Follow the instructions to build a 32-bit Windows binary of jsonwatch on recent Debian and Ubuntu.
rustup target add i686-pc-windows-gnu
sudo apt install build-essential mingw-w64
cargo install just
~/.cargo/config
.[target.i686-pc-windows-gnu]
linker = "/usr/bin/i686-w64-mingw32-gcc"
git clone https://github.com/dbohdan/jsonwatch
cd jsonwatch
just release-windows
You must run jsonwatch with a subcommand.
jsonwatch processes valid JSON. The following behavior applies:
Some security measures are in place:
-vv
has any control characters escaped to prevent display issues and security risks like ANSI escape sequence injection.
Command output is also escaped because commands that access remote data sources are expected.Control characters are escaped as follows (\\
represents a literal backslash character):
Character | Escaped as | Example |
---|---|---|
Newline (\n ) |
Passed through | A\nB → A\nB |
Tab (\t ) |
Passed through | A\tB → A\tB |
Carriage return (\r ) |
\\u{d} |
A\rB → A\\u{d}B |
Escape (\x1b ) |
\\u{1b} |
\x1b[32m → \\u{1b}[32m |
Other control chars | \\u{xx} |
ASCII BEL (\x07 ) → \\u{7} |
Non-control characters are printed as is.
Track changes in JSON data
Usage: jsonwatch [OPTIONS] <COMMAND>
Commands:
cmd Execute a command and track changes in the JSON output
url Fetch a URL and track changes in the JSON data
init Generate shell completions
help Print this message or the help of the given subcommand(s)
Options:
-D, --no-date Don't print date and time for each diff
-I, --no-initial-values Don't print initial JSON values
-c, --changes <count> Exit after a number of changes
-n, --interval <seconds> Polling interval in seconds [default: 2]
-v, --verbose... Verbose mode ('-v' for errors, '-vv' for errors and
input data)
-h, --help Print help
-V, --version Print version
cmd
subcommandYou can use cmd
or command
as the name of the subcommand.
Execute a command and track changes in the JSON output
Usage: jsonwatch cmd <command> [arg]...
Arguments:
<command> Command to execute
[arg]... Arguments to the command
Options:
-h, --help Print help
url
subcommandFetch a URL and track changes in the JSON data
Usage: jsonwatch url [OPTIONS] <url>
Arguments:
<url> URL to fetch
Options:
-A, --user-agent <user-agent> Custom user-agent string [default: curl/7.58.0]
-H, --header <header> Custom headers in the format "X-Foo: bar"
-h, --help Print help
init
subcommandGenerate shell completions
Usage: jsonwatch init <SHELL>
Arguments:
<SHELL> The shell to generate completions for [possible values: bash,
elvish, fish, powershell, zsh]
Options:
-h, --help Print help
This example uses the POSIX shell to generate random JSON test data.
$ jsonwatch -n 1 cmd sh -c "echo '{ \"filename\": \"'\$(mktemp -u)'\"}'"
{
"filename": "/tmp/tmp.dh3Y7LJTaK"
}
2020-01-19T18:52:19+0000 .filename: "/tmp/tmp.dh3Y7LJTaK" -> "/tmp/tmp.i4s56VENEJ"
2020-01-19T18:52:20+0000 .filename: "/tmp/tmp.i4s56VENEJ" -> "/tmp/tmp.zzMUSn45Fc"
2020-01-19T18:52:21+0000 .filename: "/tmp/tmp.zzMUSn45Fc" -> "/tmp/tmp.Jj1cKt6VLr"
2020-01-19T18:52:22+0000 .filename: "/tmp/tmp.Jj1cKt6VLr" -> "/tmp/tmp.1LGk4ok8O2"
2020-01-19T18:52:23+0000 .filename: "/tmp/tmp.1LGk4ok8O2" -> "/tmp/tmp.wWulyho8Qj"
The command in this example tracks Docker process information when you have a single running container.
$ jsonwatch -n 1 command docker ps -a "--format={{json .}}"
2020-01-19T18:57:20+0000
+ .Command: "\"bash\""
+ .CreatedAt: "2020-01-19 18:57:20 +0000 UTC"
+ .ID: "dce7fb2194ed"
+ .Image: "i386/ubuntu:latest"
+ .Labels: ""
+ .LocalVolumes: "0"
+ .Mounts: ""
+ .Names: "dreamy_edison"
+ .Networks: "bridge"
+ .Ports: ""
+ .RunningFor: "Less than a second ago"
+ .Size: "0B"
+ .Status: "Created"
2020-01-19T18:57:21+0000 .RunningFor: "Less than a second ago" -> "1 second ago"
2020-01-19T18:57:23+0000
.RunningFor: "1 second ago" -> "3 seconds ago"
.Status: "Created" -> "Up 1 second"
2020-01-19T18:57:24+0000
.RunningFor: "3 seconds ago" -> "4 seconds ago"
.Status: "Up 1 second" -> "Up 2 seconds"
2020-01-19T18:57:25+0000
.RunningFor: "4 seconds ago" -> "5 seconds ago"
.Status: "Up 2 seconds" -> "Up 3 seconds"
For multiple running containers, you will need a more complex jsonwatch command. The command needs to transform the JSON Lines output into a single JSON document. For example, it can be the following command with the POSIX shell and jq:
jsonwatch -I cmd sh -c 'docker ps -a "--format={{json .}}" | jq -s .'
cmd.exe
on WindowsThis example is a simple test on Windows.
We start watching the output of a cmd.exe
command, then manually edit the file the command prints and are shown the changes.
> jsonwatch command cmd.exe /c "type tests\weather1.json"
{
"clouds": {
"all": 92
},
"name": "Kiev",
"coord": {
"lat": 50.43,
"lon": 30.52
},
"sys": {
"country": "UA",
"message": 0.0051,
"sunset": 1394985874,
"sunrise": 1394942901
},
"weather": [
{
"main": "Snow",
"id": 612,
"icon": "13d",
"description": "light shower sleet"
},
{
"main": "Rain",
"id": 520,
"icon": "09d",
"description": "light intensity shower rain"
}
],
"rain": {
"3h": 2
},
"base": "cmc stations",
"dt": 1394979003,
"main": {
"pressure": 974.8229,
"humidity": 91,
"temp_max": 277.45,
"temp": 276.45,
"temp_min": 276.15
},
"id": 703448,
"wind": {
"speed": 10.27,
"deg": 245.507
},
"cod": 200
}
2020-01-19T18:51:04+0000 + .test: true
2020-01-19T18:51:10+0000 .test: true -> false
2020-01-19T18:51:23+0000 - .test: false
The API in this example no longer works without a key.
$ jsonwatch --no-initial-values -n 300 url 'http://api.openweathermap.org/data/2.5/weather?q=Kiev,ua'
2014-03-17T23:06:19+0200
+ .rain.1h: 0.76
- .rain.3h: 0.5
.dt: 1395086402 -> 1395089402
.main.temp: 279.07 -> 278.66
.main.temp_max: 279.82 -> 280.15
.main.temp_min: 277.95 -> 276.05
.sys.message: 0.0353 -> 0.0083
Try this on a mobile device.
$ jsonwatch -I -n 300 url https://ipinfo.io/
jsonwatch is distributed under the MIT license.
See the file LICENSE
for details.
Wapp is copyright (c) 2017 D. Richard Hipp and is distributed under the Simplified BSD License.