ことはじめ
- 設定が間違ってないかどうか、全ホストのとあるconfigファイルをちょっと確認したかった
- rootでしか表示できないファイルだったのでcatするにしてもsudo(パスワード入力)が必要だった
- expectを使ったスクリプトよりpythonの方がわかりやすいと思った
現象
@kanedaq さんの
とかを参考にコードを書いたのだけど、なぜか動かない。
動かないというかsudoパスワードを入力した後の結果が全く返ってこないという現象に出会った。
(おそらくの)原因
- パスワードの入力タイミングが早すぎたのが原因と思われる
- ちょっと反応の悪いホストの場合、sudoのパスワードプロンプトが表示されるのをちゃんと待ってからパスワードを入力する必要がある模様
解決策
- 考えてみればそりゃそうかという感じだが、一律で5秒sleepをはさむとかすると対象ホストが増えれば増えるほど比例して待ち時間が長くなるのが嫌だった
- なので、パスワードプロンプトが表示されるまで待って入力可能になった瞬間に入力するようにする
環境
- 5.4.72-microsoft-standard-WSL2
- Ubuntu 20.04.3 LTS
- Python 3.8.5
- Paramiko 2.7.2
リモートでsudoコマンドを実行する最低限のコード
#!/usr/bin/env python3
# -*- coding: utf-8 -*-
import paramiko
import time
client = paramiko.SSHClient()
client.set_missing_host_key_policy(paramiko.AutoAddPolicy())
# 接続
client.connect(
hostname="hostname",
username="testuser",
password="password",
port=22,
)
# cmd実行
cmd = "sudo whoami"
stdin, stdout, stderr = client.exec_command(cmd, get_pty=True)
while len(stdout.channel.in_buffer) == 0:
# stdoutにパスワードプロンプトが出力されるまで待ち続ける
continue
# とてつもなく反応が悪いホストの場合は入力可能になるまで更に待った方がいい?
# time.sleep(1)
# sudoパスワード入力
stdin.channel.send("password" + "\n")
# stdinだけ閉じる
stdin.channel.shutdown_write()
# 実行結果
# (留意点: get_pty=Trueにしているとstderrもこっちに出力されている)
print(stdout.read().decode().strip())
# 切断
client.close()