встраивание коротких скриптов Python в скрипт bash - PullRequest
49 голосов
/ 03 февраля 2010

Я хотел бы встроить текст коротких сценариев Python в сценарий bash, чтобы использовать, скажем, мой .bash_profile. Какой лучший способ сделать это?

Решение, которое я имею до сих пор, состоит в том, чтобы вызвать интерпретатор python с опцией -c и сообщить интерпретатору exec все, что он читает из stdin. Оттуда я могу создавать простые инструменты, подобные следующим, что позволяет мне обрабатывать текст для использования в моем интерактивном приглашении:

function pyexec() {
    echo "$(/usr/bin/python -c 'import sys; exec sys.stdin.read()')"
}

function traildirs() {
    pyexec <<END
trail=int('${1:-3}')
import os
home = os.path.abspath(os.environ['HOME'])
cwd = os.environ['PWD']
if cwd.startswith(home):
    cwd = cwd.replace(home, '~', 1)
parts = cwd.split('/')
joined = os.path.join(*parts[-trail:])
if len(parts) <= trail and not joined.startswith('~'):
    joined = '/'+joined
print joined
END
}

export PS1="\h [\$(traildirs 2)] % "

Хотя такой подход пахнет немного странно, и мне интересно, какие альтернативы для этого могут быть.

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

Ответы [ 9 ]

42 голосов
/ 03 февраля 2010

Зачем вам нужно использовать -c? Это работает для меня:

python << END
... code ...
END

без необходимости ничего дополнительного.

29 голосов
/ 03 февраля 2010

Интерпретатор python принимает - в командной строке как синоним для stdin, поэтому вы можете заменить вызовы pyexec на:

python - <<END

См. Ссылку на командную строку здесь .

14 голосов
/ 12 октября 2015

Одна проблема с использованием bash here document заключается в том, что сценарий затем передается в Python на stdin, поэтому, если вы хотите использовать сценарий Python в качестве фильтра, он становится громоздким.Одна альтернатива - использовать bash process substitution, что-то вроде этого:

... | python <( echo '
code here
' ) | ...

Если сценарий слишком длинный, вы также можете использовать here document внутри парена, например так:

... | python <(
cat << "END"
code here
END
 ) | ...

Внутри скрипта вы можете читать / писать, как обычно, с / на стандартный ввод / вывод (например, sys.stdin.readlines, чтобы сожрать весь ввод).

Также,python -c можно использовать, как уже упоминалось в других ответах, но вот как мне нравится делать это, чтобы красиво отформатировать, сохраняя при этом правила отступов Python ( credits ):

read -r -d '' script <<-"EOF"
    code goes here prefixed by hard tab
EOF
python -c "$script"

Просто убедитесь, что первый символ каждой строки внутри документа является жесткой вкладкой.Если вам нужно поместить это внутри функции, то я использую нижеприведенный трюк, который я где-то видел, чтобы он выглядел выровненным:

function somefunc() {
    read -r -d '' script <<-"----EOF"
        code goes here prefixed by hard tab
----EOF
    python -c "$script"
}
7 голосов
/ 27 августа 2015

Иногда не рекомендуется использовать здесь документ.Другой альтернативой является использование python -c:

py_script="
import xml.etree.cElementTree as ET,sys
...
"

python -c "$py_script" arg1 arg2 ...
7 голосов
/ 24 декабря 2013

Если вам нужно использовать вывод python в скрипте bash, вы можете сделать что-то вроде этого:

#!/bin/bash

ASDF="it didn't work"

ASDF=`python <<END
ASDF = 'it worked'
print ASDF
END`

echo $ASDF
5 голосов
/ 01 августа 2016

Пример копирования-вставки с вводом:

input="hello"
output=`python <<END
print "$input world";
END`

echo $output
2 голосов
/ 03 февраля 2010

Интересно ... Я тоже хочу ответ; -)

Он не спрашивает, как выполнить код Python в скрипте bash, но на самом деле имеет переменные окружения, установленные в python.

Поместите это в скрипт bash и попытайтесь заставить его сказать "это сработало".

export ASDF="it didn't work"

python <<END
import os
os.environ['ASDF'] = 'it worked'
END

echo $ASDF

Проблема в том, что питон выполняется в копии окружения. Никаких изменений в этой среде не видно после выхода из Python.

Если есть решение для этого, я бы тоже хотел его увидеть.

1 голос
/ 20 июня 2017

Попробуйте это:

#!/bin/bash
a="test"
python -c "print  '$a this is a test'.title()"
0 голосов
/ 04 апреля 2014

Если вы используете zsh, вы можете встроить Python в скрипт, используя zsh's join и параметр python stdin (python -):

py_cmd=${(j:\n:)"${(f)$(
    # You can also add comments, as long as you balance quotes
    <<<'if var == "quoted text":'
    <<<'  print "great!"')}"}

catch_output=$(echo $py_cmd | python -)

Вы можете сделать отступ для фрагмента Python,поэтому внутри функций он выглядит лучше, чем решения EOF или <<END.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...