1.基本的な紹介
インストール
pip3 install pexpect
Pexpectには2つの重要なメソッドがあります-expect()
およびsend()
(またはsendline()
send()+メソッドに類似し\n
ているのはラップできることです)。
expect()
方法待機サブアプリケーションは、指定された文字列を返します。
指定する文字列は正規の式なので、複雑なパターンに一致させることができます。
このsend()
メソッドは、文字列サブアプリケーションを書き込みます。サブアプリケーションの観点からは、誰かが端末でテキストを入力するようなものです。
呼び出しごとexpect()
に、サブアプリケーションbefore
とafter
プロパティがテキストに設定され、印刷できます。このbefore
プロパティには、文字列パターンが目的のパターンと一致するまで、すべてのテキストサブアプリケーションの戻り値が含まれます。after
テキストを含む文字列が予想されるパターンに一致します。match
プロパティはrematchオブジェクトに設定されます。
コマンドを実行してキーペアを作成します
[test@VM-0-11-centos ~]$ ssh-keygen
Generating public/private rsa key pair.
Enter file in which to save the key (/root/.ssh/id_rsa):
pexpect
文字列に応答してキャプチャしようとするモジュールを使用する
In [1]: import pexpect
In [2]: child = pexpect.spawn("ssh-keygen")
In [3]: child.expect("/root/.ssh/id")
Out[3]: 0
In [4]: child.before
Out[4]: b'Generating public/private rsa key pair.\r\nEnter file in which to save the key ('
In [5]: child.after
Out[5]: b'/root/.ssh/id'
デモンストレーションの例
最初に既存のキーペアを削除または移動します
次の手順は、.ssh
メッシュロードがあるかどうかをテストし、名前が変更されている場合は、信頼関係の失敗を防ぐために確立されています。
test -d ~/.ssh && mv ~/.ssh ~/myssh
In [1]: import pexpect
In [2]: cmd = "ssh-keygen"
In [3]: child = pexpect.spawn(cmd) // 执行 shell 命令,生成子程序
// 捕获子程序输出的字符串, 因为 ) 会被 python 识别解释,所以这里使用了 [)]
In [4]: child.expect(".ssh/id_rsa[)]")
Out[4]: 0
// 根据子程序的需要,发送进一步的指令
// 这里是直接输入一个回车键,相当于按下了回车键
In [5]: child.sendline()
Out[5]: 1
// 继续捕获
In [6]: child.expect("no passphrase.:")
Out[6]: 0
// 这里是打印出了匹配模式之前的输出内容,不是必须的操作
// 只是进行简单的验证子程序输出的内容而已
In [7]: child.before
Out[7]: b": \r\nCreated directory '/home/test/.ssh'.\r\nEnter passphrase (empty for "
// 这里是输出的字符串中,匹配到的那部分字符串
In [8]: child.after
Out[9]: b'no passphrase):'
In [9]: child.sendline()
Out[9]: 1
In [10]: child.expect("again:")
Out[10]: 0
In [11]: print(child.before.decode()+child.after.decode())
Enter same passphrase again:
In [12]: child.sendline()
Out[12]: 1
In [13]: child.close()
In [14]: !ls .ssh
id_rsa id_rsa.pub
In [15]:
極小法
sshキーペアを作成するには、次のシェルコマンドを使用して、非対話的に独自のキーペアを作成できます。上記の例は、pexpectを示すためのものです。
ssh-keygen -t rsa -f ~/.ssh/id_rsa -N ""
- -tはキー暗号化タイプを指定します
- -fは、秘密鍵ファイルの出力パスを指定します
- -N新しいキーの暗号化パスワード。
""
識別子は空です(または秘密キーを暗号化しないため)。
2つ目は、1つのコマンドの複数の出力内容の状況に対処する
場合によっては、実行するコマンドが複数の状況で結果を返すことがあります。
たとえば、パスワードを要求すると、正しいパスワードが入力され、通常のコマンドプロンプトが返されたり、間違ったパスワードが入力されたりする場合があります。このとき、パスワードの再入力が必要なプロンプトコンテンツが返されます。
たとえば、上記のコマンドはキーペアを作成したばかりで、キーペアがすでに存在する場合、中央は既存のキーペアを上書きするかどうかをマルチに要求し、期待される入力はy
またはn
です。
試験状況は以下のとおりです。
[test@VM-0-11-centos ~]$ ls .ssh/
id_rsa id_rsa.pub
[test@VM-0-11-centos ~]$ ssh-keygen
Generating public/private rsa key pair.
Enter file in which to save the key (/home/test/.ssh/id_rsa):
/home/test/.ssh/id_rsa already exists.
Overwrite (y/n)? n
[test@VM-0-11-centos ~]$
入力時n
およびキャリッジリターン後、既存のキーペアを上書きしないことを示すと、プログラムは新しいキーペアの作成を続行しません。
入力y
してEnterキーを押すと、プログラムは引き続き新しいキーペアを作成し、元のキーペアを上書きします。
[test@VM-0-11-centos ~]$ ssh-keygen
Generating public/private rsa key pair.
Enter file in which to save the key (/home/test/.ssh/id_rsa):
/home/test/.ssh/id_rsa already exists.
Overwrite (y/n)? y
Enter passphrase (empty for no passphrase):
Enter same passphrase again:
Your identification has been saved in /home/test/.ssh/id_rsa.
Your public key has been saved in /home/test/.ssh/id_rsa.pub.
The key fingerprint is:
SHA256:OMu/CTZd4kwnC+uD1/2S8Nqry6iUG/112Z1Vu452EhI test@VM-0-11-centos
The key's randomart image is:
+---[RSA 2048]----+
| |
| |
| .|
| . E o|
| + S o . ..|
| + X.* . + .+|
| +.O.=+..+ oo.|
| ..=oB.+=. oo. |
| ooo.X=o+o.o. |
+----[SHA256]-----+
[test@VM-0-11-centos ~]$
上記の状況に対処するために、pexpectモジュールexpect
メソッドはタイプパラメータリストを取ることができます。このリストには複数の正規式が含まれており、各正規式は可能な文字列の結果を表します。といった:
i = child.expect["Overwrite", "no passphrase"]
i
の値は、キャプチャリストのインデックス番号です。これは、リスト内のどの文字列が実際にキャプチャされるかを決定するために使用されます。次に例を示します。
一致する"Overwrite"
場合i
、値は0、
一致する"no passphrase"
場合i
、値は1というようになります。
したがって、最適化後のコードは次のようになります。
In [15]: import pexpect
In [16]: cmd = "ssh-keygen"
In [17]: child = pexpect.spawn(cmd)
In [18]: child.expect(".ssh/id_rsa[)]:")
Out[18]: 0
In [20]: child.sendline()
Out[7]: 1
In [8]: i = child.expect(["Overwrite", "no passphrase"])
In [10]: if i == 0:
...: child.sendline("y")
...: child.expect("empty for no passphrase")
...: child.sendline()
...: elif i == 1:
...: child.expect("empty for no passphrase")
...: child.sendline()
...:
In [11]: child.expect("again:")
Out[11]: 0
In [12]: child.sendline()
Out[12]: 1
In [13]: child.close()
In [14]: !ls ~/.ssh
id_rsa id_rsa.pub
3つの小さな演習
MySQLが初期化
された後、デフォルトのパスワードを変更するスクリプトを作成する練習をしてください。スクリプトによって実装される関数:
- デフォルトのパスワードを除外する
- デフォルトのパスワードを変更する