Как исправить флаги Шебанга, которые не распознаются в некоторых системах - PullRequest
8 голосов
/ 20 апреля 2011

По какой-то причине флаг -O (оптимизированный) не распознается в строке shebang на Red Hat Enterprise Server (выпуск 5.3), к которому я обращаюсь. В других системах флаг распознается без каких-либо проблем.

Выполнение приведенного ниже сценария в OS X работает нормально. Распознавание флага -O может быть проверено, потому что он разрешает (если отсутствует) или отключает (когда предоставляется) что-либо под условным условием if __debug__:

#!/usr/bin/env python -O                                                                                                                                                                       

if __name__ == '__main__':

    if __debug__:
        print 'lots of debugging output on'

    print 'Fin'

Выполнение того же сценария в системе RHE приводит к:

/ usr / bin / env: python -O: такого файла нет или каталог

Без флага -O скрипт нормально выполняется в системе RHE (т. Е. Встроенная переменная __debug__ будет установлена ​​на True).

Существует ли кроссплатформенный способ решения этой проблемы? Есть ли вообще платформенный способ исправить проблему флагов в строке shebang для интерпретатора python?

Редактировать: Любые другие обходные пути для установки переменной __debug__ (без использования флагов Шебанга) также будут интересны для всего интерпретатора.

Ответы [ 8 ]

4 голосов
/ 20 апреля 2011

Чтобы немного расширить сказанное unutbu , у вас есть возможность инициализировать PYTHONOPTIMIZE во время выполнения.Это работает для всех современных оболочек:

% PYTHONOPTIMIZE=1 foo.py
Fin

И для полноты:

% foo.py
lots of debugging output on
Fin
4 голосов
/ 20 апреля 2011

Некоторые системы не допускают множественных аргументов в строке стиля #!."Env hack" не является официально рекомендованным способом решения проблемы пути в любом случае - предпочтительным способом решения этой проблемы является переустановка строки #! для ссылки на /bin/python, /usr/bin/python, так какподходит для системы.

http://pubs.opengroup.org/onlinepubs/009695399/utilities/sh.html

3 голосов
/ 20 апреля 2011

Как насчет создания небольшого сценария оболочки:

pythono

#!/bin/sh    
/usr/bin/env python -O "$@"

Затем измените ваш скрипт на:

#!pythono       

Также обратите внимание, что установка переменной окружения PYTHONOPTIMIZE в непустую строку аналогична использованию флага -O. Со справочной страницы man python:

   PYTHONOPTIMIZE
          If this is set to a non-empty string it is equivalent to  specifying  the
          -O option. If set to an integer, it is equivalent to specifying -O multi‐
          ple times.
1 голос
/ 29 января 2012

Пожалуйста, попробуйте это:

#!/bin/sh
''''exec python -O -- "$0" ${1+"$@"} # '''
if __name__ == '__main__':

    if __debug__:
        print 'lots of debugging output on'

    print 'Fin'
# vi: syntax=python
0 голосов
/ 26 апреля 2018

Я считаю, что причина, по которой вы используете #!/usr/bin/env python, заключается в том, что вы можете использовать PATH, чтобы найти вашу любимую версию python.

Если это НЕ тот случай, и вы в порядке, используя /usr/bin/python (или какой-либо другой жестко закодированный путь к интерпретатору), то самым прямым решением должно быть использование #!/usr/bin/python -O, как предложено @ keith-thompson

Однако, если вы хотите продолжать полагаться на PATH, чтобы найти python, вам потребуется вызвать оболочку, чтобы получить контроль над командной строкой:

#!/bin/sh
exec python -O - "$@" <<EOF

# ... your python code starts here ...
if __name__ == '__main__':

    if __debug__:
        print 'lots of debugging output on'

    print 'Fin'
# ... your python code ends here ...

EOF

Это похоже на решение pythono, предложенное @unutbu, за исключением того, что оно не полагается на PATH при поиске промежуточного сценария, что означает, что он немного лучше работает и немного более безопасен.

Недостатком этого решения является смешивание двух языков, что означает, что вы не можете просто сказать python myscript.py, чтобы выполнить код с __debug__, установленным на True. Если вы собираетесь выполнять код иногда напрямую через скрипт (например, ~/bin/myscript.py) с включенным -O, но в других случаях запускать скрипт вручную в среде отладки (например, python ~/bin/myscript.py) с помощью -O выключен, тогда я считаю, что вам лучше всего использовать экспертные приемы, подобные предложению @ ade-yu, или использовать простой параметр pythono, предложенный @ unutbu.

Надеюсь, это поможет!

0 голосов
/ 12 мая 2016

Просто сделай свой шебанг без флага;затем снова запустите среду с флагом, передавшим его в heredoc.

#!/usr/bin/env python

/usr/bin/env python -O <<EOF
code goes here...
...
EOF

В основном ваш завершающий EOF находится в конце файла.

0 голосов
/ 22 июля 2014

Предполагая, что вы хотите продолжать использовать #!/usr/bin/env, вы можете воспользоваться тем, что

  1. python имеет эквиваленты переменных среды для своих ключей командной строки
  2. env может использоваться для установки переменных среды перед выполнением команды

Соединяя их, вы получаете следующее решение:

#!/usr/bin/env PYTHONOPTIMIZE=1 python

Вы запросили«кросс-платформенный».Это работает только для Unix (например, Linux, OS X и т. Д.).Я не могу говорить за Windows.Я ожидаю, что это будет работать и под cygwin, но с YMMV.

0 голосов
/ 29 января 2012

Измените shebang на:

#!/usr/bin/python -O

Это, конечно, предполагает, что интерпретатор Python установлен как /usr/bin/python;в противном случае настройте при необходимости.

См. также этот вопрос и мой ответ на него .

...