[RndTbl] shell quoting inside $( )?
Trevor Cordes
trevor at tecnopolis.ca
Sun Feb 26 21:56:54 CST 2023
On 2023-02-27 Adam Thompson wrote:
> Found my answer, sort of. Either use mkfiko and tee, or use
> bash/zsh/ksh88 process substitution a la "cmd >(subcmd1) >(subcmd2)",
That's what I said half an hour ago! Doh
I managed to improve mine to eliminate the eval:
$ read SUBJ EXPD <<<$(echo $((openssl x509 -noout -text -in /etc/pki/tls/certs/tecnopolis.ca.crt |tee >(date -d"$(sed -n 's/^.*Not After : //p')" +%Y%b%d) >(sed -n 's/^.*Subject: .*CN = //p') 1>&2 ) 2>/dev/null))
$ echo "subj $SUBJ expd $EXPD"
subj tecnopolis.ca expd 2024Feb22
> but I don't see any good way of getting the output from subcmd1/2
> into variables as they run in subshells. It would be do-able by
> piping the whole thing into a "while read X" loop, but that's
> arguably getting into "the cure is worse than the disease" territory.
Yes, the subshell/command problem is the difficult factor here. My
updated example above also uses read, but without a loop. You need
the echo and multi-subshells to get the 2 outputs onto 1 line.
Here's the funny part: the >() constructs start async ps's and you
don't know whose output will come first! Yet no matter what I did
the SUBJ always comes out first. I even put sleeps in the >()
constructs to try to influence who outputs first, but it didn't
matter! I wonder why the output order is the way it is (backwards)
and always constant...
> Untested as yet, but should work:
>
> ( openssl x509 -noout -text -in "$1" >(sed -n 's/^.*Not After : /A
> /p' | xargs date +%Y%b%d -d) >(sed -n 's/^.*Subject: .*CN = /B /p') )
> | while read X; do case $X in A) EXPD="$X" ;; B) SUBJ="$X" ;; esac ;
> <do something with EXPD and SUBJ>
Pretty sure you are *forced* to use tee or something like it. You
can't just use >() with openssl. >() replaces itself with
/dev/fd/X and sets up an async to read from it, which means nothing
to openssl. You need tee to do the writing to that fd/X. Ran into
that grief when I was working on it.
Nice: you are getting around the order issue with A / B, which is
smart, but then kind of forces you into the loop. Still one line
though. And the loop is no more evil than my read <<< echo hack.
> If there were an easy way to "promote" shell variables up out of
> their subshell namespaces without needing `` or $() or read,
> subshells would be a heck of a lot more useful...
I was trying really hard to use my own fd's like 3 & 4 (not the
ones used by >()) to get the output out of each >() construct
and be able to differentiate them. But it wouldn't work... maybe
because the >() is async, and I need to write to each fd in the
construct and then read them out of the construct. Dunno. Use
of fds 3 & 4 hurts my brain. Ideally the EXPD >() could write out
to fd3 and SUBJ to fd4 and an outer shell could then read them.
Or maybe that's impossible.
More information about the Roundtable
mailing list