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