Этот ответобсуждает, как запустить многострочный фрагмент Python из командной строки в терминале. Я заметил, что ответ отлично работает в скриптах оболочки, даже с вложенными отступами, что очень хорошо, например
#!/bin/bash
some_text="Hello world"
echo $some_text
cat <<EOF | python -
import sys;
for r in range(3):
print r
for a in range(2):
print "hello"
EOF
отпечатки:
0
hello
hello
1
hello
hello
2
hello
hello
Однако у меня возникли трудности с разделением переменных между скриптом оболочки и фрагментом Python.
Как собрать вывод скрипта Python в скрипте Bash? (например, в переменной, такой как
$output
).Как передать переменную bash (например
$some_text
, ) в скрипт Python?
решение1
Получение переменной в Python
Поскольку (когда EOF
маркер не заключен в кавычки) подстановка переменных происходит до того, как текст передается из heredoc в python
стандартный ввод, вы можете вставить переменную прямо в скрипт.
python - <<EOF
some_text = "$some_text"
EOF
Если some_text
было test
, python увидел бы some_text = "test"
. Однако следует отметить, что это можно рассматривать как уязвимость внедрения кода. Если some_text
было "; import os; os.system("evil-command"); x = "
, например, python увидел бы:
some_text = ""; import os; os.system("evil-command"); x = ""
и выполнить эту злую команду.
Если вы хотите иметь возможность вставить свой код Python прямо в скрипт без каких-либо изменений, вы можете экспортировать свою переменную.
export some_text
и используйте os.environ
для его извлечения.
some_text = os.environ['some_text']
Это гораздо более разумный и безопасный подход.
Получение вывода из Python
Для сбора выходных данных скрипта можно использовать подстановку команд.
output=$(
python - <<EOF
import sys;
for r in range(3):
print r
for a in range(2):
print "hello"
EOF
)
(обратите внимание, что все конечные символы новой строки удаляются)
решение2
Проблема вашего подхода в том, что встроенный скрипт Python больше не имеет доступа к исходному stdin (поскольку его stdin — это... он сам).
Если это проблема, вы можете написать:
python -c '
import sys;
for r in range(3):
print r
for a in range(2):
print "hello"
'
Или если скрипт Python может содержать одинарные кавычки:
python -c "$(cat << 'EOF'
import sys;
for r in range(3):
print r
for a in range(2):
print "hello"
EOF
)"
Или:
python <(cat << 'EOF'
import sys;
for r in range(3):
print r
for a in range(2):
print "hello"
EOF
)
решение3
Используйте тире в качестве имени файла:
ruby - a b <<'END'
puts ARGV.join(",")
END
python - a b <<'END'
import sys
print ",".join(sys.argv[1:])
END
Я не знаю, sys.argv[1:]
правильно ли это сделать в Python. Для -e / -c вы можете указать конец аргументов с помощью --:
set -- -a -b -c
ruby -e 'puts ARGV.join(",")' -- "$@"
python -c 'import sys; print ",".join(sys.argv[2:])' -- "$@"
Захват вывода и перенаправление STDERR:
x=$(ruby <<'END' 2> /dev/null
puts "a"
abort "b"
END
)
решение4
1) Вы можете написать присваивание переменных файлу на Python, а затем передать это в свой скрипт Bash.
2) Поскольку ваше слово (EOF) не заключено в кавычки, все строки here-document подвергаются расширению параметров. Вы можете использовать это для передачи чего-либо в скрипт python.