2016-11-17 20 views
3

私はUbuntuのターミナルで実行する場合:チルダ(〜)subprocess.Popenで動作していない()

sudo dd if=/dev/sda of=~/file bs=8k count=200k; rm -f ~/file 

それが正常に動作します。私はニシキヘビsubprocess.Popen()を通してそれを実行した場合

output, err = subprocess.Popen(['sudo', 'dd', 'if=/dev/' + disk, 'of=~/disk_benchmark_file', 'bs=8k', 'count=200k'], stderr=subprocess.PIPE).communicate() 
print err 

それは動作しません。私が手にエラーではありません:

ddは:「〜/ disk_benchmark_file」のオープンに失敗しました:そのようなファイルやディレクトリ

私はPopen()コールチルダ~/home/userにして変更すると、それは動作します!

なぜそれはそうですか? もっと重要なこと:私はそれを機能させるにはどうすればいいですか? 私は、プロダクションでユーザー名を知りません。

+0

あなたは 'で試してみました$ HOME'? – Will

答えて

6

['sudo', 'dd', 'if=/dev/' + disk, 'of=' + os.path.expanduser('~/disk_benchmark_file'), 'bs=8k', 'count=200k'] 
+0

これはまさに、探していたものです:-)それはうまくいきました! – RichArt

3

は、ホームのシェルのショートカットです。あなたのコマンドがシェルによって解釈されるためには、あなたのPopenにshell=Trueを設定する必要があります。

shell引数(デフォルトはFalse)は、シェルを実行するプログラムとして使用するかどうかを指定します。シェルがTrueの場合、それは文字列としてではなく、シーケンス

https://docs.python.org/2/library/subprocess.html

注意として引数を渡すことをお勧めします、しかしこれを行うことについて、いくつかの警告があります。

+2

'shell = True'を使用しないでください。 –

+1

良い説明:-) 'shell = True'はお勧めできませんので、解決策はos.path.expandとなります。 – RichArt

+0

ありがとう@RichArt、慎重に使用してください。しかし、それを阻止する理由の大部分は墨塗りのセキュリティ問題。これがプロダクションコードではなく、入力を制御していればうまくいくはずです。 Dan D.のような絶対的なものを扱わない限り、 – bravosierra99

4
import os 
import shlex 

outfile = os.path.expanduser('~/file') 
cmd_string = 'sudo dd if=/dev/sda of=%s bs=8k count=200k; rm -f %s' % (outfile, outfile) 
cmd_list = shlex.split(cmd_string) 

# Then use cmd_list as argument for Popen 

shlex.splitサブプロセスにcommandとして使用されなければならないリストを生成するための標準的で安全な方法です。すべての例外を処理してコードを読みやすくすることができます

os.path.expanduser('~')を使用しています。あなたのコードで

>>> import os 
>>> os.path.expanduser('~/disk_benchmark_file') 
'/home/dan/disk_benchmark_file' 

の発生:

['sudo', 'dd', 'if=/dev/' + disk, 'of=~/disk_benchmark_file', 'bs=8k', 'count=200k'] 

を置き換えてください:あなたはos.path.expanduser()とそれらのパス名をラップする必要が

+1

'os.path'には' expand'メソッドがありません。 –

+1

私は心から......... –

+0

あなたの答えをありがとう。いいね、このshlex。 – RichArt

関連する問題