简体   繁体   English

卡在 fork 中的 os.read()

[英]getting stuck at os.read() inside a fork

I have used the code below to create a child process, get inside an ssh container run a command inside the child and get its output.我使用下面的代码创建了一个子进程,进入 ssh 容器,在子进程中运行命令并获取其 output。

import os
import pty

def wall(host, pw):
    pid, fd = pty.fork()
    if pid == 0: # Child
        os.execvp('ssh', ['ssh', host, 'ls', '/usr/bin/wall'])
        os._exit(1) # fail to execv

    # read '..... password:', write password
    os.read(fd, 1024)
    os.write(fd, pw + '\n')

    result = []
    while True:
        try:
            #time.sleep(1)
            data = os.read(fd, 1024)
        except OSError:
            break
        if not data:
            break
        result.append(data)
    pid, status = os.waitpid(pid, 0)
    #pid, status = os.waitpid(pid,os.WNOHANG)
    return status, ''.join(result)

status, output = wall('localhost', "secret")
print status
print output

Even though this works the first time you call wall() (or sometimes the first few times you call wall()), if you call wall() again it gets stuck at data=os.read(fd,1024) or at os.waitpid(pid,0).即使这在您第一次调用 wall() 时有效(或者有时在您调用 wall() 的前几次),如果您再次调用 wall(),它会卡在 data=os.read(fd,1024) 或 os .waitpid(pid,0)。 Is there any solution to this working everytime I call wall().每次我调用 wall().

Note: I'm not allowed to use external libraries like pexpect, paramiko etc.注意:我不允许使用 pexpect、paramiko 等外部库。

Perhaps sometimes os.read doesn't wait for the password prompt.也许有时 os.read 不会等待密码提示。 In that case only two options:在这种情况下,只有两种选择:

  • Use a specialized package for connecting by ssh;使用专用的 package 通过 ssh 连接; for example How to make ssh connection with python例如如何使 ssh 与 python 连接
  • Parse the output and pass the password only after prompt.解析 output 并在提示后才传递密码。 Try to debug the first call of os.read;尝试调试 os.read 的第一次调用; probably that will clarify unstable behavior.可能这将澄清不稳定的行为。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM