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

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

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

Какие у меня варианты?

9 ответов

Решение

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

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

export PYTHONUNBUFFERED=1
script.py

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

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

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

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

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

Похоже, что работает довольно хорошо на FreeBSD.

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

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

my2c

Вот сценарий, альтернативный / usr / bin / env, который позволяет передавать аргументы в строке 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+=( "$@" ) # remainder of arguments preserved "as-is".
exec $PROG "${ARGS[@]}"

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

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

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

Это кладжа и требует bash, но он работает:

#!/bin/bash

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

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

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

Работает на RHEL 6.5. Я уверен, что эта особенность env почти универсальный.

Недавно я написал патч для версии 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плюс путь к сценарию и аргументы этого сценария.

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

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

Крайнее левое поле, которое эквивалентно {} заменяется следующим первым аргументом, который при вызове хэш-взрыва является именем скрипта. Этот аргумент затем удаляется.

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

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

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

Другие вопросы по тегам