猿问

在 python 中运行选项中带有空格的子进程

我尝试寻找答案一段时间,但到目前为止我还没有找到适合我的具体情况的任何内容。我想在 python 中运行命令:


ssh -o ConnectTimeout=3 -o ProxyCommand="ssh -q -W %h:%p bastion.host.com" host.com  "screen -dmS TEST /bin/bash --login -c 'yes | script.sh --option-1 value1 -option2 value2 2>&1 | tee output.log'"

这是我的代码:


import subprocess


server_command = "screen -dmS TEST /bin/bash --login -c 'yes | script.sh --option-1 value1 -option2 value2 2>&1 | tee output.log'"

command = ['ssh', '-o', 'ConnectTimeout=3', 'ProxyCommand="ssh -q -W %h:%p bastion.host.com"', 'host.com', server_command]

    

p = subprocess.Popen(command, stdin=None, stdout=subprocess.PIPE, stderr=subprocess.PIPE, shell=False)

stdout, stderr = p.communicate(input=None)

一切正常(屏幕在脚本运行时生成),直到我添加带有空格的选项:ProxyCommand="ssh -q -W %h:%p bastion.host.com"。


之后我收到错误:


>>> print(stderr)

b'ssh: Could not resolve hostname ProxyCommand="ssh -q -W %h:%p bastion.host.com": Name or service not known\r\n'

我怎样才能将此选项传递给我的命令?


慕盖茨4494581
浏览 99回答 1
1回答

斯蒂芬大帝

您的 SSH 命令包含无效参数:ProxyCommand是一个选项,因此需要在它前面加上-o,与ConnectTimeout(并且,正如 Charles Duffy 所指出的,需要删除该选项字符串内的冗余引号,因为该命令不会传递给壳):server_command = 'screen -dmS TEST /bin/bash --login -c \'yes | script.sh --option-1 value1 -option2 value2 2>&1 | tee output.log\''command = ['ssh', '-o', 'ConnectTimeout=3', '-o', 'ProxyCommand=ssh -q -W %h:%p bastion.host.com', 'host.com', server_command]一般来说,当您的命令行包含空格和/或引号并传递给另一个命令时,可能需要对它进行 shell 引用。Python 函数shlex.quote可以自动执行此操作。screen在您的情况下,这是没有必要的,因为您(正确地)手动引用了您传递给inside 的命令server_command。或者,您也可以编写以下内容:script_command = 'yes | script.sh --option-1 value1 -option2 value2 2>&1 | tee output.log'server_command = f'screen -dmS TEST /bin/bash --login -c {shlex.quote(script_command)}'— 请注意 shell 命令行内没有手动引号。相对于手动引用的优点是,这也适用于 shell 引用的嵌套级别,例如,当嵌套命令调用时。
随时随地看视频慕课网APP

相关分类

Python
我要回答