35

I'm trying to execute python scripts automatically generated by zc.buildout so I don't have control over them. My problem is that the shebang line (#!) is too long for either bash (80 character limit) or direct execution (some Linux kernel constant I don't know).

This is an example script to help you reproduce my problem:

#!/././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././bin/bash
echo Hola!

How can be bash or the kernel configured to allow for bigger shebang lines?

2
  • 1
    If you pass the script as an argument to the interpreter (bash x.sh rather than ./x.sh) the shebang line would just be ignored as a comment and should not affect the execution. Commented May 30, 2012 at 9:39
  • I know, the problem is that I'm not the one invoking those scripts either... Commented May 31, 2012 at 9:28

3 Answers 3

39

Limited to 127 chars on 99.9% of systems due to kernel compile time buffer limit.

It's limited in the kernel by BINPRM_BUF_SIZE, set in include/linux/binfmts.h.

Sign up to request clarification or add additional context in comments.

1 Comment

See also man execve: "A maximum line length of 127 characters is allowed for the first line in a #! executable shell script."
15

If you don't want to recompile your kernel to get longer shebang lines, you could write a wrapper:

#!/bin/bash

if [[ $# -eq 0 ]]; then
    echo "usage: ${0##*/} script [args ...]"
    exit
fi

# we're going to expand a variable *unquoted* to use word splitting, but
# we don't want to have path expansion effects, so turn that off
set -f

shebang=$(head -1 "$1")
if [[ $shebang == '#!'* ]]; then
    interp=( ${shebang#\#!} )        # use an array in case a argument is there too
else
    interp=( /bin/sh )
fi

# now run it
exec "${interp[@]}" "$@"

and then run the script like: wrapper.sh script.sh

1 Comment

+1 Simple workaround that solves all the problems without needing any kernel changes, patches or other hacks.
10

Updated @glenn jackman's script to support passing in command line arguments.

Incidentally, I ran into this problem when creating a python virtualenv inside of a very deep directory hierarchy.

In my case, this was a virtualenv created inside a Mesos framework dir.

The extra long shebang rendered calling xxx/.../venv/bin/pip useless.

The wrapper script proved most useful.

#!/usr/bin/env bash

script="$1" 
shebang=$(head -1 "$script")

# use an array in case a argument is there too
interp=( ${shebang#\#!} )        

# now run it, passing in the remaining command line arguments
shift 1
exec "${interp[@]}" "$script" "${@}"

1 Comment

Can you elaborate on how you're using this script with the virtual env? Our build fails during the initial creation of the virtual env because the #! path to easy_install is too long already.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.