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

スクリプトが1つのボックスに「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ボックスと同じように動作する必要があると仮定します。これについては後でテストしてみましょう。

コメントの提案の1つは、とのod -cb < <(cat test.txt)出力を投稿して、2つの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に変更

関連情報