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, checkcapture_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 Popen bên trong sẽ tự động được tạo với stdoutstderr đều được đặt thành PIPE. Các đối số stdoutstderr 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ành PIPEstderr thành STDOUT, 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ệ TimeoutExpired sẽ đượ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ượng Popen bên trong sẽ tự động được tạo với stdin được đặt thành PIPE và đố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ệ CalledProcessError sẽ đượ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 encodingerrors đượ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à 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. Nó được chuyển trực tiếp đến Popen. Á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.environ hoặc os.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ố encodingerrors

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%%SystemRoot%\System32\cmd.exe. Kết quả là việc thả chương trình độc hại có tên cmd.exe và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 -N chỉ ra rằng phần tử con đã bị chấm dứt bởi tín hiệu N (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. None nế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à stderr sẽ 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. None nếu stderr không bị bắt.

check_returncode()

Nếu returncode khác 0, hãy tăng CalledProcessError.

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 Popen và cho biết rằng tệp đặc biệt os.devnull sẽ đượ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 Popen và 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ới Popen.communicate().

subprocess.STDOUT

Giá trị đặc biệt có thể được sử dụng làm đối số stderr cho Popen và 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ặc check_output() nắm bắt. Nếu không thì None. Đây luôn là bytes khi bất kỳ đầu ra nào được ghi lại bất kể cài đặt text=True. Nó có thể vẫn là None thay vì b'' khi không quan sát thấy đầu ra.

stdout

Bí danh cho đầu ra, đối xứng với stderr.

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à bytes khi đầu ra stderr được ghi lại bất kể cài đặt text=True. Nó có thể vẫn là None thay 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 stdoutstderr

exception subprocess.CalledProcessError

Lớp con của SubprocessError, được nâng lên khi một quá trình được chạy bởi check_call(), check_output() hoặc run() (với check=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ặc check_output() nắm bắt. Nếu không thì None.

stdout

Bí danh cho đầu ra, đối xứng với stderr.

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.

Thay đổi trong phiên bản 3.5: Đã thêm thuộc tính stdoutstderr

Đố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, stdoutstderr 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ủa None, sẽ không có chuyển hướng nào xảy ra. PIPE chỉ ra rằng cần tạo một đường ống mới cho trẻ. DEVNULL chỉ ra rằng tệp đặc biệt os.devnull sẽ đượ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, stdoutstderr sẽ được mở ở chế độ văn bản bằng cách sử dụng encodingerrors đượ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 định os.linesep. Đối với stdoutstderr, 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ớp io.TextIOWrapper khi đố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, stdoutstderr 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ố encodingerrors.

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.stdoutPopen.stderr không được cập nhật bằng phương thức Popen.communicate().

Nếu shellTrue, 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()shutil).

Thay đổi trong phiên bản 3.3: Khi universal_newlinesTrue, lớp sử dụng mã hóa locale.getpreferredencoding(False) thay vì locale.getpreferredencoding(). Xem lớp io.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 Windows CreateProcess(). Các đối số cho Popen như 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ố shellexecutable để 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ụng shutil.which(). Trên tất cả các nền tảng, chuyển sys.executable là 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ường PATH. Đối với Windows, hãy xem tài liệu về các tham số lpApplicationNamelpCommandLine của WinAPI CreateProcess, đồ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ằng shell=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ường PATH. 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 shellFalse và 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 shellFalse và 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 shellTrue, 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à, Popen thự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ường COMSPEC chỉ định shell mặc định. Lần duy nhất bạn cần chỉ định shell=True trê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ần shell=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:

  • 0 có 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)

  • 1 có nghĩa là dòng được đệm (chỉ sử dụng được nếu text=True hoặc universal_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ếu shell=True, trên POSIX đối số executable chỉ định một shell thay thế cho /bin/sh mặ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%%SystemRoot%\System32\cmd.exe. Kết quả là việc thả chương trình độc hại có tên cmd.exe vào thư mục hiện tại không còn hoạt động.

stdin, stdoutstderr 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ủa None, sẽ không có chuyển hướng nào xảy ra. PIPE chỉ ra rằng cần tạo một đường ống mới cho trẻ. DEVNULL chỉ ra rằng tệp đặc biệt os.devnull sẽ đượ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_sessionprocess_group sẽ thay thế mã sử dụng preexec_fn để gọi os.setsid() hoặc os.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, 12 sẽ 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_list của STARTUPINFO.lpAttributeList hoặ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ừ False thà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ừ False thành True khi 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ành True khi 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 qua grp.getgrnam() và giá trị trong gr_gid sẽ đượ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 qua grp.getgrnam() và các giá trị trong gr_gid sẽ đượ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 qua pwd.getpwnam() và giá trị trong pw_uid sẽ đượ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.environ hoặc os.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, stdoutstderr sẽ được mở ở chế độ văn bản với encodingerrors đượ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: encodingerrors đã đượ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àm CreateProcess cơ 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)  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.Popen với các đối số executable, args, cwdenv. Giá trị cho args có 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 ResourceWarning nế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ụng os.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ới returncode khá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()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()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=PIPE hoặc stderr=PIPE và 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ụng Popen.communicate() khi sử dụng ống để tránh điều đó.

Ghi chú

Khi tham số timeout không phải là None thì (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ô-đun asyncio để chờ không đồng bộ: xem asyncio.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ặc None nế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ài None trong bộ kết quả, bạn cũng cần cung cấp stdout=PIPE và/hoặc stderr=PIPE.

Nếu quá trình không kết thúc sau timeout giây, một ngoại lệ TimeoutExpired sẽ đượ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ọi communicate() 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(), TimeoutExpired sẽ tăng lên, đừng gọi wait(). Sử dụng lệnh gọi communicate() bổ sung để hoàn tất việc xử lý các đường ống và điền thuộc tính returncode.

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ồm CREATE_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 SIGTERM cho trẻ. Trên Windows, hàm API TerminateProcess() 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ủa terminate().

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ố stdinPIPE, thuộc tính này là một đối tượng luồng có thể ghi được trả về bởi open(). Nếu đối số encoding hoặc errors được chỉ định hoặc đối số text hoặc universal_newlinesTrue thì 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à PIPE thì thuộc tính này là None.

Popen.stdout

Nếu đối số stdoutPIPE thì thuộc tính này là một đối tượng luồng có thể đọc được và được trả về bởi open(). Đọ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_newlinesTrue thì 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à PIPE thì thuộc tính này là None.

Popen.stderr

Nếu đối số stderrPIPE thì thuộc tính này là một đối tượng luồng có thể đọc được và được trả về bởi open(). 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_newlinesTrue thì 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à PIPE thì 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 True thì đâ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ức poll(), wait() hoặc communicate() nếu chúng phát hiện rằng quá trình đã kết thúc.

Giá trị None cho 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 -N chỉ ra rằng phần tử con đã bị chấm dứt bởi tín hiệu N (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 STARTUPINFO nhấ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 dwFlags chỉ định STARTF_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ếu STARTF_USESTDHANDLES khô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 dwFlags chỉ định STARTF_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 dwFlags chỉ định STARTF_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 dwFlags chỉ định STARTF_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ố nCmdShow cho 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 khi Popen được gọi bằng shell=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ạo Popen, nếu không, OSError sẽ xuất hiện với lỗi Windows ERROR_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.hStdOutputSTARTUPINFO.hStdError chứa thông tin bổ sung.

subprocess.STARTF_USESHOWWINDOW

Chỉ định rằng thuộc tính STARTUPINFO.wShowWindow chứ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ố Popen creationflags để 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ụng os.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ố Popen creationflags để 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ố Popen creationflags để 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ố Popen creationflags để 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ố Popen creationflags để 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ố Popen creationflags để 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ố Popen creationflags để 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ố Popen creationflags để 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ố Popen creationflags để 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ố Popen creationflags để 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.

subprocess.CREATE_BREAKAWAY_FROM_JOB

Tham số Popen creationflags để chỉ định rằng một quy trình mới không được liên kết với công việc.

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=PIPE hoặc stderr=PIPE vớ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%%SystemRoot%\System32\cmd.exe. Kết quả là việc thả chương trình độc hại có tên cmd.exe và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ượng CalledProcessError sẽ có mã trả về trong thuộc tính returncode. Nếu check_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=PIPE hoặc stderr=PIPE vớ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%%SystemRoot%\System32\cmd.exe. Kết quả là việc thả chương trình độc hại có tên cmd.exe và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ượng CalledProcessError sẽ có mã trả về trong thuộc tính returncode và bất kỳ đầu ra nào trong thuộc tính output.

Đ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ủa run(): truyền input=None sẽ hoạt động giống như input=b'' (hoặc input='', 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 True như được mô tả trong Đối số thường được sử dụngrun().

Để 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: encodingerrors đã đượ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%%SystemRoot%\System32\cmd.exe. Kết quả là việc thả chương trình độc hại có tên cmd.exe và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ủa os.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ô-đun subprocess.

Một ví dụ thực tế hơn sẽ như thế này:

thử:
    retcode = call("mycmd" + " myarg", shell=True)
    nếu  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  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  None  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ộ. encodingerrors đượ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ố encodingerrors.

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ố encodingerrors.

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:

  1. 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.

  2. 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 TimeoutExpired vì 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):

  1. Các đối số được phân cách bằng khoảng trắng, đó là khoảng trắng hoặc tab.

  2. 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ố.

  3. 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.

  4. 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.

  5. 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

shlex

Mô-đ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