【问题标题】:Python - subprocess.Popen - ssh -t user@host 'service --status-all'Python - subprocess.Popen - ssh -t user@host 'service --status-all'
【发布时间】:2013-01-02 16:54:47
【问题描述】:

我已经阅读了很多示例,但没有一个适用于此特定任务。

Python 代码:

x = Popen(commands, stdout=PIPE, stderr=PIPE, shell=True)
print commands
stdout = x.stdout.read()
stderr = x.stderr.read()
print stdout, stderr
return stdout

输出:

[user@host]$ python helpers.py
['ssh', '-t', 'user@host', ' ', "'service --status-all'"]
 usage: ssh [-1246AaCfgKkMNnqsTtVvXxYy] [-b bind_address] [-c cipher_spec]
           [-D [bind_address:]port] [-e escape_char] [-F configfile]
           [-I pkcs11] [-i identity_file]
           [-L [bind_address:]port:host:hostport]
           [-l login_name] [-m mac_spec] [-O ctl_cmd] [-o option] [-p port]
           [-R [bind_address:]port:host:hostport] [-S ctl_path]
           [-W host:port] [-w local_tun[:remote_tun]]
           [user@]hostname [command]

为什么会出现这个错误? 使用 os.popen(...) 它可以工作,它至少可以执行,但我无法通过 SSH 隧道检索远程命令的输出。

【问题讨论】:

  • 输出表明您没有向命令传递足够/正确的参数。
  • 去掉空格项,去掉最后一个参数两边的单引号。
  • 顺便说一句,您是否使用公钥身份验证?还是密码认证?
  • 考虑使用paramiko / fabric
  • 不相关:使用stdout, stderr = x.communicate() 而不是stdout = x.stdout.read(); stderr = x.stderr.read()。如果commands 产生足够的输出,后者可能会导致死锁。另一种方法是使用不同的线程同时读取标准输出/标准错误使用selectfnctl模块(Unix)

标签: python linux ssh subprocess popen


【解决方案1】:

我认为你的命令列表是错误的:

commands = ['ssh', '-t', 'user@host', "service --status-all"]
x = Popen(commands, stdout=PIPE, stderr=PIPE)

此外,如果您要将列表传递给Popen,我认为您不应该传递shell=True

例如要么这样做:

Popen('ls -l',shell=True)

或者这个:

Popen(['ls','-l'])

但不是这个:

Popen(['ls','-l'],shell=True)

最后,还有一个方便的函数可以像你的 shell 一样将字符串拆分成一个列表:

import shlex
shlex.split("program -w ith -a 'quoted argument'")

将返回:

['program', '-w', 'ith', '-a', 'quoted argument']

【讨论】:

  • 我爱你!我想我已经尝试了一切,除了删除 ' 和 shell=True 的组合。我已经分别尝试了它们,但最终出现了错误,但是删除了这两个它都有效。 ()上帝(假装>)我喜欢人们在这里回答的速度..
  • 哦,不要对菜鸟问题无礼。因为我们中的一些人即使我们已经编写了 Python 10 年并且没有立即被选中,也会让大脑冻结,这给了我对人类的希望:) 所以,如果可以的话,我会给你更多的分数,以获得一个很好的答案! (还不能将您的答案标记为解决方案,1 分钟左右)
  • @mgilson 你能解释一下为什么有必要将单个命令分解成每个部分(以空格分隔)才能像这样传递它吗? commands = ['ssh', '-t', 'user@host', "service --status-all"]
  • 这就是 shell 通常为你做的事情。在 python 中,我们只是更明确一点。当然,根据字符串的不同,我们通常可以使用shlex.split 来拆分字符串,如果您愿意,我们可以使用 shell。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2010-10-30
  • 2014-12-01
  • 2023-03-09
  • 2012-11-08
  • 2011-06-25
  • 2016-02-26
相关资源
最近更新 更多