Должно работать с
command_str = "'print(\"test\")'"
или эквивалентно
command_str = '\'print("test")\''
Объяснение
Самые внешние кавычки и экранирование предназначены для локального Python.Таким образом, в любом случае локальной строкой Python будет 'print("test")'
.
. Для локальной оболочки нет необходимости в кавычках или экранировании, поскольку subcommand.run(...)
не вызовет ее, если не будет передано shell=True
.
Таким образом, одинарные кавычки в строке Python предназначены для удаленной оболочки (предположительно bash
или другой sh
-совместимой оболочки).Таким образом, аргумент, передаваемый удаленному Python, равен print("test")
.(И двойные кавычки здесь означают строковый литерал для печати на удаленном питоне.)
Можем ли мы обойтись без экранирования (без \
)?
Поскольку существует три уровняучаствует (локальный Python, удаленная оболочка, удаленный Python), я так не думаю.
Можем ли мы сделать с одним типом кавычек?
Да, с немного большим количеством экранирования.Давайте построим это сзади (или изнутри).
Мы хотим напечатать
test
Это необходимо экранировать для удаленного Python (чтобы сформировать строковый литерал вместо идентификатора):
"test"
Вызовите это с помощью функции print()
:
print("test")
Довольно знакомо до сих пор.
Теперь мы хотим передать это в качестве аргументаpython -c
на sh
-подобной оболочке.Чтобы защитить (
и )
, которые будут интерпретироваться этим, мы цитируем все это.Чтобы уже существующее "
не заканчивало цитату, мы избегаем их:
"print(\"test\")"
Вы можете попробовать это в терминале:
$> echo "print(\"test\")"
print("test")
Perfect!
Теперь мы должны представить все это в (локальном) Python.Мы обертываем еще один слой кавычек вокруг него, чтобы избежать четырех (!) Существующих кавычек, а также двух обратных косых черт:
"\"print(\\\"test\\\")\""
(Готово. Это также можно использовать как command_str
.)
Можем ли мы сделать только одинарные кавычки ('
) и убежать?
Не знаю, но, по крайней мере, не так легко.Зачем?Потому что, кроме Python, двойные и одинарные кавычки не взаимозаменяемы с sh
и bash
: в одинарных кавычках эти оболочки принимают необработанную строку без экранирования до тех пор, пока не произойдет закрытие '
.
У меня болит мозг!
Если буквально, иди к врачу.Если фигурально, то да, мой тоже.И будущие читатели вашего кода (в том числе и вы сами), вероятно, почувствуют то же самое, когда попытаются распутать этот кавычки-лес.
Но в нашей любимой стандартной библиотеке Python есть безболезненная альтернатива !
import shlex
command_str = shlex.quote('print("test")')
Это гораздо проще понять.Внутренние кавычки (здесь двойные кавычки, но на самом деле это не имеет значения: shlex.quote("print('test')")
работает так же хорошо) предназначены для удаленного Python.Внешние кавычки, очевидно, для локального Python.И эта утилита заботится обо всех кавычках и выходах за пределы этого для удаленной оболочки.