Điều gì xảy ra với đầu ra của một quá trình đã bị từ chối và mất thiết bị đầu cuối của nó?


26

Nếu tôi đóng thiết bị đầu cuối ảo, nơi một quá trình đã được bắt đầu, thì đầu ra chỉ đi thẳng vào /dev/null, hoặc nó có thể gây ô nhiễm bộ nhớ bằng cách nào đó? Dù sao tôi có thể lấy đầu ra để tiếp tục đọc nó tại bất kỳ thời điểm nào sau đó không?

[EDIT]: Vì vậy, thời điểm từ chối một quá trình có hiệu quả là sự chấm dứt quyền lực của tôi để kiểm soát đầu ra của nó?

Tôi cũng nhận thấy rằng nếu tôi từ chối một quá trình dừng lại, ban đầu mọi thứ dường như bình thường: nó không bị chấm dứt cũng không được hiển thị trong các công việc. Nhưng nếu tôi đăng xuất (và tôi không có nghĩa là đóng thiết bị đầu cuối, suchẳng hạn như thoát khỏi ), quá trình này sẽ chấm dứt. Tất cả đều giống nhau, một quá trình từ chối chạy nền có thể tiếp tục chạy.


2
Đối với những người khác, dù sao tôi cũng có thể lấy đầu ra, không phải không có những mánh khóe bẩn thỉu. Nhưng hãy xem Làm thế nào tôi có thể từ chối nó một quy trình đang chạy và liên kết nó với một vỏ màn hình mới? và các câu hỏi được trích dẫn khác cho các thủ thuật bẩn (tất cả dựa trên việc đính kèm trình gỡ lỗi vào chương trình và bằng cách nào đó làm cho nó mở một tệp đầu ra khác).
Gilles 'SO- ngừng trở nên xấu xa'

Cảm ơn các liên kết đến câu hỏi đó. Nó đã cho tôi câu trả lời tốt nhất cho đến nay! Đặc biệt là rettychương trình thông minh .
rozcietrzewiacz

1
Xem thêm câu trả lời này trên một câu hỏi liên quan.
Stéphane Gimenez

Câu trả lời:


11

Việc một quá trình bị "từ chối" chỉ có ý nghĩa đối với lớp vỏ tương tác đã tạo ra quá trình này. Điều đó có nghĩa là shell không bao gồm (nữa) quy trình trong bảng công việc của nó và SIGHUP sẽ không được gửi đến quy trình này khi shell thoát ra. Nó không thực sự liên quan đến câu hỏi của bạn.

Về những gì xảy ra với các đầu ra được gửi đến một thiết bị đầu cuối ảo đã bị xóa: Tôi đã tự mình thực hiện một số thử nghiệm và tôi nhận thấy rằng /dev/pts/xcác thiết bị không thể truy cập được và sẽ không được phân bổ lại cho đến khi tất cả các bộ lọc chỉ ra chúng đã bị đóng. Vì vậy, tôi không thể thấy lý do tại sao ghi vào thiết bị đầu cuối bị xóa sẽ được lưu trữ. Tôi đoán điều này thậm chí không được xác định bởi POSIX.

Về việc lấy đầu ra của một số quá trình ghi vào một thiết bị đầu cuối, tôi không nghĩ rằng nó có thể, ngay cả khi thiết bị đầu cuối vẫn còn sống. Tất cả những gì bạn có thể làm là lấy đầu vào trực tiếp vào thiết bị đầu cuối (tức là tổ hợp phím hoặc tổ hợp phím mô phỏng bằng phần chính của một pty). Nếu các tiến trình sẽ đọc trên stdin những gì được ghi vào thiết bị đầu cuối của chúng, điều đó sẽ dẫn đến một vòng lặp tự io cho hầu hết quá trình.

Về nhận xét cuối cùng về việc chấm dứt quá trình, tôi thực sự không biết điều gì đang xảy ra, nhưng tôi sẽ nghi ngờ những hành vi khá kỳ lạ với các tín hiệu (SIGTTOU, SIGTTIN, SIGHUP hoặc những người khác) liên quan đến trạng thái nền trước / nền của các nhóm quy trình, khi phiên nhà lãnh đạo thoát (ví dụ su, trong trường hợp bạn đã đề cập).

Trả lời Chỉnh sửa: Không, liên quan đến đầu ra, không có gì thay đổi khi một quy trình bị từ chối: nó vẫn được gắn vào thiết bị đầu cuối kiểm soát của nó (trừ khi nó tự tách ra như daemon). Bạn có thể thấy rằng sử dụng ps. Tuy nhiên, bạn sẽ không thể sử dụng fg/ bg/ jobscác lệnh được cung cấp bởi shell nữa cho quy trình này. Điều đó có nghĩa là có thể khó để cung cấp nó với đầu vào từ thiết bị đầu cuối (yêu cầu phải nằm trong nhóm quy trình nền trước).

-
1. trừ khi quá trình sẵn sàng hoặc bị tấn công bằng một số công cụ sửa lỗi (xem các bình luận ở trên).


1
Cảm ơn đã làm rõ điều này một chút. Trên thực tế, thực tế từ chối một quy trình vẫn liên quan đến câu hỏi của tôi: Sau khi từ chối một quy trình, tôi dường như mất khả năng kiểm soát đầu ra của nó, phải không? (Ngay cả khi thiết bị đầu cuối đã đóng nit.) Tôi sẽ chỉnh sửa câu hỏi để bao gồm trường hợp đó.
rozcietrzewiacz

4

Chỉ để giải quyết câu hỏi cụ thể này:

Nếu tôi đóng thiết bị đầu cuối ảo, nơi một quá trình đã được bắt đầu, thì đầu ra chỉ đi thẳng đến / dev / null, hay nó có thể gây ô nhiễm bộ nhớ bằng cách nào đó?

Thiết bị đầu cuối và (các) chương trình được kết nối với nó giao tiếp qua một thiết bị tty bằng cách đọc và viết nó như một tập tin. Cụ thể, một thiết bị đầu cuối ảo tạo ra một "pseudo-tty" (gọi tắt là "pty") và sau đó sinh ra một quá trình shell (hoặc khác) và kết nối stdin / out / err của quá trình đó với pty. (Các chi tiết khác nhau tùy theo hệ điều hành.)

Khi bạn đóng thiết bị đầu cuối ảo, thiết bị đầu cuối ảo sẽ đóng phần cuối của kết nối (pty "master"). Sau đó, nếu chương trình ở đầu kia của kết nối ghi vào tty, một lỗi sẽ được trả về và dữ liệu không đi đến đâu cả. Tương tự, nếu nó đọc từ tty, nó sẽ lấy lại chỉ báo EOF (cuối tệp).


Cảm ơn - giải thích tốt đẹp và rõ ràng từ quan điểm lập trình nhiều hơn một chút.
rozcietrzewiacz

3

Để trả lời phần thú vị nhất trong câu hỏi của bạn: để thay đổi đầu ra của chương trình đang chạy, bạn phải chỉnh sửa mô tả tệp của nó. Điều đó khá dễ thực hiện với gdb. Đó là một hack, nhưng hoạt động.

Xem:

https: // stack

Một tập lệnh trợ giúp có sẵn tại http://users.linpro.no/ingvar/fdswap.sh.txt .


0

Nhờ bình luận của Gilles, chỉ cho tôi câu hỏi này , tôi đã biết về một chương trình gọi là retty .

Nó dường như sử dụng một số hack bẩn để gắn lại vào một (giả giả) một cách hiệu quả cho phép tiếp tục đọc đầu ra của một quá trình - bất kể nó có bị từ chối hay không. Vì vậy, điều này dường như trả lời hầu hết các phần đầu tiên của câu hỏi của tôi. Thứ hai đã được trả lời bởi Stéphane .

Khi sử dụng trang web của chúng tôi, bạn xác nhận rằng bạn đã đọc và hiểu Chính sách cookieChính sách bảo mật của chúng tôi.
Licensed under cc by-sa 3.0 with attribution required.