18

サブプロセス モジュールのPopen関数を使用して、コマンド ライン ツールを実行しています。

subprocess.Popen(args, bufsize=0, executable=None, stdin=None, stdout=None, stderr=None, preexec_fn=None, close_fds=False, shell=False, cwd=None, env=None, universal_newlines=False, startupinfo=None, creationflags=0)

私が使用しているツールは、ファイルのリストを取得して処理します。場合によっては、このファイルのリストが非常に長くなることがあります。args パラメータの最大長を見つける方法はありますか? 多数のファイルがツールに渡されると、次のエラーが発生します。

Traceback (most recent call last):
  File "dump_output_sopuids.py", line 68, in <module>
    uid_map = create_sopuid_to_path_dict_dcmdump(dicom_files)
  File "dump_output_sopuids.py", line 41, in create_sopuid_to_path_dict_dcmdump
    dcmdump_output = subprocess.Popen(cmd,stdout=subprocess.PIPE).communicate(0)[0]
  File "c:\python26\lib\subprocess.py", line 621, in __init__
    errread, errwrite)
  File "c:\python26\lib\subprocess.py", line 830, in _execute_child
    startupinfo)
WindowsError: [Error 206] The filename or extension is too long

この最大長を見つける一般的な方法はありますか? msdn で次の記事を見つけました:コマンド プロンプト (Cmd.exe) コマンド ライン文字列の制限ですが、値をハード コードしたくありません。コマンドを複数の呼び出しに分割するために、実行時に値を取得したいと思います。

Windows XP 64 で Python 2.6 を使用しています。

編集:コード例の追加

paths = ['file1.dat','file2.dat',...,'fileX.dat']
cmd = ['process_file.exe','+p'] + paths
cmd_output = subprocess.Popen(cmd,stdout=subprocess.PIPE).communicate(0)[0]

この問題は、pathsリスト内の実際の各エントリが通常非常に長いファイル パスであり、その数が数千あるために発生します。

コマンドを への複数の呼び出しに分割してもかまいませんprocess_file.exe。引数の最大長を取得する一般的な方法を探しているので、実行ごとに送信するパスの数がわかります。

4

2 に答える 2

12

shell=False を渡す場合、Cmd.exe は機能しません。

Windows では、サブプロセスは Win32 API の CreateProcess 関数を使用して新しいプロセスを作成します。この関数のドキュメントには、2 番目の引数 (subprocess.list2cmdline によって作成される) の最大長は 32,768 文字であり、Unicode 終了の null 文字を含むと記載されています。lpApplicationName が NULL の場合、lpCommandLine のモジュール名部分は MAX_PATH 文字に制限されます。

あなたの例を考えると、実行可能 (args[0]) の値を指定し、最初のパラメーターに args を使用することをお勧めします。CreateProcess のドキュメントとサブプロセス モジュールのソース コードの私の読みが正しければ、これで問題が解決するはずです。

[編集: Windows マシンを手に入れてテストした後、args[1:] ビットを削除しました]

于 2010-03-04T18:29:16.873 に答える