ash while loops and variable scope

Harald Becker ralda at
Sat Sep 4 00:52:16 UTC 2010

 Hi Stuart!

> In some other parts, I've used constructs like
> for var in $( foo ); do
> 	blah
> done
> but that doesn't work in the above case since listener-prog returns one
> entry per line.  The difference in terms of variables being set inside
> the for loop I guess is that there are no pipes involved... $( foo )
> gets evaluated, then that is passed to the for loop.  I could of course
> change it to ensure each event has no spaces in it, and then for loops
> would quite successfully in that case.
Your assumption that no pipe is involved in this case is wrong. As soon
as it's needed to run a program and to substitute its output, there will
always be a pipe involved. An implicit pipe in this case. The multi line
output from listener prog doesn't really matter at this case, but it
nevertheless won't succeed for your needs.

The for loop in your example works in the following manner:

- an implicit pipe is created
- foo is evaluated in a subshell with stdout of foo redirected to the pipe
- the pipe output is read by a function in the current shell and split
into words according to the setting of IFS
- those words are used as arguments to the for loop

The difference between for and while in this case is, that the loop body
of the for loop is executed only after foo has exited and all it's
output has been collected by the current shell (in a memory buffer,
possibly being huge if foo does output a lot of data before it exits).
The while loop on the other hand consumes the input data from the
implicit pipe line by line, as it arrives and is parsed by the 'read'
builtin. Word splitting is done in either case (for/read) according to
the setting of the variable IFS (Input Field Separator). Where read
always consume a single line, the for loop uses new line as an
additional word separator. So it doesn't matter if the output of foo is
contained on a single line, split by space or one argument per line.
Each word is collected and all words are used successively as arguments
to the for loop, AFTER foo is done (has exited successfully).

> That link is one I intend to have a look at... is there somewhere that
> describes the 'Busybox ash' scripting language?
As far as I know, there is no special documentation of the busybox ash.
The closest document is the man page of the original ash with some
additions from bash. If all features has been compiled into busybox,
there shouldn't be much, that has been left out from the original ash.
Newer versions of busybox ash implemented even more and more needed
features from bash. So both man pages may be used as documentation. The
ash man page as the basical reference and the bash man page describing
the additions.

... and the only source how to find how the versions and shells differ,
is the busybox source code :-( ... that is definitely one of the most
imported topics busybox is lacking, an up to date and complete
documentation ... but no one has written it yet ... and I'm sure it
would be welcome. The only other source of information I know, beside
digging into busybox source code, is asking at this mailing list.

I suggest: Take a deep look at the ash man page, which is very close to
that one of the original sh, which you already studied as I remember.
Then try to write your scripts according to the ash man page. They
should work with the busybox ash. If not, please drop a note here and
you will be informed, if there is a difference in busybox or possibly a
bug. In addition, if  you need features from bash not included in ash,
ask. Some of the simpler features have been included in busybox, or
there may exist simple workarounds.

> There is a bug ... it's in my understanding of how ash works, not in ash
> itself. :-)
The probability of this being the bug is one of the highest ;-)


More information about the busybox mailing list