subprocess --- Quản lý quy trình con¶
Source code: Lib/subprocess.py
Mô-đun subprocess cho phép bạn tạo ra các quy trình mới, kết nối với các đường dẫn đầu vào/đầu ra/lỗi của chúng và lấy mã trả về của chúng. Mô-đun này nhằm thay thế một số mô-đun và chức năng cũ hơn:
os.system
os.spawn*
Bạn có thể tìm thấy thông tin về cách sử dụng mô-đun subprocess để thay thế các mô-đun và chức năng này trong các phần sau.
Xem thêm
PEP 324 -- PEP đề xuất mô-đun quy trình con
sẵn có: not Android, not iOS, not WASI.
Mô-đun này không được hỗ trợ trên mobile platforms hoặc WebAssembly platforms.
Sử dụng Mô-đun subprocess¶
Cách tiếp cận được khuyến nghị để gọi các quy trình con là sử dụng hàm run() cho tất cả các trường hợp sử dụng mà nó có thể xử lý. Đối với các trường hợp sử dụng nâng cao hơn, giao diện Popen cơ bản có thể được sử dụng trực tiếp.
- subprocess.run(args, *, stdin=None, input=None, stdout=None, stderr=None, capture_output=False, shell=False, cwd=None, timeout=None, check=False, encoding=None, errors=None, text=None, env=None, universal_newlines=None, **other_popen_kwargs)¶
Chạy lệnh được mô tả bởi args. Đợi lệnh hoàn tất, sau đó trả về phiên bản
CompletedProcess.Các đối số được hiển thị ở trên chỉ là những đối số phổ biến nhất, được mô tả bên dưới trong Đối số thường được sử dụng (do đó việc sử dụng ký hiệu chỉ từ khóa trong chữ ký viết tắt). Chữ ký đầy đủ của hàm phần lớn giống với chữ ký của hàm tạo
Popen- hầu hết các đối số của hàm này đều được chuyển qua giao diện đó. (timeout, input, check và capture_output thì không.)Nếu capture_output là đúng, thiết bị xuất chuẩn và thiết bị xuất chuẩn sẽ bị ghi lại. Khi được sử dụng, đối tượng
Popenbên trong sẽ tự động được tạo với stdout và stderr đều được đặt thànhPIPE. Các đối số stdout và stderr có thể không được cung cấp cùng lúc với capture_output. Nếu bạn muốn ghi lại và kết hợp cả hai luồng thành một, hãy đặt stdout thànhPIPEvà stderr thànhSTDOUT, thay vì sử dụng capture_output.Một timeout có thể được chỉ định trong vài giây, nó được chuyển nội bộ tới
Popen.communicate(). Nếu hết thời gian chờ, tiến trình con sẽ bị hủy và chờ đợi. Ngoại lệTimeoutExpiredsẽ được kích hoạt lại sau khi quá trình con kết thúc. Bản thân quá trình tạo quy trình ban đầu không thể bị gián đoạn trên nhiều API nền tảng, do đó bạn không được đảm bảo sẽ thấy ngoại lệ hết thời gian chờ cho đến ít nhất sau khi quá trình tạo quy trình mất nhiều thời gian.Đối số input được chuyển tới
Popen.communicate()và do đó chuyển tới stdin của quy trình con. Nếu được sử dụng thì nó phải là một chuỗi byte hoặc một chuỗi nếu encoding hoặc errors được chỉ định hoặc text là đúng. Khi được sử dụng, đối tượngPopenbên trong sẽ tự động được tạo với stdin được đặt thànhPIPEvà đối số stdin cũng có thể không được sử dụng.Nếu check là đúng và quá trình thoát ra với mã thoát khác 0 thì ngoại lệ
CalledProcessErrorsẽ được đưa ra. Các thuộc tính của ngoại lệ đó chứa các đối số, mã thoát, thiết bị xuất chuẩn và thiết bị xuất chuẩn nếu chúng bị bắt.Nếu encoding hoặc errors được chỉ định hoặc text là đúng, các đối tượng tệp cho stdin, stdout và stderr sẽ được mở ở chế độ văn bản bằng cách sử dụng encoding và errors được chỉ định hoặc mặc định
io.TextIOWrapper. Đối số universal_newlines tương đương với text và được cung cấp để tương thích ngược. Theo mặc định, các đối tượng tệp được mở ở chế độ nhị phân.Nếu env không phải là
Nonethì đó phải là ánh xạ xác định các biến môi trường cho quy trình mới; chúng được sử dụng thay vì hành vi mặc định là kế thừa môi trường của quy trình hiện tại. Nó được chuyển trực tiếp đếnPopen. Ánh xạ này có thể là str thành str trên bất kỳ nền tảng nào hoặc byte thành byte trên nền tảng POSIX giống nhưos.environhoặcos.environb.Ví dụ:
>>> subprocess.run(["ls", "-l"]) # doesn không chụp được đầu ra CompletedProcess(args=['ls', '-l'], returncode=0) >>> subprocess.run("exit 1", shell=True, check=True) Traceback (cuộc gọi gần đây nhất): ... subprocess.CalledProcessError: Lệnh 'exit 1' trả về trạng thái thoát khác 0 1 >>> subprocess.run(["ls", "-l", "/dev/null"], capture_output=True) CompletedProcess(args=['ls', '-l', '/dev/null'], returncode=0, stdout=b'crw-rw-rw- 1 gốc gốc 1, 3 ngày 23 tháng 1 16:23 /dev/null\n', stderr=b'')
Added in version 3.5.
Thay đổi trong phiên bản 3.6: Đã thêm thông số encoding và errors
Thay đổi trong phiên bản 3.7: Đã thêm tham số text, làm bí danh dễ hiểu hơn của universal_newlines. Đã thêm tham số capture_output.
Thay đổi trong phiên bản 3.12: Đã thay đổi thứ tự tìm kiếm shell của Windows cho
shell=True. Thư mục hiện tại và%PATH%được thay thế bằng%COMSPEC%và%SystemRoot%\System32\cmd.exe. Kết quả là việc thả chương trình độc hại có têncmd.exevào thư mục hiện tại không còn hoạt động.
- class subprocess.CompletedProcess¶
Giá trị trả về từ
run(), biểu thị một quá trình đã kết thúc.- args¶
Các đối số được sử dụng để khởi động quá trình. Đây có thể là một danh sách hoặc một chuỗi.
- returncode¶
Trạng thái thoát của tiến trình con. Thông thường, trạng thái thoát là 0 cho biết nó đã chạy thành công.
Giá trị âm
-Nchỉ ra rằng phần tử con đã bị chấm dứt bởi tín hiệuN(chỉ POSIX).
- stdout¶
Đã thu được thiết bị xuất chuẩn từ tiến trình con. Một chuỗi byte hoặc một chuỗi nếu
run()được gọi có mã hóa, lỗi hoặc văn bản=True.Nonenếu thiết bị xuất chuẩn không được chụp.Nếu bạn chạy quy trình với
stderr=subprocess.STDOUT, stdout và stderr sẽ được kết hợp trong thuộc tính này vàstderrsẽ làNone.
- stderr¶
Đã thu thập stderr từ tiến trình con. Một chuỗi byte hoặc một chuỗi nếu
run()được gọi có mã hóa, lỗi hoặc văn bản=True.Nonenếu stderr không bị bắt.
- check_returncode()¶
Nếu
returncodekhác 0, hãy tăngCalledProcessError.
Added in version 3.5.
- subprocess.DEVNULL¶
Giá trị đặc biệt có thể được sử dụng làm đối số stdin, stdout hoặc stderr cho
Popenvà cho biết rằng tệp đặc biệtos.devnullsẽ được sử dụng.Added in version 3.3.
- subprocess.PIPE¶
Giá trị đặc biệt có thể được sử dụng làm đối số stdin, stdout hoặc stderr cho
Popenvà cho biết rằng cần mở một đường dẫn đến luồng tiêu chuẩn. Hữu ích nhất vớiPopen.communicate().
- subprocess.STDOUT¶
Giá trị đặc biệt có thể được sử dụng làm đối số stderr cho
Popenvà cho biết rằng lỗi tiêu chuẩn sẽ được xử lý giống như đầu ra tiêu chuẩn.
- exception subprocess.SubprocessError¶
Lớp cơ sở cho tất cả các ngoại lệ khác từ mô-đun này.
Added in version 3.3.
- exception subprocess.TimeoutExpired¶
Lớp con của
SubprocessError, được nâng lên khi hết thời gian chờ trong khi chờ tiến trình con.- cmd¶
Lệnh được sử dụng để sinh ra tiến trình con.
- timeout¶
Thời gian chờ tính bằng giây.
- output¶
Đầu ra của tiến trình con nếu nó được
run()hoặccheck_output()nắm bắt. Nếu không thìNone. Đây luôn làbyteskhi bất kỳ đầu ra nào được ghi lại bất kể cài đặttext=True. Nó có thể vẫn làNonethay vìb''khi không quan sát thấy đầu ra.
- stderr¶
Đầu ra Stderr của tiến trình con nếu nó được
run()ghi lại. Nếu không thìNone. Đây luôn làbyteskhi đầu ra stderr được ghi lại bất kể cài đặttext=True. Nó có thể vẫn làNonethay vìb''khi không quan sát thấy đầu ra stderr.
Added in version 3.3.
Thay đổi trong phiên bản 3.5: Đã thêm thuộc tính stdout và stderr
- exception subprocess.CalledProcessError¶
Lớp con của
SubprocessError, được nâng lên khi một quá trình được chạy bởicheck_call(),check_output()hoặcrun()(vớicheck=True) trả về trạng thái thoát khác 0.- returncode¶
Trạng thái thoát của tiến trình con. Nếu quá trình thoát do tín hiệu, đây sẽ là số tín hiệu âm.
- cmd¶
Lệnh được sử dụng để sinh ra tiến trình con.
- output¶
Đầu ra của tiến trình con nếu nó được
run()hoặccheck_output()nắm bắt. Nếu không thìNone.
Thay đổi trong phiên bản 3.5: Đã thêm thuộc tính stdout và stderr
Đối số thường được sử dụng¶
Để hỗ trợ nhiều trường hợp sử dụng khác nhau, hàm tạo Popen (và các hàm tiện lợi) chấp nhận một số lượng lớn các đối số tùy chọn. Đối với hầu hết các trường hợp sử dụng thông thường, nhiều đối số trong số này có thể được giữ nguyên ở giá trị mặc định một cách an toàn. Các đối số thường được yêu cầu nhất là:
args là bắt buộc đối với tất cả các cuộc gọi và phải là một chuỗi hoặc một chuỗi các đối số chương trình. Việc cung cấp một chuỗi các đối số thường được ưu tiên hơn vì nó cho phép mô-đun xử lý mọi việc thoát và trích dẫn các đối số cần thiết (ví dụ: để cho phép khoảng trắng trong tên tệp). Nếu truyền một chuỗi, shell phải là
True(xem bên dưới) hoặc nếu không thì chuỗi đó chỉ cần đặt tên cho chương trình sẽ được thực thi mà không chỉ định bất kỳ đối số nào.stdin, stdout và stderr chỉ định lần lượt các xử lý đầu vào tiêu chuẩn, đầu ra tiêu chuẩn và xử lý tệp lỗi tiêu chuẩn của chương trình được thực hiện. Các giá trị hợp lệ là
None,PIPE,DEVNULL, bộ mô tả tệp hiện có (số nguyên dương) và file object hiện có với bộ mô tả tệp hợp lệ. Với cài đặt mặc định củaNone, sẽ không có chuyển hướng nào xảy ra.PIPEchỉ ra rằng cần tạo một đường ống mới cho trẻ.DEVNULLchỉ ra rằng tệp đặc biệtos.devnullsẽ được sử dụng. Ngoài ra, stderr có thể làSTDOUT, cho biết rằng dữ liệu stderr từ tiến trình con phải được ghi vào cùng một trình xử lý tệp như đối với stdout.Nếu encoding hoặc errors được chỉ định hoặc text (còn được gọi là universal_newlines) là đúng thì các đối tượng tệp stdin, stdout và stderr sẽ được mở ở chế độ văn bản bằng cách sử dụng encoding và errors được chỉ định trong lệnh gọi hoặc cài đặt mặc định cho
io.TextIOWrapper.Đối với stdin, ký tự kết thúc dòng
'\n'trong đầu vào sẽ được chuyển đổi thành dấu phân cách dòng mặc địnhos.linesep. Đối với stdout và stderr, tất cả các kết thúc dòng ở đầu ra sẽ được chuyển đổi thành'\n'. Để biết thêm thông tin, hãy xem tài liệu về lớpio.TextIOWrapperkhi đối số newline cho hàm tạo của nó làNone.Nếu chế độ văn bản không được sử dụng, stdin, stdout và stderr sẽ được mở dưới dạng luồng nhị phân. Không có chuyển đổi mã hóa hoặc kết thúc dòng nào được thực hiện.
Thay đổi trong phiên bản 3.6: Đã thêm thông số encoding và errors.
Thay đổi trong phiên bản 3.7: Đã thêm tham số text làm bí danh cho universal_newlines.
Ghi chú
Thuộc tính dòng mới của các đối tượng tệp
Popen.stdin,Popen.stdoutvàPopen.stderrkhông được cập nhật bằng phương thứcPopen.communicate().Nếu shell là
True, lệnh được chỉ định sẽ được thực thi thông qua shell. Điều này có thể hữu ích nếu bạn đang sử dụng Python chủ yếu cho luồng điều khiển nâng cao mà nó cung cấp trên hầu hết các shell hệ thống và vẫn muốn truy cập thuận tiện vào các tính năng shell khác như ống shell, ký tự đại diện tên tệp, mở rộng biến môi trường và mở rộng~sang thư mục chính của người dùng. Tuy nhiên, lưu ý rằng bản thân Python cung cấp việc triển khai nhiều tính năng giống shell (cụ thể làglob,fnmatch,os.walk(),os.path.expandvars(),os.path.expanduser()vàshutil).Thay đổi trong phiên bản 3.3: Khi universal_newlines là
True, lớp sử dụng mã hóalocale.getpreferredencoding(False)thay vìlocale.getpreferredencoding(). Xem lớpio.TextIOWrapperđể biết thêm thông tin về thay đổi này.Ghi chú
Đọc phần Security Considerations trước khi sử dụng
shell=True.
Các tùy chọn này, cùng với tất cả các tùy chọn khác, được mô tả chi tiết hơn trong tài liệu về hàm tạo Popen.
Nhà xây dựng Popen¶
Việc tạo và quản lý quy trình cơ bản trong mô-đun này được xử lý bởi lớp Popen. Nó cung cấp rất nhiều tính linh hoạt để các nhà phát triển có thể xử lý các trường hợp ít phổ biến hơn mà các chức năng tiện lợi không đề cập đến.
- class subprocess.Popen(args, bufsize=-1, executable=None, stdin=None, stdout=None, stderr=None, preexec_fn=None, close_fds=True, shell=False, cwd=None, env=None, universal_newlines=None, startupinfo=None, creationflags=0, restore_signals=True, start_new_session=False, pass_fds=(), *, group=None, extra_groups=None, user=None, umask=-1, encoding=None, errors=None, text=None, pipesize=-1, process_group=None)¶
Thực hiện một chương trình con trong một tiến trình mới. Trên POSIX, lớp sử dụng hành vi giống
os.execvpe()để thực thi chương trình con. Trên Windows, lớp sử dụng hàm WindowsCreateProcess(). Các đối số choPopennhư sau.args phải là một chuỗi các đối số chương trình hoặc một chuỗi đơn hoặc path-like object. Theo mặc định, chương trình thực thi là mục đầu tiên trong args nếu args là một chuỗi. Nếu args là một chuỗi thì việc diễn giải sẽ phụ thuộc vào nền tảng và được mô tả bên dưới. Xem các đối số shell và executable để biết thêm những khác biệt so với hành vi mặc định. Trừ khi có quy định khác, bạn nên chuyển args theo trình tự.
Cảnh báo
Để có độ tin cậy tối đa, hãy sử dụng đường dẫn đủ điều kiện cho tệp thực thi. Để tìm kiếm tên không đủ tiêu chuẩn trên
PATH, hãy sử dụngshutil.which(). Trên tất cả các nền tảng, chuyểnsys.executablelà cách được khuyến nghị để khởi chạy lại trình thông dịch Python hiện tại và sử dụng định dạng dòng lệnh-mđể khởi chạy mô-đun đã cài đặt.Việc giải quyết đường dẫn của executable (hoặc mục đầu tiên của args) phụ thuộc vào nền tảng. Đối với POSIX, hãy xem
os.execvpe()và lưu ý rằng khi phân giải hoặc tìm kiếm đường dẫn thực thi, cwd sẽ ghi đè thư mục làm việc hiện tại và env có thể ghi đè biến môi trườngPATH. Đối với Windows, hãy xem tài liệu về các tham sốlpApplicationNamevàlpCommandLinecủa WinAPICreateProcess, đồng thời lưu ý rằng khi phân giải hoặc tìm kiếm đường dẫn thực thi bằngshell=False, cwd không ghi đè thư mục làm việc hiện tại và env không thể ghi đè biến môi trườngPATH. Sử dụng đường dẫn đầy đủ sẽ tránh được tất cả các biến thể này.Một ví dụ về việc chuyển một số đối số sang chương trình bên ngoài dưới dạng một chuỗi là:
Popen(["/usr/bin/git", "commit", "-m", "Sửa lỗi."])
Trên POSIX, nếu args là một chuỗi thì chuỗi đó được hiểu là tên hoặc đường dẫn của chương trình cần thực thi. Tuy nhiên, điều này chỉ có thể thực hiện được nếu không truyền đối số cho chương trình.
Ghi chú
Có thể không rõ ràng về cách chia lệnh shell thành một chuỗi đối số, đặc biệt là trong các trường hợp phức tạp.
shlex.split()có thể minh họa cách xác định mã thông báo chính xác cho args:>>> nhập shlex, quy trình con >>> command_line = đầu vào() /bin/vikings -input egg.txt -output "spam spam.txt" -cmd "echo '$MONEY'" >>> args = shlex.split(command_line) >>> in(args) ['/bin/vikings', '-input', 'eggs.txt', '-output', 'spam spam.txt', '-cmd', "echo '$MONEY'"] >>> p = subprocess.Popen(args) # Success!
Đặc biệt lưu ý rằng các tùy chọn (chẳng hạn như -input) và các đối số (chẳng hạn như eggs.txt) được phân tách bằng khoảng trắng trong shell sẽ nằm trong các thành phần danh sách riêng biệt, trong khi các đối số cần thoát khỏi trích dẫn hoặc dấu gạch chéo ngược khi được sử dụng trong shell (chẳng hạn như tên tệp chứa dấu cách hoặc lệnh echo hiển thị ở trên) là các thành phần danh sách đơn.
Trên Windows, nếu args là một chuỗi, nó sẽ được chuyển đổi thành chuỗi theo cách được mô tả trong Chuyển đổi chuỗi đối số thành chuỗi trên Windows. Điều này là do
CreateProcess()cơ bản hoạt động trên chuỗi.Thay đổi trong phiên bản 3.6: Tham số args chấp nhận path-like object nếu shell là
Falsevà một chuỗi chứa các đối tượng giống đường dẫn trên POSIX.Thay đổi trong phiên bản 3.8: Tham số args chấp nhận path-like object nếu shell là
Falsevà một chuỗi chứa byte và các đối tượng giống đường dẫn trên Windows.Đối số shell (mặc định là
False) chỉ định xem có sử dụng shell làm chương trình để thực thi hay không. Nếu shell làTrue, bạn nên chuyển args dưới dạng một chuỗi thay vì một chuỗi.Trên POSIX với
shell=True, shell mặc định là/bin/sh. Nếu args là một chuỗi, chuỗi đó chỉ định lệnh thực thi thông qua shell. Điều này có nghĩa là chuỗi phải được định dạng chính xác như khi gõ vào dấu nhắc shell. Ví dụ: điều này bao gồm trích dẫn hoặc dấu gạch chéo ngược thoát khỏi tên tệp có dấu cách trong đó. Nếu args là một chuỗi, mục đầu tiên chỉ định chuỗi lệnh và mọi mục bổ sung sẽ được coi là đối số bổ sung cho chính shell. Điều đó có nghĩa là,Popenthực hiện tương đương với:Popen(['/bin/sh', '-c', args[0], args[1], ...])
Trên Windows có
shell=True, biến môi trườngCOMSPECchỉ định shell mặc định. Lần duy nhất bạn cần chỉ địnhshell=Truetrên Windows là khi lệnh bạn muốn thực thi được tích hợp vào shell (ví dụ: dir hoặc copy). Bạn không cầnshell=Trueđể chạy tệp bó hoặc tệp thực thi dựa trên bảng điều khiển.Ghi chú
Đọc phần Security Considerations trước khi sử dụng
shell=True.bufsize sẽ được cung cấp dưới dạng đối số tương ứng cho hàm
open()khi tạo các đối tượng tệp ống stdin/stdout/stderr:0có nghĩa là không có bộ đệm (đọc và ghi là một lệnh gọi hệ thống và có thể trả về ngắn gọn)1có nghĩa là dòng được đệm (chỉ sử dụng được nếutext=Truehoặcuniversal_newlines=True)bất kỳ giá trị dương nào khác có nghĩa là sử dụng bộ đệm có kích thước xấp xỉ đó
bufsize âm (mặc định) có nghĩa là mặc định hệ thống của io.DEFAULT_BUFFER_SIZE sẽ được sử dụng.
Thay đổi trong phiên bản 3.3.1: bufsize hiện được mặc định là -1 để bật tính năng đệm theo mặc định nhằm phù hợp với hành vi mà hầu hết các mã mong đợi. Trong các phiên bản trước Python 3.2.4 và 3.3.1, nó được đặt mặc định không chính xác thành
0, không có bộ đệm và cho phép đọc ngắn. Điều này là vô tình và không phù hợp với hành vi của Python 2 như hầu hết các mã mong đợi.Đối số executable chỉ định chương trình thay thế sẽ thực thi. Nó rất hiếm khi cần thiết. Khi
shell=False, executable thay thế chương trình để thực thi do args chỉ định. Tuy nhiên, args ban đầu vẫn được chuyển vào chương trình. Hầu hết các chương trình đều coi chương trình được chỉ định bởi args làm tên lệnh, khi đó tên này có thể khác với chương trình được thực thi thực sự. Trên POSIX, tên args trở thành tên hiển thị cho tệp thực thi trong các tiện ích như ps. Nếushell=True, trên POSIX đối số executable chỉ định một shell thay thế cho/bin/shmặc định.Thay đổi trong phiên bản 3.6: Tham số executable chấp nhận path-like object trên POSIX.
Thay đổi trong phiên bản 3.8: Tham số executable chấp nhận byte và path-like object trên Windows.
Thay đổi trong phiên bản 3.12: Đã thay đổi thứ tự tìm kiếm shell của Windows cho
shell=True. Thư mục hiện tại và%PATH%được thay thế bằng%COMSPEC%và%SystemRoot%\System32\cmd.exe. Kết quả là việc thả chương trình độc hại có têncmd.exevào thư mục hiện tại không còn hoạt động.stdin, stdout và stderr chỉ định lần lượt các xử lý đầu vào tiêu chuẩn, đầu ra tiêu chuẩn và xử lý tệp lỗi tiêu chuẩn của chương trình được thực thi. Các giá trị hợp lệ là
None,PIPE,DEVNULL, bộ mô tả tệp hiện có (số nguyên dương) và file object hiện có với bộ mô tả tệp hợp lệ. Với cài đặt mặc định củaNone, sẽ không có chuyển hướng nào xảy ra.PIPEchỉ ra rằng cần tạo một đường ống mới cho trẻ.DEVNULLchỉ ra rằng tệp đặc biệtos.devnullsẽ được sử dụng. Ngoài ra, stderr có thể làSTDOUT, cho biết rằng dữ liệu stderr từ các ứng dụng phải được ghi vào cùng một trình xử lý tệp như đối với stdout.Nếu preexec_fn được đặt thành một đối tượng có thể gọi được, đối tượng này sẽ được gọi trong tiến trình con ngay trước khi tiến trình con đó được thực thi. (chỉ POSIX)
Cảnh báo
Tham số preexec_fn là NOT SAFE để sử dụng khi có các luồng trong ứng dụng của bạn. Tiến trình con có thể bị bế tắc trước khi lệnh thực thi được gọi.
Ghi chú
Nếu bạn cần sửa đổi môi trường cho trẻ, hãy sử dụng tham số env thay vì thực hiện trong preexec_fn. Các tham số start_new_session và process_group sẽ thay thế mã sử dụng preexec_fn để gọi
os.setsid()hoặcos.setpgid()ở trẻ em.Thay đổi trong phiên bản 3.8: Tham số preexec_fn không còn được hỗ trợ trong trình thông dịch phụ. Việc sử dụng tham số trong trình thông dịch phụ sẽ tăng
RuntimeError. Hạn chế mới có thể ảnh hưởng đến các ứng dụng được triển khai trong mod_wsgi, uWSGI và các môi trường nhúng khác.Nếu close_fds là đúng, tất cả các bộ mô tả tệp ngoại trừ
0,1và2sẽ bị đóng trước khi tiến trình con được thực thi. Mặt khác, khi close_fds sai, bộ mô tả tệp sẽ tuân theo cờ kế thừa của chúng như được mô tả trong Kế thừa của bộ mô tả tệp.Trên Windows, nếu close_fds là đúng thì sẽ không có bộ điều khiển nào được kế thừa bởi tiến trình con trừ khi được chuyển một cách rõ ràng trong phần tử
handle_listcủaSTARTUPINFO.lpAttributeListhoặc bằng cách chuyển hướng bộ điều khiển tiêu chuẩn.Thay đổi trong phiên bản 3.2: Mặc định cho close_fds đã được thay đổi từ
Falsethành cài đặt được mô tả ở trên.Thay đổi trong phiên bản 3.7: Trên Windows, mặc định cho close_fds đã được thay đổi từ
FalsethànhTruekhi chuyển hướng các thẻ điều khiển tiêu chuẩn. Hiện tại, bạn có thể đặt close_fds thànhTruekhi chuyển hướng các thẻ điều khiển tiêu chuẩn.pass_fds là một chuỗi mô tả tệp tùy chọn để giữ mở giữa cha mẹ và con. Việc cung cấp bất kỳ pass_fds nào đều buộc close_fds phải là
True. (chỉ POSIX)Thay đổi trong phiên bản 3.2: Tham số pass_fds đã được thêm vào.
Nếu cwd không phải là
None, hàm sẽ thay đổi thư mục làm việc thành cwd trước khi thực thi con. cwd có thể là một đối tượng chuỗi, byte hoặc path-like. Trên POSIX, hàm tìm kiếm executable (hoặc mục đầu tiên trong args) liên quan đến cwd nếu đường dẫn thực thi là đường dẫn tương đối.Thay đổi trong phiên bản 3.6: Tham số cwd chấp nhận path-like object trên POSIX.
Thay đổi trong phiên bản 3.7: Tham số cwd chấp nhận path-like object trên Windows.
Thay đổi trong phiên bản 3.8: Tham số cwd chấp nhận đối tượng byte trên Windows.
Nếu restore_signals là đúng (mặc định) thì tất cả các tín hiệu mà Python đã đặt thành SIG_IGN sẽ được khôi phục về SIG_DFL trong tiến trình con trước lệnh thực thi. Hiện tại, điều này bao gồm các tín hiệu SIGPIPE, SIGXFZ và SIGXFSZ. (chỉ POSIX)
Thay đổi trong phiên bản 3.2: restore_signals đã được thêm vào.
Nếu start_new_session đúng, lệnh gọi hệ thống
setsid()sẽ được thực hiện trong tiến trình con trước khi thực thi tiến trình con.sẵn có: POSIX
Thay đổi trong phiên bản 3.2: start_new_session đã được thêm vào.
Nếu process_group là số nguyên không âm, lệnh gọi hệ thống
setpgid(0, value)sẽ được thực hiện trong tiến trình con trước khi thực thi tiến trình con.sẵn có: POSIX
Thay đổi trong phiên bản 3.11: process_group đã được thêm vào.
Nếu group không phải là
None, lệnh gọi hệ thống setregid() sẽ được thực hiện trong tiến trình con trước khi thực thi tiến trình con. Nếu giá trị được cung cấp là một chuỗi, nó sẽ được tra cứu thông quagrp.getgrnam()và giá trị tronggr_gidsẽ được sử dụng. Nếu giá trị là số nguyên, nó sẽ được truyền nguyên văn. (chỉ POSIX)sẵn có: POSIX
Added in version 3.9.
Nếu extra_groups không phải là
None, lệnh gọi hệ thống setgroups() sẽ được thực hiện trong tiến trình con trước khi thực thi tiến trình con. Các chuỗi được cung cấp trong extra_groups sẽ được tra cứu thông quagrp.getgrnam()và các giá trị tronggr_gidsẽ được sử dụng. Các giá trị số nguyên sẽ được truyền nguyên văn. (chỉ POSIX)sẵn có: POSIX
Added in version 3.9.
Nếu user không phải là
None, lệnh gọi hệ thống setreuid() sẽ được thực hiện trong tiến trình con trước khi thực thi tiến trình con. Nếu giá trị được cung cấp là một chuỗi, nó sẽ được tra cứu thông quapwd.getpwnam()và giá trị trongpw_uidsẽ được sử dụng. Nếu giá trị là số nguyên, nó sẽ được truyền nguyên văn. (chỉ POSIX)Ghi chú
Việc chỉ định user sẽ không loại bỏ tư cách thành viên nhóm bổ sung hiện có! Người gọi cũng phải vượt qua
extra_groups=()để giảm tư cách thành viên nhóm của tiến trình con vì mục đích bảo mật.sẵn có: POSIX
Added in version 3.9.
Nếu umask không âm, lệnh gọi hệ thống umask() sẽ được thực hiện trong tiến trình con trước khi thực thi tiến trình con.
sẵn có: POSIX
Added in version 3.9.
Nếu env không phải là
None, thì đó phải là ánh xạ xác định các biến môi trường cho quy trình mới; chúng được sử dụng thay vì hành vi mặc định là kế thừa môi trường của quy trình hiện tại. Ánh xạ này có thể là str thành str trên bất kỳ nền tảng nào hoặc byte thành byte trên nền tảng POSIX giống nhưos.environhoặcos.environb.Ghi chú
Nếu được chỉ định, env phải cung cấp bất kỳ biến nào cần thiết để chương trình thực thi. Trên Windows, để chạy side-by-side assembly, env must được chỉ định phải bao gồm
%SystemRoot%hợp lệ.Nếu encoding hoặc errors được chỉ định hoặc text là đúng, thì các đối tượng tệp stdin, stdout và stderr sẽ được mở ở chế độ văn bản với encoding và errors được chỉ định, như được mô tả ở trên trong Đối số thường được sử dụng. Đối số universal_newlines tương đương với text và được cung cấp để tương thích ngược. Theo mặc định, các đối tượng tệp được mở ở chế độ nhị phân.
Added in version 3.6: encoding và errors đã được thêm vào.
Added in version 3.7: text đã được thêm làm bí danh dễ đọc hơn cho universal_newlines.
Nếu được cung cấp, startupinfo sẽ là một đối tượng
STARTUPINFO, được chuyển đến hàmCreateProcesscơ bản.Nếu được cung cấp, creationflags, có thể là một hoặc nhiều cờ sau:
pipesize có thể được sử dụng để thay đổi kích thước của pipe khi
PIPEđược sử dụng cho stdin, stdout hoặc stderr. Kích thước của đường ống chỉ được thay đổi trên các nền tảng hỗ trợ điều này (chỉ có Linux tại thời điểm viết bài). Các nền tảng khác sẽ bỏ qua tham số này.Thay đổi trong phiên bản 3.10: Đã thêm tham số pipesize.
Các đối tượng Popen được hỗ trợ dưới dạng trình quản lý bối cảnh thông qua câu lệnh
with: khi thoát, các bộ mô tả tệp tiêu chuẩn sẽ bị đóng và quá trình này được chờ đợi.với Popen(["ifconfig"], stdout=PIPE) là Proc: log.write(proc.stdout.read())
Popen và các hàm khác trong mô-đun này sử dụng nó sẽ tạo ra auditing event
subprocess.Popenvới các đối sốexecutable,args,cwdvàenv. Giá trị choargscó thể là một chuỗi đơn hoặc một danh sách các chuỗi, tùy thuộc vào nền tảng.Thay đổi trong phiên bản 3.2: Đã thêm hỗ trợ quản lý bối cảnh.
Thay đổi trong phiên bản 3.6: Hàm hủy Popen hiện phát ra cảnh báo
ResourceWarningnếu tiến trình con vẫn đang chạy.Thay đổi trong phiên bản 3.8: Popen có thể sử dụng
os.posix_spawn()trong một số trường hợp để có hiệu suất tốt hơn. Trên Hệ thống con Windows dành cho Linux và Mô phỏng người dùng QEMU, hàm tạo Popen sử dụngos.posix_spawn()không còn đưa ra ngoại lệ đối với các lỗi như thiếu chương trình, nhưng quy trình con không thành công vớireturncodekhác 0.
Ngoại lệ¶
Các ngoại lệ được đưa ra trong tiến trình con, trước khi chương trình mới bắt đầu thực thi, sẽ được đưa ra lại trong tiến trình mẹ.
Ngoại lệ phổ biến nhất được nêu ra là OSError. Ví dụ: điều này xảy ra khi cố gắng thực thi một tệp không tồn tại. Các ứng dụng nên chuẩn bị cho trường hợp ngoại lệ OSError. Lưu ý rằng, khi shell=True, OSError sẽ chỉ được trẻ nâng lên nếu không tìm thấy chính shell đã chọn. Để xác định xem shell có tìm thấy ứng dụng được yêu cầu hay không, cần kiểm tra mã trả về hoặc đầu ra từ quy trình con.
Một ValueError sẽ được nâng lên nếu Popen được gọi với các đối số không hợp lệ.
check_call() và check_output() sẽ tăng CalledProcessError nếu quá trình được gọi trả về mã trả về khác 0.
Tất cả các hàm và phương thức chấp nhận tham số timeout, chẳng hạn như run() và Popen.communicate() sẽ tăng TimeoutExpired nếu hết thời gian chờ trước khi quá trình thoát.
Tất cả các ngoại lệ được xác định trong mô-đun này đều kế thừa từ SubprocessError.
Added in version 3.3: Lớp cơ sở SubprocessError đã được thêm vào.
Cân nhắc về bảo mật¶
Không giống như một số hàm popen khác, thư viện này sẽ không ngầm chọn gọi shell hệ thống. Điều này có nghĩa là tất cả các ký tự, bao gồm cả siêu ký tự shell, có thể được chuyển đến các tiến trình con một cách an toàn. Nếu shell được gọi một cách rõ ràng, thông qua shell=True, thì trách nhiệm của ứng dụng là đảm bảo rằng tất cả khoảng trắng và siêu ký tự đều được trích dẫn một cách thích hợp để tránh các lỗ hổng shell injection. Trên some platforms, có thể sử dụng shlex.quote() để thoát này.
Trên Windows, các tệp bó (*.bat hoặc *.cmd) có thể được hệ điều hành khởi chạy trong shell hệ thống bất kể các đối số được chuyển đến thư viện này. Điều này có thể dẫn đến các đối số được phân tích cú pháp theo quy tắc shell, nhưng không có bất kỳ lối thoát nào được Python thêm vào. Nếu bạn cố tình khởi chạy một tệp bó có đối số từ các nguồn không đáng tin cậy, hãy xem xét chuyển shell=True để cho phép Python thoát các ký tự đặc biệt. Xem gh-114539 để thảo luận thêm.
Đối tượng Popen¶
Các phiên bản của lớp Popen có các phương thức sau:
- Popen.poll()¶
Kiểm tra xem tiến trình con đã kết thúc chưa. Đặt và trả về thuộc tính
returncode. Nếu không, trả vềNone.
- Popen.wait(timeout=None)¶
Đợi quá trình con kết thúc. Đặt và trả về thuộc tính
returncode.Nếu quá trình không kết thúc sau timeout giây, hãy đưa ra ngoại lệ
TimeoutExpired. Việc bắt ngoại lệ này và thử lại việc chờ đợi là an toàn.Ghi chú
Điều này sẽ bế tắc khi sử dụng
stdout=PIPEhoặcstderr=PIPEvà quy trình con tạo ra đủ đầu ra cho một đường ống sao cho nó chặn việc chờ bộ đệm đường ống hệ điều hành chấp nhận nhiều dữ liệu hơn. Sử dụngPopen.communicate()khi sử dụng ống để tránh điều đó.Ghi chú
Khi tham số
timeoutkhông phải làNonethì (trên POSIX) chức năng này sẽ được triển khai bằng vòng lặp bận (cuộc gọi không chặn và thời gian ngủ ngắn). Sử dụng mô-đunasynciođể chờ không đồng bộ: xemasyncio.create_subprocess_exec.Thay đổi trong phiên bản 3.3: timeout đã được thêm vào.
- Popen.communicate(input=None, timeout=None)¶
Tương tác với tiến trình: Gửi dữ liệu tới stdin. Đọc dữ liệu từ thiết bị xuất chuẩn và thiết bị xuất chuẩn, cho đến khi đạt đến cuối tệp. Đợi quá trình kết thúc và đặt thuộc tính
returncode. Đối số input tùy chọn phải là dữ liệu được gửi đến tiến trình con hoặcNonenếu không có dữ liệu nào được gửi đến tiến trình con. Nếu luồng được mở ở chế độ văn bản, input phải là một chuỗi. Nếu không thì nó phải là byte.communicate()trả về một bộ(stdout_data, stderr_data). Dữ liệu sẽ ở dạng chuỗi nếu luồng được mở ở chế độ văn bản; mặt khác, byte.Lưu ý rằng nếu bạn muốn gửi dữ liệu đến stdin của tiến trình, bạn cần tạo đối tượng Popen bằng
stdin=PIPE. Tương tự, để nhận được bất kỳ thứ gì khác ngoàiNonetrong bộ kết quả, bạn cũng cần cung cấpstdout=PIPEvà/hoặcstderr=PIPE.Nếu quá trình không kết thúc sau timeout giây, một ngoại lệ
TimeoutExpiredsẽ được đưa ra. Bắt ngoại lệ này và thử lại giao tiếp sẽ không mất bất kỳ đầu ra nào. Việc cung cấp input cho lệnh gọicommunicate()sau thời gian chờ tiếp theo có hành vi không xác định và có thể trở thành lỗi trong tương lai.Quá trình con không bị hủy nếu hết thời gian chờ, do đó, để dọn dẹp đúng cách, một ứng dụng hoạt động tốt phải hủy tiến trình con và kết thúc giao tiếp:
proc = subprocess.Popen(...) thử: outs, errs = proc.communicate(timeout=15) ngoại trừ Hết thời gian chờHết hạn: proc.kill() outs, errs = proc.communicate()
Sau khi gọi tới
communicate(),TimeoutExpiredsẽ tăng lên, đừng gọiwait(). Sử dụng lệnh gọicommunicate()bổ sung để hoàn tất việc xử lý các đường ống và điền thuộc tínhreturncode.Ghi chú
Dữ liệu đọc được lưu vào bộ nhớ đệm, vì vậy không sử dụng phương pháp này nếu kích thước dữ liệu lớn hoặc không giới hạn.
Thay đổi trong phiên bản 3.3: timeout đã được thêm vào.
- Popen.send_signal(signal)¶
Gửi tín hiệu signal cho trẻ.
Không làm gì nếu quá trình hoàn thành.
Ghi chú
Trên Windows, SIGTERM là bí danh của
terminate(). CTRL_C_EVENT và CTRL_BREAK_EVENT có thể được gửi đến các tiến trình được bắt đầu bằng tham số creationflags bao gồmCREATE_NEW_PROCESS_GROUP.
- Popen.terminate()¶
Dừng con lại. Trên hệ điều hành POSIX, phương thức này sẽ gửi
SIGTERMcho trẻ. Trên Windows, hàm APITerminateProcess()của Win32 được gọi để ngăn chặn trẻ em.
- Popen.kill()¶
Giết chết đứa trẻ. Trên hệ điều hành POSIX, hàm này sẽ gửi SIGKILL cho trẻ. Trên Windows
kill()là bí danh củaterminate().
Các thuộc tính sau cũng được lớp đặt để bạn truy cập. Việc gán lại chúng cho các giá trị mới không được hỗ trợ:
- Popen.args¶
Đối số args khi nó được chuyển tới
Popen-- một chuỗi các đối số chương trình hoặc một chuỗi đơn.Added in version 3.3.
- Popen.stdin¶
Nếu đối số stdin là
PIPE, thuộc tính này là một đối tượng luồng có thể ghi được trả về bởiopen(). Nếu đối số encoding hoặc errors được chỉ định hoặc đối số text hoặc universal_newlines làTruethì luồng đó là luồng văn bản, nếu không thì đó là luồng byte. Nếu đối số stdin không phải làPIPEthì thuộc tính này làNone.
- Popen.stdout¶
Nếu đối số stdout là
PIPEthì thuộc tính này là một đối tượng luồng có thể đọc được và được trả về bởiopen(). Đọc từ luồng cung cấp đầu ra từ tiến trình con. Nếu đối số encoding hoặc errors được chỉ định hoặc đối số text hoặc universal_newlines làTruethì luồng đó là luồng văn bản, nếu không thì đó là luồng byte. Nếu đối số stdout không phải làPIPEthì thuộc tính này làNone.
- Popen.stderr¶
Nếu đối số stderr là
PIPEthì thuộc tính này là một đối tượng luồng có thể đọc được và được trả về bởiopen(). Việc đọc từ luồng cung cấp đầu ra lỗi từ tiến trình con. Nếu đối số encoding hoặc errors được chỉ định hoặc đối số text hoặc universal_newlines làTruethì luồng đó là luồng văn bản, nếu không thì đó là luồng byte. Nếu đối số stderr không phải làPIPEthì thuộc tính này làNone.
Cảnh báo
Sử dụng communicate() thay vì .stdin.write, .stdout.read hoặc .stderr.read để tránh bế tắc do bất kỳ bộ đệm đường ống hệ điều hành nào khác lấp đầy và chặn tiến trình con.
- Popen.pid¶
ID tiến trình của tiến trình con.
Lưu ý rằng nếu bạn đặt đối số shell thành
Truethì đây là ID tiến trình của shell được sinh ra.
- Popen.returncode¶
Mã trả về của trẻ. Ban đầu
None,returncodeđược thiết lập bằng lệnh gọi tới các phương thứcpoll(),wait()hoặccommunicate()nếu chúng phát hiện rằng quá trình đã kết thúc.Giá trị
Nonecho biết quy trình chưa kết thúc tại thời điểm gọi phương thức cuối cùng.Giá trị âm
-Nchỉ ra rằng phần tử con đã bị chấm dứt bởi tín hiệuN(chỉ POSIX).Khi
shell=True, mã trả về phản ánh trạng thái thoát của chính shell (ví dụ:/bin/sh), có thể ánh xạ tín hiệu tới các mã như128+N. Xem tài liệu về shell (ví dụ: Trạng thái thoát của hướng dẫn sử dụng Bash) để biết chi tiết.
Trình trợ giúp Windows Popen¶
Lớp STARTUPINFO và các hằng số sau chỉ có trên Windows.
- class subprocess.STARTUPINFO(*, dwFlags=0, hStdInput=None, hStdOutput=None, hStdError=None, wShowWindow=0, lpAttributeList=None)¶
Hỗ trợ một phần cấu trúc STARTUPINFO của Windows được sử dụng để tạo
Popen. Các thuộc tính sau có thể được đặt bằng cách chuyển chúng dưới dạng đối số chỉ từ khóa.Thay đổi trong phiên bản 3.7: Hỗ trợ đối số chỉ từ khóa đã được thêm vào.
- dwFlags¶
Trường bit xác định xem các thuộc tính
STARTUPINFOnhất định có được sử dụng hay không khi quá trình tạo cửa sổ.si = subprocess.STARTUPINFO() si.dwFlags = subprocess.STARTF_USESTDHANDLES | subprocess.STARTF_USESHOWWINDOW
- hStdInput¶
Nếu
dwFlagschỉ địnhSTARTF_USESTDHANDLES, thuộc tính này là bộ điều khiển đầu vào tiêu chuẩn cho quy trình. NếuSTARTF_USESTDHANDLESkhông được chỉ định, mặc định cho đầu vào tiêu chuẩn là bộ đệm bàn phím.
- hStdOutput¶
Nếu
dwFlagschỉ địnhSTARTF_USESTDHANDLES, thuộc tính này là bộ điều khiển đầu ra tiêu chuẩn cho quy trình. Nếu không, thuộc tính này sẽ bị bỏ qua và mặc định cho đầu ra tiêu chuẩn là bộ đệm của cửa sổ bảng điều khiển.
- hStdError¶
Nếu
dwFlagschỉ địnhSTARTF_USESTDHANDLES, thuộc tính này là phần xử lý lỗi tiêu chuẩn cho quy trình. Nếu không, thuộc tính này sẽ bị bỏ qua và mặc định cho lỗi tiêu chuẩn là bộ đệm của cửa sổ bảng điều khiển.
- wShowWindow¶
Nếu
dwFlagschỉ địnhSTARTF_USESHOWWINDOW, thuộc tính này có thể là bất kỳ giá trị nào có thể được chỉ định trong tham sốnCmdShowcho hàm ShowWindow, ngoại trừSW_SHOWDEFAULT. Ngược lại, thuộc tính này sẽ bị bỏ qua.SW_HIDEđược cung cấp cho thuộc tính này. Nó được sử dụng khiPopenđược gọi bằngshell=True.
- lpAttributeList¶
Từ điển các thuộc tính bổ sung để tạo quy trình như được cung cấp trong
STARTUPINFOEX, xem UpdateProcThreadAttribute.Các thuộc tính được hỗ trợ:
- handle_list
Trình tự các tay cầm sẽ được kế thừa. close_fds phải đúng nếu không trống.
Các thẻ điều khiển phải được
os.set_handle_inheritable()tạm thời có thể kế thừa khi được chuyển tới hàm tạoPopen, nếu không,OSErrorsẽ xuất hiện với lỗi WindowsERROR_INVALID_PARAMETER(87).Cảnh báo
Trong quy trình đa luồng, hãy thận trọng để tránh rò rỉ các thẻ điều khiển được đánh dấu là có thể kế thừa khi kết hợp tính năng này với lệnh gọi đồng thời tới các hàm tạo quy trình khác kế thừa tất cả các thẻ điều khiển như
os.system(). Điều này cũng áp dụng cho việc chuyển hướng tay cầm tiêu chuẩn, tạm thời tạo ra các tay cầm có thể kế thừa.
Added in version 3.7.
Hằng số Windows¶
Mô-đun subprocess hiển thị các hằng số sau.
- subprocess.STD_INPUT_HANDLE¶
Thiết bị đầu vào tiêu chuẩn Ban đầu, đây là bộ đệm đầu vào của bảng điều khiển,
CONIN$.
- subprocess.STD_OUTPUT_HANDLE¶
Thiết bị đầu ra tiêu chuẩn. Ban đầu, đây là bộ đệm màn hình bảng điều khiển đang hoạt động,
CONOUT$.
- subprocess.STD_ERROR_HANDLE¶
Thiết bị lỗi tiêu chuẩn. Ban đầu, đây là bộ đệm màn hình bảng điều khiển đang hoạt động,
CONOUT$.
- subprocess.SW_HIDE¶
Ẩn cửa sổ. Một cửa sổ khác sẽ được kích hoạt.
- subprocess.STARTF_USESTDHANDLES¶
Chỉ định rằng các thuộc tính
STARTUPINFO.hStdInput,STARTUPINFO.hStdOutputvàSTARTUPINFO.hStdErrorchứa thông tin bổ sung.
- subprocess.STARTF_USESHOWWINDOW¶
Chỉ định rằng thuộc tính
STARTUPINFO.wShowWindowchứa thông tin bổ sung.
- subprocess.STARTF_FORCEONFEEDBACK¶
Tham số
STARTUPINFO.dwFlagsđể chỉ định rằng con trỏ chuột Working in Background sẽ được hiển thị trong khi một tiến trình đang khởi chạy. Đây là hành vi mặc định cho các tiến trình GUI.Added in version 3.13.
- subprocess.STARTF_FORCEOFFFEEDBACK¶
Tham số
STARTUPINFO.dwFlagsđể chỉ định rằng con trỏ chuột sẽ không bị thay đổi khi khởi chạy một tiến trình.Added in version 3.13.
- subprocess.CREATE_NEW_CONSOLE¶
Quy trình mới có bảng điều khiển mới, thay vì kế thừa bảng điều khiển gốc của nó (mặc định).
- subprocess.CREATE_NEW_PROCESS_GROUP¶
Tham số
Popencreationflagsđể chỉ định rằng một nhóm quy trình mới sẽ được tạo. Cờ này là cần thiết để sử dụngos.kill()trên quy trình con.Cờ này bị bỏ qua nếu
CREATE_NEW_CONSOLEđược chỉ định.
- subprocess.ABOVE_NORMAL_PRIORITY_CLASS¶
Tham số
Popencreationflagsđể chỉ định rằng một quy trình mới sẽ có mức độ ưu tiên trên mức trung bình.Added in version 3.7.
- subprocess.BELOW_NORMAL_PRIORITY_CLASS¶
Tham số
Popencreationflagsđể chỉ định rằng một quy trình mới sẽ có mức độ ưu tiên dưới mức trung bình.Added in version 3.7.
- subprocess.HIGH_PRIORITY_CLASS¶
Tham số
Popencreationflagsđể chỉ định rằng một quy trình mới sẽ có mức độ ưu tiên cao.Added in version 3.7.
- subprocess.IDLE_PRIORITY_CLASS¶
Tham số
Popencreationflagsđể chỉ định rằng một quy trình mới sẽ có mức độ ưu tiên không hoạt động (thấp nhất).Added in version 3.7.
- subprocess.NORMAL_PRIORITY_CLASS¶
Tham số
Popencreationflagsđể chỉ định rằng một quy trình mới sẽ có mức độ ưu tiên bình thường. (mặc định)Added in version 3.7.
- subprocess.REALTIME_PRIORITY_CLASS¶
Tham số
Popencreationflagsđể chỉ định rằng một quy trình mới sẽ có mức độ ưu tiên theo thời gian thực. Bạn hầu như không bao giờ nên sử dụng REALTIME_PRIORITY_CLASS vì điều này làm gián đoạn các luồng hệ thống quản lý hoạt động nhập chuột, nhập bàn phím và xóa đĩa nền. Lớp này có thể thích hợp cho các ứng dụng "giao tiếp" trực tiếp với phần cứng hoặc thực hiện các tác vụ ngắn gọn và hạn chế bị gián đoạn.Added in version 3.7.
- subprocess.CREATE_NO_WINDOW¶
Tham số
Popencreationflagsđể chỉ định rằng một quy trình mới sẽ không tạo cửa sổ.Added in version 3.7.
- subprocess.DETACHED_PROCESS¶
Tham số
Popencreationflagsđể chỉ định rằng một quy trình mới sẽ không kế thừa bảng điều khiển gốc của nó. Giá trị này không thể được sử dụng với CREATE_NEW_CONSOLE.Added in version 3.7.
- subprocess.CREATE_DEFAULT_ERROR_MODE¶
Tham số
Popencreationflagsđể chỉ định rằng một quy trình mới không kế thừa chế độ lỗi của quy trình gọi. Thay vào đó, quy trình mới sẽ có chế độ lỗi mặc định. Tính năng này đặc biệt hữu ích cho các ứng dụng shell đa luồng chạy với các lỗi cứng bị tắt.Added in version 3.7.
API cấp cao cũ hơn¶
Trước Python 3.5, ba hàm này bao gồm API cấp cao cho subprocess. Bây giờ bạn có thể sử dụng run() trong nhiều trường hợp, nhưng rất nhiều mã hiện có gọi các hàm này.
- subprocess.call(args, *, stdin=None, stdout=None, stderr=None, shell=False, cwd=None, timeout=None, **other_popen_kwargs)¶
Chạy lệnh được mô tả bởi args. Đợi lệnh hoàn thành rồi trả về thuộc tính
returncode.Mã cần chụp thiết bị xuất chuẩn hoặc thiết bị xuất chuẩn nên sử dụng
run()thay thếchạy(...).returncode
Để chặn thiết bị xuất chuẩn hoặc thiết bị xuất chuẩn, hãy cung cấp giá trị
DEVNULL.Những lập luận trình bày ở trên chỉ là một số lý lẽ phổ biến. Chữ ký hàm đầy đủ giống với chữ ký của hàm tạo
Popen- hàm này chuyển trực tiếp tất cả các đối số được cung cấp ngoài timeout tới giao diện đó.Ghi chú
Không sử dụng
stdout=PIPEhoặcstderr=PIPEvới chức năng này. Quá trình con sẽ chặn nếu nó tạo ra đủ đầu ra cho một đường ống để lấp đầy bộ đệm đường ống của hệ điều hành vì các đường ống không được đọc từ đó.Thay đổi trong phiên bản 3.3: timeout đã được thêm vào.
Thay đổi trong phiên bản 3.12: Đã thay đổi thứ tự tìm kiếm shell của Windows cho
shell=True. Thư mục hiện tại và%PATH%được thay thế bằng%COMSPEC%và%SystemRoot%\System32\cmd.exe. Kết quả là việc thả chương trình độc hại có têncmd.exevào thư mục hiện tại không còn hoạt động.
- subprocess.check_call(args, *, stdin=None, stdout=None, stderr=None, shell=False, cwd=None, timeout=None, **other_popen_kwargs)¶
Chạy lệnh với các đối số. Chờ lệnh hoàn tất. Nếu mã trả về bằng 0 thì trả về, nếu không thì tăng
CalledProcessError. Đối tượngCalledProcessErrorsẽ có mã trả về trong thuộc tínhreturncode. Nếucheck_call()không thể bắt đầu quá trình, nó sẽ truyền bá ngoại lệ đã được nêu ra.Mã cần chụp thiết bị xuất chuẩn hoặc thiết bị xuất chuẩn nên sử dụng
run()thay thếrun(..., check=True)
Để chặn thiết bị xuất chuẩn hoặc thiết bị xuất chuẩn, hãy cung cấp giá trị
DEVNULL.Những lập luận trình bày ở trên chỉ là một số lý lẽ phổ biến. Chữ ký hàm đầy đủ giống với chữ ký của hàm tạo
Popen- hàm này chuyển trực tiếp tất cả các đối số được cung cấp ngoài timeout tới giao diện đó.Ghi chú
Không sử dụng
stdout=PIPEhoặcstderr=PIPEvới chức năng này. Quá trình con sẽ chặn nếu nó tạo ra đủ đầu ra cho một đường ống để lấp đầy bộ đệm đường ống của hệ điều hành vì các đường ống không được đọc từ đó.Thay đổi trong phiên bản 3.3: timeout đã được thêm vào.
Thay đổi trong phiên bản 3.12: Đã thay đổi thứ tự tìm kiếm shell của Windows cho
shell=True. Thư mục hiện tại và%PATH%được thay thế bằng%COMSPEC%và%SystemRoot%\System32\cmd.exe. Kết quả là việc thả chương trình độc hại có têncmd.exevào thư mục hiện tại không còn hoạt động.
- subprocess.check_output(args, *, stdin=None, stderr=None, shell=False, cwd=None, encoding=None, errors=None, universal_newlines=None, timeout=None, text=None, **other_popen_kwargs)¶
Chạy lệnh với các đối số và trả về đầu ra của nó.
Nếu mã trả về khác 0, nó sẽ tăng
CalledProcessError. Đối tượngCalledProcessErrorsẽ có mã trả về trong thuộc tínhreturncodevà bất kỳ đầu ra nào trong thuộc tínhoutput.Điều này tương đương với:
run(..., check=True, stdout=PIPE).stdout
Những lập luận trình bày ở trên chỉ là một số lý lẽ phổ biến. Chữ ký đầy đủ của hàm phần lớn giống với chữ ký của
run()- hầu hết các đối số được truyền trực tiếp qua giao diện đó. Tồn tại một sai lệch API so với hành vi củarun(): truyềninput=Nonesẽ hoạt động giống nhưinput=b''(hoặcinput='', tùy thuộc vào các đối số khác) thay vì sử dụng trình xử lý tệp đầu vào tiêu chuẩn của cha mẹ.Theo mặc định, hàm này sẽ trả về dữ liệu dưới dạng byte được mã hóa. Việc mã hóa thực tế của dữ liệu đầu ra có thể phụ thuộc vào lệnh được gọi, do đó việc giải mã thành văn bản thường cần được xử lý ở cấp ứng dụng.
Hành vi này có thể bị ghi đè bằng cách đặt text, encoding, errors hoặc universal_newlines thành
Truenhư được mô tả trong Đối số thường được sử dụng vàrun().Để ghi lại lỗi tiêu chuẩn trong kết quả, hãy sử dụng
stderr=subprocess.STDOUT:>>> subprocess.check_output( ... "ls non_exist_file; thoát 0", ... stderr=subprocess.STDOUT, ... vỏ=Đúng) 'ls: non_exist_file: Không có tập tin hoặc thư mục như vậy\n'
Added in version 3.1.
Thay đổi trong phiên bản 3.3: timeout đã được thêm vào.
Thay đổi trong phiên bản 3.4: Hỗ trợ cho đối số từ khóa input đã được thêm vào.
Thay đổi trong phiên bản 3.6: encoding và errors đã được thêm vào. Xem
run()để biết chi tiết.Added in version 3.7: text đã được thêm làm bí danh dễ đọc hơn cho universal_newlines.
Thay đổi trong phiên bản 3.12: Đã thay đổi thứ tự tìm kiếm shell của Windows cho
shell=True. Thư mục hiện tại và%PATH%được thay thế bằng%COMSPEC%và%SystemRoot%\System32\cmd.exe. Kết quả là việc thả chương trình độc hại có têncmd.exevào thư mục hiện tại không còn hoạt động.
Thay thế các chức năng cũ hơn bằng Mô-đun subprocess¶
Trong phần này, “a trở thành b” có nghĩa là b có thể được dùng thay thế cho a.
Ghi chú
Tất cả các hàm "a" trong phần này đều bị lỗi (ít nhiều) trong âm thầm nếu không tìm thấy chương trình đã thực thi; thay thế "b" sẽ tăng OSError.
Ngoài ra, các thay thế bằng check_output() sẽ không thành công với CalledProcessError nếu thao tác được yêu cầu tạo ra mã trả về khác 0. Đầu ra vẫn có sẵn dưới dạng thuộc tính output của ngoại lệ được nêu ra.
Trong các ví dụ sau, chúng tôi giả định rằng các hàm liên quan đã được nhập từ mô-đun subprocess.
Thay thế thay thế lệnh shell /bin/sh¶
đầu ra=$(mycmd myarg)
trở thành:
đầu ra = check_output(["mycmd", "myarg"])
Thay thế đường ống vỏ¶
đầu ra=$(dmesg | grep hda)
trở thành:
p1 = Popen(["dmesg"], stdout=PIPE)
p2 = Popen(["grep", "hda"], stdin=p1.stdout, stdout=PIPE)
p1.stdout.close() # Allow p1 để nhận SIGPIPE nếu p2 thoát.
đầu ra = p2.communicate()[0]
Cuộc gọi p1.stdout.close() sau khi khởi động p2 rất quan trọng để p1 nhận được SIGPIPE nếu p2 thoát trước p1.
Ngoài ra, đối với đầu vào đáng tin cậy, hỗ trợ đường ống riêng của shell vẫn có thể được sử dụng trực tiếp:
đầu ra=$(dmesg | grep hda)
trở thành:
đầu ra = check_output("dmesg | grep hda", shell=True)
Thay thế os.system()¶
sts = os.system("mycmd" + "myarg")
# becomes
retcode = call("mycmd" + " myarg", shell=True)
Ghi chú:
Việc gọi chương trình thông qua shell thường không cần thiết.
Giá trị trả về của
call()được mã hóa khác với giá trị củaos.system().Hàm
os.system()bỏ qua các tín hiệu SIGINT và SIGQUIT trong khi lệnh đang chạy, nhưng người gọi phải thực hiện việc này một cách riêng biệt khi sử dụng mô-đunsubprocess.
Một ví dụ thực tế hơn sẽ như thế này:
thử:
retcode = call("mycmd" + " myarg", shell=True)
nếu mã hóa lại < 0:
print("Con đã bị chấm dứt bởi tín hiệu", -retcode, file=sys.stderr)
khác:
print("Con được trả về", retcode, file=sys.stderr)
ngoại trừ OSError là e:
print("Thực thi thất bại:", e, file=sys.stderr)
Thay thế gia đình os.spawn¶
ví dụ về P_NOWAIT:
pid = os.spawnlp(os.P_NOWAIT, "/bin/mycmd", "mycmd", "myarg")
==>
pid = Popen(["/bin/mycmd", "myarg"]).pid
ví dụ về P_WAIT:
retcode = os.spawnlp(os.P_WAIT, "/bin/mycmd", "mycmd", "myarg")
==>
retcode = call(["/bin/mycmd", "myarg"])
Ví dụ về vectơ:
os.spawnvp(os.P_NOWAIT, đường dẫn, args)
==>
Popen([path] + args[1:])
Ví dụ về môi trường:
os.spawnlpe(os.P_NOWAIT, "/bin/mycmd", "mycmd", "myarg", env)
==>
Popen(["/bin/mycmd", "myarg"], env={"PATH": "/usr/bin"})
Thay thế os.popen()¶
Việc xử lý mã trả về được dịch như sau:
pipe = os.popen(cmd, 'w')
...
rc = pipe.close()
nếu rc không phải là None và rc >> 8:
print("Có một số lỗi")
==>
quá trình = Popen(cmd, stdin=PIPE)
...
quá trình.stdin.close()
nếu process.wait() != 0:
print("Có một số lỗi")
Chức năng gọi Shell kế thừa¶
Mô-đun này cũng cung cấp các chức năng kế thừa sau từ mô-đun 2.x commands. Các hoạt động này ngầm gọi shell hệ thống và không có đảm bảo nào được mô tả ở trên về tính nhất quán trong xử lý bảo mật và ngoại lệ là hợp lệ cho các chức năng này.
- subprocess.getstatusoutput(cmd, *, encoding=None, errors=None)¶
Trả về
(exitcode, output)khi thực thi cmd trong shell.Thực thi chuỗi cmd trong shell với
check_output()và trả về(exitcode, output)gồm 2 bộ. encoding và errors được sử dụng để giải mã đầu ra; xem ghi chú trên Đối số thường được sử dụng để biết thêm chi tiết.Dòng mới ở cuối bị loại bỏ khỏi đầu ra. Mã thoát cho lệnh có thể được hiểu là mã trả về của subprocess. Ví dụ:
>>> subprocess.getstatusoutput('ls /bin/ls') (0, '/bin/ls') >>> subprocess.getstatusoutput('cat /bin/junk') (1, 'cat: /bin/junk: Không có tập tin hoặc thư mục như vậy') >>> subprocess.getstatusoutput('/bin/junk') (127, 'sh:/bin/rác: không tìm thấy') >>> subprocess.getstatusoutput('/bin/kill $$') (-15, '')
sẵn có: Unix, Windows.
Thay đổi trong phiên bản 3.3.4: Hỗ trợ Windows đã được thêm vào.
Hàm bây giờ trả về (exitcode, đầu ra) thay vì (trạng thái, đầu ra) như trong Python 3.3.3 trở về trước. mã thoát có cùng giá trị với
returncode.Thay đổi trong phiên bản 3.11: Đã thêm thông số encoding và errors.
- subprocess.getoutput(cmd, *, encoding=None, errors=None)¶
Trả về đầu ra (stdout và stderr) của việc thực thi cmd trong shell.
Giống như
getstatusoutput(), ngoại trừ mã thoát bị bỏ qua và giá trị trả về là một chuỗi chứa đầu ra của lệnh. Ví dụ:>>> subprocess.getoutput('ls /bin/ls') '/bin/ls'
sẵn có: Unix, Windows.
Thay đổi trong phiên bản 3.3.4: Đã thêm hỗ trợ Windows
Thay đổi trong phiên bản 3.11: Đã thêm thông số encoding và errors.
Ghi chú¶
Hành vi hết thời gian chờ¶
Khi sử dụng tham số timeout trong các hàm như run(), Popen.wait() hoặc Popen.communicate(), người dùng nên lưu ý các hành vi sau:
Process Creation Delay: Quá trình tạo quy trình ban đầu không thể bị gián đoạn trên nhiều API nền tảng. Điều này có nghĩa là ngay cả khi chỉ định thời gian chờ, bạn không được đảm bảo sẽ thấy ngoại lệ hết thời gian chờ cho đến ít nhất sau khi quá trình tạo quá trình mất nhiều thời gian.
Extremely Small Timeout Values: Việc đặt các giá trị thời gian chờ rất nhỏ (chẳng hạn như vài mili giây) có thể dẫn đến các ngoại lệ gần như ngay lập tức đối với
TimeoutExpiredvì việc tạo quy trình và lập lịch hệ thống vốn dĩ đã yêu cầu thời gian.
Chuyển đổi chuỗi đối số thành chuỗi trên Windows¶
Trên Windows, chuỗi args được chuyển đổi thành chuỗi có thể được phân tích cú pháp bằng các quy tắc sau (tương ứng với các quy tắc được sử dụng trong thời gian chạy MS C):
Các đối số được phân cách bằng khoảng trắng, đó là khoảng trắng hoặc tab.
Một chuỗi được bao quanh bởi dấu ngoặc kép được hiểu là một đối số duy nhất, bất kể khoảng trắng chứa bên trong. Một chuỗi trích dẫn có thể được nhúng vào một đối số.
Dấu ngoặc kép đứng trước dấu gạch chéo ngược được hiểu là dấu ngoặc kép theo nghĩa đen.
Dấu gạch chéo ngược được hiểu theo nghĩa đen, trừ khi chúng ngay trước dấu ngoặc kép.
Nếu dấu gạch chéo ngược ngay trước dấu ngoặc kép thì mỗi cặp dấu gạch chéo ngược được hiểu là dấu gạch chéo ngược theo nghĩa đen. Nếu số dấu gạch chéo ngược là số lẻ thì dấu gạch chéo ngược cuối cùng sẽ thoát khỏi dấu ngoặc kép tiếp theo như được mô tả trong quy tắc 3.
Xem thêm
shlexMô-đun cung cấp chức năng phân tích cú pháp và thoát dòng lệnh.
Vô hiệu hóa việc sử dụng posix_spawn()¶
Trên Linux, subprocess mặc định sử dụng lệnh gọi hệ thống vfork() nội bộ khi thấy an toàn để thực hiện điều đó thay vì fork(). Điều này cải thiện đáng kể hiệu suất.
subprocess._USE_POSIX_SPAWN = Sai # See CPython phát hành gh-NNNNNN.
Việc đặt giá trị này thành sai trên bất kỳ phiên bản Python nào là an toàn. Nó sẽ không có hiệu lực đối với các phiên bản cũ hơn hoặc mới hơn nếu không được hỗ trợ. Đừng cho rằng thuộc tính có sẵn để đọc. Bất chấp tên gọi, giá trị thực không cho biết hàm tương ứng sẽ được sử dụng, chỉ có thể là như vậy.
Vui lòng gửi các vấn đề bất cứ khi nào bạn phải sử dụng các núm riêng tư này để tìm cách tái tạo sự cố mà bạn đang gặp phải. Liên kết đến vấn đề đó từ nhận xét trong mã của bạn.
Added in version 3.8: _USE_POSIX_SPAWN