Xả quy trình con Python

Nếu bạn đã từng muốn đơn giản hóa tập lệnh dòng lệnh của mình hoặc sử dụng Python cùng với các ứng dụng dòng lệnh—hoặc bất kỳ ứng dụng nào cho vấn đề đó—thì mô-đun Python

$ python timer.py 5
0 có thể giúp bạn. Từ việc chạy các lệnh shell và các ứng dụng dòng lệnh đến khởi chạy các ứng dụng GUI, mô-đun Python
$ python timer.py 5
0 có thể trợ giúp

Show

Đến cuối hướng dẫn này, bạn sẽ có thể

  • Hiểu cách mô-đun Python
    $ python timer.py 5
    
    0 tương tác với hệ điều hành
  • Phát hành các lệnh shell như
    $ python timer.py 5
    
    3 hoặc
    $ python timer.py 5
    
    4
  • Đưa đầu vào vào một quy trình và sử dụng đầu ra của nó
  • Xử lý lỗi khi sử dụng
    $ python timer.py 5
    
    0
  • Hiểu các trường hợp sử dụng cho
    $ python timer.py 5
    
    0 bằng cách xem xét các ví dụ thực tế

Trong hướng dẫn này, bạn sẽ có một mô hình tinh thần cấp cao để hiểu các quy trình, quy trình con và Python trước khi bị mắc kẹt vào mô-đun

$ python timer.py 5
0 và thử nghiệm với một ví dụ. Sau đó, bạn sẽ bắt đầu khám phá trình bao và tìm hiểu cách bạn có thể tận dụng
$ python timer.py 5
0 của Python với các hệ thống và trình bao dựa trên Windows và UNIX. Cụ thể, bạn sẽ đề cập đến giao tiếp với các quy trình, đường ống và xử lý lỗi

Ghi chú.

$ python timer.py 5
0 không phải là mô-đun tự động hóa GUI hay cách để đạt được đồng thời. Để tự động hóa GUI, bạn có thể muốn xem PyAutoGUI. Đối với đồng thời, hãy xem phần hướng dẫn này về các mô-đun liên quan đến
$ python timer.py 5
0

Khi bạn đã có kiến ​​thức cơ bản, bạn sẽ khám phá một số ý tưởng thiết thực về cách tận dụng

$ python timer.py 5
0 của Python. Bạn cũng sẽ nhúng ngón chân của mình vào cách sử dụng nâng cao của Python's
$ python timer.py 5
0 bằng cách thử nghiệm với hàm tạo
$ python timer.py 5
33 bên dưới

Mã nguồn. Nhấp vào đây để tải xuống mã nguồn miễn phí mà bạn sẽ sử dụng để làm quen với mô-đun Python

$ python timer.py 5
0

Quy trình và quy trình con

Trước hết, bạn có thể thắc mắc tại sao lại có một

$ python timer.py 5
35 trong tên mô-đun Python
$ python timer.py 5
0. Và chính xác thì một quá trình là gì? . Bạn sẽ có một mô hình tinh thần cấp cao để suy nghĩ về các quy trình. Nếu bạn đã quen thuộc với các quy trình, thì bạn có thể chuyển thẳng sang phần sử dụng cơ bản của mô-đun Python
$ python timer.py 5
0

Loại bỏ các quảng cáo

Quy trình và hệ điều hành

Bất cứ khi nào bạn sử dụng máy tính, bạn sẽ luôn tương tác với các chương trình. Một quy trình là sự trừu tượng của hệ điều hành về một chương trình đang chạy. Vì vậy, sử dụng máy tính luôn liên quan đến các quá trình. Menu bắt đầu, thanh ứng dụng, trình thông dịch dòng lệnh, trình soạn thảo văn bản, trình duyệt, v.v.—mọi ứng dụng đều bao gồm một hoặc nhiều quy trình

Một hệ điều hành điển hình sẽ báo cáo hàng trăm hoặc thậm chí hàng nghìn quy trình đang chạy mà bạn sẽ khám phá ngay sau đây. Tuy nhiên, các đơn vị xử lý trung tâm (CPU) thường chỉ có một số ít lõi, điều đó có nghĩa là chúng chỉ có thể chạy một số lệnh đồng thời. Vì vậy, bạn có thể tự hỏi làm thế nào mà hàng ngàn quy trình có thể chạy cùng một lúc

Tóm lại, hệ điều hành là một bộ đa nhiệm kỳ diệu—vì nó phải. CPU là bộ não của máy tính, nhưng nó hoạt động ở thang thời gian nano giây. Hầu hết các thành phần khác của máy tính đều chậm hơn nhiều so với CPU. Chẳng hạn, việc đọc đĩa cứng từ tính lâu hơn hàng nghìn lần so với hoạt động của CPU thông thường

Nếu một tiến trình cần ghi thứ gì đó vào ổ cứng hoặc chờ phản hồi từ máy chủ từ xa, thì CPU sẽ không hoạt động trong hầu hết thời gian. Đa nhiệm khiến CPU luôn bận rộn

Một phần khiến hệ điều hành trở nên tuyệt vời trong đa nhiệm là nó cũng được tổ chức tuyệt vời. Hệ điều hành theo dõi các quy trình trong bảng quy trình hoặc khối điều khiển quy trình. Trong bảng này, bạn sẽ tìm thấy các phần xử lý tệp của quy trình, bối cảnh bảo mật, các tham chiếu đến không gian địa chỉ của quy trình, v.v.

Bảng quy trình cho phép hệ điều hành từ bỏ một quy trình cụ thể theo ý muốn, vì nó có tất cả thông tin cần thiết để quay lại và tiếp tục quy trình sau đó. Một tiến trình có thể bị gián đoạn hàng nghìn lần trong khi thực thi, nhưng hệ điều hành luôn tìm thấy chính xác điểm mà nó đã dừng lại khi quay lại

Tuy nhiên, một hệ điều hành không khởi động với hàng ngàn quy trình. Nhiều quy trình mà bạn quen thuộc được bắt đầu bởi chính bạn. Trong phần tiếp theo, bạn sẽ xem xét thời gian tồn tại của một quy trình

Quy trình trọn đời

Hãy nghĩ về cách bạn có thể bắt đầu một ứng dụng Python từ dòng lệnh. Đây là một ví dụ về quy trình dòng lệnh của bạn khi bắt đầu quy trình Python

Xả quy trình con Python

Quá trình bắt đầu một quá trình khác được gọi là cha mẹ và quá trình mới được gọi là con. Các tiến trình cha và con hầu như chạy độc lập. Đôi khi đứa trẻ kế thừa các tài nguyên hoặc bối cảnh cụ thể từ cha mẹ

Như bạn đã học trong Quy trình và Hệ điều hành, thông tin về các quy trình được lưu giữ trong một bảng. Mỗi quy trình theo dõi cha mẹ của nó, điều này cho phép hệ thống phân cấp quy trình được biểu diễn dưới dạng cây. Bạn sẽ khám phá cây quy trình của hệ thống trong phần tiếp theo

Ghi chú. Cơ chế chính xác để tạo các quy trình khác nhau tùy thuộc vào hệ điều hành. Để có cái nhìn tổng quan ngắn gọn, bài viết trên Wikipedia về quản lý quy trình có một phần ngắn về tạo quy trình

Để biết thêm chi tiết về cơ chế Windows, hãy xem trang tài liệu API win32 về cách tạo quy trình

Trên các hệ thống dựa trên UNIX, các quy trình thường được tạo bằng cách sử dụng

$ python timer.py 5
38 để sao chép quy trình hiện tại và sau đó thay thế quy trình con bằng một trong các họ hàm
$ python timer.py 5
39

Mối quan hệ cha-con giữa một quy trình và quy trình con của nó không phải lúc nào cũng giống nhau. Đôi khi, hai quy trình sẽ chia sẻ các tài nguyên cụ thể, chẳng hạn như đầu vào và đầu ra, nhưng đôi khi chúng sẽ không. Đôi khi các tiến trình con tồn tại lâu hơn tiến trình cha. Một đứa trẻ sống lâu hơn cha mẹ có thể dẫn đến quá trình mồ côi hoặc thây ma, mặc dù thảo luận thêm về những điều đó nằm ngoài phạm vi của hướng dẫn này

Khi một tiến trình chạy xong, nó thường sẽ kết thúc. Mỗi quá trình, khi thoát, sẽ trả về một số nguyên. Số nguyên này được gọi là mã trả về hoặc trạng thái thoát. Số không đồng nghĩa với thành công, trong khi bất kỳ giá trị nào khác được coi là thất bại. Các số nguyên khác nhau có thể được sử dụng để chỉ ra lý do tại sao một quá trình không thành công

Cũng giống như cách bạn có thể trả về một giá trị từ một hàm trong Python, hệ điều hành mong đợi một giá trị trả về số nguyên từ một quy trình sau khi nó thoát. Đây là lý do tại sao hàm C

$ python timer.py 5
00 chuẩn thường trả về một số nguyên

$ python timer.py 5
1

Ví dụ này cho thấy số lượng mã C tối thiểu cần thiết để tệp biên dịch với

$ python timer.py 5
01 mà không có bất kỳ cảnh báo nào. Nó có hàm
$ python timer.py 5
00 trả về một số nguyên. Khi chương trình này chạy, hệ điều hành sẽ hiểu việc thực thi của nó là thành công vì nó trả về 0

Vì vậy, những quy trình nào đang chạy trên hệ thống của bạn ngay bây giờ? . Có thể xem quy trình nào đang chạy và cách chúng được cấu trúc sẽ hữu ích khi trực quan hóa cách thức hoạt động của mô-đun

$ python timer.py 5
0

Loại bỏ các quảng cáo

Các quy trình đang hoạt động trên hệ thống của bạn

Bạn có thể tò mò muốn biết những quy trình nào đang chạy trên hệ thống của mình ngay bây giờ. Để làm được điều đó, bạn có thể sử dụng các tiện ích dành riêng cho nền tảng để theo dõi chúng

  • các cửa sổ
  • Linux + macOS

Có nhiều công cụ có sẵn cho Windows, nhưng một công cụ dễ cài đặt, nhanh chóng và sẽ hiển thị cho bạn cây quy trình mà không cần nỗ lực nhiều là Process Hacker

Bạn có thể cài đặt Process Hacker bằng cách truy cập trang tải xuống hoặc bằng Chocolatey

$ python timer.py 5
5

Mở ứng dụng và bạn sẽ thấy ngay cây quy trình

Một trong những lệnh gốc mà bạn có thể sử dụng với PowerShell là

$ python timer.py 5
04, liệt kê các quy trình đang hoạt động trên dòng lệnh.
$ python timer.py 5
05 là một tiện ích nhắc lệnh thực hiện tương tự

Phiên bản chính thức của Microsoft Process Hacker là một phần của các tiện ích Sysinternals, cụ thể là Process Monitor và Process Explorer. Bạn cũng nhận được PsList, một tiện ích dòng lệnh tương tự như

$ python timer.py 5
06 trên UNIX. Bạn có thể cài đặt Sysiternals bằng cách truy cập trang tải xuống hoặc bằng cách sử dụng Chocolatey

$ python timer.py 5
9

Bạn cũng có thể sử dụng Trình quản lý tác vụ cơ bản nhưng cổ điển hơn—có thể truy cập bằng cách nhấn Win +X and selecting the Task Manager.

Đối với các hệ thống dựa trên UNIX, có nhiều tiện ích dòng lệnh để lựa chọn

  • ______207. Trình theo dõi tài nguyên và quy trình cổ điển, thường được cài đặt theo mặc định. Khi nó đang chạy, để xem chế độ xem dạng cây, còn được gọi là chế độ xem rừng, hãy nhấn Shift + V. The forest view may not work on the default macOS
    $ python timer.py 5
    
    07.
  • $ python timer.py 5
    
    09. Phiên bản nâng cao và thân thiện hơn của
    $ python timer.py 5
    
    07
  • $ python timer.py 5
    
    41. Một phiên bản khác của
    $ python timer.py 5
    
    07 với nhiều thông tin hơn nhưng kỹ thuật hơn
  • $ python timer.py 5
    
    43. Một triển khai Python của
    $ python timer.py 5
    
    07 với hình ảnh đẹp mắt
  • $ python timer.py 5
    
    06. Một tiện ích đặc biệt để khám phá cây quy trình

Trên macOS, bạn cũng có ứng dụng Giám sát hoạt động trong các tiện ích của mình. Trong menu View, nếu bạn chọn All Processes, Hierarchally, bạn sẽ có thể xem cây quy trình của mình

Bạn cũng có thể khám phá thư viện psutil của Python, cho phép bạn truy xuất thông tin quy trình đang chạy trên cả hệ thống dựa trên Windows và UNIX

Một thuộc tính chung của theo dõi quy trình trên các hệ thống là mỗi quy trình có một số nhận dạng quy trình hoặc PID, là một số nguyên duy nhất để xác định quy trình trong ngữ cảnh của hệ điều hành. Bạn sẽ thấy con số này trên hầu hết các tiện ích được liệt kê ở trên

Cùng với PID, thông thường sẽ thấy mức sử dụng tài nguyên, chẳng hạn như tỷ lệ phần trăm CPU và dung lượng RAM mà một quy trình cụ thể đang sử dụng. Đây là thông tin mà bạn tìm kiếm nếu một chương trình đang ăn cắp tất cả tài nguyên của bạn

Việc sử dụng tài nguyên của các quy trình có thể hữu ích để phát triển hoặc gỡ lỗi các tập lệnh sử dụng mô-đun

$ python timer.py 5
0, ngay cả khi bạn không cần PID hoặc bất kỳ thông tin nào về tài nguyên mà các quy trình đang sử dụng trong chính mã đó. Trong khi chơi với các ví dụ sắp tới, hãy cân nhắc để mở một biểu diễn của cây quy trình để xem các quy trình mới bật lên

Bây giờ bạn có một cái nhìn toàn cảnh về các quy trình. Bạn sẽ đào sâu mô hình tinh thần của mình trong suốt hướng dẫn, nhưng bây giờ là lúc để xem cách bắt đầu các quy trình của riêng bạn với mô-đun Python

$ python timer.py 5
0

Tổng quan về Mô-đun Python $ python timer.py 5 0

Mô-đun Python

$ python timer.py 5
0 dùng để khởi chạy các tiến trình con. Các quy trình này có thể là bất kỳ thứ gì từ ứng dụng GUI đến trình bao. Mối quan hệ cha-con của các quy trình là nơi phụ trong tên
$ python timer.py 5
0 đến từ. Khi bạn sử dụng
$ python timer.py 5
0, Python là cha tạo một tiến trình con mới. Quá trình con mới đó là gì, tùy thuộc vào bạn

Python

$ python timer.py 5
0 ban đầu được đề xuất và chấp nhận cho Python 2. 4 thay thế cho việc sử dụng mô-đun
$ python timer.py 5
63. Một số thay đổi được ghi lại đã xảy ra muộn nhất là 3. 8. Các ví dụ trong bài viết này đã được thử nghiệm với Python 3. 10. 4, nhưng bạn chỉ cần 3. 8+ để làm theo hướng dẫn này

Hầu hết các tương tác của bạn với mô-đun Python

$ python timer.py 5
0 sẽ thông qua hàm
$ python timer.py 5
65. Chức năng chặn này sẽ bắt đầu một quy trình và đợi cho đến khi quy trình mới thoát ra trước khi tiếp tục

Tài liệu khuyến nghị sử dụng

$ python timer.py 5
65 cho tất cả các trường hợp mà nó có thể xử lý. Đối với các trường hợp cạnh mà bạn cần kiểm soát nhiều hơn, lớp
$ python timer.py 5
67 có thể được sử dụng.
$ python timer.py 5
67 là lớp cơ sở cho toàn bộ mô-đun
$ python timer.py 5
0. Tất cả các chức năng trong mô-đun
$ python timer.py 5
0 là các trình bao bọc thuận tiện xung quanh hàm tạo
$ python timer.py 5
33 và các phương thức thể hiện của nó. Gần cuối hướng dẫn này, bạn sẽ đi sâu vào lớp
$ python timer.py 5
67

Ghi chú. Nếu bạn đang cố gắng quyết định xem mình có cần

$ python timer.py 5
0 hay không, hãy xem phần quyết định xem bạn có cần
$ python timer.py 5
0 cho nhiệm vụ của mình không

Bạn có thể bắt gặp các chức năng khác như

$ python timer.py 5
505,
$ python timer.py 5
506 và
$ python timer.py 5
507, nhưng những chức năng này thuộc về API
$ python timer.py 5
0 cũ hơn từ Python 3. 5 trở về trước. Mọi thứ mà ba chức năng này làm đều có thể được sao chép bằng chức năng
$ python timer.py 5
65 mới hơn. API cũ hơn chủ yếu vẫn còn đó để tương thích ngược và bạn sẽ không đề cập đến nó trong hướng dẫn này

Ngoài ra còn có một lượng dự phòng khá lớn trong mô-đun

$ python timer.py 5
0, nghĩa là có nhiều cách khác nhau để đạt được cùng một mục tiêu cuối cùng. Bạn sẽ không khám phá tất cả các biến thể trong hướng dẫn này. Tuy nhiên, những gì bạn sẽ tìm thấy là những kỹ thuật mạnh mẽ sẽ giúp bạn đi đúng hướng

Cách sử dụng cơ bản của Mô-đun Python $ python timer.py 5 0

Trong phần này, bạn sẽ xem xét một số ví dụ cơ bản nhất minh họa việc sử dụng mô-đun

$ python timer.py 5
0. Bạn sẽ bắt đầu bằng cách khám phá chương trình hẹn giờ dòng lệnh đơn giản với chức năng
$ python timer.py 5
65

Nếu bạn muốn làm theo các ví dụ, hãy tạo một thư mục mới. Tất cả các ví dụ và chương trình có thể được lưu trong thư mục này. Điều hướng đến thư mục mới được tạo này trên dòng lệnh để chuẩn bị cho các ví dụ sắp tới. Tất cả mã trong hướng dẫn này là thư viện tiêu chuẩn Python—không yêu cầu phụ thuộc bên ngoài—vì vậy không cần môi trường ảo

Loại bỏ các quảng cáo

Ví dụ về bộ đếm thời gian

Để nắm bắt được mô-đun Python

$ python timer.py 5
0, bạn sẽ muốn có một chương trình cơ bản để chạy và thử nghiệm với. Đối với điều này, bạn sẽ sử dụng một chương trình được viết bằng Python

$ python timer.py 5
8

Chương trình hẹn giờ sử dụng

$ python timer.py 5
515 để chấp nhận một số nguyên làm đối số. Số nguyên biểu thị số giây mà bộ hẹn giờ sẽ đợi cho đến khi thoát, mà chương trình sử dụng
$ python timer.py 5
516 để đạt được. Nó sẽ phát một hoạt ảnh nhỏ biểu thị từng giây trôi qua cho đến khi thoát

Nó không nhiều, nhưng điều quan trọng là nó hoạt động như một quy trình đa nền tảng chạy trong vài giây và bạn có thể dễ dàng sửa lại. Bạn sẽ gọi nó bằng

$ python timer.py 5
0 như thể nó là một tệp thực thi riêng biệt

Ghi chú. Việc gọi các chương trình Python bằng mô-đun Python

$ python timer.py 5
0 không có nhiều ý nghĩa—thường không cần các mô-đun Python khác ở trong các quy trình riêng biệt vì bạn chỉ có thể nhập chúng

Lý do chính mà bạn sẽ sử dụng các chương trình Python cho hầu hết các ví dụ trong hướng dẫn này là vì chúng đa nền tảng và rất có thể bạn đã cài đặt Python

Bạn có thể nghĩ rằng bắt đầu một quy trình mới có thể là một cách gọn gàng để đạt được đồng thời, nhưng đó không phải là trường hợp sử dụng dự định cho mô-đun

$ python timer.py 5
0. Có thể những gì bạn cần là các mô-đun Python khác dành riêng cho đồng thời, sẽ được trình bày trong phần sau

Mô-đun

$ python timer.py 5
0 chủ yếu để gọi các chương trình khác ngoài Python. Nhưng, như bạn có thể thấy, bạn cũng có thể gọi Python nếu muốn. Để thảo luận thêm về các trường hợp sử dụng của
$ python timer.py 5
0, hãy xem phần này được thảo luận sâu hơn hoặc một trong những ví dụ sau

Được rồi, sẵn sàng để bị mắc kẹt trong. Khi bạn đã sẵn sàng chương trình

$ python timer.py 5
522, hãy mở phiên tương tác Python và gọi bộ hẹn giờ bằng
$ python timer.py 5
0

>>>

$ python timer.py 5
8

Với mã này, bạn sẽ thấy hoạt ảnh phát ngay trong REPL. Bạn đã nhập

$ python timer.py 5
0 và sau đó gọi hàm
$ python timer.py 5
65 với một danh sách các chuỗi là đối số duy nhất. Đây là tham số
$ python timer.py 5
526 của hàm
$ python timer.py 5
65

Khi thực thi

$ python timer.py 5
65, quy trình hẹn giờ bắt đầu và bạn có thể thấy đầu ra của nó trong thời gian thực. Sau khi hoàn thành, nó trả về một thể hiện của lớp
$ python timer.py 5
529

Trên dòng lệnh, bạn có thể đã quen với việc khởi động chương trình bằng một chuỗi

$ python timer.py 5

Tuy nhiên, với

$ python timer.py 5
65, bạn cần truyền lệnh theo trình tự, như trong ví dụ về
$ python timer.py 5
65. Mỗi mục trong chuỗi đại diện cho một mã thông báo được sử dụng cho lệnh gọi hệ thống để bắt đầu một quy trình mới

Ghi chú. Gọi

$ python timer.py 5
65 không giống như gọi các chương trình trên dòng lệnh. Hàm
$ python timer.py 5
65 thực hiện lệnh gọi hệ thống, không cần trình bao. Bạn sẽ đề cập đến tương tác với trình bao trong phần sau

Các trình bao thường thực hiện mã thông báo của riêng chúng, đó là lý do tại sao bạn chỉ cần viết các lệnh dưới dạng một chuỗi dài trên dòng lệnh. Tuy nhiên, với mô-đun Python

$ python timer.py 5
0, bạn phải chia nhỏ lệnh thành các mã thông báo theo cách thủ công. Chẳng hạn, tên thực thi, cờ và đối số sẽ là một mã thông báo

Ghi chú. Bạn có thể sử dụng mô-đun

$ python timer.py 5
535 để trợ giúp nếu cần, lưu ý rằng mô-đun này được thiết kế cho các hệ thống tuân thủ POSIX và có thể không hoạt động tốt trong môi trường Windows

>>>

$ python timer.py 5
3

Hàm

$ python timer.py 5
536 chia một lệnh điển hình thành các mã thông báo khác nhau cần thiết. Mô-đun
$ python timer.py 5
535 có thể hữu ích khi không rõ cách phân chia các lệnh phức tạp hơn có các ký tự đặc biệt, như dấu cách

>>>

$ python timer.py 5
0

Bạn sẽ lưu ý rằng thư chứa khoảng trắng được giữ nguyên dưới dạng một mã thông báo và không cần thêm dấu ngoặc kép nữa. Các dấu ngoặc kép bổ sung trên vỏ phục vụ để nhóm mã thông báo lại với nhau, nhưng vì

$ python timer.py 5
0 sử dụng các chuỗi nên phần nào sẽ được hiểu là một mã thông báo luôn rõ ràng

Bây giờ bạn đã quen thuộc với một số kiến ​​thức cơ bản để bắt đầu các quy trình mới với mô-đun Python

$ python timer.py 5
0, sắp tới bạn sẽ thấy rằng bạn có thể chạy bất kỳ loại quy trình nào, không chỉ Python hoặc các chương trình dựa trên văn bản

Việc sử dụng $ python timer.py 5 0 để chạy bất kỳ ứng dụng nào

Với

$ python timer.py 5
0, bạn không bị giới hạn trong các ứng dụng dựa trên văn bản như shell. Bạn có thể gọi bất kỳ ứng dụng nào bạn có thể bằng menu Bắt đầu hoặc thanh ứng dụng, miễn là bạn biết tên hoặc đường dẫn chính xác của chương trình mà bạn muốn chạy

  • các cửa sổ
  • Linux
  • hệ điều hành Mac

>>>

$ python timer.py 5
4

>>>

$ python timer.py 5
6

Tùy thuộc vào bản phân phối Linux của bạn, bạn có thể có một trình soạn thảo văn bản khác, chẳng hạn như

$ python timer.py 5
542,
$ python timer.py 5
543,
$ python timer.py 5
544 hoặc
$ python timer.py 5
545

>>>

$ python timer.py 5
50

Các lệnh này sẽ mở ra một cửa sổ soạn thảo văn bản. Thông thường,

$ python timer.py 5
529 sẽ không được trả về cho đến khi bạn đóng cửa sổ soạn thảo. Tuy nhiên, trong trường hợp của macOS, vì bạn cần chạy quy trình trình khởi chạy
$ python timer.py 5
547 để khởi chạy TextEdit, nên
$ python timer.py 5
529 sẽ được trả về ngay lập tức

Các quy trình của trình khởi chạy chịu trách nhiệm khởi chạy một quy trình cụ thể và sau đó kết thúc. Đôi khi các chương trình, chẳng hạn như trình duyệt web, được tích hợp sẵn. Cơ chế của các quy trình trình khởi chạy nằm ngoài phạm vi của hướng dẫn này, nhưng đủ để nói rằng chúng có thể điều khiển cây quy trình của hệ điều hành để gán lại các mối quan hệ cha-con

Ghi chú. Có nhiều vấn đề mà ban đầu bạn có thể cần đến

$ python timer.py 5
0 để giải quyết, nhưng sau đó bạn sẽ tìm thấy một mô-đun hoặc thư viện cụ thể giải quyết vấn đề đó cho bạn. Đây có xu hướng là một chủ đề với
$ python timer.py 5
0 vì nó là một tiện ích cấp thấp

Một ví dụ về điều mà bạn có thể muốn làm với

$ python timer.py 5
0 là mở trình duyệt web đến một trang cụ thể. Tuy nhiên, để làm được điều đó, có lẽ tốt nhất là sử dụng mô-đun Python
$ python timer.py 5
552. Mô-đun
$ python timer.py 5
552 sử dụng
$ python timer.py 5
0 dưới mui xe nhưng xử lý tất cả các khác biệt về trình duyệt và nền tảng phức tạp mà bạn có thể gặp phải

Mặt khác,

$ python timer.py 5
0 có thể là một công cụ cực kỳ hữu ích để hoàn thành công việc một cách nhanh chóng. Nếu bạn không cần một thư viện chính thức, thì
$ python timer.py 5
0 có thể là con dao Quân đội Thụy Sĩ của bạn. Tất cả phụ thuộc vào trường hợp sử dụng của bạn. Thảo luận thêm về chủ đề này sẽ đến sau

Bạn đã bắt đầu thành công các quy trình mới bằng Python. Đó là

$ python timer.py 5
0 ở mức cơ bản nhất. Tiếp theo, bạn sẽ xem xét kỹ hơn đối tượng
$ python timer.py 5
529 được trả về từ
$ python timer.py 5
65

Loại bỏ các quảng cáo

Đối tượng $ python timer.py 5 529

Khi bạn sử dụng

$ python timer.py 5
65, giá trị trả về là một thể hiện của lớp
$ python timer.py 5
529. Đúng như tên gọi,
$ python timer.py 5
65 chỉ trả về đối tượng sau khi tiến trình con kết thúc. Nó có nhiều thuộc tính khác nhau có thể hữu ích, chẳng hạn như
$ python timer.py 5
526 đã được sử dụng cho quy trình và
$ python timer.py 5
565

Để thấy rõ điều này, bạn có thể gán kết quả của

$ python timer.py 5
65 cho một biến, sau đó truy cập các thuộc tính của nó, chẳng hạn như
$ python timer.py 5
567

>>>

$ python timer.py 5
51

Quá trình này có một mã trả về cho biết lỗi, nhưng nó không đưa ra một ngoại lệ. Thông thường, khi một quy trình

$ python timer.py 5
0 không thành công, bạn sẽ luôn muốn đưa ra một ngoại lệ, bạn có thể thực hiện điều này bằng cách chuyển vào một đối số
$ python timer.py 5
569

>>>

$ python timer.py 5
52

Có nhiều cách khác nhau để đối phó với sự cố, một số trong số đó sẽ được đề cập trong phần tiếp theo. Điểm quan trọng cần lưu ý bây giờ là

$ python timer.py 5
65 sẽ không nhất thiết đưa ra một ngoại lệ nếu quy trình không thành công trừ khi bạn đã thông qua một đối số
$ python timer.py 5
569

$ python timer.py 5
529 cũng có một số thuộc tính liên quan đến đầu vào/đầu ra (I/O), bạn sẽ đề cập chi tiết hơn trong phần giao tiếp với quy trình. Tuy nhiên, trước khi giao tiếp với các quy trình, bạn sẽ học cách xử lý lỗi khi viết mã với
$ python timer.py 5
0

$ python timer.py 5 0 ngoại lệ

Như bạn đã thấy trước đó, ngay cả khi một quy trình thoát với mã trả về biểu thị lỗi, Python sẽ không đưa ra ngoại lệ. Đối với hầu hết các trường hợp sử dụng của mô-đun

$ python timer.py 5
0, điều này không lý tưởng. Nếu một quy trình không thành công, bạn thường sẽ muốn xử lý nó bằng cách nào đó chứ không chỉ tiếp tục

Rất nhiều

$ python timer.py 5
0 trường hợp sử dụng liên quan đến các tập lệnh cá nhân ngắn mà bạn có thể không dành nhiều thời gian cho hoặc ít nhất là không nên dành nhiều thời gian cho nó. Nếu bạn đang mày mò với một kịch bản như thế này, thì bạn sẽ muốn
$ python timer.py 5
0 thất bại sớm và ầm ĩ

$ python timer.py 5 578 cho mã thoát khác không

Nếu một quy trình trả về mã thoát khác không, bạn nên hiểu đó là một quy trình không thành công. Trái ngược với những gì bạn có thể mong đợi, mô-đun Python

$ python timer.py 5
0 không tự động đưa ra một ngoại lệ đối với mã thoát khác không. Một quy trình bị lỗi thường không phải là thứ mà bạn muốn chương trình của mình âm thầm vượt qua, vì vậy bạn có thể chuyển một đối số
$ python timer.py 5
569 cho
$ python timer.py 5
65 để đưa ra một ngoại lệ

>>>

$ python timer.py 5
52

$ python timer.py 5
578 được nâng lên ngay khi quy trình con chạy vào mã trả về khác không. Nếu bạn đang phát triển một kịch bản cá nhân ngắn, thì có lẽ điều này là đủ tốt cho bạn. Nếu bạn muốn xử lý lỗi dễ dàng hơn, hãy đọc tiếp phần xử lý ngoại lệ

Một điều cần lưu ý là

$ python timer.py 5
578 không áp dụng cho các quy trình có thể bị treo và chặn quá trình thực thi của bạn vô thời hạn. Để đề phòng điều đó, bạn muốn tận dụng tham số
$ python timer.py 5
584

$ python timer.py 5 585 cho các quy trình mất quá nhiều thời gian

Đôi khi các quy trình không hoạt động tốt và chúng có thể mất quá nhiều thời gian hoặc bị treo vô thời hạn. Để xử lý những tình huống đó, bạn nên sử dụng tham số

$ python timer.py 5
584 của hàm
$ python timer.py 5
65

Truyền đối số

$ python timer.py 5
588 cho
$ python timer.py 5
65 sẽ khiến hàm tắt quy trình và gây ra lỗi
$ python timer.py 5
585 sau một giây

>>>

$ python timer.py 5
54

Trong ví dụ này, dấu chấm đầu tiên của hoạt ảnh hẹn giờ đã được xuất, nhưng quy trình con đã bị tắt trước khi có thể hoàn thành

Loại lỗi khác có thể xảy ra là nếu chương trình không tồn tại trên hệ thống cụ thể đó, điều này làm phát sinh một loại lỗi cuối cùng

Loại bỏ các quảng cáo

$ python timer.py 5 591 cho các chương trình không tồn tại

Loại ngoại lệ cuối cùng mà bạn sẽ xem xét là

$ python timer.py 5
591, loại ngoại lệ này sẽ xuất hiện nếu bạn thử gọi một chương trình không tồn tại trên hệ thống đích

>>>

$ python timer.py 5
55

Loại lỗi này được nêu ra bất kể là gì, vì vậy bạn không cần phải chuyển bất kỳ đối số nào cho

$ python timer.py 5
591

Đó là những ngoại lệ chính mà bạn sẽ gặp phải khi sử dụng mô-đun Python

$ python timer.py 5
0. Đối với nhiều trường hợp sử dụng, biết các ngoại lệ và đảm bảo rằng bạn sử dụng các đối số
$ python timer.py 5
584 và
$ python timer.py 5
596 là đủ. Đó là bởi vì nếu quy trình con không thành công, thì điều đó thường có nghĩa là tập lệnh của bạn không thành công

Tuy nhiên, nếu bạn có một chương trình phức tạp hơn, thì bạn có thể muốn xử lý lỗi một cách khéo léo hơn. Chẳng hạn, bạn có thể cần gọi nhiều tiến trình trong một khoảng thời gian dài. Đối với điều này, bạn có thể sử dụng cấu trúc

$ python timer.py 5
597 …
$ python timer.py 5
598

Một ví dụ về xử lý ngoại lệ

Đây là đoạn mã hiển thị các ngoại lệ chính mà bạn sẽ muốn xử lý khi sử dụng

$ python timer.py 5
0

$ python timer.py 5
56

Đoạn mã này cho bạn thấy một ví dụ về cách bạn có thể xử lý ba ngoại lệ chính do mô-đun

$ python timer.py 5
0 đưa ra

Bây giờ bạn đã sử dụng

$ python timer.py 5
0 ở dạng cơ bản và xử lý một số trường hợp ngoại lệ, đã đến lúc làm quen với những gì cần thiết để tương tác với trình bao

Giới thiệu về Shell và các chương trình dựa trên văn bản với $ python timer.py 5 0

Một số trường hợp sử dụng phổ biến nhất của mô-đun

$ python timer.py 5
0 là để tương tác với các chương trình dựa trên văn bản, thường có sẵn trên trình bao. Đó là lý do tại sao trong phần này, bạn sẽ bắt đầu khám phá tất cả các bộ phận chuyển động có liên quan khi tương tác với các chương trình dựa trên văn bản và có thể đặt câu hỏi liệu bạn có cần shell hay không.

Shell thường đồng nghĩa với giao diện dòng lệnh hoặc CLI, nhưng thuật ngữ này không hoàn toàn chính xác. Thực tế, có hai quy trình riêng biệt tạo nên trải nghiệm dòng lệnh điển hình

  1. Trình thông dịch, thường được coi là toàn bộ CLI. Các trình thông dịch phổ biến là Bash trên Linux, Zsh trên macOS hoặc PowerShell trên Windows. Trong hướng dẫn này, trình thông dịch sẽ được gọi là shell
  2. Giao diện hiển thị đầu ra của trình thông dịch trong một cửa sổ và gửi các lần nhấn phím của người dùng tới trình thông dịch. Giao diện là một quá trình riêng biệt với trình bao, đôi khi được gọi là trình giả lập thiết bị đầu cuối

Khi ở trên dòng lệnh, người ta thường nghĩ rằng bạn đang tương tác trực tiếp với trình bao, nhưng bạn thực sự đang tương tác với giao diện. Giao diện đảm nhiệm việc gửi các lệnh của bạn tới trình bao và hiển thị kết quả đầu ra của trình bao lại cho bạn

Với sự khác biệt quan trọng này, đã đến lúc chuyển sự chú ý của bạn sang những gì mà

$ python timer.py 5
65 đang thực sự làm. Người ta thường nghĩ rằng việc gọi
$ python timer.py 5
65 bằng cách nào đó cũng giống như nhập lệnh trong giao diện đầu cuối, nhưng có những điểm khác biệt quan trọng

Mặc dù tất cả các quy trình mới được tạo với cùng một cuộc gọi hệ thống, ngữ cảnh mà cuộc gọi hệ thống được thực hiện là khác nhau. Hàm

$ python timer.py 5
65 có thể thực hiện cuộc gọi hệ thống trực tiếp và không cần thông qua trình bao để thực hiện việc này

Trên thực tế, nhiều chương trình được coi là chương trình shell, chẳng hạn như Git, thực sự chỉ là các chương trình dựa trên văn bản không cần shell để chạy. Điều này đặc biệt đúng với môi trường UNIX, nơi tất cả các tiện ích quen thuộc như

$ python timer.py 5
3,
$ python timer.py 5
908,
$ python timer.py 5
909 và
$ python timer.py 5
910 thực sự là các tệp thực thi riêng biệt có thể được gọi trực tiếp.

>>>

$ python timer.py 5
57

Tuy nhiên, có một số công cụ dành riêng cho trình bao. Việc tìm kiếm các công cụ được nhúng trong trình bao phổ biến hơn nhiều trên các trình bao Windows như PowerShell, trong đó các lệnh như

$ python timer.py 5
3 là một phần của chính trình bao chứ không phải các tệp thực thi riêng biệt như trong môi trường UNIX

>>>

$ python timer.py 5
58

Trong PowerShell,

$ python timer.py 5
3 là bí danh mặc định cho
$ python timer.py 5
913, nhưng cách gọi đó cũng không hoạt động vì
$ python timer.py 5
913 không phải là tệp thực thi riêng biệt—nó là một phần của chính PowerShell

Thực tế là nhiều chương trình dựa trên văn bản có thể hoạt động độc lập với trình bao có thể khiến bạn tự hỏi liệu bạn có thể loại bỏ quy trình trung gian hay không—cụ thể là trình bao—và sử dụng trực tiếp

$ python timer.py 5
0 với các chương trình dựa trên văn bản thường được liên kết với trình bao

Loại bỏ các quảng cáo

Các trường hợp sử dụng cho Shell và $ python timer.py 5 0

Có một vài lý do phổ biến khiến bạn có thể muốn gọi trình bao bằng mô-đun quy trình con

$ python timer.py 5
917

  • Khi bạn biết một số lệnh nhất định chỉ khả dụng thông qua trình bao, điều này phổ biến hơn trong Windows
  • Khi bạn có kinh nghiệm viết shell script với một shell cụ thể, vì vậy bạn muốn tận dụng khả năng của mình ở đó để thực hiện một số tác vụ nhất định trong khi vẫn làm việc chủ yếu bằng Python
  • Khi bạn đã kế thừa một shell script lớn có thể không làm được gì mà Python không làm được, nhưng sẽ mất nhiều thời gian để triển khai lại trong Python

Đây không phải là một danh sách đầy đủ

Bạn có thể sử dụng trình bao để ngắt chương trình hoặc để thực hiện một số thao tác xử lý văn bản. Tuy nhiên, cú pháp có thể rất khó hiểu khi so sánh với Python. Với Python, quy trình xử lý văn bản dễ viết hơn, dễ bảo trì hơn, hiệu suất cao hơn và đa nền tảng để khởi động. Vì vậy, nó rất đáng để xem xét việc không có vỏ

Tuy nhiên, điều thường xảy ra là bạn không có thời gian hoặc không đáng để nỗ lực triển khai lại các tập lệnh shell hiện có trong Python. Trong những trường hợp đó, sử dụng

$ python timer.py 5
0 cho một số Python cẩu thả không phải là điều xấu

Các lý do phổ biến để sử dụng bản thân

$ python timer.py 5
0 tương tự như việc sử dụng shell với
$ python timer.py 5
0

  • Khi bạn phải sử dụng hoặc phân tích hộp đen, hoặc thậm chí là hộp trắng
  • Khi bạn muốn một trình bao bọc cho một ứng dụng
  • Khi bạn cần khởi chạy một ứng dụng khác
  • Là một giải pháp thay thế cho các tập lệnh Shell cơ bản

Ghi chú. Hộp đen có thể là một chương trình có thể được sử dụng miễn phí nhưng không có mã nguồn, vì vậy không có cách nào để biết chính xác nó làm gì và không có cách nào để sửa đổi phần bên trong của nó

Tương tự, hộp trắng có thể là chương trình có sẵn mã nguồn nhưng không thay đổi được. Nó cũng có thể là một chương trình có mã nguồn mà bạn có thể thay đổi, nhưng độ phức tạp của nó có nghĩa là bạn sẽ mất nhiều thời gian để hiểu nó để có thể thay đổi nó.

Trong những trường hợp này, bạn có thể sử dụng

$ python timer.py 5
0 để bọc các hộp có độ mờ khác nhau, bỏ qua mọi nhu cầu thay đổi hoặc triển khai lại mọi thứ trong Python

Thường thì bạn sẽ thấy rằng đối với

$ python timer.py 5
0 trường hợp sử dụng, sẽ có một thư viện dành riêng cho nhiệm vụ đó. Ở phần sau của hướng dẫn, bạn sẽ kiểm tra tập lệnh tạo dự án Python, hoàn chỉnh với môi trường ảo và kho lưu trữ Git được khởi tạo đầy đủ. Tuy nhiên, các thư viện Cookiecutter và Copier đã tồn tại cho mục đích đó

Mặc dù các thư viện cụ thể có thể thực hiện nhiệm vụ của bạn, nhưng vẫn có thể đáng để thực hiện với

$ python timer.py 5
0. Thứ nhất, bạn có thể thực hiện những gì bạn đã biết cách làm nhanh hơn nhiều so với việc học một thư viện mới

Ngoài ra, nếu bạn đang chia sẻ tập lệnh này với bạn bè hoặc đồng nghiệp, sẽ rất thuận tiện nếu tập lệnh của bạn hoàn toàn là Python mà không có bất kỳ phần phụ thuộc nào khác, đặc biệt nếu tập lệnh của bạn cần hoạt động trên các môi trường tối thiểu như máy chủ hoặc hệ thống nhúng

Tuy nhiên, nếu bạn đang sử dụng

$ python timer.py 5
0 thay vì
$ python timer.py 5
925 để đọc và ghi một số tệp bằng Bash, bạn có thể cân nhắc học cách đọc và viết bằng Python. Học cách đọc và ghi tệp không mất nhiều thời gian và nó chắc chắn sẽ xứng đáng với một nhiệm vụ thông thường như vậy

Ngoài ra, đã đến lúc làm quen với môi trường shell trên cả hệ thống dựa trên Windows và UNIX

Cách sử dụng cơ bản của $ python timer.py 5 0 với Shell dựa trên UNIX

Để chạy một lệnh trình bao bằng cách sử dụng

$ python timer.py 5
65, thì
$ python timer.py 5
526 phải chứa trình bao mà bạn muốn sử dụng, cờ để cho biết rằng bạn muốn nó chạy một lệnh cụ thể và lệnh mà bạn đang chuyển vào

>>>

$ python timer.py 5
59

Ở đây, một lệnh shell phổ biến được trình bày. Nó sử dụng

$ python timer.py 5
3 dẫn vào
$ python timer.py 5
909 để lọc một số mục nhập. Shell tiện dụng cho loại hoạt động này vì bạn có thể tận dụng bộ điều khiển đường ống (
$ python timer.py 5
931). Bạn sẽ trình bày chi tiết hơn về các đường ống sau

Bạn có thể thay thế

$ python timer.py 5
932 bằng vỏ bạn chọn. Cờ
$ python timer.py 5
933 là viết tắt của command, nhưng có thể khác tùy thuộc vào shell mà bạn đang sử dụng. Điều này gần như chính xác tương đương với những gì xảy ra khi bạn thêm đối số
$ python timer.py 5
934

>>>

$ python timer.py 5
90

Đối số

$ python timer.py 5
934 sử dụng
$ python timer.py 5
936 đằng sau hậu trường, vì vậy nó gần như tương đương với ví dụ trước

Ghi chú. Trên các hệ thống dựa trên UNIX, trình bao

$ python timer.py 5
937 theo truyền thống là trình bao Bourne. Điều đó nói rằng, trình bao Bourne hiện đã khá cũ, vì vậy nhiều hệ điều hành sử dụng
$ python timer.py 5
937 làm liên kết đến Bash hoặc Dash

Điều này thường có thể khác với trình bao được sử dụng với giao diện đầu cuối mà bạn tương tác. Chẳng hạn, kể từ macOS Catalina, trình bao mặc định mà bạn sẽ tìm thấy trên ứng dụng dòng lệnh đã thay đổi từ Bash thành Zsh, nhưng

$ python timer.py 5
937 thường vẫn trỏ tới Bash. Tương tự như vậy, trên Ubuntu,
$ python timer.py 5
937 trỏ đến Dash, nhưng mặc định mà bạn thường tương tác trên ứng dụng dòng lệnh vẫn là Bash

Vì vậy, việc gọi

$ python timer.py 5
937 trên hệ thống của bạn có thể dẫn đến một hệ vỏ khác với những gì được tìm thấy trong hướng dẫn này. Tuy nhiên, tất cả các ví dụ vẫn hoạt động

Bạn sẽ lưu ý rằng mã thông báo sau

$ python timer.py 5
942 phải là một mã thông báo duy nhất, bao gồm tất cả các khoảng trắng. Ở đây bạn đang trao quyền điều khiển cho trình bao để phân tích cú pháp lệnh. Nếu bạn bao gồm nhiều mã thông báo hơn, điều này sẽ được hiểu là có nhiều tùy chọn hơn để chuyển sang trình bao có thể thực thi được, chứ không phải là các lệnh bổ sung để chạy bên trong trình bao

Loại bỏ các quảng cáo

Cách sử dụng cơ bản của $ python timer.py 5 0 với Windows Shell

Trong phần này, bạn sẽ đề cập đến cách sử dụng cơ bản shell với

$ python timer.py 5
0 trong môi trường Windows

Để chạy một lệnh trình bao bằng cách sử dụng

$ python timer.py 5
65, thì
$ python timer.py 5
526 phải chứa trình bao mà bạn muốn sử dụng, cờ để cho biết rằng bạn muốn nó chạy một lệnh cụ thể và lệnh mà bạn đang chuyển vào

>>>

$ python timer.py 5
91

Lưu ý rằng cả

$ python timer.py 5
947 và
$ python timer.py 5
948 đều hoạt động. Nếu bạn không có PowerShell Core, thì bạn có thể gọi
$ python timer.py 5
949 hoặc
$ python timer.py 5
950

Bạn sẽ lưu ý rằng mã thông báo sau

$ python timer.py 5
951 phải là một mã thông báo duy nhất, bao gồm tất cả các khoảng trắng. Ở đây bạn đang trao quyền điều khiển cho trình bao để phân tích cú pháp lệnh. Nếu bạn bao gồm nhiều mã thông báo hơn, điều này sẽ được hiểu là có nhiều tùy chọn hơn để chuyển sang trình bao có thể thực thi được, chứ không phải là các lệnh bổ sung để chạy bên trong trình bao

Nếu bạn cần Dấu nhắc Lệnh, thì tệp thực thi là

$ python timer.py 5
952 hoặc
$ python timer.py 5
953 và cờ để chỉ ra rằng mã thông báo sau đây là một lệnh là
$ python timer.py 5
954

>>>

$ python timer.py 5
92

Ví dụ cuối cùng này chính xác tương đương với việc gọi

$ python timer.py 5
65 với
$ python timer.py 5
934. Nói cách khác, sử dụng đối số
$ python timer.py 5
934 giống như thêm
$ python timer.py 5
958 và
$ python timer.py 5
959 vào danh sách đối số của bạn

Ghi chú. Quá trình phát triển của Windows rất khác so với quá trình phát triển của các hệ thống dựa trên UNIX. Shell được biết đến rộng rãi nhất là Windows Command Prompt, hiện là Shell kế thừa. Dấu nhắc lệnh được tạo để mô phỏng môi trường MS-DOS trước Windows. Nhiều tập lệnh shell, hoặc tập lệnh hàng loạt

$ python timer.py 5
960, được viết cho môi trường này vẫn còn được sử dụng cho đến ngày nay

Hàm

$ python timer.py 5
65 với tham số
$ python timer.py 5
962 hầu như sẽ luôn kết thúc bằng Dấu nhắc Lệnh. Mô-đun
$ python timer.py 5
0 sử dụng biến môi trường Windows
$ python timer.py 5
964, mà trong hầu hết các trường hợp sẽ trỏ đến
$ python timer.py 5
953, Dấu nhắc Lệnh. Hiện tại, có rất nhiều chương trình đánh đồng
$ python timer.py 5
964 với
$ python timer.py 5
953 nên việc thay đổi nó sẽ gây ra nhiều sự cố ở những nơi không mong muốn. Vì vậy, thay đổi
$ python timer.py 5
964 thường không được khuyến khích

Tại thời điểm này, bạn nên biết về một vấn đề bảo mật quan trọng mà bạn sẽ muốn biết nếu bạn có các phần tử hướng tới người dùng trong chương trình Python của mình, bất kể hệ điều hành là gì. Đó là một lỗ hổng không chỉ giới hạn ở

$ python timer.py 5
0. Hơn nữa, nó có thể được khai thác trong nhiều lĩnh vực khác nhau

Cảnh báo bảo mật

Nếu tại bất kỳ thời điểm nào bạn dự định lấy thông tin đầu vào của người dùng và bằng cách nào đó dịch nó thành lệnh gọi tới

$ python timer.py 5
0, thì bạn phải hết sức cẩn thận trước các cuộc tấn công tiêm nhiễm. Đó là, tính đến các tác nhân độc hại tiềm ẩn. Có nhiều cách để gây ra sự tàn phá nếu bạn cứ để mọi người chạy mã trên máy của mình

Để sử dụng một ví dụ rất đơn giản, nơi bạn lấy đầu vào của người dùng và gửi nó, chưa được lọc, tới quy trình con để chạy trên trình bao

  • các cửa sổ
  • Linux + macOS

$ python timer.py 5
93

$ python timer.py 5
94

Bạn có thể tưởng tượng trường hợp sử dụng dự định là bọc

$ python timer.py 5
3 và thêm thứ gì đó vào đó. Vì vậy, hành vi dự kiến ​​của người dùng là cung cấp một đường dẫn như
$ python timer.py 5
972. Tuy nhiên, nếu một tác nhân độc hại nhận ra điều gì đang xảy ra, họ có thể thực thi hầu hết mọi mã mà họ muốn. Lấy ví dụ sau đây, nhưng hãy cẩn thận với điều này

  • các cửa sổ
  • Linux + macOS

$ python timer.py 5
973

$ python timer.py 5
974

Một lần nữa, hãy cẩn thận. Những dòng trông ngây thơ này có thể thử và xóa mọi thứ trên hệ thống. Trong trường hợp này, phần độc hại nằm trong dấu ngoặc kép nên nó sẽ không chạy, nhưng nếu không có dấu ngoặc kép thì bạn sẽ gặp rắc rối. Phần quan trọng thực hiện điều này là lệnh gọi tới

$ python timer.py 5
908 với các cờ có liên quan để xóa đệ quy tất cả các tệp, thư mục và thư mục con và nó sẽ hoạt động để buộc xóa thông qua. Nó có thể chạy
$ python timer.py 5
976 và có khả năng là
$ python timer.py 5
908 dưới dạng các lệnh hoàn toàn riêng biệt bằng cách thêm dấu chấm phẩy, đóng vai trò là dấu tách lệnh cho phép nhiều dòng mã thường chạy trên một dòng

Việc chạy các lệnh độc hại này sẽ gây ra thiệt hại không thể khắc phục đối với hệ thống tệp và sẽ yêu cầu cài đặt lại hệ điều hành. Cẩn thận

May mắn thay, hệ điều hành sẽ không cho phép bạn làm điều này với một số tệp đặc biệt quan trọng. Lệnh

$ python timer.py 5
908 sẽ cần sử dụng
$ python timer.py 5
979 trong các hệ thống dựa trên UNIX hoặc được chạy với tư cách quản trị viên trong Windows để hoàn toàn thành công trong tình trạng lộn xộn của nó. Tuy nhiên, lệnh có thể sẽ xóa rất nhiều nội dung quan trọng trước khi dừng

Vì vậy, hãy đảm bảo rằng nếu bạn đang xây dựng động các đầu vào của người dùng để cung cấp cho cuộc gọi

$ python timer.py 5
0, thì bạn phải hết sức cẩn thận. Với cảnh báo đó, sắp tới bạn sẽ đề cập đến việc sử dụng kết quả đầu ra của các lệnh và xâu chuỗi các lệnh lại với nhau—nói ngắn gọn là cách giao tiếp với các quy trình sau khi chúng bắt đầu

Loại bỏ các quảng cáo

Giao tiếp với các quy trình

Bạn đã sử dụng mô-đun

$ python timer.py 5
0 để thực thi các chương trình và gửi các lệnh cơ bản tới trình bao. Nhưng một cái gì đó quan trọng vẫn còn thiếu. Đối với nhiều tác vụ mà bạn có thể muốn sử dụng
$ python timer.py 5
0, bạn có thể muốn tự động gửi đầu vào hoặc sử dụng đầu ra trong mã Python của mình sau

Để giao tiếp với quy trình của bạn, trước tiên bạn nên hiểu một chút về cách các quy trình giao tiếp nói chung, sau đó bạn sẽ xem xét hai ví dụ để hiểu rõ các khái niệm

Luồng I/O tiêu chuẩn

Một luồng ở mức cơ bản nhất đại diện cho một chuỗi các phần tử không có sẵn cùng một lúc. Khi bạn đọc các ký tự và dòng từ một tệp, bạn đang làm việc với một luồng ở dạng một đối tượng tệp, đối tượng cơ bản nhất của nó là một bộ mô tả tệp. Bộ mô tả tệp thường được sử dụng cho luồng. Vì vậy, không có gì lạ khi thấy các thuật ngữ luồng, tệp và giống như tệp được sử dụng thay thế cho nhau

Khi các quy trình được khởi tạo, có ba luồng đặc biệt mà một quy trình sử dụng. Một quá trình làm như sau

  1. Đọc
    $ python timer.py 5
    
    983 cho đầu vào
  2. Ghi vào
    $ python timer.py 5
    
    984 cho đầu ra chung
  3. Viết thư cho
    $ python timer.py 5
    
    985 để báo cáo lỗi

Đây là các luồng tiêu chuẩn—một mẫu đa nền tảng để giao tiếp theo quy trình

Đôi khi tiến trình con kế thừa các luồng này từ tiến trình cha. Đây là điều đang xảy ra khi bạn sử dụng

$ python timer.py 5
986 trong REPL và có thể thấy đầu ra của lệnh.
$ python timer.py 5
984 của trình thông dịch Python được kế thừa bởi quy trình con

Khi bạn đang ở trong môi trường REPL, bạn đang xem quy trình giao diện dòng lệnh, hoàn chỉnh với ba luồng I/O tiêu chuẩn. Giao diện có quy trình shell là quy trình con, bản thân nó có Python REPL khi còn nhỏ. Trong tình huống này, trừ khi bạn chỉ định khác,

$ python timer.py 5
983 sẽ xuất phát từ bàn phím, trong khi
$ python timer.py 5
984 và
$ python timer.py 5
985 được hiển thị trên màn hình. Giao diện, trình bao và REPL chia sẻ các luồng

Xả quy trình con Python

Bạn có thể coi các luồng I/O tiêu chuẩn là bộ phân phối byte. Quy trình con điền vào

$ python timer.py 5
984 và
$ python timer.py 5
985, và bạn điền vào
$ python timer.py 5
983. Sau đó, bạn đọc các byte trong
$ python timer.py 5
984 và
$ python timer.py 5
985, và quy trình con đọc từ
$ python timer.py 5
983

Như với một bộ phân phối, bạn có thể dự trữ

$ python timer.py 5
983 trước khi nó được liên kết với một quy trình con. Quá trình con sau đó sẽ đọc từ
$ python timer.py 5
983 và khi nó cần. Tuy nhiên, khi một quá trình đã đọc từ một luồng, các byte sẽ được phân phối. Bạn không thể quay lại và đọc lại chúng

Ba luồng hoặc tệp này là cơ sở để giao tiếp với quy trình của bạn. Trong phần tiếp theo, bạn sẽ bắt đầu thấy điều này hoạt động bằng cách lấy đầu ra của chương trình tạo số ma thuật

Ví dụ về trình tạo số ma thuật

Thông thường, khi sử dụng mô-đun

$ python timer.py 5
0, bạn sẽ muốn sử dụng đầu ra cho một thứ gì đó chứ không chỉ hiển thị đầu ra như bạn vẫn làm từ trước đến nay. Trong phần này, bạn sẽ sử dụng một trình tạo số ma thuật để xuất ra một số ma thuật.

Hãy tưởng tượng rằng trình tạo số ma thuật là một chương trình tối nghĩa nào đó, một hộp đen, được kế thừa qua nhiều thế hệ quản trị viên hệ thống trong công việc của bạn. Nó đưa ra một con số kỳ diệu mà bạn cần cho các phép tính bí mật của mình. Bạn sẽ đọc từ

$ python timer.py 5
984 của
$ python timer.py 5
0 và sử dụng nó trong chương trình Python bao bọc của bạn

$ python timer.py 5
95

Được rồi, không thực sự quá kỳ diệu. Điều đó nói lên rằng, đó không phải là trình tạo số ma thuật mà bạn quan tâm—nó tương tác với một hộp đen giả định với

$ python timer.py 5
0 mới là điều thú vị. Để lấy đầu ra của trình tạo số để sử dụng sau này, bạn có thể chuyển đối số
$ python timer.py 5
803 sang
$ python timer.py 5
65

>>>

$ python timer.py 5
96

Việc truyền đối số

$ python timer.py 5
805 của
$ python timer.py 5
806 đến
$ python timer.py 5
65 làm cho đầu ra của quy trình có sẵn tại thuộc tính
$ python timer.py 5
808 của đối tượng quy trình đã hoàn thành. Bạn sẽ lưu ý rằng nó được trả về dưới dạng đối tượng byte, vì vậy bạn cần chú ý đến mã hóa khi đọc nó

Cũng lưu ý rằng thuộc tính

$ python timer.py 5
808 của
$ python timer.py 5
529 không còn là luồng. Luồng đã được đọc và nó được lưu trữ dưới dạng đối tượng byte trong thuộc tính
$ python timer.py 5
808

Với đầu ra có sẵn, bạn có thể sử dụng nhiều hơn một quy trình con để lấy các giá trị và thao tác trên chúng trong mã của mình

>>>

$ python timer.py 5
97

Trong ví dụ này, bạn bắt đầu hai quy trình số ma thuật lấy hai số ma thuật rồi cộng chúng lại với nhau. Hiện tại, bạn dựa vào việc giải mã tự động đối tượng byte bằng hàm tạo

$ python timer.py 5
812. Tuy nhiên, trong phần tiếp theo, bạn sẽ học cách giải mã và mã hóa rõ ràng

Loại bỏ các quảng cáo

Giải mã các luồng tiêu chuẩn

Các quy trình giao tiếp theo byte và bạn có một vài cách khác nhau để xử lý việc mã hóa và giải mã các byte này. Bên dưới bề mặt,

$ python timer.py 5
0 có một số cách để chuyển sang chế độ văn bản

Chế độ văn bản có nghĩa là

$ python timer.py 5
0 sẽ cố gắng tự mã hóa. Để làm điều đó, nó cần biết mã hóa ký tự nào sẽ sử dụng. Hầu hết các tùy chọn để thực hiện việc này trong
$ python timer.py 5
0 sẽ cố gắng sử dụng mã hóa mặc định. Tuy nhiên, bạn thường muốn rõ ràng về việc sử dụng mã hóa nào để ngăn chặn một lỗi khó phát hiện trong tương lai

Bạn có thể chuyển đối số

$ python timer.py 5
816 cho Python để xử lý mã hóa bằng cách sử dụng mã hóa mặc định. Tuy nhiên, như đã đề cập, việc chỉ định mã hóa một cách rõ ràng bằng cách sử dụng đối số
$ python timer.py 5
817 luôn an toàn hơn, vì không phải tất cả các hệ thống đều hoạt động với UTF-8 gần như phổ biến

>>>

$ python timer.py 5
98

Nếu ở chế độ văn bản, thuộc tính

$ python timer.py 5
808 trên
$ python timer.py 5
529 hiện là một chuỗi chứ không phải đối tượng byte

Bạn cũng có thể giải mã các byte được trả về bằng cách gọi trực tiếp phương thức

$ python timer.py 5
820 trên thuộc tính
$ python timer.py 5
984 mà hoàn toàn không yêu cầu chế độ văn bản

>>>

$ python timer.py 5
99

Có nhiều cách khác để đưa

$ python timer.py 5
65 vào chế độ văn bản. Bạn cũng có thể đặt giá trị
$ python timer.py 5
806 cho
$ python timer.py 5
824 hoặc
$ python timer.py 5
825, điều này cũng sẽ đặt
$ python timer.py 5
65 ở chế độ văn bản. Điều này có vẻ dư thừa, nhưng phần lớn trong số này được giữ lại để tương thích ngược, vì mô-đun
$ python timer.py 5
0 đã thay đổi qua nhiều năm

Bây giờ bạn đã biết cách đọc và giải mã đầu ra của một quy trình, đã đến lúc xem xét việc ghi vào đầu vào của một quy trình

Ví dụ về trò chơi phản ứng

Trong phần này, bạn sẽ sử dụng

$ python timer.py 5
0 để tương tác với trò chơi dòng lệnh. Đó là một chương trình cơ bản được thiết kế để kiểm tra thời gian phản ứng của con người. Tuy nhiên, với kiến ​​thức của bạn về các luồng I/O tiêu chuẩn, bạn sẽ có thể hack nó. Mã nguồn của trò chơi sử dụng mô-đun
$ python timer.py 5
829 và
$ python timer.py 5
830

$ python timer.py 5
80

Chương trình bắt đầu, yêu cầu người dùng nhấn enter, sau một khoảng thời gian ngẫu nhiên sẽ yêu cầu người dùng nhấn enter lần nữa. Nó tính từ lúc thông báo xuất hiện cho đến khi người dùng nhấn enter, hoặc ít nhất đó là suy nghĩ của nhà phát triển game

Hàm

$ python timer.py 5
831 sẽ đọc từ
$ python timer.py 5
983 cho đến khi xuống một dòng mới, có nghĩa là một lần nhấn phím Enter trong ngữ cảnh này. Nó trả về mọi thứ mà nó sử dụng từ
$ python timer.py 5
983 ngoại trừ dòng mới. Với kiến ​​thức đó, bạn có thể sử dụng
$ python timer.py 5
0 để tương tác với trò chơi này.

>>>

$ python timer.py 5
81

Thời gian phản ứng là 0 mili giây. Không tệ. Xem xét thời gian phản ứng trung bình của con người là khoảng 270 mili giây, chương trình của bạn chắc chắn là siêu phàm. Lưu ý rằng trò chơi làm tròn đầu ra của nó, vì vậy 0 mili giây không có nghĩa là nó diễn ra tức thời

Đối số

$ python timer.py 5
835 được chuyển đến
$ python timer.py 5
65 là một chuỗi bao gồm hai dòng mới. Tham số
$ python timer.py 5
817 được đặt thành
$ python timer.py 5
838, đặt
$ python timer.py 5
65 ở chế độ văn bản. Điều này thiết lập quy trình để nó nhận thông tin đầu vào mà bạn cung cấp cho nó

Trước khi chương trình bắt đầu,

$ python timer.py 5
983 đã được lưu trữ, chờ chương trình sử dụng các dòng mới mà nó chứa. Một dòng mới được sử dụng để bắt đầu trò chơi và dòng mới tiếp theo được sử dụng để phản ứng với
$ python timer.py 5
841

Bây giờ bạn đã biết điều gì đang xảy ra—cụ thể là có thể nói rằng

$ python timer.py 5
983 có thể được dự trữ—bạn có thể tự hack chương trình mà không cần
$ python timer.py 5
0. Nếu bạn bắt đầu trò chơi và sau đó nhấn Enter một vài lần, trò chơi đó sẽ tích trữ
$ python timer.py 5
983 với một số dòng mới mà chương trình sẽ tự động sử dụng sau khi nhận được . Vì vậy, thời gian phản ứng của bạn thực sự chỉ là thời gian cần thiết để trò chơi phản ứng thực thi
$ python timer.py 5
846 và sử dụng đầu vào.

Tuy nhiên, nhà phát triển trò chơi đã khôn ngoan với điều này và thề sẽ phát hành một phiên bản khác, phiên bản này sẽ bảo vệ chống lại việc khai thác này. Trong thời gian chờ đợi, bạn sẽ tìm hiểu sâu hơn một chút về

$ python timer.py 5
0 và tìm hiểu về cách nó kết nối các luồng I/O tiêu chuẩn

Loại bỏ các quảng cáo

Đường ống và Shell

Để thực sự hiểu các quy trình con và chuyển hướng luồng, bạn thực sự cần hiểu các đường ống và chúng là gì. Điều này đặc biệt đúng nếu bạn muốn kết nối hai quy trình lại với nhau, chẳng hạn như đưa một

$ python timer.py 5
984 vào một
$ python timer.py 5
983 của quy trình khác. Trong phần này, bạn sẽ nắm bắt được các đường ống và cách sử dụng chúng với mô-đun
$ python timer.py 5
0

Giới thiệu về ống

Đường dẫn hoặc đường dẫn là một luồng đặc biệt, thay vì có một tệp xử lý như hầu hết các tệp, có hai. Một tay cầm là chỉ đọc và tay cầm kia là chỉ ghi. Cái tên rất mô tả—một đường ống phục vụ để chuyển một luồng byte từ quy trình này sang quy trình khác. Nó cũng được lưu vào bộ đệm, vì vậy một quy trình có thể ghi vào nó và nó sẽ giữ các byte đó cho đến khi nó được đọc, giống như một bộ phân phối

Bạn có thể quen nhìn thấy các đường ống trên dòng lệnh, như bạn đã làm trong phần về trình bao

$ python timer.py 5
82

Lệnh này yêu cầu trình bao tạo một quy trình

$ python timer.py 5
3 để liệt kê tất cả các tệp trong
$ python timer.py 5
852. Người vận hành đường ống (
$ python timer.py 5
931) yêu cầu hệ vỏ tạo một đường ống từ quy trình
$ python timer.py 5
984 của quy trình
$ python timer.py 5
3 và đưa nó vào quy trình
$ python timer.py 5
983 của quy trình
$ python timer.py 5
909. Quá trình
$ python timer.py 5
909 lọc ra tất cả các dòng không chứa chuỗi
$ python timer.py 5
859

Windows không có

$ python timer.py 5
909, nhưng tương đương với lệnh tương tự sẽ như sau

$ python timer.py 5
83

Tuy nhiên, trên Windows PowerShell, mọi thứ hoạt động rất khác. Như bạn đã học trong phần trình bao Windows của hướng dẫn này, các lệnh khác nhau không phải là các tệp thực thi riêng biệt. Do đó, PowerShell đang chuyển hướng nội bộ đầu ra của một lệnh sang một lệnh khác mà không bắt đầu các quy trình mới

Ghi chú. Nếu bạn không có quyền truy cập vào hệ điều hành dựa trên UNIX nhưng có Windows 10 trở lên, thì bạn thực sự có quyền truy cập vào hệ điều hành dựa trên UNIX. Kiểm tra Hệ thống con Windows dành cho Linux, sẽ cung cấp cho bạn quyền truy cập vào trình bao Linux đầy đủ tính năng

Bạn có thể sử dụng đường ống cho các quy trình khác nhau trên PowerShell, mặc dù việc tìm hiểu những điểm phức tạp của quy trình nào nằm ngoài phạm vi của hướng dẫn này. Để biết thêm thông tin về đường ống PowerShell, hãy xem tài liệu. Vì vậy, đối với phần còn lại của các ví dụ đường ống, chỉ các ví dụ dựa trên UNIX sẽ được sử dụng, vì cơ chế cơ bản giống nhau cho cả hai hệ thống. Dù sao thì chúng gần như không phổ biến trên Windows

Nếu bạn muốn để trình bao xử lý các quy trình đường ống với nhau, thì bạn chỉ cần chuyển toàn bộ chuỗi dưới dạng lệnh vào

$ python timer.py 5
0

>>>

$ python timer.py 5
84

Bằng cách này, bạn có thể để trình bao đã chọn đảm nhiệm việc chuyển quy trình này sang quy trình khác, thay vì cố gắng triển khai lại mọi thứ trong Python. Đây là một sự lựa chọn hoàn toàn hợp lệ trong những tình huống nhất định

Ở phần sau của hướng dẫn, bạn cũng sẽ thấy rằng bạn không thể xử lý đường ống trực tiếp với

$ python timer.py 5
65. Đối với điều đó, bạn sẽ cần
$ python timer.py 5
33 phức tạp hơn. Đường ống thực tế được thể hiện trong Kết nối hai quy trình với nhau bằng đường ống, gần cuối hướng dẫn

Cho dù bạn có định chuyển quy trình này sang quy trình khác bằng mô-đun

$ python timer.py 5
0 hay không, thì mô-đun
$ python timer.py 5
0 sử dụng rộng rãi các đường ống phía sau hậu trường

Các đường ống của $ python timer.py 5 0

Mô-đun Python

$ python timer.py 5
0 sử dụng rộng rãi các đường ống để tương tác với các quy trình mà nó bắt đầu. Trong ví dụ trước, bạn đã sử dụng tham số
$ python timer.py 5
805 để có thể truy cập
$ python timer.py 5
984

>>>

$ python timer.py 5
96

$ python timer.py 5
803 tương đương với việc đặt rõ ràng các tham số
$ python timer.py 5
984 và
$ python timer.py 5
985 thành hằng số
$ python timer.py 5
873

>>>

$ python timer.py 5
86

Hằng số

$ python timer.py 5
874 không có gì đặc biệt. Đó chỉ là một con số biểu thị cho
$ python timer.py 5
0 rằng một đường ống sẽ được tạo. Sau đó, hàm tạo một đường ống để liên kết đến ________ 2984 của quy trình con, sau đó hàm này sẽ đọc vào thuộc tính ________ 2984 của đối tượng ________ 2529. Vào thời điểm đó là
$ python timer.py 5
529, nó không còn là một đường ống nữa mà là một đối tượng byte có thể được truy cập nhiều lần

Ghi chú. Bộ đệm ống có dung lượng hạn chế. Tùy thuộc vào hệ thống mà bạn đang chạy, bạn có thể dễ dàng gặp phải giới hạn đó nếu định lưu trữ một lượng lớn dữ liệu trong bộ đệm. Để khắc phục giới hạn này, bạn có thể sử dụng các tệp thông thường

Bạn cũng có thể chuyển một đối tượng tệp tới bất kỳ tham số luồng tiêu chuẩn nào

>>>

$ python timer.py 5
87

Tuy nhiên, bạn không thể truyền trực tiếp một đối tượng byte hoặc một chuỗi vào đối số

$ python timer.py 5
983. Nó cần phải là một cái gì đó giống như tập tin

Lưu ý rằng

$ python timer.py 5
881 được trả về đầu tiên là từ cuộc gọi đến
$ python timer.py 5
882 trả về vị trí luồng mới, trong trường hợp này là điểm bắt đầu của luồng

Tham số

$ python timer.py 5
835 tương tự như tham số
$ python timer.py 5
805 ở chỗ nó là một phím tắt. Sử dụng tham số
$ python timer.py 5
835 sẽ tạo bộ đệm để lưu trữ nội dung của
$ python timer.py 5
835, sau đó liên kết tệp với quy trình mới để đóng vai trò là
$ python timer.py 5
983 của nó

Để thực sự liên kết hai quy trình với một đường ống từ bên trong

$ python timer.py 5
0 là điều mà bạn không thể làm với
$ python timer.py 5
65. Thay vào đó, bạn có thể ủy thác hệ thống ống nước cho shell, như bạn đã làm trước đó trong phần Giới thiệu về Shell và Chương trình dựa trên văn bản với
$ python timer.py 5
0

Nếu bạn cần liên kết các quy trình khác nhau mà không ủy thác bất kỳ công việc nào cho trình bao, thì bạn có thể làm điều đó với hàm tạo

$ python timer.py 5
33 bên dưới. Bạn sẽ đề cập đến
$ python timer.py 5
33 trong phần sau. Tuy nhiên, trong phần tiếp theo, bạn sẽ mô phỏng một đường ống với
$ python timer.py 5
65 vì trong hầu hết các trường hợp, việc các quy trình được liên kết trực tiếp với nhau là không quan trọng

Mô phỏng đường ống với $ python timer.py 5 65

Mặc dù bạn không thể thực sự liên kết hai quy trình cùng với một đường ống bằng cách sử dụng hàm

$ python timer.py 5
65, nhưng ít nhất là không ủy thác nó cho trình bao, bạn có thể mô phỏng đường ống bằng cách sử dụng hợp lý thuộc tính
$ python timer.py 5
984

Nếu bạn đang sử dụng hệ thống dựa trên UNIX, trong đó hầu hết tất cả các lệnh trình bao điển hình đều là các tệp thực thi riêng biệt, thì bạn chỉ cần đặt

$ python timer.py 5
835 của quy trình thứ hai thành thuộc tính
$ python timer.py 5
808 của quy trình thứ nhất
$ python timer.py 5
529

>>>

$ python timer.py 5
88

Ở đây, thuộc tính

$ python timer.py 5
808 của đối tượng
$ python timer.py 5
529 của
$ python timer.py 5
3 được đặt thành
$ python timer.py 5
835 của
$ python timer.py 5
804. Điều quan trọng là nó được đặt thành
$ python timer.py 5
835 thay vì
$ python timer.py 5
983. Điều này là do thuộc tính
$ python timer.py 5
808 không phải là một đối tượng giống như tệp. Đó là một đối tượng byte, vì vậy nó không thể được sử dụng làm đối số cho
$ python timer.py 5
983

Thay vào đó, bạn cũng có thể thao tác trực tiếp với các tệp, đặt chúng thành các tham số luồng tiêu chuẩn. Khi sử dụng tệp, bạn đặt đối tượng tệp làm đối số thành

$ python timer.py 5
983, thay vì sử dụng tham số
$ python timer.py 5
835

>>>

$ python timer.py 5
89

Như bạn đã tìm hiểu trong phần trước, đối với Windows PowerShell, làm điều gì đó như thế này hoàn toàn không có ý nghĩa gì vì hầu hết thời gian, các tiện ích này là một phần của chính PowerShell. Bởi vì bạn không xử lý các tệp thực thi riêng biệt, đường ống trở nên ít cần thiết hơn. Tuy nhiên, mô hình cho đường ống vẫn giống nhau nếu cần phải làm điều gì đó như thế này

Với hầu hết các công cụ hiện có, giờ là lúc nghĩ về một số ứng dụng thực tế cho

$ python timer.py 5
0

ý tưởng thiết thực

Khi bạn gặp vấn đề muốn giải quyết bằng Python, đôi khi mô-đun

$ python timer.py 5
0 là cách dễ nhất, mặc dù nó có thể không đúng nhất

Việc sử dụng

$ python timer.py 5
0 thường rất khó để hoạt động trên các nền tảng khác nhau và nó tiềm ẩn những mối nguy hiểm cố hữu. Nhưng mặc dù nó có thể liên quan đến một số Python cẩu thả, nhưng sử dụng
$ python timer.py 5
0 có thể là một cách rất nhanh chóng và hiệu quả để giải quyết vấn đề

Như đã đề cập, đối với hầu hết các nhiệm vụ mà bạn có thể tưởng tượng sẽ thực hiện với

$ python timer.py 5
0, thường có một thư viện dành riêng cho nhiệm vụ cụ thể đó. Thư viện gần như chắc chắn sẽ sử dụng
$ python timer.py 5
0 và các nhà phát triển sẽ làm việc chăm chỉ để làm cho mã đáng tin cậy và giải quyết tất cả các trường hợp góc cạnh có thể gây khó khăn cho việc sử dụng
$ python timer.py 5
0

Vì vậy, mặc dù có các thư viện chuyên dụng, nhưng việc chỉ sử dụng

$ python timer.py 5
0 thường có thể đơn giản hơn, đặc biệt nếu bạn đang ở trong một môi trường mà bạn cần hạn chế các phụ thuộc của mình

Trong các phần sau, bạn sẽ khám phá một vài ý tưởng thiết thực

Tạo một dự án mới. Một ví dụ

Giả sử bạn thường cần tạo các dự án cục bộ mới, mỗi dự án hoàn chỉnh với một môi trường ảo và được khởi tạo dưới dạng kho lưu trữ Git. Bạn có thể truy cập thư viện Cookiecutter dành riêng cho nhiệm vụ đó và đó sẽ là một ý tưởng tồi

Tuy nhiên, sử dụng Cookiecutter có nghĩa là học Cookiecutter. Hãy tưởng tượng bạn không có nhiều thời gian và dù sao thì môi trường của bạn cũng cực kỳ tối giản—tất cả những gì bạn thực sự có thể tin tưởng là Git và Python. Trong những trường hợp này,

$ python timer.py 5
0 có thể nhanh chóng thiết lập dự án cho bạn

$ python timer.py 5
80

Đây là một công cụ dòng lệnh mà bạn có thể gọi để bắt đầu một dự án. Nó sẽ đảm nhiệm việc tạo tệp

$ python timer.py 5
820 và tệp
$ python timer.py 5
821, sau đó nó sẽ chạy một số lệnh để tạo môi trường ảo, khởi tạo kho lưu trữ git và thực hiện cam kết đầu tiên của bạn. Nó thậm chí còn đa nền tảng, chọn sử dụng
$ python timer.py 5
925 để tạo các tệp và thư mục, loại bỏ sự khác biệt của hệ điều hành

Điều này có thể được thực hiện với Cookiecutter? . Nhưng nếu bạn chỉ cần một cái gì đó nhanh và bẩn, sử dụng các lệnh bạn đã biết, thì chỉ cần sử dụng

$ python timer.py 5
0 có thể là một lựa chọn tuyệt vời

Thay đổi thuộc tính mở rộng

Dùng Dropbox có thể bạn chưa biết có cách bỏ qua file khi đồng bộ. Ví dụ: bạn có thể giữ môi trường ảo trong thư mục dự án của mình và sử dụng Dropbox để đồng bộ hóa mã nhưng giữ môi trường ảo cục bộ

Điều đó nói rằng, nó không dễ dàng như việc thêm một tệp

$ python timer.py 5
826. Thay vào đó, nó liên quan đến việc thêm các thuộc tính đặc biệt vào tệp, có thể được thực hiện từ dòng lệnh. Các thuộc tính này khác nhau giữa các hệ thống giống UNIX và Windows

  • các cửa sổ
  • Linux
  • hệ điều hành Mac

$ python timer.py 5
81

$ python timer.py 5
82

$ python timer.py 5
83

Có một số dự án dựa trên UNIX, chẳng hạn như dropboxignore, sử dụng các tập lệnh shell để giúp bỏ qua các tệp và thư mục dễ dàng hơn. Mã tương đối phức tạp và không hoạt động trên Windows

Với mô-đun

$ python timer.py 5
0, bạn có thể bọc các lệnh shell khác nhau khá dễ dàng để tạo ra tiện ích của riêng mình

$ python timer.py 5
84

Đây là đoạn trích đơn giản hóa từ kho lưu trữ dotDropboxIgnore của tác giả. Hàm

$ python timer.py 5
828 phát hiện hệ điều hành bằng mô-đun
$ python timer.py 5
829 và trả về một đối tượng là một phần trừu tượng xung quanh trình bao dành riêng cho hệ thống. Mã này chưa triển khai hành vi trên macOS, vì vậy mã sẽ tăng
$ python timer.py 5
830 nếu phát hiện mã này đang chạy trên macOS

Đối tượng shell cho phép bạn gọi một phương thức

$ python timer.py 5
831 với danh sách các đối tượng
$ python timer.py 5
925
$ python timer.py 5
833 để đặt Dropbox bỏ qua các tệp đó

Trên lớp

$ python timer.py 5
834, hàm tạo kiểm tra xem PowerShell Core có khả dụng hay không và nếu không, sẽ quay trở lại Windows PowerShell cũ hơn, được cài đặt theo mặc định trên Windows 10

Trong phần tiếp theo, bạn sẽ xem xét một số mô-đun khác có thể thú vị cần lưu ý khi quyết định có sử dụng

$ python timer.py 5
0 hay không

Các mô-đun Python được liên kết với $ python timer.py 5 0

Khi quyết định xem một nhiệm vụ nhất định có phù hợp với

$ python timer.py 5
0 hay không, có một số mô-đun liên quan mà bạn có thể muốn biết

Trước khi có

$ python timer.py 5
0, bạn có thể sử dụng
$ python timer.py 5
839 để chạy lệnh. Tuy nhiên, cũng như nhiều thứ mà trước đây
$ python timer.py 5
63 được sử dụng, các mô-đun thư viện tiêu chuẩn đã thay thế
$ python timer.py 5
63, vì vậy nó chủ yếu được sử dụng nội bộ. Hầu như không có bất kỳ trường hợp sử dụng nào để tự mình sử dụng
$ python timer.py 5
63

Có một trang tài liệu chính thức nơi bạn có thể kiểm tra một số cách cũ để hoàn thành nhiệm vụ với

$ python timer.py 5
63 và tìm hiểu cách bạn có thể làm điều tương tự với
$ python timer.py 5
0

Có thể sẽ hấp dẫn khi nghĩ rằng

$ python timer.py 5
0 có thể được sử dụng đồng thời và trong những trường hợp đơn giản, nó có thể được. Nhưng, phù hợp với triết lý cẩu thả của Python, có lẽ sẽ chỉ nhanh chóng hack một cái gì đó cùng nhau. Nếu bạn muốn thứ gì đó mạnh mẽ hơn, thì có lẽ bạn sẽ muốn bắt đầu xem xét mô-đun
$ python timer.py 5
846

Tùy thuộc vào nhiệm vụ mà bạn đang cố gắng thực hiện, bạn có thể hoàn thành nhiệm vụ đó với các mô-đun

$ python timer.py 5
847 hoặc
$ python timer.py 5
848. Nếu mọi thứ được viết bằng Python, thì các mô-đun này có thể là lựa chọn tốt nhất của bạn

Mô-đun

$ python timer.py 5
847 cũng có API cấp cao để tạo và quản lý các quy trình con, vì vậy nếu bạn muốn kiểm soát nhiều hơn đối với các quy trình song song không phải Python, thì đó có thể là một quy trình cần kiểm tra

Bây giờ là lúc đi sâu vào

$ python timer.py 5
0 và khám phá lớp
$ python timer.py 5
67 cơ bản và hàm tạo của nó

Lớp học $ python timer.py 5 67

Như đã đề cập, lớp cơ bản cho toàn bộ mô-đun

$ python timer.py 5
0 là lớp
$ python timer.py 5
67 và hàm tạo
$ python timer.py 5
33. Mỗi chức năng trong
$ python timer.py 5
0 gọi hàm tạo
$ python timer.py 5
33 dưới mui xe. Sử dụng hàm tạo
$ python timer.py 5
33 cho bạn nhiều quyền kiểm soát đối với các quy trình con mới bắt đầu

Tóm lại, về cơ bản,

$ python timer.py 5
65 là hàm tạo của lớp
$ python timer.py 5
33, một số thiết lập và sau đó là lệnh gọi phương thức
$ python timer.py 5
861 trên đối tượng
$ python timer.py 5
67 mới được khởi tạo. Phương thức
$ python timer.py 5
861 là một phương thức chặn trả về dữ liệu
$ python timer.py 5
984 và
$ python timer.py 5
985 sau khi quá trình kết thúc

Tên của

$ python timer.py 5
67 xuất phát từ một lệnh UNIX tương tự viết tắt của pipe open. Lệnh tạo một đường ống và sau đó bắt đầu một quy trình mới gọi trình bao. Tuy nhiên, mô-đun
$ python timer.py 5
0 không tự động gọi trình bao

Hàm

$ python timer.py 5
65 là một hàm chặn, có nghĩa là không thể tương tác động với một quy trình với nó. Tuy nhiên, hàm tạo
$ python timer.py 5
33 bắt đầu một quy trình mới và tiếp tục, khiến quy trình chạy song song

Nhà phát triển trò chơi phản ứng mà bạn đã hack trước đó đã phát hành phiên bản mới của trò chơi của họ, phiên bản mà bạn không thể gian lận bằng cách tải

$ python timer.py 5
983 bằng dòng mới

$ python timer.py 5
85

Lúc này chương trình sẽ hiển thị một ký tự ngẫu nhiên, bạn cần bấm chính xác ký tự đó để trò chơi ghi lại thời gian phản ứng của bạn

Phải làm gì?

Sử dụng $ python timer.py 5 33

Việc sử dụng hàm tạo

$ python timer.py 5
33 rất giống với việc sử dụng
$ python timer.py 5
65. Nếu có một đối số mà bạn có thể chuyển đến
$ python timer.py 5
65, thì thông thường bạn sẽ có thể chuyển nó đến
$ python timer.py 5
33. Sự khác biệt cơ bản là nó không phải là một cuộc gọi chặn—thay vì đợi cho đến khi quá trình kết thúc, nó sẽ chạy quá trình song song. Vì vậy, bạn cần tính đến bản chất không chặn này nếu bạn muốn đọc đầu ra của quy trình mới

$ python timer.py 5
86

Chương trình này gọi quy trình hẹn giờ trong trình quản lý bối cảnh và gán

$ python timer.py 5
984 cho một đường ống. Sau đó, nó chạy phương thức
$ python timer.py 5
878 trên đối tượng
$ python timer.py 5
67 và đọc
$ python timer.py 5
984 của nó

Phương pháp

$ python timer.py 5
878 là một phương pháp cơ bản để kiểm tra xem một tiến trình có còn đang chạy hay không. Nếu đúng như vậy, thì
$ python timer.py 5
878 trả về
$ python timer.py 5
883. Nếu không, nó sẽ trả về mã thoát của quy trình

Sau đó, chương trình sử dụng

$ python timer.py 5
884 để thử và đọc bao nhiêu byte có sẵn tại
$ python timer.py 5
808

Ghi chú. Nếu bạn đặt đối tượng

$ python timer.py 5
67 ở chế độ văn bản và sau đó gọi
$ python timer.py 5
887 trên
$ python timer.py 5
808, lệnh gọi tới
$ python timer.py 5
887 sẽ bị chặn cho đến khi nó xuống một dòng mới. Trong trường hợp này, một dòng mới sẽ trùng với thời điểm kết thúc chương trình hẹn giờ. Hành vi này không được mong muốn trong tình huống này

Để đọc bao nhiêu byte có sẵn tại thời điểm đó, bỏ qua các dòng mới, bạn cần đọc với

$ python timer.py 5
884. Điều quan trọng cần lưu ý là
$ python timer.py 5
884 chỉ khả dụng trên các luồng byte, vì vậy bạn cần đảm bảo xử lý mã hóa theo cách thủ công và không sử dụng chế độ văn bản

Đầu ra của chương trình này in đầu tiên

$ python timer.py 5
883 vì quá trình này chưa kết thúc. Chương trình sau đó in những gì có sẵn trong
$ python timer.py 5
984 cho đến nay, đó là thông báo bắt đầu và ký tự đầu tiên của hoạt ảnh

Sau ba giây, bộ đếm thời gian vẫn chưa kết thúc, vì vậy bạn lại nhận được

$ python timer.py 5
883, cùng với hai nhân vật hoạt hình khác. Sau ba giây nữa, quá trình kết thúc, vì vậy,
$ python timer.py 5
878 tạo ra
$ python timer.py 5
881 và bạn nhận được các ký tự cuối cùng của hoạt ảnh và
$ python timer.py 5
897

$ python timer.py 5
87

Trong ví dụ này, bạn đã thấy hàm tạo của

$ python timer.py 5
33 hoạt động rất khác so với hàm tạo của
$ python timer.py 5
65. Trong hầu hết các trường hợp, bạn không cần loại kiểm soát chi tiết này. Điều đó có nghĩa là, trong các phần tiếp theo, bạn sẽ thấy cách bạn có thể ghép nối quy trình này với quy trình khác và cách bạn có thể hack trò chơi phản ứng mới

Kết nối hai quy trình với nhau bằng đường ống

Như đã đề cập trong phần trước, nếu bạn cần kết nối các quy trình với nhau bằng đường ống, bạn cần sử dụng hàm tạo

$ python timer.py 5
33. Điều này chủ yếu là do
$ python timer.py 5
65 là lệnh gọi chặn, do đó, khi quá trình tiếp theo bắt đầu, quá trình đầu tiên đã kết thúc, nghĩa là bạn không thể liên kết trực tiếp với
$ python timer.py 5
984 của nó

Quy trình này sẽ chỉ được trình bày cho các hệ thống UNIX, vì đường ống trong Windows ít phổ biến hơn nhiều, như đã đề cập trong phần mô phỏng đường ống

$ python timer.py 5
88

Trong ví dụ này, hai quá trình được bắt đầu song song. Chúng được nối với nhau bằng một đường ống chung và vòng lặp

$ python timer.py 5
03 đảm nhận việc đọc đường ống tại
$ python timer.py 5
984 để xuất các dòng

Một điểm quan trọng cần lưu ý là trái ngược với

$ python timer.py 5
65, trả về một đối tượng
$ python timer.py 5
529, hàm tạo
$ python timer.py 5
33 trả về một đối tượng
$ python timer.py 5
67. Các thuộc tính luồng tiêu chuẩn của một
$ python timer.py 5
529 trỏ tới các đối tượng hoặc chuỗi byte, nhưng các thuộc tính tương tự của một đối tượng
$ python timer.py 5
67 trỏ tới các luồng thực tế. Điều này cho phép bạn giao tiếp với các quy trình khi chúng đang chạy

Tuy nhiên, việc bạn có thực sự cần nối các quy trình với nhau hay không lại là một vấn đề khác. Hãy tự hỏi bản thân xem có mất nhiều thứ không bằng cách dàn xếp quy trình với Python và chỉ sử dụng

$ python timer.py 5
65. Tuy nhiên, có một số tình huống mà bạn thực sự cần đến
$ python timer.py 5
67, chẳng hạn như hack phiên bản mới của trò chơi thời gian phản ứng

Tương tác động với một quy trình

Giờ bạn đã biết mình có thể sử dụng

$ python timer.py 5
33 để tương tác linh hoạt với một quy trình khi nó chạy, đã đến lúc chuyển kiến ​​thức đó sang khai thác lại trò chơi thời gian phản ứng

$ python timer.py 5
89

Với tập lệnh này, bạn đang kiểm soát hoàn toàn việc lưu vào bộ đệm của một quy trình, đó là lý do tại sao bạn chuyển các đối số như

$ python timer.py 5
14 cho quy trình Python và
$ python timer.py 5
15 thành
$ python timer.py 5
16. Các đối số này là để đảm bảo rằng không có quá trình đệm bổ sung nào đang diễn ra

Tập lệnh hoạt động bằng cách sử dụng một hàm sẽ tìm kiếm một trong danh sách các chuỗi bằng cách lấy từng ký tự một từ

$ python timer.py 5
984 của quy trình. Khi mỗi ký tự đi qua, tập lệnh sẽ tìm kiếm chuỗi

Ghi chú. Để làm cho điều này hoạt động trên cả hệ thống dựa trên Windows và UNIX, hai chuỗi được tìm kiếm. hoặc là

$ python timer.py 5
18 hoặc là
$ python timer.py 5
19. Dấu xuống dòng kiểu Windows cùng với dòng mới điển hình là bắt buộc trên các hệ thống Windows

Sau khi tập lệnh đã tìm thấy một trong các chuỗi mục tiêu, trong trường hợp này là chuỗi ký tự trước ký tự mục tiêu, sau đó, tập lệnh sẽ lấy ký tự tiếp theo và viết ký tự đó vào _____2983 của quy trình, sau đó là một dòng mới

Với tốc độ một phần nghìn giây, nó không hoàn toàn tốt như bản hack gốc, nhưng nó vẫn rất siêu phàm. Tốt lắm

Bỏ tất cả niềm vui này sang một bên, việc tương tác với các quy trình bằng cách sử dụng

$ python timer.py 5
67 có thể rất phức tạp và dễ xảy ra lỗi. Trước tiên, hãy xem liệu bạn có thể sử dụng riêng
$ python timer.py 5
65 hay không trước khi sử dụng hàm tạo
$ python timer.py 5
33

Nếu bạn thực sự cần tương tác với các quy trình ở cấp độ này, mô-đun

$ python timer.py 5
847 có API cấp cao để tạo và quản lý các quy trình con

Chức năng quy trình con của

$ python timer.py 5
847 dành cho việc sử dụng phức tạp hơn của
$ python timer.py 5
0, nơi bạn có thể cần sắp xếp các quy trình khác nhau. Đây có thể là trường hợp nếu bạn đang thực hiện xử lý phức tạp nhiều tệp hình ảnh, video hoặc âm thanh chẳng hạn. Nếu bạn đang sử dụng
$ python timer.py 5
0 ở cấp độ này, thì có lẽ bạn đang xây dựng một thư viện

Phần kết luận

Bạn đã hoàn thành hành trình của mình với mô-đun Python

$ python timer.py 5
0. Bây giờ bạn có thể quyết định xem
$ python timer.py 5
0 có phù hợp với vấn đề của bạn hay không. Bạn cũng có thể quyết định xem bạn có cần gọi trình bao hay không. Ngoài ra, bạn sẽ có thể chạy các quy trình con và tương tác với đầu vào và đầu ra của chúng

Bạn cũng có thể bắt đầu khám phá các khả năng thao tác quy trình với hàm tạo

$ python timer.py 5
33

Trên đường đi, bạn đã

  • Tìm hiểu về các quy trình nói chung
  • Đi từ cách sử dụng cơ bản đến nâng cao của
    $ python timer.py 5
    
    0
  • Hiểu cách phát sinh và xử lý lỗi khi sử dụng
    $ python timer.py 5
    
    65
  • Làm quen với shell và sự phức tạp của chúng trên cả hệ thống giống Windows và UNIX
  • Khám phá các trường hợp sử dụng cho
    $ python timer.py 5
    
    0 thông qua các ví dụ thực tế
  • Hiểu các luồng I/O tiêu chuẩn và cách tương tác với chúng
  • Làm quen với các đường ống, cả trong vỏ và với
    $ python timer.py 5
    
    0
  • Nhìn vào hàm tạo
    $ python timer.py 5
    
    33 và sử dụng nó cho một số giao tiếp quy trình nâng cao

Bây giờ bạn đã sẵn sàng đưa nhiều tệp thực thi vào phạm vi ảnh hưởng Pythonic của mình

Mã nguồn. Nhấp vào đây để tải xuống mã nguồn miễn phí mà bạn sẽ sử dụng để làm quen với mô-đun Python

$ python timer.py 5
0

Đánh dấu là đã hoàn thành

🐍 Thủ thuật Python 💌

Nhận một Thủ thuật Python ngắn và hấp dẫn được gửi đến hộp thư đến của bạn vài ngày một lần. Không có thư rác bao giờ. Hủy đăng ký bất cứ lúc nào. Được quản lý bởi nhóm Real Python

Xả quy trình con Python

Gửi cho tôi thủ thuật Python »

Giới thiệu về Ian Currie

Xả quy trình con Python
Xả quy trình con Python

Ian là một mọt sách Python, người sử dụng nó cho mọi thứ, từ mày mò đến giúp mọi người và công ty quản lý công việc hàng ngày cũng như phát triển doanh nghiệp của họ

» Thông tin thêm về Ian


Mỗi hướng dẫn tại Real Python được tạo bởi một nhóm các nhà phát triển để nó đáp ứng các tiêu chuẩn chất lượng cao của chúng tôi. Các thành viên trong nhóm đã làm việc trong hướng dẫn này là

Xả quy trình con Python

Aldren

Xả quy trình con Python

Bartosz

Xả quy trình con Python

Geir Arne

Xả quy trình con Python

Jim

Xả quy trình con Python

kate

Bậc thầy Kỹ năng Python trong thế giới thực Với quyền truy cập không giới hạn vào Python thực

Xả quy trình con Python

Tham gia với chúng tôi và có quyền truy cập vào hàng nghìn hướng dẫn, khóa học video thực hành và cộng đồng các Pythonistas chuyên gia

Nâng cao kỹ năng Python của bạn »

Bậc thầy Kỹ năng Python trong thế giới thực
Với quyền truy cập không giới hạn vào Python thực

Tham gia với chúng tôi và có quyền truy cập vào hàng ngàn hướng dẫn, khóa học video thực hành và cộng đồng Pythonistas chuyên gia

Nâng cao kỹ năng Python của bạn »

Bạn nghĩ sao?

Đánh giá bài viết này

Tweet Chia sẻ Chia sẻ Email

Bài học số 1 hoặc điều yêu thích mà bạn đã học được là gì?

Mẹo bình luận. Những nhận xét hữu ích nhất là những nhận xét được viết với mục đích học hỏi hoặc giúp đỡ các sinh viên khác. Nhận các mẹo để đặt câu hỏi hay và nhận câu trả lời cho các câu hỏi phổ biến trong cổng thông tin hỗ trợ của chúng tôi

Cuộc gọi quy trình con có tăng ngoại lệ không?

Hàm call() của quy trình con Python trả về mã đã thực thi của chương trình. Nếu không có đầu ra chương trình, hàm sẽ trả về đoạn mã mà nó đã thực hiện thành công. Nó cũng có thể gây ra ngoại lệ CalledProcessError .

Quy trình con Check_call trả về cái gì?

quy trình con. check_call() nhận giá trị trả về cuối cùng từ tập lệnh và 0 thường có nghĩa là "tập lệnh đã hoàn thành thành công".