質問

paramikoを介して対話型コマンドを実行しようとしています。cmd を実行するとパスワードの入力を求められますが、paramiko の exec_command でパスワードを入力する方法がわからず、実行がハングします。cmd の実行で対話型の入力が必要な場合、端末に値を送信する方法はありますか?

ssh = paramiko.SSHClient()
ssh.connect(server, username=username, password=password)
ssh_stdin, ssh_stdout, ssh_stderr = ssh.exec_command("psql -U factory -d factory -f /tmp/data.sql")

これにどう対処できるか知っている人はいますか?ありがとう。

役に立ちましたか?

解決

良いデモを。

デモではサブディレクトリ、demo.pyinteractive.pyは、おそらくあなたの状況に行き過ぎだろうフルインタラクティブTTYの例を持っています。

ssh_stdin上のあなたの例では、標準のPythonファイルオブジェクトのように動作し、そうssh_stdin.writeは限りチャネルがまだ開いているように動作する必要があります。

私は、標準入力に書き込むために必要なことがありませんが、ドキュメントは、チャネルがそのように、おそらく動作しませんパスワードを送信するための標準的なstdin.writeメソッドを使用して、できるだけ早くコマンドは終了として閉じていることを示唆しています。あなたはより多くの制御を与えるチャネル自体に低いレベルのparamikoのコマンドがあります - どのように<のhref = "http://docs.paramiko.org/en/2.4/api/client.html#paramiko.client.SSHClientご覧ください。 exec_command」REL = "nofollowをnoreferrer"> SSHClient.exec_command の方法は、すべての血みどろの詳細は実装されます。

他のヒント

を使用して対話型の SSH セッションを作成しようとすると、同じ問題が発生しました ssh, 、パラミコのフォーク。

調べてみるとこんな記事を見つけました。

リンクを更新しました (リンクが 404 を生成する前の最後のバージョン): http://web.archive.org/web/20170912043432/http://jessenoller.com/2009/02/05/ssh-programming-with-paramiko-completely-Difference/

例を続けるには、次のことができます

ssh_stdin, ssh_stdout, ssh_stderr = ssh.exec_command("psql -U factory -d factory -f /tmp/data.sql")
ssh_stdin.write('password\n')
ssh_stdin.flush()
output = ssh_stdout.read()

この記事ではさらに詳しく説明し、exec_command を中心とした完全に対話型のシェルについて説明します。これはソース内の例よりもはるかに使いやすいことがわかりました。

元のリンク: http://jessenoller.com/2009/02/05/ssh-programming-with-paramiko-completely-Difference/

あなたは(期待するとsshのラッパー)の両方の長所を取得するPexpectを必要とします。

私はparamikoに慣れていないんだけど、これは動作する可能性があります:

ssh_stdin.write('input value')
ssh_stdin.flush()

STDINの情報について:

http://docs.python.org/library /sys.html?highlight=stdin#sys.stdinする

ssh = paramiko.SSHClient()
ssh.set_missing_host_key_policy(paramiko.AutoAddPolicy())
ssh.connect(server_IP,22,username, password)


stdin, stdout, stderr = ssh.exec_command('/Users/lteue/Downloads/uecontrol-CXC_173_6456-R32A01/uecontrol.sh -host localhost ')
alldata = ""
while not stdout.channel.exit_status_ready():
   solo_line = ""        
   # Print stdout data when available
   if stdout.channel.recv_ready():
      # Retrieve the first 1024 bytes
      solo_line = stdout.channel.recv(1024) 
      alldata += solo_line
   if(cmp(solo_line,'uec> ') ==0 ):    #Change Conditionals to your code here  
     if num_of_input == 0 :
      data_buffer = ""    
      for cmd in commandList :
       #print cmd
       stdin.channel.send(cmd)        # send input commmand 1
      num_of_input += 1
     if num_of_input == 1 :
      stdin.channel.send('q \n')      # send input commmand 2 , in my code is exit the interactive session, the connect will close.
      num_of_input += 1 
print alldata
ssh.close()              

stdout.channel.recv_ready() をチェックせずに直接使用すると stdout.read() がハングする理由:while stdout.channel.exit_status_ready():

私の場合、リモートサーバーでコマンドを実行した後、セッションはユーザー入力を待機し、「q」を入力すると接続が閉じられます。ただし、 'q' を入力する前に、 stdout.read() は EOF を待機します。バッファが大きい場合、このメソッドは機能しないようです。

  • while で stdout.read(1) を試してみましたが、うまくいきました
    while で stdout.readline() を試しましたが、それも機能します。
    stdin、stdout、stderr = ssh.exec_command('/Users/lteue/Downloads/uecontrol')
    stdout.read() がハングする

の例を見て、同様の方法で行います。

のhttpから

(sorce:// jessenoller。 COM / 2009/02/05 / SSH-プログラミングと-paramiko-完全-異なる/ の):

    ssh.connect('127.0.0.1', username='jesse', 
        password='lol')
    stdin, stdout, stderr = ssh.exec_command(
        "sudo dmesg")
    stdin.write('lol\n')
    stdin.flush()
    data = stdout.read.splitlines()
    for line in data:
        if line.split(':')[0] == 'AirPort':
            print line

あなたは「OK」、パスワード等好きな確認メッセージ送信するには、このメソッドを使用することができます。これは、例えばと私のソリューションです:

def SpecialConfirmation(command, message, reply):
    net_connect.config_mode()    # To enter config mode
    net_connect.remote_conn.sendall(str(command)+'\n' )
    time.sleep(3)
    output = net_connect.remote_conn.recv(65535).decode('utf-8')
    ReplyAppend=''
    if str(message) in output:
        for i in range(0,(len(reply))):
            ReplyAppend+=str(reply[i])+'\n'
        net_connect.remote_conn.sendall(ReplyAppend)
        output = net_connect.remote_conn.recv(65535).decode('utf-8') 
    print (output)
    return output

CryptoPkiEnroll=['','','no','no','yes']

output=SpecialConfirmation ('crypto pki enroll TCA','Password' , CryptoPkiEnroll )
print (output)
ライセンス: CC-BY-SA帰属
所属していません StackOverflow
scroll top