Как я могу использовать SSH с печатью Python? - PullRequest
0 голосов
/ 13 мая 2018

Я хотел бы запустить SSH с печатью Python. Ниже приведены мои тестовые коды.

import subprocess

# case1:
command_str = "\"print(\'test\')\""

# case 2:
# command_str = "\\\"print(\'test\')\\\""

ssh_command = ['ssh', 'USER_X@localhost', 'python', '-c']
ssh_command.append(command_str)
process = subprocess.run(ssh_command, stdout=subprocess.PIPE)
print(process.stdout)

вариант 1 и вариант 2 не работают. Выходы следующие,

вариант 1:

bash: -c: line 0: syntax error near unexpected token `('
bash: -c: line 0: `python -c print('test')'
b''

дело 2:

bash: -c: line 0: syntax error near unexpected token `('
bash: -c: line 0: `python -c \"print('test')\"'
b''

Пожалуйста, дайте мне знать, как это работает.

Ответы [ 2 ]

0 голосов
/ 13 мая 2018

Должно работать с

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.И эта утилита заботится обо всех кавычках и выходах за пределы этого для удаленной оболочки.

0 голосов
/ 13 мая 2018

Правильный синтаксис для python 2 и 3 :

python -c 'print("test")'

enter image description here

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