bash while/read 루프는 mips/musl/busybox 기반 가상 머신에서 다르게 동작합니다.

bash while/read 루프는 mips/musl/busybox 기반 가상 머신에서 다르게 동작합니다.

qemu(mips)에서 실행되는 musl/busybox 기반 시스템에서 이 스크립트는

#!/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???"

인쇄

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

Arch Linux 시스템에서는 동일한 버전의 bash를 사용하여 인쇄합니다.

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

musl/busybox 기반 시스템은 프로세스 대체 예에 대해 "ABC" 문자열을 인쇄하지만 x86_64 상자는 그렇지 않습니다.> test.txt으로 바꾸면 스크립트는 두 시스템 모두에서 동일하게 작동합니다 echo 'some text' > test.txt.

스크립트가 한 상자에는 "ABC"를 인쇄하고 다른 상자에는 인쇄하지 않는 이유와 특정 조건(지금까지의 파이프 및 프로세스 대체 예)에서만 인쇄하는 이유가 무엇인지 혼란스럽습니다. 행동 변화의 원인이 무엇인지 궁금합니다. bash로 인해 발생합니까? coreutils/busybox? 도서관? 일부 환경 변수? 내가 생각하지 못한 다른 것이 있습니까? 동작의 변경이 의도적인 것입니까(그렇다면 일부 문서에 대한 포인터가 도움이 될 것입니다), 아니면 버그입니까? 제가 잘못 구성한 걸까요?

문제 해결 제안은 훌륭할 것이며, 심지어는 문제에 더 적합한 다른 곳을 정중하게 알려줄 수도 있습니다. 메일링 리스트에 게시하려고 하지만 이 동작의 원인이 무엇인지 확신할 수 없어서 어느 메일링 리스트에 게시해야 할지 모르겠습니다. 그러므로 저는 좀 더 일반적인 포럼이 적절할 것이라고 생각했습니다. 제가 틀렸다면 기꺼이 정정해 드리겠습니다.


편집하다:

VM과 Arch 상자 모두 /usr/bin/bash에 bash-4.3.042가 설치되어 있습니다(pacman을 통해, VM에서는 사용자 정의 PKGBUILD임). Arch 상자는 glibc 및 GNU coreutils를 사용하고 x86_64 노트북에서 실행되는 반면 VM은 qemu(qemu-system-mips)에서 실행되는 musl 및 busybox 기반 시스템입니다. PATH에 있는 busybox 유틸리티를 사용하여 Arch 상자에서 테스트 스크립트를 실행해 보았지만 아무 것도 변경되지 않은 것 같습니다. 이것으로부터 나는 가상 머신의 bash가 문제라고 가정합니다. 왜냐하면 내장되지 않은 유일한 관련 항목은 "cat"이라고 믿기 때문입니다. 또한 bash 바이너리(정적으로 연결됨)를 사용하여 Arch 상자에서 qemu-mips를 통해 스크립트를 실행해 보았는데 VM에서 실행한 것과 동일한 결과를 얻었습니다(파이프 및 프로세스 대체 예제에 대해 "ABC" 인쇄). 가상 머신의 bash 바이너리에 문제가 있다는 가설을 뒷받침하는 것 같습니다. 나는 bash가 Arch 상자에서와 동일하게 작동해야 한다고 가정합니다. 이에 대해서는 나중에 테스트해 보겠습니다.

의견의 제안 중 하나는 od -cb < <(cat test.txt)및 의 출력을 게시하여 od -cb <(cat test.txt)둘 사이에 차이가 있는지 확인하는 것이었습니다. 모든 기반을 다루기 위해 몇 가지 다른 버전을 시도했습니다.

아치 상자에서:

$ 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

가상 머신에서 bash 사용(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

od busybox 사용(가상 머신에서 bash 바이너리(qemu-mips를 통해) 및 시스템 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

그래서 이것은 예상되는 것 같습니다.

편집하다:

VM의 bash는 musl 1.1.12에 정적으로 연결되어 있으며 내부 readline으로 구축되었습니다. Bash 버전이 최대한 유사하게 구성되었는지 확인하기 위해 Arch 패키지 bash와 내부 readline을 사용하여 빌드를 테스트했습니다(둘 다 동일하게 작동함). 둘 다 glibc와 동적으로 연결되었습니다.

실제로 두 시스템 모두에서 bash임을 증명하려면 다음을 수행하십시오.

아치 상자:

$ /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.

가상 기기:

/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.

일부 배경 정보: musl/busybox 기반 시스템에서 오류 없이 실행하기 위해 상당히 복잡한 bash 스크립트를 얻으려고 노력하고 있지만 스크립트의 일부에는 프로세스 대체에 의해 제공되는 while 루프가 포함되어 있습니다. musl/busybox 기반 시스템에서 빈 입력이 예기치 않게 제공되었습니다(예: $i == ""). 이 문제는 해결할 수 있지만 왜 예상대로 작동하지 않는지 이해하고 싶습니다.

답변1

관찰된 동작은 작업 제어 지원 없이 bash 빌드에 의해 트리거된 bash의 버그입니다. 크로스 컴파일을 하고 있기 때문에 작업 제어에 대한 구성 확인은 기본적으로 "누락"으로 설정됩니다(구성에 무엇을 사용해야 하는지 알려줘야 할까요?CLFS). 이것메일링 리스트 보고서테스트 케이스 세트가 줄어들고해당 주의 개발 브랜치에서 수정되었습니다.관심이 있을 수도 있습니다. 구체적인 수정사항은subst.c로 변경.

관련 정보