More shell tricks: first class lists and jq

https://news.ycombinator.com/rss Hits: 3
Summary

More shell tricks: first class lists, jq, and the es shell Preamble It’s not a secret that most common shells don’t have first class lists. Sure, you can pass a list to a program by passing each element in argv (e.g. with "$@" or "${list_variable[@]}"), but what if you want to return a list? There are a couple of options. The challenge As a more practical example of this, let’s implement split-by-double-dash, a function (or a program) that would return two lists: args that come before -- and ones that come after. That’s a common format used by command line utilities. So, for example, split-by-double-dash a b c -- d e f should return the lists [a, b, c] and [d, e, f], somehow. One possible use case for this would be a wrapper around a utility that accepts arguments in this form. The quoting way with jq Some utilities can return text quoted in the syntax of shell. For examples, getopt and jq can do that. getopt can indeed help us solve the problem of parsing cli options, but we’ll focus on jq here. Side note: jq is an amazing utility (in fact, a programming language) that can manipulate structured data in all kinds of ways. Here’s an example: jq -nr '["foo", "baz", "baz quux"] | @sh' 'foo' 'baz' 'baz quux' We ask jq to turn a list into a string suitable for consumption with shell’s eval. -n tells that there’s no input to read, -r tells jq to output text, not JSON. So let’s see how to use the output in the shell: eval set -- "$(jq -nr '["foo", "bar", "baz quux"] | @sh')" # Now, let's verify that arguments has been passed correctly, by printing each one on a separate line with printf. printf 'arg: %s\n' "$@" # Output: # arg: foo # arg: bar # arg: baz quux You might think: “wait, you can’t use eval”. But that’s actually safe, since jq does the escaping for us. Actually, I don’t think there’s a way to do this without eval, since the list is dynamic and has to be interpreted by the shell. In fact, lists can be nested, which is what we want, since we want to return two list...

First seen: 2025-08-07 16:23

Last seen: 2025-08-07 18:24