6

All my Python and Perl scripts are simply NOT iterpreted via shebang. Never. But they work as expected when I explicitly call the binary.

I double checked my Perl and Python installations, it is just too strange: they shebang-way execution works very well in the target system chroot on a sane host but not in the actual running system.

I work on a homemade Linux system which worked just great before that problem appeared. See by yourself:

A test on the 'xscreensaver-text' Perl program, once via shebang then with the interpreter on the 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

SO this for Perl programs but the same happens with Python scripts. We've been messing with encodings and terminfo's and different kernel, still no success. I've even rebuilt my entire system. It works just great in a chroot env, but once I boot it I have this problem.

Here's an strace output:

$ 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 +++

Contents (only the beginning) of the script :

$ 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
    $ perl -E 'say unpack("H*", scalar <>)' /usr/bin/xscreensaver-text 23212f7573722f62696e2f7065726c202d770a – appzer0 Oct 5 '13 at 21:29
  • 4
    Do all shebangs fail or only Perl and python? What about #!/bin/sh or, better #!/usr/bin/env perl. I assume that by home made, you mean a LFS install and your own compiled kernel? – terdon Oct 5 '13 at 21:50
  • 1
    @terdon I tried a Ruby script and it is exactly the same behaviour. – appzer0 Oct 5 '13 at 22:03
  • 1
    Could those interpreters possibly be scripts themselves? – Stéphane Chazelas Oct 5 '13 at 22:05
  • 1
    Does modprobe -r binfmt_script return anything else than FATAL: Module binfmt_script is builtin? Does modprobe -c | grep binfmt return anything interesting? – Stéphane Chazelas Oct 5 '13 at 22:38
15

Your kernel was compiled without CONFIG_BINFMT_SCRIPT=y. This setting controls shebang support.

From 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                                   

Reconfigure and recompile your kernel. (Technically, it can also be built as a module, but there's no point in doing that for something as fundamental as #! support.)

  • 1
    You'd think his Though we tried with different kernels, including some that were working OK, same problem would rule that out but it could actually be that he did build it as a module and forgot to include the module or run the depmod. So I agree that's the best bet so far. +1 – Stéphane Chazelas Oct 5 '13 at 23:17
  • #!/bin/sh shouldn't work also. – Alex Oct 5 '13 at 23:18
  • 4
    @Alex, that's a different issue. If the system returns ENOEXEC on a file, most user space applications (through execvp() or a shell) try to run it with /bin/sh, that's why he gets shell syntax errors when running the perl script. And that's why you wouldn't notice non-working shebangs if they were all #! /bin/sh ones. – Stéphane Chazelas Oct 5 '13 at 23:21
  • Confirm, execv*() functions are frontend for execve() so that's no the case, but the bash at least try to fix NOEXEC running the file as a shell script if there is a #! – Alex Oct 6 '13 at 0:20
  • 1
    Thanks so much! BINFMT_SCRIPT was compiled as a module, thus non-loaded. – appzer0 Oct 6 '13 at 8:45

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.