ash while loops and variable scope
Denys Vlasenko
vda.linux at googlemail.com
Fri Sep 3 12:46:27 UTC 2010
On Fri, Sep 3, 2010 at 6:05 AM, Stuart Longland <redhatter at gentoo.org> wrote:
> In the scripts, I often perform some action (after a delay in a
> backgrounded subshell) then start up a program to "listen" for events
> that occur, and mark off a checklist when each event is heard. The
> logic I'd like to use is something like this:
>
> evt_a_seen=0
> evt_b_seen=0
> ( sleep 0.5 ; do_something ) &
>
> listener-prog | while read event; do
> case "${event}" in
> EVENT_A)
> evt_a_seen=1
> ;;
> EVENT_B)
> evt_b_seen=1
> ;;
> esac
> done
>
> if [ ${evt_a_seen} = 0 ] || [ ${evt_b_seen} = 0 ]; then
> exit 1
> fi
>
> The do_something is something along the lines of toggling a relay, then
> listener-prog is some tool that listens on an event device to detect if
> changes actually occurred and reports this on stdout.
>
> What I find though, is although both variables may get set to 1 within
> the loop, the moment I leave, they're back at their original values.
> It's as if the contents of the while X ; do Y; done loop was executed in
> a subshell.
Yes. That's how it is implemented in all shells I know.
> The hack around has been to create some temporary files using touch,
> then delete them. Ugly, but I know it works. I'm just not sure if the
> behaviour I'm experiencing is deliberate, or whether there is a bug in
> my binary or Busybox itself.
It's not a bug.
As to a work-around, sometimes it is feasible to do this:
listener-prog | {
while read event; do
case "${event}" in
EVENT_A)
evt_a_seen=1
;;
EVENT_B)
evt_b_seen=1
;;
esac
done
if [ ${evt_a_seen} = 0 ] || [ ${evt_b_seen} = 0 ]; then
exit 1
fi
...
}
--
vda
More information about the busybox
mailing list