我尝试寻找答案已有一段时间,但到目前为止,对于我的具体情况,我没有找到任何东西。我想在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'
如何将这个选项传递给我的命令?
最佳答案
您的SSH命令包含无效参数:ProxyCommand
是一个选项,因此需要在它前面加上-o
,与ConnectTimeout
相同(并且,如Charles Duffy所述,该选项字符串中的多余引号需要删除,因为该命令不是传递给 shell ):
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
中手动引用了要传递给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 报价一起使用,例如嵌套命令调用时。
关于python - 在python中的选项中使用空格运行子进程,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/63940560/