Tập lệnh python của tôi chặn tín hiệu SIGINT bằng tín hiệu
quy trình
mô-đun để ngăn chặn thoát sớm, nhưng tín hiệu này được chuyển đến một tiến trình con mà tôi mở bằng Popen. là có một số cách để ngăn chặn đi qua tín hiệu này để các subprocess để nó cũng không phải là exited sớm khi người dùng nhấn ctrl-c?Làm thế nào để dừng SIGINT được chuyển đến subprocess trong python?
Trả lời
Bạn có thể gán lại vai trò của ctrl-c bằng cách sử dụng mô-đun tty
, cho phép bạn thao tác chuyển nhượng tín hiệu. Tuy nhiên, hãy cảnh báo rằng trừ khi bạn đặt chúng trở lại cách chúng trước khi bạn sửa đổi chúng, chúng sẽ tiếp tục tồn tại trong toàn bộ phiên của trình bao, ngay cả sau khi chương trình thoát. Dưới đây là một đoạn mã đơn giản để giúp bạn bắt đầu lưu trữ các cài đặt tty cũ của bạn, gán lại ctrl-c thành ctrl-x và sau đó khôi phục các cài đặt tty trước đó của bạn khi thoát.
import sys
import tty
# Back up previous tty settings
stdin_fileno = sys.stdin.fileno()
old_ttyattr = tty.tcgetattr(stdin_fileno)
try:
print 'Reassigning ctrl-c to ctrl-x'
# Enter raw mode on local tty
tty.setraw(stdin_fileno)
raw_ta = tty.tcgetattr(stdin_fileno)
raw_ta[tty.LFLAG] |= tty.ISIG
raw_ta[tty.OFLAG] |= tty.OPOST | tty.ONLCR
# ^X is the new ^C, set this to 0 to disable it entirely
raw_ta[tty.CC][tty.VINTR] = '\x18'
# Set raw tty as active tty
tty.tcsetattr(stdin_fileno, tty.TCSANOW, raw_ta)
# Dummy program loop
import time
for _ in range(5):
print 'doing stuff'
time.sleep(1)
finally:
print 'Resetting ctrl-c'
# Restore previous tty no matter what
tty.tcsetattr(stdin_fileno, tty.TCSANOW, old_ttyattr)
xử lý tín hiệu được thừa kế khi bạn bắt đầu một tiến trình con, vì vậy nếu bạn sử dụng các module tín hiệu bỏ qua SIGINT (signal.signal(signal.SIGINT, signal.SIG_IGN)
), sau đó tiến trình con của bạn tự động sẽ còn.
Có hai cảnh báo quan trọng, mặc dù:
- Bạn phải thiết lập lờ handler trước bạn đẻ trứng quá trình con
- Tuỳ chỉnh xử lý tín hiệu được đặt lại vào xử lý mặc định, kể từ khi quá trình con sẽ không có quyền truy cập vào mã trình xử lý để chạy nó.
Vì vậy, nếu bạn cần tùy chỉnh việc xử lý SIGINT thay vì bỏ qua, bạn có thể tạm thời bỏ qua SIGINT trong khi bạn sinh ra quá trình con, sau đó đặt lại trình xử lý tín hiệu tùy chỉnh của bạn.
Nếu bạn đang cố gắng nắm bắt SIGINT và đặt cờ để bạn có thể thoát ra tại điểm an toàn thay vì ngay lập tức, hãy nhớ rằng khi bạn đến điểm an toàn đó, mã của bạn sẽ phải dọn sạch con cháu của nó theo cách thủ công. quá trình con và bất kỳ quá trình nào nó bắt đầu sẽ bỏ qua SIGINT.
Nếu điều này hoạt động (mà nó sẽ không luôn luôn), nó là một lựa chọn tốt hơn so với mucking với thiết bị đầu cuối. – zwol
Nếu sử dụng fork()/exec() thay vì popen(), bạn có thể thực hiện SIG_IGN sau fork() trước exec(). Điều đó tránh tạm thời vô hiệu hóa trình xử lý trong phụ huynh. Có vẻ như sẽ có điều kiện chạy đua bất kể bạn làm gì, nhưng cách ngã ba()/exec() có vẻ an toàn hơn một chút. Tất nhiên, OP đã hỏi về Popen của python, nhưng câu hỏi này thực sự có vẻ là về Posix; đó là lý do tôi đến đây. – thejoshwolfe
@thejoshwolfe: Để tránh điều kiện chạy đua, bạn sử dụng sigprocmask() để trì hoãn tín hiệu, đặt bộ điều khiển, ngã ba, đặt bộ điều khiển trở lại và sau đó sử dụng lại sigprocmask để bật lại tín hiệu. (Và nếu có bất kỳ tín hiệu nào đến giữa các lệnh gọi tới sigprocmask, chúng sẽ được phân phối tại thời điểm này.) –
- 1. Python Subprocess - Chuyển hướng stdout/err đến hai địa điểm
- 2. Chương trình SDL/C++ OpenGL, làm thế nào để tôi ngừng SDL bắt được SIGINT
- 3. Làm thế nào để gửi SIGINT đến một quá trình từ xa qua SSH?
- 4. Làm thế nào để ngăn chặn python từ truyền tín hiệu đến các quy trình con?
- 5. Python subprocess: làm thế nào để sử dụng ống ba lần?
- 6. Làm thế nào để dừng UIPanGestureRecognizer khi đối tượng di chuyển đến khung nhất định
- 7. Python Subprocess Grep
- 8. Làm thế nào để dừng một lệnh python socket.accept()?
- 9. Python subprocess Trợ giúp
- 10. Python subprocess để Bash: dấu ngoặc nhọn
- 11. Làm thế nào để tạm dừng một NSThread cho đến khi được thông báo?
- 12. Làm thế nào để dừng một cuộc gọi được gửi đến ExecutorService?
- 13. Làm cách nào để gửi tín hiệu SIGINT từ tập lệnh đến tập lệnh? BASH
- 14. Làm cách nào để in tất cả các đối số được chuyển đến tập lệnh python?
- 15. python subprocess ẩn stdout và chờ nó để hoàn thành
- 16. Python: subprocess với thư mục làm việc khác nhau
- 17. Làm thế nào để chuyển tệp giữa hai máy tính được kết nối trong python?
- 18. Làm thế nào để chuyển một toán tử đến một hàm python?
- 19. Làm thế nào để dừng Swing EDT
- 20. Làm thế nào để dừng dịch vụ?
- 21. Làm thế nào để gọi ssh bằng mô-đun subprocess để nó sử dụng biến SSH_ASKPASS
- 22. Đàn áp đầu ra trong python subprocess gọi
- 23. Làm thế nào để dừng Handler Runnable?
- 24. Dừng một Runnable được gửi đến ExecutorService
- 25. Android: Làm thế nào để dừng Runnable?
- 26. đường ống trong vỏ thông qua mô-đun Python subprocess
- 27. Làm thế nào để tạm dừng và chờ nhập lệnh trong một tập lệnh python
- 28. Các chuỗi Python trong Python được nhúng: Làm thế nào?
- 29. Python subprocess Popen.communicate() tương đương với Popen.stdout.read()?
- 30. Python - Subprocess - Cách gọi lệnh Piped trong Windows?
Bạn đang sử dụng nền tảng nào? – ChristopheD
Tôi đang sử dụng Ubuntu linux. – shino