python - Paramiko 的 Read 方法都不适合我?

标签 python fabric paramiko

我有我写的这个类:

class Remote(object):
    def __init__(self, address, username, password):
        self.address  = address
        self.username = username
        self.password = password

    def stdout(self, s):
        print('out: ' + s)

    def stderr(self, s):
        print('err: ' + s)

    def sh(self, s):
        from paramiko  import AutoAddPolicy, SSHClient
        from threading import Thread
        from time      import sleep

        ssh = SSHClient()
        ssh.set_missing_host_key_policy(AutoAddPolicy())
        ssh.connect(self.address, username = self.username, password = self.password)
        stdin, stdout, stderr = ssh.exec_command(s)

        def monitor(channel, method):
            while True:
                for line in channel.readlines():
                    method(line)
                sleep(1)

        Thread(target = monitor, args = (stdout, self.stdout)).start()
        Thread(target = monitor, args = (stderr, self.stderr)).start()

然后我试着像这样运行它:

>>> from remote import Remote
>>> address  = <removed>
>>> username = 'root'
>>> password = <removed>
>>> r = Remote(address, username, password)
>>> r.sh('echo Hello')

我没有得到任何输出。如果我改变周围的监控方法,而不是:

for line in channel.readlines():
    method(line)

我只有 method(channel.read())method(channel.readline()),但在那种情况下,我只看到:

out:
err:

每秒一次 - 它实际上从未给我预期的结果:

out: Hello

我知道我的地址、用户名和密码都是正确的,因为我可以将它们输入 fabric 就好了。

>>> from fabric.api        import env
>>> from fabirc.operations import sudo
>>> env.host_string, env.user, env.password = address, username, password
>>> sudo('echo Hello')
[<omitted>]: Hello

我在基于 paramiko 的类中做错了什么,fabric 显然能够处理?

编辑

我希望该方法是异步的。它应该立即返回。例如,如果我这样做:

r1 = Remote(<one set of credentials removed>)
r2 = Remote(<another set of credentials removed>)
r1.sh('echo Hello; sleep 5; echo World')
r2.sh('echo Hello; sleep 5; echo World')

那么结果应该是:

out: Hello
out: Hello
out: World
out: World

表明这两个调用是并行运行的,而不是:

out: Hello
out: World
out: Hello
out: World

这表明这两个调用是同步运行的。

最佳答案

问题是 monitor 中的 while True 循环阻止线程结束。保留第一部分不变并将最后几行更改为:

def monitor(channel, method):
    while True:
        l = channel.readline()
        if l:
            method(l)
        else:
            break
tout = Thread(target = monitor, args = (stdout, self.stdout))
terr = Thread(target = monitor, args = (stderr, self.stderr))
tout.start()
terr.start()
tout.join()
terr.join()
ssh.close()

将逐行打印给定命令行的输出,同时有一些东西要返回。

关于python - Paramiko 的 Read 方法都不适合我?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/36780291/

相关文章:

python - 使用 Itertools 从多个列表中创建元素组合列表

python - 刚开始编写 Fabric 文件来安装包

python - 只有 pwd 命令在 Paramiko 中成功,其他命令失败并显示 "ksh: ...: cannot execute - No such file or directory"

python - 防止 Paramiko 退出

python - 返回文件或目录未找到,但 bash 命令中未提及文件或目录?

python - 用于命令行输入/输出的 GUI 界面

python - tf.keras.losses 中 "BinaryCrossentropy"和 "binary_crossentropy"的区别?

python - 在 Python 3.3 中是否有一种漂亮的 yield 方法?

python - 织物与预期

python - Conda activate env 适用于 bash 但不适用于结构