为了账号安全,请及时绑定邮箱和手机立即绑定

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

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

慕盖茨4494581 2023-08-15 16:49:34
我尝试寻找答案一段时间,但到目前为止我还没有找到适合我的具体情况的任何内容。我想在 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 subprocessserver_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'我怎样才能将此选项传递给我的命令?
查看完整描述

1 回答

?
斯蒂芬大帝

TA贡献1827条经验 获得超8个赞

您的 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 引用的嵌套级别,例如,当嵌套命令调用时。


查看完整回答
反对 回复 2023-08-15
  • 1 回答
  • 0 关注
  • 97 浏览
慕课专栏
更多

添加回答

举报

0/150
提交
取消
意见反馈 帮助中心 APP下载
官方微信