Невозможно передать аргумент python с помощью "#!/Usr/bin/env python"

Мне нужно было иметь прямо исполняемый python script, поэтому я начал файл с #!/usr/bin/env python. Однако мне также нужен небуферизованный вывод, поэтому я попробовал #!/usr/bin/env python -u, но это не работает с python -u: no such file or directory.

Я выяснил, что #/usr/bin/python -u работает, но мне нужно, чтобы python в PATH поддерживал виртуальные среды env.

Каковы мои варианты?

Ответы

Ответ 1

Лучше использовать переменную окружения, чтобы включить это. См. Документ python: http://docs.python.org/2/using/cmdline.html

для вашего случая:

export PYTHONUNBUFFERED=1
script.py

Ответ 2

В некоторой среде env не разделяет аргументы. Итак, ваш env ищет "python -u" на вашем пути. Мы можем использовать sh для работы. Замените свой shebang следующими строками кода, и все будет хорошо.

#!/bin/sh
''''exec python -u -- "$0" ${1+"[email protected]"} # '''
# vi: syntax=python

p.s. нам не нужно беспокоиться о пути к sh, правильно?

Ответ 3

Передача аргументов в строку shebang не является стандартной и, поскольку вы экспериментировали, не работают в сочетании с env в Linux. Решение с bash заключается в использовании встроенной команды "set" для установки необходимых параметров. Я думаю, вы можете сделать то же самое, чтобы установить небуферизованный вывод stdin с помощью команды python.

my2c

Ответ 4

Когда вы используете shebang в Linux, вся остальная часть строки после имени интерпретатора интерпретируется как один аргумент. python -u передается env, как если бы вы набрали: /usr/bin/env 'python -u'. /usr/bin/env ищет двоичный файл с именем python -u, который не существует.

Ответ 5

Вот альтернатива /usr/bin/env script, которая позволяет передавать аргументы в строке hash-bang на основе /bin/ bash и с ограничением на то, что пробелы запрещены в исполняемом пути, Я называю это "envns" (env No Spaces):

#!/bin/bash

ARGS=( $1 )  # separate $1 into multiple space-delimited arguments.
shift # consume $1

PROG=`which ${ARGS[0]}`
unset ARGS[0] # discard executable name

ARGS+=( "[email protected]" ) # remainder of arguments preserved "as-is".
exec $PROG "${ARGS[@]}"

Предполагая, что этот script находится в /usr/local/bin/envns, здесь ваша строка shebang:

#!/usr/local/bin/envns python -u

Протестировано на Ubuntu 13.10 и cygwin x64.

Ответ 6

Это kludge и требует bash, но он работает:

#!/bin/bash

python -u <(cat <<"EOF"
# Your script here
print "Hello world"
EOF
)

Ответ 7

Это может быть немного устаревшим, но env (1) manual говорит, что для этого можно использовать '-S'

#!/usr/bin/env -S python -u

Кажется, что на FreeBSD очень хорошо работает.

Ответ 8

Построение ответа Ларри Цая, env позволяет вам установить переменную непосредственно в командной строке. Это означает, что -u можно заменить эквивалентной установкой PYTHONUNBUFFERED до python:

#!/usr/bin/env PYTHONUNBUFFERED="YESSSSS" python

Работает на RHEL 6.5. Я почти уверен, что функция env - это всего лишь универсальная.

Ответ 9

Недавно я написал патч для версии GNU Coreutils env для решения этой проблемы:

http://lists.gnu.org/archive/html/coreutils/2017-05/msg00018.html

Если у вас есть это, вы можете сделать:

#!/usr/bin/env :lang:--foo:bar

env разделит :lang:foo:--bar на поля lang, foo и --bar. Он будет искать PATH для интерпретатора lang, а затем вызывать его с помощью аргументов --foo, bar, а также путь к аргументам script и script.

Существует также возможность передать имя script в середине параметров. Предположим, вы хотите запустить lang -f <thecriptname> other-arg, а затем остальные аргументы. С этим исправленным env он выполняется следующим образом:

#!/usr/bin/env :lang:-f:{}:other-arg

Левое поле, эквивалентное {}, заменяется первым следующим аргументом, который под вызовом hash bang является именем script. Затем этот аргумент удаляется.

Здесь other-arg может быть обработано lang или, возможно, что-то обработано script.

Чтобы лучше понять, просмотрите многочисленные тестовые примеры echo в патче.

Я выбрал символ :, потому что это существующий разделитель, используемый в PATH для POSIX-систем. Поскольку env выполняет поиск PATH, он вряд ли будет использоваться для программы, имя которой содержит двоеточие. Маркер {} поступает из утилиты find, которая использует его для обозначения вставки пути в командную строку -exec.