Bug 685

Summary: [shell] return values with spaces are not escaped correctly
Product: Busybox Reporter: Andy B <ab>
Component: Standard ComplianceAssignee: unassigned
Status: RESOLVED INVALID    
Severity: normal CC: busybox-cvs
Priority: P3    
Version: 1.15.x   
Target Milestone: ---   
Hardware: Other   
OS: Linux   
Host: Target:
Build:

Description Andy B 2009-10-27 17:43:15 UTC
The following commands do not work correctly in ash and hush:

filename "a\ b" is split into two entries in the result list.
In result lists, spaces in entries are not correctly escaped and processed afterwards.

incorrect - e.g. #1:
# for i in `find .`
> do
> echo $i
> done
.
./ab
./a
b
#

incorrect - e.g. #2:
# for i in `ls ./a*`
> do
> echo $i
> done
./a
b
./ab

if resolved directly by the shell, results are correct.

correct - e.g. +1 (find):
# find .
.
./ab
./a b
#

correct - e.g. #1 (workaround):
# for i in ./a*
> do
> echo $i
> done
./a b
./ab
#

I checked with other special characters like "[" or "\"".

Two spaces in a filename are treated as one new line.
touch a\ \ b
# for i in `find . -name "a\ \ b"`; do echo $i; md5sum $i > $i.md5; done
./a
md5sum: can't open './a': No such file or directory
b
md5sum: can't open 'b': No such file or directory
#

Greetings from Austria,
Andy B.
Comment 1 Denys Vlasenko 2009-10-27 18:30:17 UTC
Which shell you are testing, ash or hush?

> incorrect - e.g. #1:
> # for i in `find .`

Did you try it in bash? It also "fails" there. This is just how it should work in this case.
You can use:
for i in "`find .`"
but this will jam *all* filenames into one $i. So probably:
find . | while read filename; do ...; done


Try this script:

#!/bin/sh
testing() {
        echo "Testing $1"
        rm -rf dir 2>/dev/null
        mkdir dir
        >"dir/a b"
        echo "Test with find"
        $1 -c 'for i in `find dir`; do echo $i; done'
        echo "Test with ls"
        $1 -c 'for i in `ls dir/a*`; do echo $i; done'
        echo
}
testing "bash"
testing "./busybox ash"
testing "./busybox hush"


It outputs:

Testing bash
Test with find
dir
dir/a
b
Test with ls
dir/a
b

Testing ./busybox ash
Test with find
dir
dir/a
b
Test with ls
dir/a
b

Testing ./busybox hush
Test with find
dir
dir/a
b
Test with ls
dir/a
b


as you see, both busybox shells are compatible with bash in this regard.