【Python】【lib】【Pexpect】サンプルコード


以下のコードの大半は、公式ページを流用して作成した。
 

Pexpect のインストール

  • 本家サイト

https://pexpect.readthedocs.io/en/stable/

  • インストール
% pip3 install pexpect
 pip3 install pexpect
Collecting pexpect
  Downloading https://files.pythonhosted.org/packages/b9/3c/e51a76fe78a877afd9acd95a51e3b7610c0983b19ef5a5dfa11735a619b8/pexpect-4.5.0-py2.py3-none-any.whl (57kB)
    100% |████████████████████████████████| 61kB 2.6MB/s 
Collecting ptyprocess>=0.5 (from pexpect)
  Downloading https://files.pythonhosted.org/packages/ff/4e/fa4a73ccfefe2b37d7b6898329e7dbcd1ac846ba3a3b26b294a78a3eb997/ptyprocess-0.5.2-py2.py3-none-any.whl
Installing collected packages: ptyprocess, pexpect
Successfully installed pexpect-4.5.0 ptyprocess-0.5.2

 

サンプルコード

pexpect_run_ls.py

spawn せずに ls -la を呼び出すのみ

#!/usr/bin/env python3
# -*- coding: utf-8 -*- 
import  sys
import  pexpect

if __name__ == '__main__':
    pexpect.run('ls -la')  # ' ls -la ' はエラーになるので注意すること

 

pexpect_spawn_ls.py

spawn を使ったパターン。
https://pexpect.readthedocs.io/en/stable/_modules/pexpect/pty_spawn.html#spawn より spawn の型は以下である

def __init__(self, command, args=[], timeout=30, maxread=2000,
             searchwindowsize=None, logfile=None, cwd=None, env=None,
             ignore_sighup=False, echo=True, preexec_fn=None,
             encoding=None, codec_errors='strict', dimensions=None,
             use_poll=False):
#!/usr/bin/env python3
# -*- coding: utf-8 -*- 
import  sys
import  pexpect

if __name__ == '__main__':
    # OK パターン
    try:
        child = pexpect.spawn('ls -la /var')
    except  Exception as e:
        print("Exception[{0}] was occured".format(str(e)))
    else:
        print("SUCCESS: 'ls -la /var'");
    finally:
        child.expect(pexpect.EOF)

#   # spawn の第2引数は args=[] なので、下記はエラーになる
#   try:
#       child = pexpect.spawn('ls', '-la', '/var')
#   except  Exception as e:
#       print("Exception[{0}] was occured".format(str(e)))
#   else:
#       print("SUCCESS: 'ls',  '-la',  '/var'");
#   finally:
#       child.expect(pexpect.EOF)

    # OK パターン
    try:
        child = pexpect.spawn('ls', ['-la', '/var'])
    except  Exception as e:
        print("Exception[{0}] was occured".format(str(e)))
    else:
        print("SUCCESS: 'ls', ['-la', '/var']")
    finally:
        child.expect(pexpect.EOF)

 

pexpect_spawn_ls_redirect.py

spawn して lsコマンドを呼び出し、その結果をファイルに書き出す。
なお、/bin/bash -c を使わずに、spawn('ls -la /var > /tmp/log.txt") としてもリダイレクトはできない。「*」「|」 も同様とのこと。

#!/usr/bin/env python3
# -*- coding: utf-8 -*- 
import  sys
import  pexpect

if __name__ == '__main__':
    child = pexpect.spawn('/bin/bash -c "ls -la /var > /tmp/log.txt"')
    child.expect(pexpect.EOF)

 

pexpect_spawn_cat_stdin.py

#!/usr/bin/env python3
# -*- coding: utf-8 -*- 
import  sys
import  pexpect

if __name__ == '__main__':

    child = pexpect.spawn('/bin/cat')

    f = open('/tmp/log.txt2', 'wb') # 'w' is invalid
    child.logfile = f

    child.send("123456789\n")
    child.expect(r"(345)..(.)")     # match against terminal echo

    print("Match: child.before=>{0}".format(child.before))     #=> Match: child.before=>b'12'
    print("Match: child.after=>{0}".format(child.after))           #=> Match: child.after=>b'345678'
    print("child.match.groups=>{0}".format(child.match.groups()))    #=> child.match.groups=>(b'345', b'8')

    child.terminate()               # end of expect mode
    child.expect(pexpect.EOF)

pexpect_ssh_localhost.py

自分のホストに ssh ログインする。具体的な入力については後述の 1, 2 の通り

下記のタイミングで「yes(改行)」を入力する

% ssh localhost
The authenticity of host 'localhost (127.0.0.1)' can't be established.
ECDSA key fingerprint is SHA256:VX8LiBOa7d8Wl9IcS1Bwu78lBlEntvTfC1kB0wnsA9M.
Are you sure you want to continue connecting (yes/no)? 

その後、以下のように表示されたらパスワードを入力する

neko@localhost's password: