如何通过SSH执行Python的print语句?求助解决调用失败问题
问题:通过SSH执行Python print语句失败,报语法错误
我试着用SSH远程执行Python的print语句,但试了两种写法都报错了,代码如下:
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)
两种情况的错误输出:
- case 1:
bash: -c: line 0: syntax error near unexpected token `(' bash: -c: line 0: `python -c print('test')' b''
- case 2:
bash: -c: line 0: syntax error near unexpected token `(' bash: -c: line 0: `python -c \"print('test')\"' b''
求正确的实现方法。
解决办法
咱们来捋清楚问题:其实就是本地和远程shell的引号转义冲突了,导致python -c没拿到完整的代码参数。远程bash需要把Python代码当成一个整体参数,但你的写法让bash把代码拆成了多个部分,自然就报语法错误了。这里有几个靠谱的实现方式:
方法一:用单引号包裹Python代码(推荐)
把Python代码用单引号括起来,同时转义内部的单引号,这样远程bash会把整个代码串当成一个参数传给Python。修改后的代码:
import subprocess # 用单引号包裹Python代码,内部的单引号用\'转义 command_str = "'print(\\'test\\')'" ssh_command = ['ssh', 'USER_X@localhost', 'python', '-c', command_str] # 加上text=True,直接返回字符串不用处理字节 process = subprocess.run(ssh_command, stdout=subprocess.PIPE, text=True) print(process.stdout.strip())
简单解释下:本地字符串'print(\\'test\\')'会被解析成'print(\'test\')',传到远程后,bash会把这个整个单引号包裹的内容作为一个参数给python -c,Python就能正确执行print('test')了。
方法二:用原始字符串+双引号包裹
如果觉得转义有点绕,用Python的原始字符串(r'')配合双引号包裹代码会更清晰,避免转义混乱:
import subprocess # 原始字符串,双引号包裹Python代码,内部单引号不用额外转义(原始字符串不处理反斜杠) command_str = r'"print(\'test\')"' ssh_command = ['ssh', 'USER_X@localhost', 'python', '-c', command_str] process = subprocess.run(ssh_command, stdout=subprocess.PIPE, text=True) print(process.stdout.strip())
这个写法里,原始字符串r'"print(\'test\')"'不会转义反斜杠,传到远程后bash会解析成"print('test')",Python能直接识别这个代码串。
方法三:构造完整命令字符串(不推荐)
要是你不想拆分命令列表,也可以直接写完整的命令字符串,用shell=True执行,但这种方式要注意更多转义问题,而且有shell注入的风险,尽量少用:
import subprocess ssh_command = "ssh USER_X@localhost python -c 'print(\\'test\\')'" process = subprocess.run(ssh_command, stdout=subprocess.PIPE, text=True, shell=True) print(process.stdout.strip())
核心要点
- 不管用哪种方法,核心都是要让远程的shell把Python代码完整地作为一个参数传给
python -c,所以必须用一层引号把代码包裹起来。 - 优先用前两种拆分命令列表的方式,安全性更高,也不容易出转义错误。
内容的提问来源于stack exchange,提问作者mora
相关产品推荐
相关产品推荐

