On Fri, 2010-09-03 at 14:05 +1000, Stuart Longland wrote:
> Hi all...
> 
> I was wondering how one updates a variable from within a while loop.
> I've written a test suite for some embedded Linux boards, which is based
> on shell scripts written in Busybox ash and a handful of C programs.
> 
> ~ # busybox 
> BusyBox v1.17.0 (2010-07-23 09:42:42 EST) multi-call binary.
> Copyright (C) 1998-2009 Erik Andersen, Rob Landley, Denys Vlasenko
> and others. Licensed under GPLv2.
> See source distribution for full notice.
> ~ # uname -a
> Linux testms 2.6.28-jem3 #82 PREEMPT Wed Sep 1 14:10:55 EST 2010
> armv5tejl GNU/Linux
> 
> Environment is ARM-EABI using glibc-2.11.2.
> 
> 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.
> 
> 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.

the pipe creates a subshell. use process substitution instead.

evt_a_seen=0
evt_b_seen=0
( sleep 0.5 ; do_something ) &

while read event; do
        case "${event}" in
                EVENT_A)
                        evt_a_seen=1
                        ;;
                EVENT_B)
                        evt_b_seen=1
                        ;;
        esac
done < <(listener-prog)

if [ ${evt_a_seen} = 0 ] || [ ${evt_b_seen} = 0 ]; then
        exit 1
fi


_______________________________________________
busybox mailing list
[email protected]
http://lists.busybox.net/mailman/listinfo/busybox

Reply via email to