在 Linux 上通过 shebang 错误解释 Perl 和 Python

在 Linux 上通过 shebang 错误解释 Perl 和 Python

我所有的 Python 和 Perl 脚本都不是通过 shebang 解释的。绝不。但当我显式调用二进制文件时,它们会按预期工作。

我仔细检查了我的 Perl 和 Python 安装,这太奇怪了:它们的 shebang 方式执行在正常主机上的目标系统 chroot 中运行得很好,但在实际运行的系统中却不然。

我在一个自制的 Linux 系统上工作,在这个问题出现之前它运行得很好。自己看:

对“xscreensaver-text”Perl 程序进行测试,先通过 shebang,然后使用 CLI 上的解释器:

$ LC_ALL=C LANG=C /usr/bin/xscreensaver-text
/usr/bin/xscreensaver-text: line 23: require: command not found
/usr/bin/xscreensaver-text: line 25: use: command not found
/usr/bin/xscreensaver-text: line 29: BEGIN: command not found
/usr/bin/xscreensaver-text: line 31: use: command not found
/usr/bin/xscreensaver-text: line 32: syntax error near unexpected token `('
/usr/bin/xscreensaver-text: line 32: `use POSIX qw(strftime);'

$ LC_ALL=C LANG=C perl /usr/bin/xscreensaver-text
poopy
Linux 3.11.1

Sat Oct  5 23:07:33 2013

up 11:35,  2 users
load average: 0.09, 0.08, 0.06

对于 Perl 程序来说是这样,但对于 Python 脚本来说也是如此。我们一直在搞乱编码、terminfo 和不同的内核,但仍然没有成功。我什至重建了我的整个系统。它在 chroot 环境中工作得很好,但是一旦我启动它,我就会遇到这个问题。

这是一个 strace 输出:

$ LC_ALL=C LANG=C strace /usr/bin/xscreensaver-text
execve("/usr/bin/xscreensaver-text", ["/usr/bin/xscreensaver-text"], [/* 50 vars */]) = -1 ENOEXEC (Exec format error)
write(2, "strace: exec: Exec format error\n", 32strace: exec: Exec format error
) = 32
exit_group(1)                           = ?
+++ exited with 1 +++

$ LC_ALL=C LANG=C strace perl /usr/bin/xscreensaver-text
execve("/usr/bin/perl", ["perl", "/usr/bin/xscreensaver-text"], [/* 50 vars */]) = 0
brk(0)                                  = 0x601000
mmap(NULL, 4096, PROT_READ|PROT_WRITE, MAP_PRIVATE|MAP_ANONYMOUS, -1, 0) = 0x7ff12e312000
access("/etc/ld.so.preload", R_OK)      = -1 ENOENT (No such file or directory)
open("/etc/ld.so.cache", O_RDONLY|O_CLOEXEC) = 3
fstat(3, {st_mode=S_IFREG|0644, st_size=240674, ...}) = 0
mmap(NULL, 240674, PROT_READ, MAP_PRIVATE, 3, 0) = 0x7ff12e2d7000
close(3)                                = 0
open("/usr/lib64/libc.so.6", O_RDONLY|O_CLOEXEC) = 3
read(3, "\177ELF\2\1\1\0\0\0\0\0\0\0\0\0\3\0>\0\1\0\0\0 \37\2\0\0\0\0\0"..., 832) = 832
fstat(3, {st_mode=S_IFREG|0755, st_size=1868472, ...}) = 0
mmap(NULL, 3981888, PROT_READ|PROT_EXEC, MAP_PRIVATE|MAP_DENYWRITE, 3, 0) = 0x7ff12dd24000
mprotect(0x7ff12dee6000, 2097152, PROT_NONE) = 0
mmap(0x7ff12e0e6000, 24576, PROT_READ|PROT_WRITE, MAP_PRIVATE|MAP_FIXED|MAP_DENYWRITE, 3, 0x1c2000) = 0x7ff12e0e6000
mmap(0x7ff12e0ec000, 16960, PROT_READ|PROT_WRITE, MAP_PRIVATE|MAP_FIXED|MAP_ANONYMOUS, -1, 0) = 0x7ff12e0ec000
close(3)                                = 0
mmap(NULL, 4096, PROT_READ|PROT_WRITE, MAP_PRIVATE|MAP_ANONYMOUS, -1, 0) = 0x7ff12e2d6000
mmap(NULL, 8192, PROT_READ|PROT_WRITE, MAP_PRIVATE|MAP_ANONYMOUS, -1, 0) = 0x7ff12e2d4000
arch_prctl(ARCH_SET_FS, 0x7ff12e2d4740) = 0
mprotect(0x7ff12e0e6000, 16384, PROT_READ) = 0
mprotect(0x7ff12e313000, 4096, PROT_READ) = 0
munmap(0x7ff12e2d7000, 240674)          = 0
brk(0)                                  = 0x601000
brk(0x622000)                           = 0x622000
clone(child_stack=0, flags=CLONE_CHILD_CLEARTID|CLONE_CHILD_SETTID|SIGCHLD, child_tidptr=0x7ff12e2d4a10) = 5680
wait4(5680, poopy
Linux 3.11.1

Sat Oct  5 23:11:49 2013

up 11:39,  2 users
load average: 0.08, 0.12, 0.08

[{WIFEXITED(s) && WEXITSTATUS(s) == 0}], 0, NULL) = 5680
--- SIGCHLD {si_signo=SIGCHLD, si_code=CLD_EXITED, si_pid=5680, si_status=0, si_utime=2, si_stime=0} ---
exit_group(0)                           = ?
+++ exited with 0 +++

脚本的内容(仅开头):

$ cat /usr/bin/xscreensaver-text
#!/usr/bin/perl -w
# Copyright � 2005-2013 Jamie Zawinski 
#
#
# Created: 19-Mar-2005.

require 5;
#use diagnostics;   # Fails on some MacOS 10.5 systems
use strict;

# Some Linux systems don't install LWP by default!
# Only error out if we're actually loading a URL instead of local data.
BEGIN { eval 'use LWP::UserAgent;' }
--*snip*--

答案1

您的内核是在没有CONFIG_BINFMT_SCRIPT=y.此设置控制 shebang 支持。

make menuconfig

Symbol: BINFMT_SCRIPT [=y]                                             
   Type  : tristate                                                    
   Prompt: Kernel support for scripts starting with #!                 
     Location:                                                         
   (1) -> Executable file formats / Emulations                         
     Defined at fs/Kconfig.binfmt:68                                   

重新配置并重新编译您的内核。 (从技术上讲,它也可以构建为模块,但对于像#!支持这样的基本功能来说这样做是没有意义的。)

相关内容