What's?
Linux上で、ファイルを実行した時に「No such file or directory」と言われることがあります。
OSとファイルの想定しているアーキテクチャ(32bit or 64bit)が異なることが理由だったりするのですが、軽く見てみましょう。
環境
CentOS 8で確認します。
$ cat /etc/redhat-release
CentOS Linux release 8.3.2011
$ uname -srvmpio
Linux 4.18.0-240.1.1.el8_3.x86_64 #1 SMP Thu Nov 19 17:20:08 UTC 2020 x86_64 x86_64 x86_64 GNU/Linux
Liberica OpenJDKで確認
Liberica OpenJDKには、64bit用のものも32bit用のものもあるので、こちらで例を示しましょう。
Liberica OpenJDK Download Center
OpenJDK 11の64bit版をダウンロードして実行。
$ curl -sL -o - https://download.bell-sw.com/java/11.0.9.1+1/bellsoft-jdk11.0.9.1+1-linux-amd64.tar.gz | \
tar zxvf -
$ ll jdk-11.0.9.1/bin/java
-rwxrwxr-x. 1 xxxxx xxxxx 13080 Nov 2 19:33 jdk-11.0.9.1/bin/java
$ jdk-11.0.9.1/bin/java --version
openjdk 11.0.9.1 2020-11-04 LTS
OpenJDK Runtime Environment (build 11.0.9.1+1-LTS)
OpenJDK 64-Bit Server VM (build 11.0.9.1+1-LTS, mixed mode)
こちらは、問題なく実行できます。
続いて、32bit版をダウンロードして同じことをしてみましょう。
※展開されるディレクトリ名は、64bit版と同じなので注意してください
$ curl -sL -o - https://download.bell-sw.com/java/11.0.9.1+1/bellsoft-jdk11.0.9.1+1-linux-i586.tar.gz | \
tar zxvf -
$ ll jdk-11.0.9.1/bin/java
-rwxrwxr-x. 1 xxxxx xxxxx 7484 Nov 2 19:49 jdk-11.0.9.1/bin/java
$ jdk-11.0.9.1/bin/java --version
-bash: jdk-11.0.9.1/bin/java: No such file or directory
32bit版の場合は「No such file or directory」と言われて実行できません。
どうやって気づけばいい?
これ、けっこう不可解なんですけど「そんなファイルないよ」と言われている割には、実はファイル自体にはアクセスできています。
ls
で見れていましたからね。
$ ll jdk-11.0.9.1/bin/java
-rwxrwxr-x. 1 xxxxx xxxxx 7484 Nov 2 19:49 jdk-11.0.9.1/bin/java
実際のところは、「実行できない」が正解です。
この状態は知らないとけっこう難しい気がしますが、file
コマンドの実行結果がヒントになります。
$ file jdk-11.0.9.1/bin/java
jdk-11.0.9.1/bin/java: ELF 32-bit LSB executable, Intel 80386, version 1 (SYSV), dynamically linked, interpreter /lib/ld-linux.so.2, for GNU/Linux 2.6.18, BuildID[sha1]=8cd726d22f9eaf779fdd9aa466608bf20e61c63f, not stripped
ELF 32-bit LSB executable
と言われているので、32bit版の実行ファイルです。
一方で64bit版は、こういう表示になります。
$ file jdk-11.0.9.1/bin/java
jdk-11.0.9.1/bin/java: ELF 64-bit LSB shared object, x86-64, version 1 (SYSV), dynamically linked, interpreter /lib64/ld-linux-x86-64.so.2, for GNU/Linux 2.6.18, BuildID[sha1]=ee4e2e08b65cabbedc10dfb7bca1bd52f9454e01, not stripped
というわけで、「あれ?」と思ったファイルには、たまにfile
コマンドで見てみてもいいのではないでしょうか。
最後に、共有ライブラリへの依存を見るldd
で確認してみましょう。
32bit版。実行可能ファイルじゃないよ、と言われます。
$ ldd jdk-11.0.9.1/bin/java
not a dynamic executable
64bit版はこんな感じになります。
$ ldd jdk-11.0.9.1/bin/java
linux-vdso.so.1 (0x00007ffc9c9f3000)
libz.so.1 => /lib64/libz.so.1 (0x00007f7ef36ae000)
libpthread.so.0 => /lib64/libpthread.so.0 (0x00007f7ef348e000)
libjli.so => /home/xxxxx/jdk-11.0.9.1/bin/../lib/jli/libjli.so (0x00007f7ef327d000)
libdl.so.2 => /lib64/libdl.so.2 (0x00007f7ef3079000)
libc.so.6 => /lib64/libc.so.6 (0x00007f7ef2cb6000)
/lib64/ld-linux-x86-64.so.2 (0x00007f7ef3ac8000)
ちなみに、32bit版を32bit OSで実行するとこんな感じになります。
$ ldd jdk-11.0.9.1/bin/java
linux-gate.so.1 => (0xb775d000)
libz.so.1 => /lib/libz.so.1 (0xb773f000)
libpthread.so.0 => /lib/libpthread.so.0 (0xb7724000)
libjli.so => /home/xxxxx/jdk-11.0.9.1/bin/../lib/jli/libjli.so (0xb7712000)
libdl.so.2 => /lib/libdl.so.2 (0xb770d000)
libc.so.6 => /lib/libc.so.6 (0xb7541000)
/lib/ld-linux.so.2 (0xb775e000)
OSは、こちらで確認。
$ cat /etc/redhat-release
CentOS Linux release 7.9.2009 (AltArch)
$ uname -srvmpio
Linux 3.10.0-1160.6.1.el7.centos.plus.i686 #1 SMP Tue Nov 17 14:19:51 UTC 2020 i686 i686 i386 GNU/Linux