SkillAgentSearch skills...

Json.bash

Command-line tool and bash library that creates JSON

Install / Use

/learn @h4l/Json.bash
About this skill

Quality Score

0/100

Supported Platforms

Universal

README

$ jb name=json.bash creates=JSON

json.bash is a command-line tool and bash library that creates JSON.

$ jb name=json.bash creates=JSON dependencies:[,]=Bash,Grep
{"name":"json.bash","creates":"JSON","dependencies":["Bash","Grep"]}

$ # Values are strings unless explicitly typed
$ jb id=42 size:number=42 surname=null data:null
{"id":"42","size":42,"surname":"null","data":null}

$ # Reference variables with @name
$ id=42 date=2023-06-23 jb @id created@date modified@date
{"id":"42","created":"2023-06-23","modified":"2023-06-23"}

$ # Pull data from files
$ printf hunter2 > /tmp/password; jb @/tmp/password
{"password":"hunter2"}

$ # Pull data from shell pipelines
$ jb sizes:number[]@<(seq 1 4)
{"sizes":[1,2,3,4]}

$ # Nest jb calls
$ jb type=club members:json[]@<(jb name=Bob; jb name=Alice)
{"type":"club","members":[{"name":"Bob"},{"name":"Alice"}]}

$ # The Bash API can reference arrays and create JSON efficiently — without forking
$ source json.bash
$ out=people json name=Bob; out=people json name=Alice; sizes=(42 91 2)
$ id="abc.123" json @id @sizes:number[] @people:json[]
{"id":"abc.123","sizes":[42,91,2],"people":[{"name":"Bob"},{"name":"Alice"}]}

json.bash's one thing is to get shell-native data (environment variables, files, program output) to somewhere else, using JSON encapsulate it robustly.

Creating JSON from the command line or a shell script can be useful when:

  • You need some ad-hoc JSON to interact with a JSON-consuming application
  • You need to bundle up some data to share or move elsewhere. JSON can a good alternative to base64-encoding or a file archive.

It does no transformation or filtering itself, instead it pulls data from things you already know how to use, like files, command-line arguments, environment variables, shell pipelines and shell scripts. It glues together data from these sources, giving it enough structure to make the data easy to consume reliably in downstream programs.

It's something like a reverse tee — it pulls together data sources, using JSON to represent the aggregation. It's not an alternative to to data-processing tools like jq, rather it helps assemble JSON to send into JSON-consuming tools like jq.


Contents

  1. Install
  2. How-to guides
  3. Background & performance notes
  4. Credits

Install

Container image

We publish the container image ghcr.io/h4l/json.bash/jb with jb-* and json.bash, perhaps useful to try without installing.

$ docker container run --rm ghcr.io/h4l/json.bash/jb msg=Hi
{"msg":"Hi"}

$ # Get a bash shell to try things interactively
$ docker container run --rm -it ghcr.io/h4l/json.bash/jb
bash-5.2# jb os-release:{}@<(xargs < /etc/os-release env -i)
{"os-release":{"NAME":"Alpine Linux","ID":"alpine","VERSION_ID":"3.18.2","PRETTY_NAME":"Alpine Linux v3.18","HOME_URL":"https://alpinelinux.org/","BUG_REPORT_URL":"https://gitlab.alpinelinux.org/alpine/aports/-/issues"}}

OS Packages

<details> <summary>Expand this for details…</summary>

Auto-generated packages

Externally-maintained packages are not yet widely available, so we provide a way to generate a package file for any package manager supported by fpm (at least apk, deb, freebsd, rpm, sh (self extracting), tar, possibly more).

We publish the container image ghcr.io/h4l/json.bash/pkg that can generate a package file in whichever format you like:

$ docker container run --rm -v "$(pwd):/pkg" ghcr.io/h4l/json.bash/pkg deb
Generating: /pkg/json.bash_0.2.2-dev.deb

$ ls
json.bash_0.2.2-dev.deb
$ dpkg -i /pkg/json.bash_0.2.2-dev.deb

Externally-maintained packages

These packages have been created and maintained by downstream users/projects.

| OS | Repository | Details | | ---------- | ------------------------------------------------------------------------ | ------------------------------------------------ | | Arch linux | User Repository | https://aur.archlinux.org/packages/json-bash-git |

json.bash needs you!

If you'd like json.bash to be available from your operating system's package manager, you can help by investigating your package manager's process for adding new packages to see if you can contribute a package, or make a request to add it.

</details>

Manual install

Installing manually is quite straightforward.

<details> <summary>Expand this for instructions…</summary>
# Alternatively, use /usr/local/bin to install system-wide
cd ~/.local/bin
curl -fsSL -O "https://raw.githubusercontent.com/h4l/json.bash/HEAD/json.bash"
chmod +x json.bash
ln -s json.bash jb
ln -s json.bash jb-array

# If your shell is bash, you can alias jb and jb-array to the bash functions for
# better performance. You should add this line to your ~/.bashrc
source json.bash; alias jb=json jb-array=json.array

# Optional: if you'd also like jb-echo, jb-cat, jb-stream
for name in jb-echo jb-cat jb-stream; do
  curl -fsSL -O "https://raw.githubusercontent.com/h4l/json.bash/HEAD/bin/${name:?}"
  chmod +x "${name:?}"
done

To uninstall, remove json.bash, jb, jb-array, jb-echo, jb-cat and jb-stream from the directory you installed them to (run which -a json.bash to find where it is).

</details>

How-to guides

  1. The json.bash commands
  2. Object keys
  3. Object values
  4. Arrays (mixed types, fixed length)
  5. Argument types
  6. Array values (uniform types, variable length)
  7. Object values (uniform types, variable length)
  8. ... arguments (merge entries into the host object/array)
  9. Missing / empty values
  10. Nested JSON with :json and :raw types
  11. File references
  12. Argument structure
  13. Error handling
  14. Security and correctness
  15. jb-cat, jb-echo, jb-stream utility programs
  16. Streaming output
  17. Configuring environment variables

These examples mostly use jb, which is the json.bash library run as a stand-alone program. From within a bash script you get better performance by running source json.bash and using the json bash function, which is a superset of stand-alone jb and much faster because it doesn't execute new child processes when called. See the Background & performance notes section for more.

The json.bash commands

jb / jb-array / json / json.array

$ # The jb program creates JSON objects
$ jb
{}

$ # The jb-array creates arrays, but otherwise works like jb.
$ jb-array :number=4
[4]

$ # From a bash shell or bash script, use the json and json.array functions
$ source json.bash  # no path is needed if json.bash is on $PATH
$ json
{}

$ # json.array creates arrays, but otherwise works like json
$ json.array
[]

Each argument defines an entry in the object or array. Arguments can contain a key, type and value in this structure:

<img width="100%" src="docs/syntax-diagrams/minimal-argument.svg" alt="A railroad syntax diagram showing a high-level summary of the key, type and value structure of an argument." title="Minimal Argument Structure Diagram">

The Argument structure section has more details.

Object keys

Each argument creates an entry in the JSON object. The first part of each argument defines the key.

$ jb msg=hi
{"msg":"hi"}

$ # Keys can contain most characters (except @:=, unless escaped)
$ jb "🐚"=JSON
{"🐚":"JSON"}

$ # Key values can come from variables
$ key="The Message" jb @key=hi
{"The Message":"hi"}

$ # Key variables can contain any characters
$ key="@key:with=reserved-chars" jb @key=hi
{"@key:with=reserved-chars":"hi"}

$ # Each argument defines a key
$ var=c jb a=X b=Y @var=Z
{"a":"X","b":"Y","c":"Z"}

$ # Keys may be reused, but should not be, because JSON parser behaviour for
$ # duplicate keys is undefined.
$ jb a=A a=B a=C
{"a":"A","a":"B","a":"C"}

$ # The reserved characters can be escaped by doubling them
$ jb =@@handle=ok a::z=ok 1+1==2=ok
{"@handle":"ok","a:z":"ok","1+1=2":"ok"}

Object values

The last part of each argument after a = or @ defines the value. Values can contain their value directly, or reference a variable or file.

$ jb message="Hello World"
{"message":"Hello World"}

$ greeting="Hi there" jb message@greeting
{"message":"Hi there"}

$ # Variable references without a value define the key and value in one go.
$ greeting="Hi" name=Bob jb @greeting @name
{"greeting":"Hi","name":"Bob"}

$ # This also applies (less usefully) to inline entries.
$ jb message
{"message":"message"}

$ # Inline values following a `=` have no content restrictions.
$ jb message=@value:with=reserved-chars
{"message":"@value:with=reserved-chars"}

$ # @ values that begin with / or ./ are references to files
$ printf hunter2 > /tmp/password; jb secret@/tmp/password
{"secret":"hunter2"}

$ # File references without a value define the key and value in one go.
$ jb

Related Skills

View on GitHub
GitHub Stars458
CategoryDevelopment
Updated27d ago
Forks8

Languages

Shell

Security Score

100/100

Audited on Mar 2, 2026

No findings