Tiếp tục lệnh chạy trong phiên SSH bị rớt


32

Đọc câu hỏi này khiến tôi băn khoăn. Giả sử screenkhông được sử dụng. Vì một phiên SSH trên mục tiêu Linux bị hủy, vì bất kỳ lý do gì và bạn kết nối lại trước khi máy chủ giết phiên vì hết thời gian, có thể lấy lại quyền kiểm soát lệnh đang chạy để nó không bị hủy vì phiên bị hỏng ?


Lệnh gì vậy? Tôi đoán nói chung câu trả lời là không.
davr

Không có lệnh cụ thể, tôi chỉ hỏi như một khái niệm chung.
John Gardeniers

1
Một người có hiểu biết toàn diện về cách các phiên tty được khởi tạo có thể cho chúng tôi biết làm thế nào. Có vẻ như nếu bạn có thể tạo lại một phiên mới trên cùng một tty và gán rõ ràng PPID trước đó thì có thể. Tôi chỉ chờ đợi một số bậc thầy râu quai nón đi cùng và thổi bay tâm trí của chúng tôi. Dù sao đó cũng là giấc mơ.
CarpeNoctem

Điều gì xảy ra nếu bạn thử nghiệm với máy tính xách tay có dây buộc và rút dây ethernet?
Paul

@ ~ drpaulbrewer - Chính xác giống như khi bạn làm điều đó với máy tính để bàn - kết nối bị ngắt. Làm thế nào kết nối bị mất là không liên quan đến câu hỏi.
John Gardeniers

Câu trả lời:


13

Cố gắng kết nối các bộ mô tả tệp STD * hiện tại của một thiết bị đầu cuối mới với một quy trình đang chạy cũ chỉ là vấn đề. Ngay cả khi bạn quản lý để làm điều đó, kiểm soát công việc của thiết bị đầu cuối sẽ không hoạt động như mong đợi. Bạn sẽ có một mớ hỗn độn bị bỏ lại nếu cuối cùng bạn thoát khỏi chương trình tiếp quản, và điều gì xảy ra với trình bao đã hy sinh các mô tả tệp của nó để được chuyển đến quy trình mới được tạo nền. Ssh sẽ mở khi vỏ đó biến mất? Chắc là không. Vì vậy, bạn sẽ cần phải chuyển hướng nó ở một nơi khác trước.

Có thể hay không, tôi cá rằng sẽ tốt hơn nếu cứ để quá trình bị bỏ rơi bị giết một cách "tự nhiên". Nếu bạn đang làm bất cứ điều gì đủ quan trọng để biện minh cho việc cố gắng thực hiện tất cả các tin tặc cần thiết để tiếp tục kiểm soát bạn đang ở trong một liên kết không ổn định, có lẽ bạn nên biết trước và chỉ cần sử dụng màn hình (hoặc vnc hoặc bất cứ điều gì nổi lên - thuyền điều khiển). :)


Tôi cảm thấy khó khăn khi chọn một câu trả lời để chấp nhận, vì vậy tôi chấp nhận câu trả lời này bởi vì tại thời điểm này, đây là câu hỏi duy nhất có upvote.
John Gardeniers

5

Tôi biết đây là một câu hỏi cũ, nhưng tôi cảm thấy cần phải bổ sung những phát hiện của mình trong trường hợp người khác gặp phải điều này giống như tôi đã làm.

Tôi chưa thấy bất kỳ hậu quả bất thường nào khi làm điều này đúng, nhưng đây là những gì tôi đã sử dụng và nó hoạt động rất tuyệt vời. Đôi khi khi chúng tôi chạy các tiến trình dài trên máy chủ của mình, đôi khi nó sẽ ngắt kết nối phiên ssh. Quá trình cùng với phiên tty dường như vẫn chạy nhưng chúng ta không thể kết nối lại với nó. Tôi tìm thấy chương trình dưới đây để kéo quá trình đến phiên mới được kết nối.

https://github.com/nelhage/reptyr

Đây là thông tin thêm

https://blog.nelhage.com/2011/02/changing-ctty/


5
Chào mừng bạn đến với Lỗi Máy chủ! Trong khi về mặt lý thuyết có thể trả lời câu hỏi, tốt hơn là nên bao gồm các phần thiết yếu của câu trả lời ở đây và cung cấp liên kết để tham khảo.
EEAA

cảm ơn bạn, @ user215086! Đáng ngạc nhiên, điều này đã làm việc! Tôi đã chỉnh sửa một tệp cấu hình dài trong một lúc, thêm một loạt các cài đặt tùy chỉnh và nhận xét được viết cẩn thận và gần như đã hoàn tất khi kết nối bị ngắt! "Noooooo !! ..." Sau khi tôi hoàn thành việc hét lên thô tục trên trần nhà, tôi đã cài đặt reptyr, et voila! Tôi đã phục hồi phiên ssh ngay tại nơi tôi để nó vẫn còn trong trình chỉnh sửa, hoàn thành một vài thứ, lưu lại, xong !! WooHoo! reptyr là tuyệt vời.
ColdCold

4

Nói chung, cách đúng đắn để xử lý việc này là chuẩn bị cho nó trước thời hạn, sử dụng GNU screenhoặc bash's nohuphoặc disowncơ chế. Nếu bạn đang sử dụng tcsh, trình bao sẽ từ chối các công việc nền khi nó thoát ra bất thường.

Nếu bạn không sử dụng screennhưng đã quản lý để giữ cho quy trình của bạn chạy thông qua một trong các phương thức bị từ chối , bạn có thể giả mạo kết nối lại với quy trình với gdb( nguồn ):

[...] Với một số hack bẩn, không thể mở lại quy trình 'stdout / stderr / stdin. [...]

Và sau đó sử dụng gdb để đính kèm vào quy trình, thực hiện một số cuộc gọi đóng (0)
gọi đóng (1)
gọi đóng (2)
gọi mở ("/ dev / pts / xx", ...)
gọi dup (0)
gọi dup (0)
tách ra

Bây giờ, bạn phải điều chỉnh quá trình này cho tình huống của bạn. Tôi nghi ngờ nó sẽ giúp ích nếu bạn không quản lý để từ chối quá trình. Nếu bạn đang sử dụng bash, hãy xem bài đăng này về việc làm bash tự động từ chối các quá trình nền khi thoát (về cơ bản, hãy tắt huponexit với shopt ). Với một quá trình tiền cảnh, bạn cần phải sử dụng nohup .


1

Chắc là không. Tôi không thể đảm bảo rằng điều đó là không thể nhưng tôi thực sự nghi ngờ điều đó.

Một điều là việc thiếu shell và các lệnh có thể chạy do hậu quả của việc chấm dứt kết nối ssh. Điều này không quá khó, bạn sẽ có thể sử dụng nohup và các cơ chế tương tự như được đề cập trong câu hỏi khác.

Nhưng sau đó, giả sử rằng bạn đã bắt đầu ssh somehost nuhup vim /some/filevà kết nối chết. Bạn chạy ssh somehostđể đăng nhập lại và có thể thấy rằng quá trình vim của bạn vẫn đang chạy. Nhưng vì vậy, làm thế nào để bạn kết nối với quá trình đó một lần nữa? Quá trình forground tương tác có một kiểm soát tty và một quy trình được mở cho quy trình vim của bạn khi nó bắt đầu sau đó đã bị đóng. Tôi không chắc chắn liệu có cách nào để "mở lại" nó một lần nữa trong shell mới của bạn không (giống như khi bạn có một số công việc nền chạy trong một shell, bạn không thể bỏ qua bất kỳ công việc nào trong shell khác).

Screenrõ ràng đã được viết để có chức năng này. Khi khởi động, nó tạo ra hai quy trình, một quy trình quản lý thiết bị đầu cuối và quy trình khách hàng. Tương tác là ứng dụng khách <-> trình quản lý đầu cuối <-> và khi bạn tách hoặc mất kết nối, tiến trình máy khách sẽ chết trong khi trình quản lý đầu cuối tiếp tục tồn tại. Màn hình có một số hỗ trợ cụ thể để gắn vào quy trình quản lý thiết bị đầu cuối sau này và tôi không nghĩ rằng điều này là có thể trong trường hợp chung.


Cảm ơn. Đó là khá nhiều những gì tôi mong đợi. Hãy xem ai đó có thể chứng minh chúng tôi sai. ;)
John Gardeniers

Tôi đã học được từ khi viết câu trả lời này rằng có một chương trình reptyr cho các quá trình "tái phân loại". Vì vậy, trong lý thuyết có thể làm được, nhưng tôi vẫn nghĩ rằng câu trả lời chung có lẽ là không.
hlovdal


1

Nếu phiên bị hủy, điều đó có nghĩa là TTL đã hết hạn, do đó bạn không còn phải lo lắng nữa (theo tôi hiểu). Nhưng, nếu kết nối mạng của bạn bị gián đoạn, phiên SSH của bạn có thể không cần phải ngừng hoạt động và bạn sẽ có thể tiếp tục kết nối của mình và tiếp tục. Có phải đó là những gì bạn đang hỏi về?


Tôi đã hỏi nói chung nhưng tôi quan tâm nhất khi sự cố mạng khiến kết nối bị giảm. Nhìn chung, tôi muốn nói rằng nó không quá tốt. Tuy nhiên, điều này chỉ được yêu cầu vì tò mò, hơn là cần thiết. Thật tuyệt khi biết câu trả lời trước khi bạn cần. ;)
John Gardeniers

một kết nối bị mất không phải là một khái niệm đơn giản, như nó có vẻ. Bạn có thể trải nghiệm một số giai đoạn khác nhau của nó. Ví dụ: bạn sẽ có thể rút cáp mạng, cắm lại sau vài giây và phiên SSH của bạn sẽ duy trì, bạn sẽ không phải kết nối lại để tiếp tục, mặc dù bạn có thể gặp phải sự chậm trễ ban đầu. Nếu bạn thấy mình có một phiên ssh bị giết, điều đó có nghĩa là một cái gì đó bị cấu hình sai (hoặc đúng hơn là không được cấu hình đúng để hỗ trợ loại gián đoạn này).
monomyth

0

Có một liên kết đến một số mã ăn cắp hacky tty trong câu hỏi này . Về lý thuyết, bạn có thể sử dụng điều này để lấy lại quyền kiểm soát quá trình nohup.


1
Lệnh disown được đề cập trong các câu trả lời cho câu hỏi đó cũng đáng để nghiên cứu thêm. Cảm ơn.
John Gardeniers
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.