使用 musl-built tclsh8.6 执行脚本给出“没有这样的文件或目录”

Executing script with musl-built tclsh8.6 gives `No such file or directory`

我正在尝试 运行 我在 x86_64 Debian 上使用 musl 工具链从源代码编译的带有 tclsh8.6 的简单 tcl 脚本。

脚本 hello.tcl 如下所示:

puts hello

当我尝试 运行 时,出现以下错误:

$ /usr/local/x86_64-linux-musl/bin/tclsh8.6 hello.tcl
-bash: /usr/local/x86_64-linux-musl/bin/tclsh8.6: No such file or directory

必要的 tcl 库和包含文件都安装到前缀 /usr/local/x86_64-linux-musl。二进制文件也存在:

$ ls -l /usr/local/x86_64-linux-musl/bin/tclsh8.6
-rwxr-xr-x 1 root root 8328 Nov 15 12:18 /usr/local/x86_64-linux-musl/bin/tclsh8.6

$ ldd /usr/local/x86_64-linux-musl/bin/tclsh8.6 
    linux-vdso.so.1 (0x00007ffd04718000)
    libtcl8.6.so => /usr/local/x86_64-linux-musl/lib/libtcl8.6.so (0x00007f005981e000)
    libc.so => /usr/local/x86_64-linux-musl/lib/libc.so (0x00007f0059587000)

我想保持基于 musl 的东西,所以我试图避免我在其他地方找到的潜在解决方案,即使用 apt-get.

重新安装 tcl 或 tcl-dev

导致此错误的原因是什么?非常感谢任何 guidance/help。谢谢:)

编辑

根据此处某些评论的要求,提供了一些附加信息。

file 命令的输出:

$ file /usr/local/x86_64-linux-musl/bin/tclsh8.6 
/usr/local/x86_64-linux-musl/bin/tclsh8.6: ELF 64-bit LSB pie executable, x86-64, version 1 (SYSV), dynamically linked, interpreter /lib/ld-musl-x86_64.so.1, not stripped

strace 命令的输出:

strace /usr/local/x86_64-linux-musl/bin/tclsh8.6 hello.tcl 
execve("/usr/local/x86_64-linux-musl/bin/tclsh8.6", ["/usr/local/x86_64-linux-musl/bin"..., "hello.tcl"], 0x7fffb8c5b278 /* 19 vars */) = -1 ENOENT (No such file or directory)
strace: exec: No such file or directory
+++ exited with 1 +++

看到此输出后,我检查了 loader/interpreter 是否存在于 /lib 处,但没有。为了解决这个问题,我 运行:

$ sudo ln -s /usr/local/x86_64-linux-musl/lib/ld-musl-x86_64.so.1 /lib/ld-musl-x86_64.so.1

当我 运行 tclsh8.6:

时,这给了我一个不同的错误
$ /usr/local/x86_64-linux-musl/bin/tclsh8.6 hello.tcl 
-bash: /usr/local/x86_64-linux-musl/bin/tclsh8.6: Permission denied

运行 它与 sudo 给出相同的结果:

$ sudo /usr/local/x86_64-linux-musl/bin/tclsh8.6 hello.tcl 
sudo: unable to execute /usr/local/x86_64-linux-musl/bin/tclsh8.6: Permission denied

解释器和脚本的权限如下:

$ ls -l /usr/local/x86_64-linux-musl/bin/tclsh8.6 
-rwxr-xr-x 1 root root 8328 Nov 15 13:34 /usr/local/x86_64-linux-musl/bin/tclsh8.6
$ ls -l hello.tcl 
-rwxr-xr-x 1 user user 11 Nov 15 12:44 hello.tcl

希望这些新信息能有所帮助。

编辑 2

更多权限信息:)

$ ls -l /lib/ld-musl-x86_64.so.1 
lrwxrwxrwx 1 root root 52 Nov 16 10:04 /lib/ld-musl-x86_64.so.1 -> /usr/local/x86_64-linux-musl/lib/ld-musl-x86_64.so.1

$ ls -l /usr/local/x86_64-linux-musl/lib/ld-musl-x86_64.so.1 
lrwxrwxrwx 1 root root 12 Nov 15 12:02 /usr/local/x86_64-linux-musl/lib/ld-musl-x86_64.so.1 -> /lib/libc.so

$ $ ls -l /lib/libc.so
-rw-r--r-- 1 root root 246 Nov 14 15:15 /lib/libc.so

这里是/lib/libc.so的内容:

/* GNU ld script
   Use the shared library, but some functions are only in
   the static library, so try that secondarily.  */
OUTPUT_FORMAT(elf64-x86-64)
GROUP ( //lib/libc.so.6 //lib/libc_nonshared.a  AS_NEEDED ( //lib/ld-linux-x86-64.so.2 ) )

它是一个链接器脚本,如果您使可执行文件失败并说库已损坏。

在@Shawn 的帮助下,我解决了我的问题。

tclsh8.6 正在 /lib/ld-musl-x86_64.so.1 寻找程序解释器,但它不存在——我想当我安装 musl-cross-make 时它没有设置它。为了解决这个问题,我只是将 ld-musl-x86_64.so.1 所在的位置符号链接到 lib:

$ sudo ln -s /usr/local/x86_64-linux-musl/lib/ld-musl-x86_64.so.1 /lib/ld-musl-x86_64.so.1

但是,我仍然遇到错误,但这次是权限错误:

$ /usr/local/x86_64-linux-musl/bin/tclsh8.6 hello.tcl 
-bash: /usr/local/x86_64-linux-musl/bin/tclsh8.6: Permission denied

事实证明,ld-musl-x86_64.so.1 最终成为解析为 /lib/libc.so 的符号链接,这是一个链接描述文件,而不是我们想要的可执行 DSO。我相应地更改了这个符号链接:

sudo ln -fs /usr/local/x86_64-linux-musl/lib/libc.so /usr/local/x86_64-linux-musl/lib/ld-musl-x86_64.so.1

在那之后,我可以执行我的脚本,一切都很顺利! :)