BashがAlpine 3.14.2で実行可能ビットを正しく評価できないのはなぜですか?

BashがAlpine 3.14.2で実行可能ビットを正しく評価できないのはなぜですか?

Bash 5.1.4(1) を実行する dockerized Alpine 3.14.2 では、Bash スクリプトで奇妙な動作が発生します。最も重要なのは、ファイルの実行可能性をテストすることですが、常に失敗します。簡単に言えば、これはifテストです。

bash-5.1# if [ ! -x /opt/java/openjdk/bin/java ]; then echo "something strange just happened"; fi
something strange just happened

しかし、私が知っている実行可能性を「テスト」するさまざまな方法は、すべてさまざまな結果を示しています。

bash-5.1# ls -la /opt/java/openjdk/bin/java
-rwxr-xr-x    1 root     root         12648 Jan 21  2021 /opt/java/openjdk/bin/java
bash-5.1# stat -c "%A" /opt/java/openjdk/bin/java
-rwxr-xr-x
bash-5.1# /opt/java/openjdk/bin/java --version
openjdk 15.0.2 2021-01-19
OpenJDK Runtime Environment AdoptOpenJDK (build 15.0.2+7)
OpenJDK 64-Bit Server VM AdoptOpenJDK (build 15.0.2+7, mixed mode, sharing)

私のスクリプトが正しく機能するために、Bash内の実行可能性テストは正しい結果を返す必要があります。しかし、なぜできませんか?

私が確認したり試したことがたくさんあります。そのうちのいくつかはコミュニティの提案に基づいています。

  • すべての(テスト済み)実行可能ファイルのスキャンに失敗しました。 Bash自体も同様です。結果は常に間違っています。
bash-5.1# if [ ! -x /bin/bash ]; then echo "this is weird"; fi
this is weird
  • @KamilMaciorowskiは、彼の意見でbashカバレッジテストを提案しました。しかし、出力は大丈夫に見えます。
bash-5.1# type -a [
[ is a shell builtin
  • 以下はコマンドの追跡です(@zevzekに感謝します)。
bash-5.1# strace -fe trace=access,faccessat,stat bash -c '[ -x /bin/bash ]'
stat("/root", {st_mode=S_IFDIR|0700, st_size=4096, ...}) = 0
stat(".", {st_mode=S_IFDIR|0700, st_size=4096, ...}) = 0
stat("/root", {st_mode=S_IFDIR|0700, st_size=4096, ...}) = 0
stat("/root", {st_mode=S_IFDIR|0700, st_size=4096, ...}) = 0
stat(".", {st_mode=S_IFDIR|0700, st_size=4096, ...}) = 0
stat("/usr/local/sbin/bash", 0x7ffc257ec050) = -1 ENOENT (No such file or directory)
stat("/usr/local/bin/bash", 0x7ffc257ec050) = -1 ENOENT (No such file or directory)
stat("/usr/sbin/bash", 0x7ffc257ec050)  = -1 ENOENT (No such file or directory)
stat("/usr/bin/bash", 0x7ffc257ec050)   = -1 ENOENT (No such file or directory)
stat("/sbin/bash", 0x7ffc257ec050)      = -1 ENOENT (No such file or directory)
stat("/bin/bash", {st_mode=S_IFREG|0755, st_size=760136, ...}) = 0
stat("/bin/bash", {st_mode=S_IFREG|0755, st_size=760136, ...}) = 0
+++ exited with 1 +++
  • Busyboxで「real」を使用すると問題はありませんが、Bashでは[機能しません。[ただし、このコンテナのソフトウェアに付属のすべてのBashスクリプトを再構築することはできません。
bash-5.1# which [
/usr/bin/[
bash-5.1# if [ ! -x /bin/bash ]; then echo "this is weird"; fi
this is weird
bash-5.1# if /usr/bin/[ ! -x /bin/bash ]; then echo "this is weird"; fi
bash-5.1#
  • ファイルシステムが「noexec」マウントされていません

  • 他のテストは[ -f /bin/bash ]正確[ -f /tmp/not_there ]ですが、-x間違っているようです。

  • Bash 5.1.1を試してみましたが、そこで動作します。その時私が経験したバッシュリリースノートしかし、2つの間に関連するコンテンツが見つかりません。

ベストアンサー1

Alpine 3.14はここで知られているバグに関連しているようです。すべての技術的詳細はすでに未解決の問題があります(最初は「実行可能」ビットを探していたので見つかりませんでした。)

つまり、まだAlpine 3.14でBashを使用しないでください。

長い答えは、影響を受ける特定のコンポーネントのセットを更新することです。これは、Docker環境ではほとんどの場合非実用的です。

おすすめ記事