2016-12-21 12 views
0

ssh接続のstdoutからチャンク内のデータを取得し、各チャンクの最後に一致するパターンをチェックし、stdin経由で適切な応答を返す作業コードがあります。Pythonのサブプロセスのようなpexpectの機能

ssh = paramiko.SSHClient() 
... 
transport = ssh.get_transport() 
session = transport.open_session() 
session.set_combine_stderr(True) 
session.get_pty() 

stdin = session.makefile('wb', -1) 
stdout = session.makefile('rb', -1) 

session.exec_command(cmd) 

for chunk in iter(lambda: session.recv(9999), ""): 

    if re.search('Password: $', chunk): 
    stdin.write(sudo_pw + '\n') 
    stdin.flush() 

    output += chunk 

今、私はローカルで以下のようなコマンドを実行している使用してサブプロセスを持っている:

p = Popen(cmd, shell=True, stdin=PIPE, stdout=PIPE, stderr=STDOUT) 
(output, err) = p.communicate() 

どのように私はチャンクで出力を分析するのとまったく同じロジックを実装し、stdinを介して適切な応答を送信することができますか?私はpexpectを使わずに解決策を探しています。

答えて

0

同じように動作する解決策が見つかりました。 Linuxでは、sudoプロンプトが検出された端末デバイスに直接読み書きを行うため、プロンプトが表示されません。 sudo -Sはうまく動作します。

master, slave = pty.openpty() 

p = Popen(cmd, shell=True, stdout=slave, stdin=slave, stderr=STDOUT) 

q = select.poll() 
q.register(master,select.POLLIN) 

output = "" 

while True: 
    if not q.poll(0): 
    time.sleep(0.1) 
    if p.poll() is not None: 
     time.sleep(0.1) 
     while q.poll(0): 
     chunk = os.read(master, 9999) 
     output += chunk 
     break 
    else: 
    chunk = os.read(master, 9999) 
    output += chunk 

    if re.search('Password: $', chunk): 
     os.write(master, sudo_pw + '\n') 

rc = p.returncode