[Techtalk] weirdness piping to a variable

Miriam English mim at miriam-english.org
Fri Oct 18 03:24:28 UTC 2013


Wow! So much information!
Thanks Peggy. It'll take me some time to digest all this.
Excellent!

Best wishes,

	- Miriam

Peggy Russell wrote:
>>> some_var=$(command | command | command)
>
>> It is similar to what I usually do too, though I tend to use backticks.
>> (I wonder if there is an advantage to one way rather than the other.)
> Hi,
>
> The above command is referred to as "command substitution".
> The back-ticks are the old style of quotes.
> The $() is a little cleaner to use, especially if you nest commands.
> I do what Daneel does, $(), to assign the output of a command to a variable
> or array.
>
> https://www.gnu.org/software/bash/manual/bash.html#Command-Substitution
> http://wiki.bash-hackers.org/scripting/obsolete
> http://pubs.opengroup.org/onlinepubs/9699919799/utilities/V3_chap02.html#tag_18_06_03
> (I write for bash, but I try to consider portability, thus the IEEE link.)
>
> Process substitution was mention. Some day you might run into this. I did ;-)
> If you depend on the sequence of events, proces substitution may not work as
> first thought. It is async. Here's a little gotcha.
>
> In the snippet:
> +++++++++++++++
> declare -A aarr=([would]="1" [wood]="2" [much]="1"
>                   [woodchuck]="2" [could]="1" [a]="2"
>                   [how]="1" [if]="1" [chuck]="2" )
> declare -i total=0
> echo "$$ $BASHPID"
>
> for word in "${!aarr[@]}"; do
>    if [[ "${total}" -eq 0 ]]; then echo "$$ $BASHPID"; fi
>    printf -- '%-10s %d\n' "${word}" "${aarr[$word]}"
>    (( total += ${aarr[$word]} ))
> #done
> done | sort -k2rn
> printf -- 'Total %2d\n' "${total}"
> +++++++++++++++
>
> The pipe put the for in a subprocess (see $$ $BASHPID). You might try process
> substitution:
>
> done > >(sort -k2rn)
> # sleep 2s
> printf -- 'Total %2d\n' "${total}"
>
> But process substitution is async. The Total may come out before the Details.
> You could try a quick fix with sleep.
>
> Or a function in the background and return the total (echo $total).
> Or you could create your own pipe and run the command in the background.
> Something like:
>
> mkfifo mypipe
> trap 'rm -v mypipe' EXIT
> ...
> printf -- '%-10s %d\n' "${word}" "${aarr[$word]}" > mypipe &
> ...
> sort -k2rn < mypipe
>
> Peggy Russell
> _______________________________________________
> Techtalk mailing list
> Techtalk at linuxchix.org
> http://mailman.linuxchix.org/mailman/listinfo/techtalk
>
>

-- 
If you don't have any failures then you're not trying hard enough.
  - Dr. Charles Elachi, director of NASA's Jet Propulsion Laboratory
-----
Website: http://miriam-english.org
Blogs:   http://miriam-e.dreamwidth.org
          http://miriam-e.livejournal.com




More information about the Techtalk mailing list