2

On a musl/busybox based system running in qemu (mips), the script

#!/usr/bin/bash

printf '%s\n' "${BASH_VERSION}"

> test.txt
echo 'test.txt:'
cat test.txt

echo "No process substitution:"
while IFS= read -r i; do
    printf 'ABC %s\n' $i | cat -vet
done < test.txt

echo 'test.txt:'
cat test.txt

echo "Process substitution:"
while IFS= read -r i; do
    printf 'ABC %s\n' $i | cat -vet
done < <(cat test.txt)

echo 'test.txt:'
cat test.txt

echo "Pipes:"
cat test.txt | while IFS= read -r i; do
    printf 'ABC %s\n' $i | cat -vet
done

echo 'test.txt:'
cat test.txt

echo "Why???"

prints

4.3.42(1)-release
test.txt:
No process substitution:
test.txt:
Process substitution:
ABC $
test.txt:
Pipes:
ABC $
test.txt:
Why???

On an Arch Linux box, with the same version of bash, it prints

4.3.42(1)-release
test.txt:
No process substitution:
test.txt:
Process substitution:
test.txt:
Pipes:
test.txt:
Why???

Note that the musl/busybox based system prints an 'ABC ' string for the process substitution examples, while the x86_64 box doesn't. The script behaves identically on both systems if I replace > test.txt with echo 'some text' > test.txt.

I'm confused as to why the script prints 'ABC ' on one box, but not on the other, and why it only does so under certain conditions (piped and process substitution examples, so far). I'd love to know what was causing the change in behavior - is it caused by bash? coreutils/busybox? the libc? some environmental variable? something else I haven't thought of? Is the change in behavior intentional (if so, a pointer to some documentation would be helpful), or a bug? Have I misconfigured something?

Troubleshooting suggestions would be nice, or even a polite pointer to somewhere else more suited to the question. I'd post to a mailing list, but I'm not sure what is causing the behavior, so I don't know which mailing list I should post to. As such, I thought a more general forum would be appropriate - I'd be happy to be corrected if I am wrong.


EDIT:

Both the VM and the Arch box have bash-4.3.042 installed (via pacman; on the VM it is a custom PKGBUILD) to /usr/bin/bash. The Arch box uses glibc and GNU coreutils, and is running on an x86_64 laptop, while the VM is a musl and busybox based system, running in qemu (qemu-system-mips). I've tried running the test script on the Arch box with the busybox utilities in the PATH, which did not seem to change anything. From this, I am assuming that the bash on the VM is the issue, as I believe the only non-builtin involved is 'cat'. I also tried running the script using the bash binary (it is statically linked) on the Arch box via qemu-mips, and got the same result as running it in the VM ('ABC ' is printed for the piped and process substitution examples), which seems to support the hypothesis that the bash binary in the VM is at fault. I am assuming that bash is supposed to behave as it does on the Arch box; I'll try to do some tests for that later.

One of the suggestions in the comments was to post the output of od -cb < <(cat test.txt) and od -cb <(cat test.txt), presumably to see whether there was a difference between the two. To try to cover all bases, I experimented with several different versions:

On the Arch box:

$ od -cb < <(cat test.txt)
0000000
$ od -cb <(cat test.txt)
0000000
$ od -cb < test.txt
0000000
$ cat test.txt | od -cb
0000000
$ # Just to show that od is actually working...
$ od -cb < <(echo 'yes')
0000000   y   e   s  \n
        171 145 163 012
0000004

Using the bash from the VM (via qemu-mips):

$ od -cb < <(cat test.txt)
0000000
$ od -cb <(cat test.txt)
0000000
$ od -cb < test.txt
0000000
$ cat test.txt | od -cb
0000000
$ # Just to show that od is actually working...
$ od -cb < <(echo 'yes')
0000000   y   e   s  \n
        171 145 163 012
0000004

Using busybox's od (both in the vm, with the bash binary (via qemu-mips), and the system bash):

$ od -cb < <(cat test.txt)
$ od -cb <(cat test.txt)
$ od -cb < test.txt
$ cat test.txt | od -cb
$ # Just to show that od is actually working...
$ od -cb < <(echo 'yes')
0000000    y   e   s  \n                                                
         171 145 163 012                                                
0000004

So this seems to be as expected.

EDIT:

The bash on the VM is statically linked against musl 1.1.12, and built with the internal readline. To ensure that the bash versions were configured as similarly as possible, I tested both the Arch-packaged bash, and a build using the internal readline (both behaved identically); both are dynamically linked against glibc.

To demonstrate that it actually is bash on both machines:

Arch box:

$ /usr/bin/bash --version
GNU bash, version 4.3.42(1)-release (x86_64-unknown-linux-gnu)
Copyright (C) 2013 Free Software Foundation, Inc.
License GPLv3+: GNU GPL version 3 or later <http://gnu.org/licenses/gpl.html>

This is free software; you are free to change and redistribute it.
There is NO WARRANTY, to the extent permitted by law.

VM:

/usr/bin/bash --version
GNU bash, version 4.3.42(1)-release (mips-unknown-linux-musl)
Copyright (C) 2013 Free Software Foundation, Inc.
License GPLv3+: GNU GPL version 3 or later <http://gnu.org/licenses/gpl.html>

This is free software; you are free to change and redistribute it.
There is NO WARRANTY, to the extent permitted by law.

Some background; I'm trying to get a reasonably complex bash script running without errors on the musl/busybox based system, however part of the script contains a while loop being fed by a process substitution. On the musl/busybox based system, this is unexpectedly fed an empty input (in the example, $i == ""). I could work around this, but I'd rather understand why it doesn't work as I expected.

  • Comments are not for extended discussion; this conversation has been moved to chat. – terdon Jan 3 '16 at 10:06
2

The behavior observed was a bug in bash, triggered by bash building without job control support. Because I was cross-compiling, the configure check for job control defaulted to 'missing' (I should have told configure what to use, see CLFS). The mailing list report has a reduced set of test cases, and the fixes in the devel branch for that week might be of interest. The specific fix is a change to subst.c.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.