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環境ではほとんどの場合非実用的です。