【问题标题】:send remote shell command and retrieve its output发送远程 shell 命令并检索其输出
【发布时间】:2014-11-19 11:15:44
【问题描述】:

因为我找不到执行以下操作的库,所以我开始着手编写自己的库。不过,我无法找到一些问题的解决方案,希望在这里也许有人有建议。

我想要的是这个。我发送了一个普通的 shell 命令,如ls -al <some path>,我希望它的输出(stdout 和 stderr)以与编写该命令时出现在终端仿真器中相同的方式和顺序。问题是,我不想在我当前使用的计算机上运行这个 shell 命令,而是通过 ssh 或串行连接远程运行。换句话说,在调用ls -al <some path> 2>&1 >/tmp/out时,我想远程接收/tmp/out的内容,不中断也不改变。

问题在于,始终使用串行连接,使用 ssh 连接取决于您选择的库,您会在输出中混入像 \x1b[K 这样的终端命令字符。我目前无法找到究竟是什么在创建这些命令,为什么没有任何东西已经在使用它们,而且我也不知道我将如何自己使用它们(有很多,天真的方法行不通) .

为什么在输出中获取特殊字符会出现问题?如果输出有一个字符串ala if expected_output == output,或者至少使用正则表达式,你经常想在你的python代码中进行比较。但是这些角色出现的时间和原因并没有什么规律。有时像ls -al <something> 这样的非常简单的命令可能会导致整个 ssh 连接中断(可能是因为这些字符,但至少可以肯定,因为我对这一切的了解还不够,甚至无法理解问题所在)。

您将如何解决远程发送命令并接收其输出的最终目标?您将如何解决其中一个提到的子问题(ssh 连接对我来说就像我是一个终端一样,消耗随机出现的特殊字符而不解释它们等)?

PS:我已经尝试过很多东西,但是在写作时我发现它们太多了,无法在此处一一列举。但是,没有任何结果会导致理想的最终结果。这确实是一个非常复杂的问题,特别是因为似乎涉及的事情是不可追溯的(例如实际涉及多少(伪)终端),而其他一些则从未被记录(一些终端处理似乎来自某个时间) ,其中一台实际的打字机连接到计算机)。

【问题讨论】:

    标签: python python-2.7 terminal


    【解决方案1】:

    你已经有了这种类型的库。试试

    Pexpect.

    您只需要通过 ssh 连接到您要连接的计算机来生成一个 pexpect 孩子。然后您可以使用.before 功能发送命令并查看输出。

    例子:

    child = pexpect.spawn('ssh admin@192.168.33.40')
    child.expect ('Password:')
    child.sendline (mypassword)
    child.expect('#') # or expect `$`.
    child.sendline('<your command>')
    child.expect('#')
    print child.before
    

    参考:http://pexpect.sourceforge.net/pexpect.html

    P.S 还有Paramiko,虽然我没用过。

    【讨论】:

    • 嗨,是的,这就是我对 pexpect 的期望。但它并没有摆脱命令字符。 Have a look here
    • @erikb85 你知道你发送的命令。检索它后用empty string 替换它是一项简单的任务。简单的str.replace()。
    • 如果只有一个这样的东西。有很多,它们是不同的,它们来自随机的地方。
    • @erikb85 一个简单的对.before 的包装器就可以解决问题。而且解决问题比编写整个库要容易得多。
    • 也许你是对的。也许我只需要使用list of definitions 并将它们全部替换为空字符串。但是,代码和解释各不相同。我希望有一个通用工具可以为所有可能的终端类型做到这一点。