Подтвердить что ты не робот

Встраивание короткого python script s внутри bash script

Я хотел бы вставить текст коротких скриптов python внутри bash script, для использования в say, my .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.

4b9b3361

Ответ 1

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

python - <<END

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

Ответ 2

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

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

не требуя ничего лишнего.

Ответ 3

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

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

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

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

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

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

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"
}

Ответ 4

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

#!/bin/bash

ASDF="it didn't work"

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

echo $ASDF

Ответ 5

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

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

python -c "$py_script" arg1 arg2 ...

Ответ 6

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

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

echo $output

Ответ 7

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

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

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

export ASDF="it didn't work"

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

echo $ASDF

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

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

Ответ 8

Попробуйте следующее:

#!/bin/bash
a="test"
python -c "print  '$a this is a test'.title()"

Ответ 9

Если вы используете zsh, вы можете встроить Python внутри script, используя zsh 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, когда внутри функций.