Ответ 1
Лучше использовать переменную окружения, чтобы включить это. См. Документ python: http://docs.python.org/2/using/cmdline.html
для вашего случая:
export PYTHONUNBUFFERED=1
script.py
Мне нужно было иметь прямо исполняемый 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
.
Каковы мои варианты?
Лучше использовать переменную окружения, чтобы включить это. См. Документ python: http://docs.python.org/2/using/cmdline.html
для вашего случая:
export PYTHONUNBUFFERED=1
script.py
В некоторой среде env не разделяет аргументы. Итак, ваш env ищет "python -u" на вашем пути. Мы можем использовать sh для работы. Замените свой shebang следующими строками кода, и все будет хорошо.
#!/bin/sh
''''exec python -u -- "$0" ${1+"[email protected]"} # '''
# vi: syntax=python
p.s. нам не нужно беспокоиться о пути к sh, правильно?
Передача аргументов в строку shebang не является стандартной и, поскольку вы экспериментировали, не работают в сочетании с env в Linux. Решение с bash заключается в использовании встроенной команды "set" для установки необходимых параметров. Я думаю, вы можете сделать то же самое, чтобы установить небуферизованный вывод stdin с помощью команды python.
my2c
Когда вы используете shebang в Linux, вся остальная часть строки после имени интерпретатора интерпретируется как один аргумент. python -u
передается env
, как если бы вы набрали: /usr/bin/env 'python -u'
. /usr/bin/env
ищет двоичный файл с именем python -u
, который не существует.
Вот альтернатива /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.
Это kludge и требует bash, но он работает:
#!/bin/bash
python -u <(cat <<"EOF"
# Your script here
print "Hello world"
EOF
)
Это может быть немного устаревшим, но env (1) manual говорит, что для этого можно использовать '-S'
#!/usr/bin/env -S python -u
Кажется, что на FreeBSD очень хорошо работает.
Построение ответа Ларри Цая, 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
, а также путь к аргументам 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
.