Как может я переменные условий применения в моей хижине?

Это технически что cat ("конкатенируйте"), как предполагается, делает, даже при том, что большинство людей просто использует его для вывода файлов к stdout. Если Вы дадите ему несколько имен файлов, то это произведет их всех последовательно, и затем можно перенаправить это в новый файл; в случае всех файлов просто используют * (или /path/to/directory/* если Вы уже не находитесь в каталоге), и Ваша оболочка развернет его до всех имен файлов

$ cat * > merged-file
34
20.02.2012, 03:45
6 ответов

Строка хижины очень ограничена. Под многими вариантами Unix (включая Linux), у Вас может быть только два слова: команда и отдельный аргумент. Существует также часто ограничение длины.

Общее решение состоит в том, чтобы записать маленькую обертку оболочки. Назовите сценарий Python foo.py, и помещенный сценарий оболочки рядом с foo.py и назовите его foo. Этот подход не требует никакого конкретного заголовка на сценарии Python.

#!/bin/sh
exec "$FOO/bar/MyCustomPython" "$0.py" "$@"

Другой заманчивый подход должен записать сценарий обертки как тот выше и поместить #!/path/to/wrapper/script как строка хижины на сценарии Python. Однако большинство нельдов не поддерживает объединение в цепочку сценариев хижины, таким образом, это не будет работать.

Если MyCustomPython был в $PATH, Вы могли использовать env искать его:

#!/usr/bin/env MyCustomPython
import …

Еще один подход должен принять меры, чтобы сценарий был оба действительным сценарием оболочки (который загружает правильный интерпретатор Python на себе), и действительный сценарий на выходном языке (здесь Python). Это требует, чтобы Вы нашли способ записать такой сценарий двойного языка для Вашего выходного языка. В Perl это известно как if $running_under_some_shell.

#!/bin/sh
eval 'exec "$FOO/bar/MyCustomPerl" -wS $0 ${1+"$@"}'
    if $running_under_some_shell;
use …

Вот один способ достигнуть того же эффекта в Python. В оболочке, "true" true утилита, которая игнорирует ее аргументы (две односимвольных строки : и ') и возвращает истинное значение. В Python, "true" строка, которая верна при интерпретации как булевская переменная, таким образом, это if инструкция это всегда верно и выполняет строковый литерал.

#!/bin/sh
if "true" : '''\'
then
exec "$FOO/bar/MyCustomPython" "$0" "$@"
exit 127
fi
'''
import …

Код Rosetta имеет такие сценарии двойного языка на нескольких других языках.

29
27.01.2020, 19:37
  • 1
    @Chris: все - внутренние одинарные кавычки. Объясните … –  Stéphane Gimenez 17.09.2011, 04:17
  • 2
    Вы - кровавый мастер... Здорово. Я использовал это для редактирования PYTHONPATH огибающая переменная к загрузочным модулям от нестандартного местоположения для сценария CGI в системе у меня не было корневого доступа к. Жизненное средство сохранения. Еще раз спасибо. –  wspurgin 16.02.2016, 23:00

Строки хижины не подвергаются переменному расширению, таким образом, Вы не можете использовать $FOO/MyCustomPython поскольку это искало бы исполняемый файл, названный dollar-F-O-O-...

Альтернатива должна иметь Вашу точку хижины к сценарию оболочки как интерпретатор, и этот сценарий оболочки может затем использовать переменные среды для определения местоположения корректной и должностного лица это.

Пример: создайте a mypython.sh сценарий в /usr/local/bin (или любой другой каталог на Вашем $PATH), со следующим содержанием:

#! /bin/sh
PYTHON="$FOO/bar/MyCustomPython"
exec "$PYTHON" "$@"

затем можно использовать эту строку хижины, чтобы выполнить сценарий Python через MyCustomPython через mypython.sh:

#!/usr/bin/env mypython.sh
12
27.01.2020, 19:37
  • 1
    Использовать $python, нет $PYTHON - условно, мы используем для своей выгоды переменные среды (ПЕЙДЖЕР, РЕДАКТОР, ОБОЛОЧКА... $PYTHON в Вашем сценарии не переменная среды), и внутренние переменные оболочки (BASH_VERSION, СЛУЧАЙНЫЙ...). Все другие имена переменной должны содержать по крайней мере одну строчную букву. Эта конвенция старается не случайно переопределять переменные окружения и внутренние переменные. Кроме того, не используйте расширения для своих сценариев. Сценарии определяют новые команды, которые можно выполнить, и командам обычно не дают расширения. –  Chris Down 16.09.2011, 21:20

Можно или использовать полный путь для пользовательской установки Python, или можно вставить его Ваш $PATH и используйте #!/usr/bin/env [command]. Иначе запишите обертку для него и использование exec заменять образ процесса, как пример:

#!/bin/bash
exec "$ENV/python" "$@"
4
27.01.2020, 19:37

Во-первых, определите, как Ваша версия Python отличается от стандартного Python, уже установленного (например, дополнительный модуль) и затем в начале программы 'переключатель', как Python называют:

#!/usr/bin/python
import os
import sys
try:
    import MyCustomModule
except ImportError:
    # only need to use expandvar if you know the string below has an envvar
    custprog = os.path.expandvar("$FOO/bar/MyCustomPython")
    os.execv(custprog, sys.argv) # call alternate python with the same arguments
    raise SystemExit('could not call %s' % custprog)
# if we get here, then we have the correct python interpreter

Это должно позволить программе быть названной любым другим экземпляром Python. Я делаю что-то подобное для экземпляра со встроенной sql библиотекой, которая не может быть импортирована как модуль в Python системы.

3
27.01.2020, 19:37

Если можно заменить $FOO в $FOO/bar/MyCustomPython с конкретными опциями пути можно сказать env строка хижины, где искать Вашу пользовательскую версию Python путем прямой установки пользовательского PATH в нем.

#!/usr/bin/env PATH="/path1/to/MyCustomPython:/path2/to/MyCustomPython" python

Править: Кажется, работает только без кавычек вокруг присвоения значения ПУТИ:

#!/usr/bin/env PATH=/path1/to/MyCustomPython:/path2/to/MyCustomPython python
0
27.01.2020, 19:37
  • 1
    Остерегайтесь этого, это не работает над всеми вариантами Unix (например, не над Linux). И Вы удаляете все существующие каталоги из пути, который, вероятно, вызовет проблемы по линии. –  Gilles 'SO- stop being evil' 17.09.2011, 23:52
  • 2
    Лучше расширьтесь PATH как это: PATH=$PATH:/path/to/whatever... –  Bengt 26.06.2014, 15:17

Я использую этот трюк. Может быть, это может быть полезно для кого-то.

В моем сценарии у каждого пользователя есть собственная среда Python в~/.envs/arqansible/bin/python

Сценарий Python, который необходимо запустить пользователям, называется resource_rundeck.py, а его шебанг — :

.
#!/usr/bin/env python

Итак, что я делаю, так это создаю вспомогательный скрипт с именем resource_rundeckв bash, как следующий:

#!/bin/bash
source ~/.envs/arqansible/bin/activate
exec "$0.py" "$@"
0
30.11.2021, 10:04

Теги

Похожие вопросы