-
Notifications
You must be signed in to change notification settings - Fork 1.6k
feature: Read input from an argv argument instead of stdin using --input
flag
#3293
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Comments
Not sure i follow, isn't $ echo '{"containers": [{"name": "a"}, {"name": "b"}]}' | jq -r '.containers[] | "name: \(.name)"'
name: a
name: b and if you want to exec something per output i usually pipe to a shell, something like: (using $ echo '{"containers": [{"name": "a"}, {"name": "b"}]}' | jq -r '.containers[] | @sh "echo some subcommand \(.name)"' | sh
some subcommand a
some subcommand b and if you want to use $ jq -rn --argjson i '{"name":"kube-proxy","id":"c31ef8zzssddrrtyt"}' '"name: \($i.name)"'
name: kube-proxy |
If I understand jq -n --argjson i '[{"name":"kube-proxy","id":"c31"},{"name":"kube-proxy","id":"c32"}]' '$i|.'
# would become:
jq -i '[{"name":"kube-proxy","id":"c31"},{"name":"kube-proxy","id":"c32"}]' '.'
# thus something following would be possible:
jq -i '[{"name":"kube-proxy","id":"c31"},{"name":"kube-proxy","id":"c32"}]' --argjson v '{"vname":"vval"}' '.' # <-- you could do something with both "input" and argjson here, and `/dev/stdin` ie FD0 would remain untouched
I also studied Maybe the example was not the best one around, but the whole point of this feature request is to be able exactly "to jump through" Ie to "decouple" |
👍 so $ jq -n --argjson a 1 --argjson b 2 '$a + $b'
3 |
Sorry, I had a work call and wrongly clicked on something - I think I closed the issue and comment midway through unintentionally @wader, can you fix this please? |
I understand, that unless you are probably heavy chaining executable user (akin to Concept of chaining is lost on many these days but some introductory text:
I essence in such setups the data often "flows" through Chainers are extremely composable. While we can emulate some structured data passing using |
Seems I can fix the closure myself. Okay maybe other example, let's say we have an hypothetical tool There are two classic approaches. Either read data from stdin: $ echo "lower" | toucase
LOWER or from argument: $ toucase "lower"
LOWER However most useful tool would support both at the same time and detect input either automatically or by hint: $ echo "lower" | toucase
LOWER
$ toucase "lower"
LOWER This is similar kind of situation. While |
I see. I'm not sure if adding yet another way to provide input is good, it's quite confusing as it is :) maybe some other maintainer has opinions? As the jq language is a superset of JSON you can do something like this if the input is "trusted" JSON |
Roger! I understand the input confusion issue, could this be made by nudging the documentation perhaps? Anyway, should I ever find time to look a it, and maybe (just maybe) produce the patch, what are the chances of it getting accepted? |
The problem: No way to read input from argument
I am again dealing with lot of
jq
-ing and I am constantly having this issue:I want to send data directly into
jq
using anargv[]
argument and not the standard input descriptor. But so far, and please correct me, if I am wrong, this seems to be impossible.While some more regular/traditional
jq
users might oppose the idea, it would be extremely powerful feature, that would come handy in many specialty situations: a subshell,parallel
,xargs
,execline
, or for examplesocat
, or in billions of other such specialty cases.More than like 5 years ago, I requested something like this, and got redirected to
--arg
and--argjson
. While I was thankful and while those are infinitely useful, it's not the same thing! I wasn'tjq
-ing that much since then, but I am, once again, and inability to do this is literally killing me.In a nutshell, this feature would come incredibly handy in ad-hoc api explorations, and quick one off jobs, which iterate over larger datasets, using any OS level iterators or executors, that fork a child, but user would also benefit from
/dev/stdin
being left alone or for left open other uses.While some might argue, that for such jobs one should use something like
python
, that language is not concise enough to cut through large swaths of data being pumped through command lines and pipelines, especially ad hoc. On the other hand,jq
language is sufficiently terse and syntax efficient for exactly that kind of work.Suggestion of solution
Thus I propose introduction of
--input / -i
argument, that would take the next string argument as input, makejq
consume it verbatim as an input buffer, preferably completely ignoring/dev/stdin
handling. Whether--input
should exist in theargv[]
as singleton, similarly to "jq program" argument, is probably best left tojq
maintainers to decide. But to maintain parity with "jq program" argument handling, and to decrease implementation complexity, I suggest singleton approach, ie only and exactly one--input
allowed only, ie eitherjq
would read fromstdin
or from--input
arg.Usage example
This is little bit contrived, but I hope it illustrates a point well, so please bear with me.
Let's say one needs to do some specific ad-hoc action for each container managed by
cri-o
on a k8s node. With--input
I can get.name
field for each record directly (as if I was using unix nativecut(1)
):Without
--input
, this needs to be done instead:Observe, that in first case,
%j
"variable" is just raw string. The "expansion" is handled byxargs
implicitly: it searches for literal string'%j'
in it's own argvector and then it just copy pastes it into it's subchild argvector:jq --input '%j' -r '"name:" +.name'
iejq
subprocess literally becomes:From:
to
after each "line expansion", at the
execve
level.When combined
-0
this makes such executions very safe, without worry, that in-between shell will somehow mangle them. And we are not even talking about reduction of number of sub-forks, pipes, file descriptor etc.Because maximum lengths for each argv element are quite big these days, this allows one to do expansions like these:
Where we save one echo and two fds per pipeline each JSON data field derefercing. If we want to be extra explicit:
But without the
--input
provision, most concise form I got to, is this (by abusing inline shell functions which removes lot of safety):While this might seem more compact (because of shell "hacks"), it is a lot worse from points of both execution complexity and string safety.
I believe you can infer much more advanced and even nested usage from here, especially if taking into account more complex
jq
programs (loaded from files) for initial jq "selector" part of the pipeline (thejq --raw-output0 -c '[.contain...
part).I hope what I wrote makes sense, and will make you consider this feature.
The text was updated successfully, but these errors were encountered: