2011-08-09 61 views
5

私は新しいparamikoユーザーですが、paramikoを使用してリモートサーバーでコマンドを実行するのが難しいです。私は、パスをエクスポートし、また、tophatというプログラムをバックグラウンドで実行したいと思います。私はparamiko.sshclient()で正常にログインできますが、exec_commandに私のコードは結果がありません。基本paramiko exec_command help

stdin, stdout, sterr = ssh.exec_command('export PATH=$PATH:/proj/genome/programs 
/tophat-1.3.0/bin:/proj/genome/programs/cufflinks-1.0.3/bin:/proj/genome/programs/ 
bowtie-0.12.7:/proj/genome/programs/samtools-0.1.16') 

stdin, stdout, sterr = ssh.exec_command('nohup tophat -o /output/path/directory -I 
10000 -p 8 --microexon-search -r 50 /proj/genome/programs/bowtie-0.12.7/indexes 
/ce9 /input/path/1 /input/path/2 &') 

にはnohup.outファイルが存在しないとPythonは単にエラーメッセージなしで次の行になります。私はnohupなしで試してみたところ、結果は同じです。私はthis paramiko tutorialに従おうとしていました。

私はexec_commandを間違って使用していますか?

+1

2番目のコマンドは最初のコマンドとは異なるシェルで実行されるため、 'export'コマンドは効果がありません。 –

+1

環境変数を1行に入れるだけでよいでしょう。つまり、 'ssh.exec_command( 'PATH =/bin:/ usr/bin:etcetera nohup ...')';これは、単一のコマンドだけのためにそれをエクスポートします。これはまさにあなたが望むものです。 –

答えて

5

exec_command()はブロッキングではなく、サーバーにコマンドを送信するだけで、Pythonは次のコードを実行します。

私はあなたがコマンドの実行が終了するのを待って、それ以降はそれ以外の作業をするべきだと思います。

「time.sleep(10)」は、「インポート時間」が必要な場合に役立ちます。 いくつかの例では、stdout ChannelFileオブジェクトを読み取ることができます。単にstdout.readlines()を使用すると、サーバーからのすべての応答を読み取ったようです。

あなたのコードは、上記2行のexec_commandですが、実際には異なるexecセッションで実行されています。これがあなたの場合に何らかの影響を与えるかどうかはわかりません。

デモフォルダのデモをご覧になることをお勧めします。彼らはChannelクラスを使用しています。これはシェルとexecの両方に対してブロック/ノンブロッキング送信を行うためのより良いAPIを備えています。

+0

私は同様の問題を抱えていました。私はちょうどチャイムして、stdout.readlines()が私のためにうまくいったと言いました。 exec_command()の実行が終了してから続行するまで、スクリプトは強制的に待機するようになりました。ありがとう! – riggspc

0

私をブロックしています。

stdin, stdout, stderr = ssh.exec_command('sleep 10; hostname') 

これは、あなたがあなたのコマンドを実行する前にbash_profileをロードするために、より良い

+2

出力を読み込もうとするとブロックされます。 – piyo

0

を返す前に10秒間待機します。それ以外の場合は、 'コマンドが見つかりません'という例外が発生することがあります。

例えば、私はその後、私は. ~/.profile; .~/.bash_profile;を入力して、そのダンプコマンドの前に手動でbash_profileをロードする必要がMySQLのテーブルを

をダンプする目的でコマンドcommand = 'mysqldump -uu -pp -h1.1.1.1 -P999 table > table.sql'を書き込みます。

my_command = 'mysqldump -uu -pp -h1.1.1.1 -P999 table > table.sql;' 

pre_command = """ 
. ~/.profile; 
. ~/.bash_profile; 
""" 

command = pre_command + my_command 

stdin, stdout, stderr = ssh.exec_command(command) 
1

私も同じ問題に遭遇したとthis articlethis answerを見た後、私は解決策は、チャンネルのrecv_exit_status()メソッドを呼び出すことです参照してください。ここに私のコードはあります:

import paramiko; 
import time; 

cli = paramiko.client.SSHClient(); 
cli.set_missing_host_key_policy(paramiko.client.AutoAddPolicy()); 
cli.connect(hostname="10.66.171.100", username="mapping"); 
stdin_, stdout_, stderr_ = cli.exec_command("ls -l ~"); 
# time.sleep(2); # Previously, I had to sleep for some time. 
stdout_.channel.recv_exit_status(); 
lines = stdout_.readlines(); 
for line in lines: 
    print line; 

cli.close(); 

私のコードは、リモートコマンドが終了するまでブロックされます。この方法はhereで説明されており、警告に注意してください。

関連する問題