7

いくつかの ssh-copy-id プロセスを生成する必要がある Python スクリプトを実行しています。これらのプロセスではパスワードを入力する必要があるため、PExpect を使用しています。

私は基本的にこれを持っています:

child = pexpect.spawn('command')
child.expect('password:')
child.sendline('the password')

そして、別のプロセスを生成したいのですが、終了したかどうかに関係なく、これはもう気にしません。

child = pexpect.spawn('command2')
child.expect('password:')
child.sendline('the password')

そして、コードは2番目の「スポーン」でぶら下がっています

ただし、最初の呼び出しをコメントアウトすると、2 番目の呼び出しが機能するため、最初の呼び出しがまだ実行されているか、何かが機能していないという事実を推測しています。

さて、私ができなかったもう1つのことは、最初のものが停止するまで待つことです. 私は試しまし

:
child.terminate() - ハングします (パラメーターとして True と False の両方を使用)

何が起こっているのかについてのアイデアはありますか?
注: 私は Python の専門家ではなく、これまで pexpect を使用したことがないため、どんなアイデアでも大歓迎です。

ありがとう!


更新: これは間違いなく ssh-copy-id に関連しています。他のプロセスでは、返されなくても spawn がうまく機能するためです。また、明らかに ssh-copy-id は決して EOF を返しません。

4

4 に答える 4

3

幸か不幸か、OpenSSH クライアントはパスワードとその出所について非常にうるさいようです。

Paramiko Python SSH2 ライブラリを使用してみてください。パスワード認証でそれを使用する方法の簡単な例を次に示します。次に、いくつかのシェル コマンド (echo "..." >> $HOME/.ssh/authorized_keys最も単純なもの) を発行して、リモート ホストに公開鍵を追加します。

于 2009-11-02T18:49:35.387 に答える
1

問題は、SSH が PTY を開こうとして、セキュリティ上の理由から PTY 以外では機能しないことだと思います。これは pexpect ではうまく機能しません。

別の ssh クライアントがあります。

http://www.digmia.com/index.php?option=com_content&view=article&id=54:Digmia%20Enterprise%20SSH&Itemid=56

それはオープンソースです、あなたはそれを使うことができます。あなたがやろうとしているのはより多くのコマンドですが、期待する必要はまったくありません。

  1. 最初にマニュアルに従ってインストールしてから、次のようにします。

  2. dssh-agent を実行し、次のように必要なパスワードを追加します。

    dssh-add -l < passwordfile
    
    • または、それが安全なマシンである場合、つまり、他の誰もそこにログインできない場合、これは非常に重要です。そうでない場合、これは巨大なセキュリティ ホールになります。

      echo "name-of-server;22;root;password;" | dssh-add -l
      
    • passwordファイルは次のようになります。

      name-of-server;22;root;password;
      
  3. そして、次のようにします(CONTENTS OF ...そのファイルの実際の内容に置き換えます):

    dssh root@name-of-server -- echo "CONTENTS OF ~/.ssh/identity.pub" > .ssh/authorized_keys \; chmod og-w .ssh .ssh/authorized_keys
    
    • あなたは(オプションで)することができます

      dssh-add -f passwords
      

    (他の誰もこのようなことをしていないことを確認してください。そうしないと、競合状態が発生します)。

また、pexpect はおそらく dssh 自体で動作するはずです (したがって、dssh-agent を使用する必要はありません)。ただし、dssh-agent を使用する方が簡単で安全です。

DSSH のインストール マニュアルは、tarball に含まれています。

これを行う簡単な方法はわかりません。OpenSSH ssh-copy-id は、パスワードの取得元について非常にうるさいです...

于 2008-12-10T21:53:02.097 に答える
0

spawn の pexpect ドキュメントを読んで、コマンドが終了するのを待っていると思います。

ニーズに応じて、いくつかの異なる可能性を提案します。

1) 生成されたプロセスを強制終了します。ただし、これは操作の破損につながる可能性があるため、それがあなたの望むものかどうかはわかりません。

child = pexpect.spawn('command')
child.expect('password:')
child.sendline('the password')
child.close(True)

2) 次のタスクに移る前に最初のタスクの完了を待つ

child = pexpect.spawn('command')
child.expect('password:')
child.sendline('the password')
child.wait()
child = pexpect.spawn('command2')
...

3) すべての子に別のインスタンスを使用し、最後にそれらすべてを待機します。これがおそらく最良の解決策です。

def exec_command(cmd):
  child = pexpect.spawn(cmd)
  child.expect('password:')
  child.sendline('the password')
  return child

commands = ['command1', 'command2']
childrens = [exec_command(cmd) for cmd in commands]
for child in childrens:
  child.wait()    

注: ここにあるコードはすべてテストされておらず、スポーン オブジェクトを削除するとコマンドが終了するまでハングするため、スクリプトがハングしているという前提で書かれています。

于 2008-12-10T18:10:05.197 に答える
0

実際、私はこれらの代替案の多くを試しましたが、どちらもうまくいきませんでした.

  • close() または terminate() の呼び出しがハングする (パラメーターとして True と False の両方を使用)
  • wait() または read(-1) または expect(pexpect.EOF) の呼び出しがハングする
  • 前の spawn コマンドのハングを気にせずに再度 spawn を呼び出す

他のコマンド (「ftp」など) を使用していくつかのテストを行いました。たとえば、.expect('something') を呼び出すと、期待どおりに動作し、EOF の前に何かが見つからない場合、それらは永遠に待機しません。 、例外がスローされるため、これは特に ssh-copy-id コマンドに関連していると思います。

于 2008-12-10T18:43:21.963 に答える