私はリモートで配備された組み込みLinuxデバイス上でpythonスクリプトを取得してscpコマンドを実行しようとしています。コマンドの実行は簡単ですが、ターゲットサーバが 'known_hosts'ファイルにリストされていない場合、scpは対話が必要な警告をスローします。私はこれを数日間止め、2つの問題を解決することはできません。Python - サブプロセスで入力プロンプトを処理する
まず、サブプロセスからの応答をノンブロッキングで正しく読み取ることができません。次のコードでは、(信頼できるホストファイルの警告が生成されたと仮定して)stderrから読み取ることができることがわかっている場合でも、必ず[(]、[]、[])を返します。
cmdString = 'scp [email protected]:file localFile -i ~/.ssh/id_rsa'
process = subprocess.Popen(shlex.split(cmdString), shell=False, stdin=subprocess.PIPE, stdout=subprocess.PIPE, stderr=subprocess.PIPE)
while(process.poll() is None):
readable, writable, exceptional = select.select([process.stdout], [], [process.stderr], 1)
if not (readable or writable or exceptional):
# Always hits this condition, although adding an "os.read(...)" here
# will return the error prompt from process.stderr.
print "timeout condition"
else:
# Never makes it here
for e in exceptional:
stderr = os.read(process.stderr.fileno(), 256)
print stderr
for r in readable:
stdout = os.read(process.stdout.fileno(), 256)
print stdout
第2に、入力パイプを介して入力を入力することによって、警告を超えてサブプロセスを進めることができません。次のコードはprocess.stderrから警告コードを読み込みますが、端末で{enter}を押すまでハングします。私は "n"、 "n \ n"、 "\ n"を送信しようとしましたが、サブプロセスが実行を継続することはありませんでした。
cmdString = 'scp [email protected]:file localFile -i ~/.ssh/id_rsa'
process = subprocess.Popen(shlex.split(cmdString), shell=False, stdin=subprocess.PIPE, stdout=subprocess.PIPE, stderr=subprocess.PIPE)
# Correctly grabs warning and displays it
stderr = os.read(process.stderr.fileno(), 256)
print stderr
# Just in case there was some weird race condition or something
time.sleep(0.5)
# Doesn't ever seem to do anything
process.stdin.write('\n')
最後に重要ですか?私は元々サブプロセスとPIPESの調査を始めました。なぜなら、私はスレッドをブロックした "os.system(cmdString)"を使ってscpを実行していたので、私はこの問題に対処しなければなりませんでした。サブプロセスを使用しているので、コマンドを実行して成功または失敗させるのは悪いですか?失敗したサブプロセスが最終的に消滅するか、最終的に数十から数百の隠されたscpが実行されているところでユーザーの入力を待つことになりますか?
ありがとうございます!
おかげで、それは標準の標準入力/標準出力/標準エラー出力を使用していないという洞察をたくさん助けました。 "pexpect"はscpを正しく動かすことができ、paramikoのためのscpアドオンもあります。 残念ながら、 "pexpect"は私に必要な仮想ptyを作成できません。また、paramikoが必要とする暗号化パッケージのコンパイル済みバージョンはありません。私が裸のサードパーティ製の組み込みデバイスに取り組んでいるので、ptyの作成を許可するようにシステム設定を変更したり、パッケージをクロスコンパイルするのは難しいです。 – digitalosmosis
@digitalosmosisあなたに役立つかもしれないより多くの「素朴な」例が追加されました。 – mweerden