2

CLISHを実行しているサーバーに接続し、パスワードプロンプトが表示されたらパスワードを入力し(動作)、「shell」コマンドを発行してbashシェルにぶつけて(動作)、ファイルの存在をテストしたい欠落している場合は「true」を出力し、存在する場合は「」(空の文字列)を出力します(機能します)。

動作しないのは、「pexpect.before」を使用してスクリプトに読み戻しているものです。私はpexpectに基本的なプロンプトを期待するように依頼し、「前に」を教えてください。私が理解していることから、「プロンプトが一致する前に画面に何が表示されますか?」期待どおりに「true」または「」(空の文字列)を取得しているだけでなく、ファイルの存在をテストするために発行したコマンドも取得しています。

たとえば、マシンに直接SSHで接続する場合は、次のようにします。password:

私のスクリプトが返すのは、コマンドと応答(質問と回答)です。

[ ! -f '/etc/logrotate.d/nginx' ] && echo 'true'

true

「true」または「」のいずれかの応答が必要です。応答を受け取っていますが、発行されたコマンドも受け取っています。

私が間違っていることがわかりますか?助けてください!SSHセッションにはもっと複雑な「期待」があるので、引き続きpexpectを使用したいと思います。

これは私のコードです:

def connection(cmd):
    msg_newkey = 'Are you sure you want to continue connecting'
    p=pexpect.spawn('ssh '+user+'@'+host)
    msg = '''Super long welcome message containing your canned warning message, etc.
          myuser@'''+myhost+''''s password:'''
    i=p.expect([msg_newkey,'password:',pexpect.EOF])
    if i==0:
        print "Accepting key."
        p.sendline('yes')
        i=p.expect([msg_newkey,'password:',pexpect.EOF])
    if i==1:
        print "Supplying password"
        p.sendline(passwd)
    elif i==2:
        if "No route to host" in p.before:
            return p.before
        else:
            pass    # Add no functionality, just saying "move on"
    i=p.expect(['MYCLISHPROMPT>',pexpect.EOF])
    if i==0:
            p.sendline('shell')
    i=p.expect(['.*@.*\$',pexpect.EOF])
    if i==0:
            p.sendline(cmd)
    p.expect(['myuser@myhost:',pexpect.EOF])
    return p.before

 def look_for_file(step, filename, mytest):
    cmd = "[ ! -f '"+filename+"' ] && echo '"+mytest+"'"
    results = connection(cmd)
    print "***"+str(result)+"***"
    assert (results == '' or results == 0), "Step failed!  Error: "+results
4

2 に答える 2

2

sendlineの文字列をエコーバックするかどうかを制御する関数setecho(およびそのペア)があります。getecho

setecho(self, state)
    This sets the terminal echo mode on or off. Note that anything the
    child sent before the echo will be lost, so you should be sure that
    your input buffer is empty before you call setecho().

ただし、これは明らかにすべての状況で機能しているわけではなく、いくつかの回避策を使用する必要があります。1つは、この回答のようにbashでエコーをオフにすることです。もう1つは、pexpectの関数を使用するreadlinereadlines、出力を読み取って、指定されたコマンドをエコーする最初の行を破棄することです。

于 2013-03-05T14:47:08.713 に答える
1

以下に示すように、pexpectログをsys.stdoutに設定する必要があるスクリプトでこの問題が発生しました。

    shell = pexpect.spawn("bash")
    shell.logfile = sys.stdout

ここで他の回答で提案された解決策を試しましたが、成功しませんでした。渡されsendline()た文字列は、何があってもログに出力されました。

ただし、pexpectログを一時的に無効にすると、問題が解決するようです。

    shell.logfile = None
    shell.sendline(MY_STRING)
    shell.logfile = sys.stdout
于 2015-01-21T22:20:26.640 に答える