Невозможно передать аргумент 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
командная строка.