如何在python的打印中使用ssh?

时间:2018-05-13 13:22:11

标签: python ssh

我想用python的print打开ssh。 以下是我的测试代码。

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 :(得分:2)

它应该与

一起使用
command_str = "'print(\"test\")'"

或等效

command_str = '\'print("test")\''

解释

最外层的引号和转义是针对本地Python的。因此,在任何一种情况下,本地Python字符串都是'print("test")'

本地shell不需要引用或转义,因为subcommand.run(...)除非shell=True通过,否则不会调用它。

因此python字符串中的单引号用于远程shell(可能是bash或其他sh - 兼容的shell)。传递给远程Python的参数因此是print("test")。 (并且那里的双引号表示要打印到远程python的字符串文字。)

我们可以不逃避(没有\)吗?

由于涉及三个级别(本地Python,远程shell,远程Python),我不这么认为。

我们可以使用单一类型的报价吗?

是的,稍微逃避一下。让我们从后面(或从里到外)构建它。

我们要打印

test

这需要为远程Python进行转义(以形成字符串文字而不是标识符):

"test"

使用print()功能调用此方法:

print("test")

到目前为止非常熟悉。

现在我们希望将此作为python -c的参数传递给sh - 就像shell一样。为了保护()被解释,我们引用了整个事情。对于已经存在的"不要终止引用,我们将它们转义:

"print(\"test\")"

您可以在终端中尝试:

$> echo "print(\"test\")"
print("test")

完美!

现在我们必须在(本地)Python中表示整个事物。我们在它周围包含另一层引号,必须转义四个(!)现有的引号以及两个反斜杠:

"\"print(\\\"test\\\")\""

(完成。这也可以用作command_str。)

我们可以只使用单引号(')和转义吗?

我不知道,但至少不那么容易。为什么?因为除了Python之外,双引号和单引号不能与shbash互换:在单引号内,这些shell假定原始字符串而不转义直到结束'发生。

我的大脑疼!

如果字面上看,去看医生。如果比喻,是的,我也是。当你的代码未来的读者(包括你自己)试图解开那个引用逃避的森林时,他们可能会有同样的感受。

但我们心爱的Python标准库中有painless alternative

import shlex

command_str = shlex.quote('print("test")')

这更容易理解。内部引号(这里是双引号,但实际上并不重要:shlex.quote("print('test')")工作得很好)适用于远程Python。外部引号显然适用于本地Python。除了远程shell之外的所有引用和转义都由此实用程序函数处理。

答案 1 :(得分:-1)

python 2 3 的正确语法为:

python -c 'print("test")'

enter image description here