Context: I have a script which makes multiple calls to bc to set some values, ie: many foo="$(echo '1/3' | /usr/bin/bc -q)"
What I want to achieve: do not call bc every times, but keep one bc instance and re-use it multiple times.
I guess coproc
may be what I need, but as I’m curious and want to understand how Bash works, I try to do it using named pipes.
This is my code so far, not the code of the script on which I intend to do this, but a code sample I wrote to try to help me understand what’s going on. It’s probably full of UUO* and questionable parts, but you’ll tell me then:
#!/bin/env -S -i bash --norc
set -euo pipefail
IFS=$'\t\n'
init_bc() {
[[ -p /tmp/bci ]] || mkfifo /tmp/bci
[[ -p /tmp/bco ]] || mkfifo /tmp/bco
tail -n1 -f >&/tmp/bci &
cat /tmp/bco &
/usr/bin/bc -q /tmp/bci >&/tmp/bco &
echo "scale=50" >/tmp/bci
wait &
}
do_bc() {
echo "${1}" >/tmp/bci >&1
}
do_exit() {
rm -vf /tmp/{bci,bco} >&2
pkill -e -P $$
}
trap do_exit TERM EXIT INT
init_bc
echo Sleeping… >&2
foo="$(do_bc "${1}")"
echo "FOO: ${foo}"
sleep 5
echo "Awake!" >&2
wait &
echo "End of script. We wait for all sub-shells." >&2
wait
Running it (waiting a few seconds and then hitting Ctrl+C) this is what I get:
$ ./piped_bc '1/7'
Sleeping…
FOO:
.14285714285714285714285714285714285714285714285714
Awake!
End of script. We wait for all sub-shells.
^Cremoved '/tmp/bci'
removed '/tmp/bco'
killed (pid 5585)
killed (pid 5586)
killed (pid 5587)
As you can see, the $foo
variable doesn’t get valued, and this is what I do not understand.
The bc result seems to be “going” to the standard output, because if I run the script adding 1>/dev/null
the result isn’t displayed, but I don’t understand why $foo is not valued then, and it upsets me (more than I’d like to admit).
Last thing which may be of interest for my question: If I do this in the terminal:
foo=$(/usr/bin/bc -q <(echo 'scale=7;1/7') &)
The variable $foo gets the result of 1/7 as expected:
$ echo $foo
.1428571
Why is it not in my script?
Any help would be, of course, greatly appreciated.
bc
to drawn a fractal at Is bash a programming language?