0

subprocess.Popen(['cp', etc..]) と wait() を使用して while ループでいくつかのファイルを転送して名前を変更しようとしています。残念ながら、wait() コマンドが正しく機能していないようです。つまり、ファイルが新しいディレクトリに完全にコピーされるのを待っていません。ほとんどの場合、ファイルは正常にコピーされますが、ランダム ファイルの小さなサブセットは正常にコピーされず (スクリプトを実行するたびに同じファイルがコピーされるわけではありません)、ゼロ バイト ファイルまたは不完全なファイルになります。subprocess.check_call() も使用してみましたが、これも機能しません。poll() 値を出力すると、プロセスが終了したことを意味する常にゼロになります。私が扱っているすべてのファイルは 150KB の範囲にあることに注意してください。私のpythonスクリプトは、python 2.7、pythonバージョンのiraf(画像縮小および分析機能)を使用してpyrafで実行されています。これは、私がirafルーチンを使用しているためです。

while count <= ncross_correlate and skip_flag != 's':
   ...more stuff
   try:
      iraf.rv.fxcor (object_fits, template_fits, apertures="*", cursor="",
      continuum="both", filter="both", rebin="smallest", pixcorr="no", 
      osample=osample_reg, rsample=osample_reg, apodize=0.1, function="gaussian",
      width="INDEF", height=0., peak="no", minwidth=3., maxwidth=21., weights=1.,
      background=0., window=300., wincenter="INDEF", output=output_name, verbose="long",
      imupdate="no", graphics="stdgraph", interactive="no", autowrite="yes",
      autodraw="yes", ccftype="image", observatory="aao", continpars="", filtpars="", 
      keywpars="")

      # Create a eps file of the cross_correlation file.
      gki_output_name = output_name + '.gki'
      iraf.plot.sgikern (gki_output_name, device='eps', generic='no', debug='no',
      verbose='no', gkiunit='no')

残念ながら、fxcor で作成された .gki ファイルを iraf 以外の読み取り可能な形式に変換する唯一の方法は、ファイル名を変更するオプションを指定せずに、私の iraf/iraf/ ディレクトリに .eps ファイルをダンプする iraf タスク sgikern を呼び出すことです。ディレクトリの配置。実際、ファイル名はランダムに生成されます。非常にイライラします!!! また、iraf.plot.sgikern を使用して作成された eps ファイルには何も問題がないことに注意してください (つまり、最初から 0 KB のファイルはありません)。コピーと名前の変更は、私が問題を抱えている場所です。

      # Find the eps file in /iraf/iraf/, rename it, and move to proper output location.
      iraf_dir = '/iraf/iraf/'
      eps_file_list = glob.glob(iraf_dir + 'sgi' + '*.eps')

      ...more code

この時点で、check_call() または Popen() を使用してみました。

      subprocess.check_call(['cp', eps_file_list[0], ccf_output_dir + object_name_sub +
                            '.eps'], stdout=subprocess.PIPE)
      subprocess.check_call(['rm', eps_file_list[0]], stdout=subprocess.PIPE)

また

      process1 = subprocess.Popen(['cp', eps_file_list[0], ccf_output_dir +
                                  object_name_sub + '.eps'], stdout=subprocess.PIPE)
      process1.wait()
      process2 = subprocess.Popen(['rm', eps_file_list[0]], stdout=subprocess.PIPE)
      process2.wait()

      ...more stuff

   # end of try statement
#end of while statement  

2 つの Popen ステートメントを 1 つの Popen ステートメントに何らかの形で結合し、完了したプロセスを返す前に他の 2 つのプロセスを強制的に終了させるために 0.01 秒程度のシェル スリープ時間を含めることができれば、おそらく修正されると思います。正確なセンタックスはわかりませんが、次のようなものかもしれません。

 process1 = subprocess.Popen(['cp', eps_file_list[0], ccf_output_dir +
            object_name_sub + '.eps']; ['rm', eps_file_list[0]]; ['sleep', 0.01],
            stdout=subprocess.PIPE)
 process1.wait()       

うまくいけば、これで私がやろうとしていることのアイデアが得られます。私はさまざまなことを試し、この問題の解決策を探していましたが、本当に行き詰まっています.

乾杯、 ブレット

4

3 に答える 3

0

おそらく、以下で十分でしょう。

subprocess.check_call(['mv', eps_file_list[0], ccf_output_dir + object_name_sub +
                        '.eps'], stdout=subprocess.PIPE)

process1 = subprocess.Popen(['mv', eps_file_list[0], ccf_output_dir +
                              object_name_sub + '.eps'], stdout=subprocess.PIPE)
process1.wait()
于 2013-01-22T07:51:13.727 に答える
0

これは完全な解決策でも満足のいく解決策でもありませんが、私が思いついた中で最高のものであり、約 99.9% の確率で動作します (作成した 4000 以上の eps のうち、5 つのファイルが 0 バイトまたは不完全でした)。これは、私がこれを行っていた元の方法よりも改善されており、約 95% の確率で成功しました。以下のコードを貼り付けました。

     try:
        iraf.rv.fxcor (object_fits, template_fits, apertures="*", cursor="",
        continuum="both", filter="both", rebin="smallest", pixcorr="no", osample=osample_reg,
        rsample=osample_reg, apodize=0.1, function="gaussian", width="INDEF", height=0., peak="no",
        minwidth=3., maxwidth=21., weights=1., background=0., window=300.,
        wincenter="INDEF", output=output_name, verbose="long", imupdate="no",
        graphics="stdgraph", interactive="no", autowrite="yes", autodraw="yes",
        ccftype="image", observatory="aao", continpars="", filtpars="", keywpars="")

        # Create a eps file of the cross_correlation file.
        gki_output_name = output_name + '.gki'
        iraf.plot.sgikern (gki_output_name, device='eps', generic='no', debug='no',
        verbose='no', gkiunit='no')
        time.sleep(0.25)

コードがファイルを別のディレクトリに移動しようとするまでに、iraf ディレクトリに作成されている ps ファイルの一部が完全に書き込まれていないことがわかったので、ここにタイムスリーパーを置きました。

        # Find the eps file in /iraf/iraf/, rename it, move to proper output location, and delete the old eps file.
        iraf_dir = '/iraf/iraf/'
        eps_file_list = glob.glob(iraf_dir + 'sgi' + '*.eps')

        ...continuation of code

        if len(eps_file_list) == 1:
           eps_file_sub = os.path.basename(eps_file_list[0])

           cmd1 = 'cp {0} {1}'.format(eps_file_list[0], ccf_output_dir + object_name_sub + '.eps')
           cmd2 = 'rm {0}'.format(eps_file_list[0])
           cmd3 = 'sleep 0.05'
           process1 = subprocess.Popen("{}; {}; {}".format(cmd1, cmd2, cmd3), shell=True, stdout=subprocess.PIPE)
           process1.wait()

process1 では、3 つのサブプロセス シェル コマンドを送信しています。1 つ目は、eps ファイルを /iraf ディレクトリから別のディレクトリにコピーすることです (最初にそれらを作成する iraf 関数では、これらのファイルに適切な名前や出力場所を指定することはできません)。2 つ目は、eps ファイルを /iraf ディレクトリから削除することです。3 番目のコマンドは、カーネルを強制的にスリープさせます。これにより、Python はスリープ コマンドに到達するまで完了信号を受信しません。この部分は完璧に機能すると思います。唯一の問題は、eps ファイルの作成に使用される iraf ルーチンが、このコマンドに達したときに十分な速さでファイルを作成しないことが非常にまれであることです。

        #endif

        num_cross = num_cross + 1
     #Endtry
     ...more code

これは非常に扱いにくい解決策であり、満足できるものではありませんが、99.9% の確率で機能します。誰かがより良い解決策を持っている場合は、私に知らせてください。これは非常に苛立たしい問題であり、私が尋ねた誰もがより良いものを思いつくことができませんでした (私の宇宙部門で定期的に Python でプログラミングする人々を含む)。

于 2013-02-05T01:18:36.110 に答える
0

コピーにshutil.copyfileを使用し、削除にos.removeを使用することを検討しましたか?

本当に Subprocess を使いたいのなら、構文は次のようなものだと思います:

process1 = subprocess.Popen('cp ' + eps_file_list[0] + ' ' + ccf_output_dir +
        object_name_sub + '.eps; rm ' + eps_file_list[0] ' + '; sleep 0.01',
        stdout=subprocess.PIPE)

このように、呼び出しているコマンドはすべて 1 つの文字列になっています。'cp whatever foo/bar.eps; rm whatever; sleep 0.01'

文字列を三重引用符でフォーマットし、コマンドを別の行に配置することもできます。

'''
cp %s %s%s
rm %s
sleep %s
''' % (eps_file_list[0], ccf_output_dir, object_name_sub, eps_file_list[0], 0.01)
于 2013-01-22T07:55:58.517 に答える