2016-10-07 11 views
3

私はapt-getツールを手助けするために、Pythonプログラムに取り組んでいます。私は選択したパッケージをダウンロードするためにpexpectを使用したい。私はchild.expectの行に固執していると信じています。それは、その行になるとタイムアウトしているようです。Pexpectでルートコマンドを実行するには?

butt = "vlc" 
child = pexpect.spawn('sudo apt-get install ' + butt) 
child.logfile = sys.stdout 
child.expect('[sudo] password for user1: ') 
child.sendline('mypassword') 

これはログファイルです。

TIMEOUT: Timeout exceeded. 
<pexpect.spawn object at 0xb5ec558c> 
version: 3.2 
command: /usr/bin/sudo 
args: ['/usr/bin/sudo', 'apt-get', 'install', 'vlc'] 
searcher: <pexpect.searcher_re object at 0xb565710c> 
buffer (last 100 chars): '[sudo] password for user1: ' 
before (last 100 chars): '[sudo] password for user1: ' 
after: <class 'pexpect.TIMEOUT'> 
match: None 
match_index: None 
exitstatus: None 
flag_eof: False 
pid: 27641 
child_fd: 4 
closed: False 
timeout: 30 
delimiter: <class 'pexpect.EOF'> 
logfile: <open file '<stdout>', mode 'w' at 0xb74d8078> 
logfile_read: None 
logfile_send: None 
maxread: 2000 
ignorecase: False 
searchwindowsize: None 
delaybeforesend: 0.05 
delayafterclose: 0.1 
delayafterterminate: 0.1 

UPDATE:

パスワードがうまく送信されます。また、次の行も期待しますが、「Y」を入力して何もしません。

child = pexpect.spawn('sudo apt-get install ' + butt) 
child.logfile = sys.stdout 
child.expect_exact('[sudo] password for user1: ') 
child.sendline('mypass') 
child.expect_exact('Do you want to continue? [Y/n] ') 
child.sendline('Y') 

解決しよう:

私は最後に次の行を追加する必要がありました。

child.expect(pexpect.EOF, timeout=None) 

答えて

1

お試しchild.expect_exact()ドキュメントから

期待()メソッドは、指定された文字列を返すように子アプリケーションを待ちます。指定した文字列は正規表現なので、複雑なパターンにマッチすることができます。

expect()は、正規表現に一致させることが目的の場合にのみ使用することをお勧めします。

child.expect('[sudo] password for user1: ') 

正規表現を使用しています。

+0

これはうまくいきました。今、私はその行と私はパスワードを送ることができると期待しています。ありがとう。 – user2631279

+0

問題ありません。喜んで助けてください。 –

1

当面の問題は、これがあることです。 [...]構造体は正規表現では特別な意味を持ちますので、実際には "d"、 "o"、 "s"、 "u"のいずれかの文字が続き、その後にはpassword for user1:の文字列が続きます。しかし、sudoが最初に[sudo]というテキストを送信しています。正規表現はその最終文字が]であるため、一致しません。

これには多数の解決策があります。 password for user1:と一致させることができます。 JLeClercが提案したようにexpect_exact()を使用することができます(これも私が好む解決策です)。通常の意味のないように、正規表現の中で括弧をエスケープすることができます:\[sudo\](これをPython文字列として指定するときは、バックスラッシュを二重にするか、生の文字列リテラルを使用する必要があります)。

もう1つの問題は、最後の数分間にパスワードを指定している場合、パスワードの入力を求められないことです。それで、expect()コールが間違いなくタイムアウトになります。これに対処する最も簡単な方法は、まずsudo -kを発行することです。同じコマンドラインでも行うことができます:

child = pexpect.spawn('sudo -k; sudo apt-get install ' + butt) 
+0

私は今参照してください。あなたが私のために書いた行を使ったとき、それは二度コマンドに入った。 -kオプションは何をしますか?ありがとう。 – user2631279

+0

これは 'sudo'を強制的にキャッシュするのではなく、パスワードの入力を促します。 'man sudo'を参照してください。 – kindall

関連する問題