3

サブプロセス ライブラリと Popen メソッドを使用して、ある場所から別の場所にファイルをコピーしようとしています。次のスクリプトを実行すると、エラーが発生しますcp: cannot stat /some/dev_path/**はファイル名に展開されておらず、そこに問題があると言われました。また、他のいくつかの投稿では、人々は Popen の代わりに call を使用することを提案していましたが、call は私の知る限り stderr を返しません。

devPath = '/some/dev_path/'
productionPath = '/some/prod_path/'

p = subprocess.Popen(['cp', '-r', devPath + '*', productionPath], stdout = subprocess.PIPE, stderr = subprocess.PIPE)
pout, perr = p.communicate()

if perr != '':
    sys.exit('Error: ' + perr)
4

1 に答える 1

13

*(グロビング)の展開は、 bashなどのシェルの機能です。shell=Trueしたがって、呼び出しでキーワード引数を使用する必要がありますsubprocess.Popen

ただし、この場合は、代わりにshutil.copytreeを使用することを強くお勧めします。

(まず第一に、それははるかに単純であり ( Zen of Pythonを参照)、エラーが発生しにくいためです。エラーの処理ははるかにクリーンであり、(あなたのような複数ファイル操作の場合) エラーのリストを含む素晴らしい例外を取得します。サブプロセスの生成とそれとの通信に対処する必要はありません. 第二に、必要がない場合に子プロセスをフォークすることは、リソースの不必要な浪費です. その他の問題には、引用/エスケープが含まれ、コードにセキュリティの脆弱性が導入される可能性があります.ユーザー入力を適切にサニタイズできません。)

例えば:

from shutil import copytree
from shutil import Error

try:
   copytree('dir_a', 'dir_b')
except (Error, OSError), e:
    print "Attempt to copy failed: %s" % e

また、文字列を連結してファイルシステム パスを構築するのではなく、代わりにos.path.join()を使用してください。os.sepこれにより、現在の OS に適したディレクトリ セパレータ ( ) が使用され、移植可能なコードを簡単に記述できるようになります。

例:

>>> import os
>>> os.path.join('/usr/lib', 'python2.7')
'/usr/lib/python2.7'

注:os.path.joinまだ(スマート)文字列操作のみを行います-そのパスがアクセス可能かどうか、または存在するかどうかは気にしません。

于 2012-09-04T16:36:20.090 に答える