32

我正在尝试执行由 zc.buildout 自动生成的 python 脚本,所以我无法控制它们。我的问题是 shebang 行(#!)对于 bash(80 个字符限制)或直接执行(一些我不知道的 Linux 内核常量)来说太长了。

这是一个示例脚本,可帮助您重现我的问题:

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

如何将 bash 或内核配置为允许更大的 shebang 行?

4

3 回答 3

36

由于内核编译时间缓冲区限制,在 99.9% 的系统上限制为 127 个字符。

它在内核中受限于BINPRM_BUF_SIZE, 设置在include/linux/binfmts.h.

于 2012-05-30T09:35:17.703 回答
13

如果您不想重新编译内核以获得更长的 shebang 行,您可以编写一个包装器:

#!/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[@]}" "$@"

然后像这样运行脚本:wrapper.sh script.sh

于 2012-05-31T00:41:11.023 回答
10

更新了@glenn jackman 的脚本以支持传入命令行参数。

顺便说一句,我在非常深的目录层次结构中创建 python virtualenv 时遇到了这个问题。

就我而言,这是在 Mesos 框架目录中创建的 virtualenv。

超长的 shebang 使呼叫xxx/.../venv/bin/pip毫无用处。

包装脚本被证明是最有用的。

#!/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" "${@}"
于 2015-01-04T09:13:46.800 回答