Подтвердить что ты не робот

Ограничение линии Shebang в bash и linux kernel

Я пытаюсь выполнить скрипты python, автоматически создаваемые zc.buildout, поэтому я не контролирую их. Моя проблема заключается в том, что строка shebang (#!) Слишком длинна для bash (ограничение 80 символов) или прямого выполнения (некоторые константы ядра Linux, которые я не знаю).

Это пример script, который поможет вам воспроизвести мою проблему:

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

Как может быть bash или ядро ​​сконфигурировано, чтобы разрешить большие строки shebang?

4b9b3361

Ответ 1

Ограничено 127 символами на 99,9% систем из-за ограничения буфера времени компиляции ядра.

В ядре оно ограничено BINPRM_BUF_SIZE, установленным в include/linux/binfmts.h.

Ответ 2

Если вы не хотите перекомпилировать ядро, чтобы получить более длинные строки, вы можете написать обертку:

#!/bin/bash
script="$1" 
shebang=$(head -1 "$script")

# 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

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[@]}" "$script"

и затем запустите скрипт как: wrapper.sh script.sh

Ответ 3

Обновлен @glenn jackman script для поддержки передачи в аргументах командной строки.

Кстати, я столкнулся с этой проблемой при создании виртуального виртуального файла python внутри очень глубокой иерархии каталогов.

В моем случае это был virtualenv, созданный внутри фрейма Mesos framework.

Дополнительная длинная shebang визуализировала вызов xxx/.../venv/bin/pip бесполезным.

Обертка script оказалась наиболее полезной.

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

Ответ 4

Вы можете передать сценарии через sed, чтобы сократить строку shebang:

sed -i.bak -E '1s|(/\.)+/|/|g' script.sh

Это должно свернуть каждый /./ до / в первой строке script.