2010-03-04 39 views
11

Tôi đang sử dụng Popen chức năng từ mô-đun subprocess để thực hiện một công cụ dòng lệnh:subprocess.Popen chiều dài tối đa của tham số args là gì?

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) 

Các công cụ tôi đang sử dụng có một danh sách các tập tin mà nó thì quá trình này. Trong một số trường hợp, danh sách tệp này có thể rất dài. Có cách nào để tìm chiều dài tối đa mà tham số args có thể được? Với một số lượng lớn tệp được chuyển đến công cụ, tôi nhận được lỗi sau:

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 

Có cách nào chung để tìm độ dài tối đa này? Tôi tìm thấy bài viết sau trên msdn: Command prompt (Cmd. exe) command-line string limitation nhưng tôi không muốn mã cứng trong giá trị. Tôi thà nhận được giá trị tại thời gian chạy để chia lệnh thành nhiều cuộc gọi.

Tôi đang sử dụng Python 2.6 trên Windows XP 64.

Edit: thêm mã ví dụ

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

Vấn đề xảy ra vì mỗi mục thực tế trong danh sách paths thường là một đường dẫn tập tin rất dài và có là vài nghìn trong số đó.

Tôi không ngại chia lệnh thành nhiều cuộc gọi đến process_file.exe. Tôi đang tìm một cách tổng quát để có được chiều dài tối đa mà args có thể được vì vậy tôi biết có bao nhiêu đường dẫn để gửi cho mỗi lần chạy.

+0

bạn có thể cung cấp giá trị mẫu cho những gì bạn cung cấp cho arg không? –

+0

Tôi khá muộn với bữa tiệc nhưng tôi muốn thêm rằng tôi đã nhận được cùng một lỗi do biến môi trường PATH của tôi trở nên quá dài sau khi thêm nhiều mục. – RedX

Trả lời

9

Nếu bạn đang chuyển shell = False thì Cmd.exe sẽ không được phát.

Trên cửa sổ, quy trình con sẽ sử dụng chức năng CreateProcess từ Win32 API để tạo quy trình mới. Các documentation cho chức năng này nói rằng đối số thứ hai (được xây dựng bởi subprocess.list2cmdline) có độ dài tối đa 32.768 ký tự, bao gồm Unicode ký tự null kết thúc. Nếu lpApplicationName là NULL, phần tên module của lpCommandLine được giới hạn trong MAX_PATH ký tự.

Đưa ra ví dụ của bạn, tôi đề xuất cung cấp giá trị cho thực thi (args [0]) và sử dụng arg cho tham số đầu tiên. Nếu tôi đọc tài liệu CreateProcess và mã nguồn của mô-đun con xử lý là chính xác, điều này sẽ giải quyết vấn đề của bạn.

[chỉnh sửa: đã xóa bit args [1:] sau khi lấy tay trên máy cửa sổ và thử nghiệm]

+0

Tôi không chắc chắn nếu tôi làm theo đề nghị của bạn về việc sử dụng args [1:] cho tham số đầu tiên. Tôi đã cập nhật câu hỏi của mình bằng ví dụ về mã. 1 cho liên kết và mẹo trên CreateProcess –

+0

Tôi đã thử điều này nhưng vẫn còn nhấn một giới hạn: subprocess.Popen (cmd [1:] + đường dẫn, thực thi = cmd [0], stdout = subprocess.PIPE). Bây giờ tôi đang sử dụng 32000 là giới hạn cho chiều dài lệnh và gọi lệnh của tôi nhiều lần và thu thập tất cả đầu ra. Tôi muốn có thể không có 32000 mã hóa cứng nhưng nhận được giá trị đó từ môi trường. –

+0

Cũng như đã đề cập trong tài liệu tôi trích dẫn, giới hạn 32768 được mã hóa cứng trong nguyên hàm CreateProcess (có giới hạn trên cho số nguyên được ký 16 bit, tức là 2 ** 15). Vì list2cmd sẽ thêm dấu ngoặc kép và dấu cách khi xây dựng dòng lệnh, bạn sẽ đạt đến giới hạn đó trước khi tính tổng ([len (a) cho a trong args]) đạt tới 2 ** 15. Không có cách nào để sử dụng các ký tự đại diện để chuyển các đối số của bạn cho tệp thực thi?(ký tự đại diện thường được xử lý bởi tập tin thực thi dưới cửa sổ) –

Các vấn đề liên quan