Yes/noまたはy/nなどの入力を促すコマンドを実行したい。コマンドlocal("my_command")
を実行すると、停止して入力を求められます。必要なものを入力すると、スクリプトは引き続き機能します。プロンプトに自動的に応答するにはどうすればよいですか?
バージョン1.9
以降、Fabricにはこれを適切に管理する方法が含まれています。
Fabricドキュメントの プロンプトに関するセクション は次のように述べています。
プロンプトディクショナリを使用すると、インタラクティブなプロンプトを制御できます。辞書のキーがコマンドの標準出力ストリームで見つかった場合、Fabricは対応する辞書の値で自動的に応答します。
Fabricが次のようなプロンプトに自動的に応答できるようにする必要があります。
with settings(prompts={'Do you want to continue [Y/n]? ': 'Y'}):
run('apt-get update')
run('apt-get upgrade')
簡単なエコーパイプを使用して、Fabricでプロンプトに応答しました。
run('echo "yes\n"| my_command')
注:この回答は数年前のものであり、その間、ファブリックは(興味深いことに似たように)これを実装しています。以下の@timothée-jeanninの回答を参照してください。
参照してください https://stackoverflow.com/a/10007635/708221
pip install fexpect
from ilogue.fexpect import expect, expecting, run
prompts = []
prompts += expect('What is your name?','John')
prompts += expect('Are you at stackoverflow?','Yes')
with expecting(prompts):
run('my_command')
Timothéeの優れた答え を少し拡張するために、Fabricがprompts
辞書を確認するときに使用する コード を次に示します。
def _get_Prompt_response(self):
"""
Iterate through the request prompts dict and return the response and
original request if we find a match
"""
for tup in env.prompts.iteritems():
if _endswith(self.capture, tup[0]):
return tup
return None, None
ファブリックは.endswith
をチェックするため、prompts
辞書のキーとして使用する文字列の末尾にスペースを含めてください。
たとえば、Django test database Promptを自動化しようとしているとしましょう。
テストデータベース「test_my_app」を削除する場合は「yes」、キャンセルする場合は「no」と入力します。
必要なのは、プロンプトが終了するだけで十分なので、それが一意になります。末尾のスペースを含めます。
Django_test_database_Prompt = "or 'no' to cancel: "
# won't work without this trailing space ^
with settings(
prompts={Django_test_database_Prompt : 'yes'}
):
run('%s %s' % (virtualenv_python_path,
test_runner_file_path,
)
)
@BobNadlerからのコメントですが、これを答えとして入れます
run( "yes | my_command");
Fabric 2.1 では、これは、invokeパッケージ(Fabric 2.1の依存関係)から利用できる auto-respond example を使用して実現できます。
>>> from invoke import Responder
>>> from fabric import Connection
>>> c = Connection('Host')
>>> sudopass = Responder(
... pattern=r'\[Sudo\] password:',
... response='mypassword\n',
... )
>>> c.run('Sudo whoami', pty=True, watchers=[sudopass])
[Sudo] password:
root
<Result cmd='Sudo whoami' exited=0>
これはSudoパスワードに限定されず、一致するパターンと返信定型文(パスワードではない可能性がある)がある場所であればどこでも使用できることに注意してください。
いくつかのヒントがあります:
pty=True
はおそらく常に必要ですpattern
内で指定されたResponder
は、多くの場合、行の末尾にスペースを含めることができるため、watcher
が一致していないように見える場合はスペースを追加してみてください。watcher docs の最後で説明されているメモによると:
Responderへのパターン引数は正規表現として扱われるため、より注意が必要ですが(上記の例で角括弧をエスケープする方法に注意してください)、より強力な機能も提供します。
したがって、必要に応じて(バックスラッシュを使用して)エスケープすることを忘れないでください。