PIPE trong quy trình con Python là gì?

Mô-đun cung cấp giao diện nhất quán để tạo và làm việc với các quy trình bổ sung. Nó cung cấp giao diện cấp cao hơn một số mô-đun có sẵn khác và nhằm thay thế các chức năng như os. hệ thống(), hệ điều hành. sinh sản *(), hệ điều hành. popen*(), popen2. *() và các lệnh. *(). Để dễ dàng so sánh với các mô-đun khác, nhiều ví dụ ở đây tạo lại các mô-đun được sử dụng cho và mở

Mô-đun định nghĩa một lớp, Popen và một số hàm bao bọc sử dụng lớp đó. Hàm tạo cho Popen nhận các đối số để thiết lập quy trình mới để cha mẹ có thể giao tiếp với nó qua đường ống. Nó cung cấp tất cả các chức năng của các mô-đun khác và các chức năng mà nó thay thế, v.v. API nhất quán cho mọi mục đích sử dụng và nhiều bước bổ sung cần thiết (chẳng hạn như đóng các bộ mô tả tệp bổ sung và đảm bảo các đường dẫn được đóng) được “tích hợp sẵn” thay vì được mã ứng dụng xử lý riêng

Ghi chú

API gần giống nhau, nhưng cách triển khai cơ bản hơi khác giữa Unix và Windows. Tất cả các ví dụ hiển thị ở đây đã được thử nghiệm trên Mac OS X. Hành vi trên hệ điều hành không phải Unix sẽ thay đổi

Chạy lệnh bên ngoài

Để chạy một lệnh bên ngoài mà không tương tác với lệnh đó, chẳng hạn như lệnh sẽ thực hiện với , Sử dụng hàm call()

import subprocess

# Simple command
subprocess.call(['ls', '-1'], shell=True)

Các đối số dòng lệnh được truyền dưới dạng một danh sách các chuỗi, giúp tránh phải thoát dấu ngoặc kép hoặc các ký tự đặc biệt khác mà trình bao có thể hiểu được

$ python subprocess_os_system.py

__init__.py
index.rst
interaction.py
repeater.py
signal_child.py
signal_parent.py
subprocess_check_call.py
subprocess_check_output.py
subprocess_check_output_error.py
subprocess_check_output_error_trap_output.py
subprocess_os_system.py
subprocess_pipes.py
subprocess_popen2.py
subprocess_popen3.py
subprocess_popen4.py
subprocess_popen_read.py
subprocess_popen_write.py
subprocess_shell_variables.py
subprocess_signal_parent_shell.py
subprocess_signal_setsid.py

Đặt đối số trình bao thành giá trị thực sẽ tạo ra một quy trình trình bao trung gian và yêu cầu nó chạy lệnh. Mặc định là chạy lệnh trực tiếp

import subprocess

# Command with shell expansion
subprocess.call('echo $HOME', shell=True)

Sử dụng trình bao trung gian có nghĩa là các biến, mẫu hình cầu và các tính năng trình bao đặc biệt khác trong chuỗi lệnh được xử lý trước khi lệnh được chạy

$ python subprocess_shell_variables.py

/Users/dhellmann

Xử lý lỗi

Giá trị trả về từ call() là mã thoát của chương trình. Người gọi có trách nhiệm phiên dịch nó để phát hiện lỗi. Hàm check_call() hoạt động giống như hàm call() ngoại trừ mã thoát được kiểm tra và nếu nó chỉ ra lỗi xảy ra thì ngoại lệ CalledProcessError sẽ xuất hiện

import subprocess

subprocess.check_call(['false'])

Lệnh sai luôn thoát với mã trạng thái khác không, mà check_call() hiểu là lỗi

$ python subprocess_check_call.py

Traceback (most recent call last):
  File "subprocess_check_call.py", line 11, in 
    subprocess.check_call(['false'])
  File "/Library/Frameworks/Python.framework/Versions/2.7/lib/python2.
7/subprocess.py", line 511, in check_call
    raise CalledProcessError(retcode, cmd)
subprocess.CalledProcessError: Command '['false']' returned non-zero e
xit status 1

Chụp đầu ra

Các kênh đầu vào và đầu ra tiêu chuẩn cho quá trình bắt đầu bằng lệnh gọi() được liên kết với đầu vào và đầu ra của cha mẹ. Điều đó có nghĩa là chương trình gọi không thể nắm bắt đầu ra của lệnh. Sử dụng check_output() để chụp đầu ra để xử lý sau

import subprocess

output = subprocess.check_output(['ls', '-1'])
print 'Have %d bytes in output' % len(output)
print output

                                  

Lệnh ls -1 chạy thành công, vì vậy văn bản nó in ra đầu ra tiêu chuẩn được ghi lại và trả về

$ python subprocess_check_output.py

Have 462 bytes in output
__init__.py
index.rst
interaction.py
repeater.py
signal_child.py
signal_parent.py
subprocess_check_call.py
subprocess_check_output.py
subprocess_check_output_error.py
subprocess_check_output_error_trap_output.py
subprocess_os_system.py
subprocess_pipes.py
subprocess_popen2.py
subprocess_popen3.py
subprocess_popen4.py
subprocess_popen_read.py
subprocess_popen_write.py
subprocess_shell_variables.py
subprocess_signal_parent_shell.py
subprocess_signal_setsid.py

Tập lệnh này chạy một loạt lệnh trong một lớp con. Thông báo được gửi đến đầu ra tiêu chuẩn và lỗi tiêu chuẩn trước khi lệnh thoát với mã lỗi

________số 8_______

Thông báo về lỗi tiêu chuẩn được in ra bàn điều khiển, nhưng thông báo về đầu ra tiêu chuẩn bị ẩn

$ python subprocess_check_output_error.py

to stderr
Traceback (most recent call last):
  File "subprocess_check_output_error.py", line 14, in 
    shell=True,
  File "/Library/Frameworks/Python.framework/Versions/2.7/lib/python2.
7/subprocess.py", line 544, in check_output
    raise CalledProcessError(retcode, cmd, output=output)
subprocess.CalledProcessError: Command 'echo to stdout; echo to stderr
 1>&2; exit 1' returned non-zero exit status 1

Để ngăn các thông báo lỗi từ các lệnh chạy qua check_output() được ghi vào bàn điều khiển, hãy đặt tham số stderr thành hằng số STDOUT

$ python subprocess_os_system.py

__init__.py
index.rst
interaction.py
repeater.py
signal_child.py
signal_parent.py
subprocess_check_call.py
subprocess_check_output.py
subprocess_check_output_error.py
subprocess_check_output_error_trap_output.py
subprocess_os_system.py
subprocess_pipes.py
subprocess_popen2.py
subprocess_popen3.py
subprocess_popen4.py
subprocess_popen_read.py
subprocess_popen_write.py
subprocess_shell_variables.py
subprocess_signal_parent_shell.py
subprocess_signal_setsid.py
0

Giờ đây, các kênh đầu ra tiêu chuẩn và lỗi được hợp nhất với nhau, vì vậy nếu lệnh in các thông báo lỗi, chúng sẽ được ghi lại và không được gửi đến bàn điều khiển

$ python subprocess_os_system.py

__init__.py
index.rst
interaction.py
repeater.py
signal_child.py
signal_parent.py
subprocess_check_call.py
subprocess_check_output.py
subprocess_check_output_error.py
subprocess_check_output_error_trap_output.py
subprocess_os_system.py
subprocess_pipes.py
subprocess_popen2.py
subprocess_popen3.py
subprocess_popen4.py
subprocess_popen_read.py
subprocess_popen_write.py
subprocess_shell_variables.py
subprocess_signal_parent_shell.py
subprocess_signal_setsid.py
1

Làm việc trực tiếp với đường ống

Bằng cách chuyển các đối số khác nhau cho stdin, stdout và stderr, có thể bắt chước các biến thể của os. giáo hoàng()

giáo hoàng

Để chạy một quy trình và đọc tất cả đầu ra của nó, hãy đặt giá trị thiết bị xuất chuẩn thành PIPE và gọi giao tiếp()

$ python subprocess_os_system.py

__init__.py
index.rst
interaction.py
repeater.py
signal_child.py
signal_parent.py
subprocess_check_call.py
subprocess_check_output.py
subprocess_check_output_error.py
subprocess_check_output_error_trap_output.py
subprocess_os_system.py
subprocess_pipes.py
subprocess_popen2.py
subprocess_popen3.py
subprocess_popen4.py
subprocess_popen_read.py
subprocess_popen_write.py
subprocess_shell_variables.py
subprocess_signal_parent_shell.py
subprocess_signal_setsid.py
2

Điều này tương tự như cách hoạt động của popen(), ngoại trừ việc đọc được quản lý nội bộ bởi đối tượng Popen

$ python subprocess_os_system.py

__init__.py
index.rst
interaction.py
repeater.py
signal_child.py
signal_parent.py
subprocess_check_call.py
subprocess_check_output.py
subprocess_check_output_error.py
subprocess_check_output_error_trap_output.py
subprocess_os_system.py
subprocess_pipes.py
subprocess_popen2.py
subprocess_popen3.py
subprocess_popen4.py
subprocess_popen_read.py
subprocess_popen_write.py
subprocess_shell_variables.py
subprocess_signal_parent_shell.py
subprocess_signal_setsid.py
3

Để thiết lập một đường ống cho phép chương trình gọi ghi dữ liệu vào nó, hãy đặt stdin thành PIPE

$ python subprocess_os_system.py

__init__.py
index.rst
interaction.py
repeater.py
signal_child.py
signal_parent.py
subprocess_check_call.py
subprocess_check_output.py
subprocess_check_output_error.py
subprocess_check_output_error_trap_output.py
subprocess_os_system.py
subprocess_pipes.py
subprocess_popen2.py
subprocess_popen3.py
subprocess_popen4.py
subprocess_popen_read.py
subprocess_popen_write.py
subprocess_shell_variables.py
subprocess_signal_parent_shell.py
subprocess_signal_setsid.py
4

Để gửi dữ liệu đến kênh đầu vào tiêu chuẩn của quy trình một lần, hãy chuyển dữ liệu tới giao tiếp(). Điều này tương tự như sử dụng popen() với chế độ 'w'

$ python subprocess_os_system.py

__init__.py
index.rst
interaction.py
repeater.py
signal_child.py
signal_parent.py
subprocess_check_call.py
subprocess_check_output.py
subprocess_check_output_error.py
subprocess_check_output_error_trap_output.py
subprocess_os_system.py
subprocess_pipes.py
subprocess_popen2.py
subprocess_popen3.py
subprocess_popen4.py
subprocess_popen_read.py
subprocess_popen_write.py
subprocess_shell_variables.py
subprocess_signal_parent_shell.py
subprocess_signal_setsid.py
5

giáo hoàng2

Để thiết lập phiên bản Popen để đọc và viết, hãy sử dụng kết hợp các kỹ thuật trước đó

$ python subprocess_os_system.py

__init__.py
index.rst
interaction.py
repeater.py
signal_child.py
signal_parent.py
subprocess_check_call.py
subprocess_check_output.py
subprocess_check_output_error.py
subprocess_check_output_error_trap_output.py
subprocess_os_system.py
subprocess_pipes.py
subprocess_popen2.py
subprocess_popen3.py
subprocess_popen4.py
subprocess_popen_read.py
subprocess_popen_write.py
subprocess_shell_variables.py
subprocess_signal_parent_shell.py
subprocess_signal_setsid.py
6

Điều này thiết lập đường ống để bắt chước popen2()

$ python subprocess_os_system.py

__init__.py
index.rst
interaction.py
repeater.py
signal_child.py
signal_parent.py
subprocess_check_call.py
subprocess_check_output.py
subprocess_check_output_error.py
subprocess_check_output_error_trap_output.py
subprocess_os_system.py
subprocess_pipes.py
subprocess_popen2.py
subprocess_popen3.py
subprocess_popen4.py
subprocess_popen_read.py
subprocess_popen_write.py
subprocess_shell_variables.py
subprocess_signal_parent_shell.py
subprocess_signal_setsid.py
7

giáo hoàng3

Cũng có thể xem cả hai luồng cho thiết bị xuất chuẩn và thiết bị xuất chuẩn, như với popen3()

$ python subprocess_os_system.py

__init__.py
index.rst
interaction.py
repeater.py
signal_child.py
signal_parent.py
subprocess_check_call.py
subprocess_check_output.py
subprocess_check_output_error.py
subprocess_check_output_error_trap_output.py
subprocess_os_system.py
subprocess_pipes.py
subprocess_popen2.py
subprocess_popen3.py
subprocess_popen4.py
subprocess_popen_read.py
subprocess_popen_write.py
subprocess_shell_variables.py
subprocess_signal_parent_shell.py
subprocess_signal_setsid.py
8

Đọc từ thiết bị xuất chuẩn hoạt động giống như với thiết bị xuất chuẩn. Truyền PIPE yêu cầu Popen đính kèm vào kênh và giao tiếp () đọc tất cả dữ liệu từ kênh đó trước khi quay lại

$ python subprocess_os_system.py

__init__.py
index.rst
interaction.py
repeater.py
signal_child.py
signal_parent.py
subprocess_check_call.py
subprocess_check_output.py
subprocess_check_output_error.py
subprocess_check_output_error_trap_output.py
subprocess_os_system.py
subprocess_pipes.py
subprocess_popen2.py
subprocess_popen3.py
subprocess_popen4.py
subprocess_popen_read.py
subprocess_popen_write.py
subprocess_shell_variables.py
subprocess_signal_parent_shell.py
subprocess_signal_setsid.py
9

giáo hoàng4

Để hướng đầu ra lỗi từ quy trình sang kênh đầu ra tiêu chuẩn của nó, hãy sử dụng STDOUT cho thiết bị lỗi chuẩn thay vì PIPE

import subprocess

# Command with shell expansion
subprocess.call('echo $HOME', shell=True)
0

Kết hợp đầu ra theo cách này tương tự như cách hoạt động của popen4()

import subprocess

# Command with shell expansion
subprocess.call('echo $HOME', shell=True)
1

Kết nối các đoạn của một đường ống

Nhiều lệnh có thể được kết nối thành một đường dẫn, tương tự như cách hoạt động của hệ vỏ Unix, bằng cách tạo các phiên bản Popen riêng biệt và xâu chuỗi các đầu vào và đầu ra của chúng lại với nhau. Thuộc tính thiết bị xuất chuẩn của một phiên bản Popen được sử dụng làm đối số tiêu chuẩn cho phiên bản tiếp theo trong đường ống, thay vì PIPE không đổi. Đầu ra được đọc từ tay cầm thiết bị xuất chuẩn cho lệnh cuối cùng trong đường ống

import subprocess

# Command with shell expansion
subprocess.call('echo $HOME', shell=True)
2

Ví dụ này tái tạo chỉ mục dòng lệnh cat. đầu tiên. kêu ". bao gồm". cắt -f 3 -d. , đọc tệp nguồn reStructuredText cho phần này và tìm tất cả các dòng bao gồm các tệp khác, sau đó chỉ in tên tệp

import subprocess

# Command with shell expansion
subprocess.call('echo $HOME', shell=True)
3

Tương tác với một lệnh khác

Tất cả các ví dụ trên giả định số lượng tương tác hạn chế. Phương thức giao tiếp () đọc tất cả đầu ra và đợi tiến trình con thoát trước khi quay lại. Cũng có thể ghi và đọc từ các tay cầm ống riêng lẻ được sử dụng bởi ví dụ Popen. Một chương trình echo đơn giản đọc từ đầu vào tiêu chuẩn và ghi vào đầu ra tiêu chuẩn minh họa điều này

import subprocess

# Command with shell expansion
subprocess.call('echo $HOME', shell=True)
4

Kịch bản, bộ lặp. py, ghi vào stderr khi nó khởi động và dừng. Thông tin đó có thể được sử dụng để hiển thị thời gian tồn tại của tiến trình con

Ví dụ tương tác tiếp theo sử dụng các thẻ điều khiển tệp stdin và stdout thuộc sở hữu của phiên bản Popen theo các cách khác nhau. Trong ví dụ đầu tiên, một chuỗi gồm 10 số được ghi vào stdin của quy trình và sau mỗi lần ghi, dòng đầu ra tiếp theo được đọc lại. Trong ví dụ thứ hai, 10 số giống nhau được viết nhưng đầu ra được đọc cùng một lúc bằng cách sử dụng giao tiếp()

import subprocess

# Command with shell expansion
subprocess.call('echo $HOME', shell=True)
5

"bộ lặp. py. đang thoát" xuất hiện tại các điểm khác nhau trong đầu ra cho từng kiểu vòng lặp

import subprocess

# Command with shell expansion
subprocess.call('echo $HOME', shell=True)
6

Báo hiệu giữa các quá trình

Các ví dụ bao gồm một cuộc biểu tình của. Vì mỗi cá thể Popen cung cấp một thuộc tính pid với id tiến trình của tiến trình con, nên có thể thực hiện điều gì đó tương tự với. Ví dụ: sử dụng tập lệnh này để quy trình con được thực thi bởi quy trình cha

import subprocess

# Command with shell expansion
subprocess.call('echo $HOME', shell=True)
7

kết hợp với quá trình cha mẹ này

import subprocess

# Command with shell expansion
subprocess.call('echo $HOME', shell=True)
8

đầu ra là

import subprocess

# Command with shell expansion
subprocess.call('echo $HOME', shell=True)
9

Nhóm/Phiên xử lý

Do cách thức hoạt động của cây quy trình trong Unix, nếu quy trình được tạo bởi Popen sinh ra các quy trình con, những quy trình con đó sẽ không nhận được bất kỳ tín hiệu nào được gửi đến quy trình cha. Điều đó có nghĩa là, chẳng hạn, sẽ khó khiến chúng chấm dứt bằng cách gửi SIGINT hoặc SIGTERM

$ python subprocess_shell_variables.py

/Users/dhellmann
0

Pid được sử dụng để gửi tín hiệu không khớp với pid của tập lệnh con đang chờ tín hiệu vì trong ví dụ này, có ba quy trình riêng biệt tương tác

  1. sub process_signal_parent_shell. py
  2. Quá trình Unix shell chạy tập lệnh được tạo bởi chương trình python chính
  3. signal_child. py

$ python subprocess_shell_variables.py

/Users/dhellmann
1

Giải pháp cho vấn đề này là sử dụng một nhóm quy trình để liên kết những đứa trẻ để chúng có thể được báo hiệu cùng nhau. Nhóm quy trình được tạo bằng os. setsid(), đặt "id phiên" thành id tiến trình của tiến trình hiện tại. Tất cả các quy trình con kế thừa id phiên và vì nó chỉ nên được đặt trong trình bao được tạo bởi Popen và hậu duệ của nó, os. setsid() không nên được gọi trong tiến trình cha. Thay vào đó, hàm được truyền cho Popen dưới dạng đối số preexec_fn để nó được chạy sau fork() bên trong quy trình mới, trước khi nó sử dụng exec() để chạy trình bao

Python ống quy trình con là gì?

Mô-đun quy trình con cho phép bạn sinh 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 dự định thay thế một số mô-đun và chức năng cũ hơn. hệ điều hành.

Đường ống có nghĩa là gì trong quy trình con?

Việc sử dụng phổ biến của đường ống là để gửi dữ liệu đến hoặc nhận dữ liệu từ một chương trình đang được chạy dưới dạng quy trình con .

Đường ống trong Python là gì?

Ống là gì? . một đường ống (. ) chuyển kết quả của phương thức này sang phương thức khác. Tôi thích Pipe vì nó làm cho mã của tôi trông gọn gàng hơn khi áp dụng nhiều phương thức cho Python iterable. a Python library that enables you to use pipes in Python. A pipe ( | ) passes the results of one method to another method. I like Pipe because it makes my code look cleaner when applying multiple methods to a Python iterable.

Làm cách nào để chuyển đầu ra trong quy trình con?

Quy trình con của Python .
quy trình con nhập khẩu
quy trình con. chạy (['ls'])
cmd=['ls'] quy trình con. chạy (cmd)
cmd=['ls'] proc1 = quy trình con. chạy (cmd, thiết bị xuất chuẩn = quy trình con. PIPE) in (proc1. thiết bị xuất chuẩn)
f = open("đầu ra. txt", "w") # điều này tạo ra quy trình con cmd=['ls'] tệp. run(cmd, stdout=f) # cái này sẽ gửi nó tới f