Live data from Hacker News

Show HN: Jb / json.bash – Command-line tool (and bash library) that creates JSON

github.com

21–30 of 56 posts

Re: Show HN: Jb / json.bash – Command-line tool (and bash library) that creates JSON

#21
post #16

I found the JSON array syntax a little unintuitive: $ jb dependencies:[,]=Bash,Grep {"dependencies":["Bash","Grep"]} One possible alternative would be to accept JSON literal snippets, like this: $ jb dependencies='["Bash", "Grep"]' This should support all forms of nested JSON objects. You could have a rule that if an argument does NOT parse as a valid JSON value it is treated as a raw string, so this would work: $ jb…

Thanks for giving it a try and your feedback. I agree, the array splitting is a bit fiddly. It is actually possible to pass JSON directly, you use the :json type on the argument:

    $ jb dependencies:json='["Bash","Grep"]'
    {"dependencies":["Bash","Grep"]}

    $ jb foo=bar bar:json='"this is a well formed string"'
    {"foo":"bar","bar":"this is a well formed string"}
And then you can indeed use command substitution to nest calls:

    $ jb foo:json=$(jb bar=baz)
    {"foo":{"bar":"baz"}}
It works even better to use process substitution, this way the shell gives jb a file path to a file to read, and so you don't need to quote the $() to avoid whitespace breaking things:

    $ jb foo:json@
Another option is to use jb-array to generate arrays. (jb-array is best for tuple-like arrays with varying types):

    $ jb dependencies:json@
And if you use it from bash as a function, you can put values into a bash array and reference it:

    $ source json.bash
    $ dependencies=(Bash Grep)
    $ json @dependencies:[]   
    {"dependencies":["Bash","Grep"]}

Re: Show HN: Jb / json.bash – Command-line tool (and bash library) that creates JSON

#24
post #22

I wonder if I could use this on my project which uses multiple glue functions to piece together JSON strings. https://github.com/fieu/discord.sh

If it helps, there's a little example of using the bash API with bash variables/arrays, should give you an idea of how it could be to use: https://github.com/h4l/json.bash/blob/main/examples/notify.s...

This example uses the pattern of setting an out=varname when calling a json function, the encoded JSON goes into $varname variable. This pattern avoids the overhead of forking processes (e.g. subshells) when generating JSON.

Otherwise you can use the more normal approach of jb writing to stdout, and capturing the output stream.

Re: Show HN: Jb / json.bash – Command-line tool (and bash library) that creates JSON

#25
post #17

Built into Powershell: > @{ hello = 'world' } | ConvertTo-Json > { "hello": "world" }

Powershell has the upper hand here!

Still, bash can try to keep up using json.bash. :)

    $ source json.bash
    $ declare -A greeting=([Hello]=World)
    $ json ...@greeting:{}
    {"Hello":"World"}
... is splatting the greeting associative array entries into the object created by the json call.

Without the ... the greeting would be a nested object. Probably more clear with multiple entries:

    $ declare -A greeting=([Hello]=World [How]="are you?")
    $ json @greeting:{}   
    {"greeting":{"Hello":"World","How":"are you?"}}
Vs:

    $ json ...@greeting:{}                                
    {"Hello":"World","How":"are you?"}

Re: Show HN: Jb / json.bash – Command-line tool (and bash library) that creates JSON

#26
{"password":"hunter2"}

A man of culture I see.

This looks really useful where you don't want to introduce another scripting VM just to spit out some JSON, i.e I have used Ruby a lot for this in the past.

I can see myself using this in container init scripts and other very low dep environments to format config files from env vars etc.

Re: Show HN: Jb / json.bash – Command-line tool (and bash library) that creates JSON

#29
post #2

As well as anyone's general thoughts/experiences, I'd appreciate opinions on the error handling mechanism jb uses to detect errors in upstream jb processes that jb is reading from. Normally, detecting errors on the other end of a pipe requires care in a shell environment (e.g. retrospectively checking PIPESTATUS). I used an approach I've called Stream Poisoning. It takes advantage of the fact that control characters…

What happens if the next program in the pipe is not jb? Does jb also exit with a code?

For example `jb | jq`, where jq or a similar program discards the cancel character.

(Away from pc, unable to check right now.)

Re: Show HN: Jb / json.bash – Command-line tool (and bash library) that creates JSON

#30
This is incredibly high-quality BASH programming, as a fellow bash freak I am studying this code, and even I am learning some new techniques.

https://github.com/h4l/json.bash/blob/main/json.bash

You've boiled it down to a set of very elegant constructs. Respect. Thank you @h4l, this is badass.

I hope you follow up with a golang or rust implementation, that would really be something else.

p.s. I noticed the following odd behaviors with escaping delimiters (e.g. "="), is there a way to get an un-escaped equal sign as the trailing part of a key or leading part of a value?

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