Show HN: Jb / json.bash – Command-line tool (and bash library) that creates JSON
31–40 of 56 posts
Re: Show HN: Jb / json.bash – Command-line tool (and bash library) that creates JSON
#32Re: Show HN: Jb / json.bash – Command-line tool (and bash library) that creates JSON
#33This 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…
I definitely like the idea of a goland/rust implementation, there are certainly things I could improve.
So the argument syntax escapes by repeating a character rather than backslash. I chose this because with backslashes escapes it would be unclear whether a backslash was in the shell syntax or the jb syntax, and users may end up needing to double escape backslashes, which is no fun! Whereas a shell will always ignore two copies of a character like =:@.
The downside of double-escaping is that the syntax can be ambiguous, so sometimes you need to include the middle type marker to disambiguate the key from the value. But the type can be empty, so just : works:
$ jb ===msg==:==hi=
{"=msg=":"=hi="}
In the key part, the first = begins the key, the == following are an escaped =. The first = following the : marks the value, and everything after is not parsed, so =hi= is literal.When you have reserved characters in keys/values (especially if they're dynamic), it's easiest to store the values in variables and reference them with @var syntax:
$ k='=msg=' v='=hi=' jb @k@v
{"=msg=":"=hi="}Re: Show HN: Jb / json.bash – Command-line tool (and bash library) that creates JSON
#34Is there a minimum bash version required? I.e. will it work with bash 3 or whatever ships with macos by default?
Re: Show HN: Jb / json.bash – Command-line tool (and bash library) that creates JSON
#35{"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.
This is just the kind of use case I had in mind. Something I've considered is publishing a mini version with only the json.encode_string function, as that's enough to create an array of JSON-encoded strings and use a hard-coded template with printf to insert the JSON string values.
That would be a fraction of the overall json.bash file size.
Re: Show HN: Jb / json.bash – Command-line tool (and bash library) that creates JSON
#36As 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.)
$ jb size:number=oops; echo $?
json.encode_number(): not all inputs are numbers: 'oops'
json(): Could not encode the value of argument 'size:number=oops' as a 'number' value. Read from inline value.
␘
1
If you pipe the jb error into jq, jq fails to parse the JSON (because of the Cancel ctrl char) and also errors: $ jb size:number=oops | jq
json.encode_number(): not all inputs are numbers: 'oops'
json(): Could not encode the value of argument 'size:number=oops' as a 'number' value. Read from inline value.
parse error: Invalid numeric literal at line 2, column 0
$ declare -p PIPESTATUS
declare -a PIPESTATUS=([0]="1" [1]="4")
So jq exits with status 4 here.Re: Show HN: Jb / json.bash – Command-line tool (and bash library) that creates JSON
#37Yeah if you need this it's definitely a sign you shouldn't be using Bash. Can you give a concrete example of when this is the sanest option?
Second is situations where you'd rather not add an additional dependency, but bash is pretty much a given. For example, CI environments, scripts in dev environments, container entrypoints. Or things that area already written in bash.
I don't advocate writing massive programs in bash, for sure it's better to turn to a proper language before things get hairy. But bash is just really ubiquitous, and most people who do any UNIX work will be able to deal with a bit of shell script.
Re: Show HN: Jb / json.bash – Command-line tool (and bash library) that creates JSON
#38Built into Powershell: > @{ hello = 'world' } | ConvertTo-Json > { "hello": "world" }
@{ Hello = 'world'; array = 1..10; object = @{ date = Get-Date } } | ConvertTo-Json
{
"array": [
1,
2,
3,
4,
5,
6,
7,
8,
9,
10
],
"object": {
"date": "2024-07-03T21:07:21.6562053+02:00"
},
"Hello": "world"
}Re: Show HN: Jb / json.bash – Command-line tool (and bash library) that creates JSON
#39Built 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 [H…
$h=@{x=1; y=2}; $h + @{z=3} | ConvertTo-Json
{
"y": 2,
"z": 3,
"x": 1
}
You can even use [ordered]$h to make keys not go random place.Re: Show HN: Jb / json.bash – Command-line tool (and bash library) that creates JSON
#40Built into Powershell: > @{ hello = 'world' } | ConvertTo-Json > { "hello": "world" }
Not only its built in, but syntax is on another level, i.e. you don't need to learn special syntax if you know PowerShell. This thing alone makes pwsh worth it instead of using number of other tools. @{ Hello = 'world'; array = 1..10; object = @{ date = Get-Date } } | ConvertTo-Json { "array": [ 1, 2, 3, 4, 5, 6, 7, 8, 9, 10 ], "object": { "date": "2024-07-03T21:07:21.6562053+02:00" }, "Hello": "world" }
For good measure, this is how you might do the same with jb:
$ jb Hello=world array:number[]@
Alternatively, using the :{} object entry syntax: jb Hello=world array:number[]@