Giết quá trình sinh ra bởi ssh khi ssh chết


23

Đây là một câu hỏi đã được giải quyết nhiều lần, không chỉ ở đây, mà còn ở các trang web khác của mạng trao đổi ngăn xếp (ví dụ: Làm thế nào để tạo ssh để giết tiến trình từ xa khi tôi tự ngắt ssh? ). Tuy nhiên, tôi không thể làm cho bất kỳ giải pháp nào làm việc cho tôi.

Tôi đang chạy một lệnh thông qua ssh. Bất cứ khi nào tôi thoát ssh, tôi cũng muốn lệnh chết. Lệnh này là một daemon gọi là ktserver chạy vô thời hạn cho đến khi bạn nhấn Ctrl-C.

Tôi chạy nó như sau: ssh -t compute-0-1 ktservervà, thực sự, khi tôi nhấn Ctrl-C, quá trình kết thúc một cách duyên dáng và phiên ssh kết thúc.

Tuy nhiên, nếu thay vì nhấn Ctrl-C, tôi sẽ giết tiến trình ssh bằng killlệnh (ví dụ: gửi SIGINT hoặc SIGHUP), ktserverquá trình này vẫn tồn tại.

Làm thế nào tôi có thể làm cho cái ktserverchết luôn luôn độc lập về cách sshbị giết?

EDIT : Nếu, thay vì ktservertôi chạy một cái gì đó hoàn toàn khác, chẳng hạn như gedit, mọi thứ hoạt động như một bùa mê (tức là gedit chết khi kết nối chết). Do đó, có thể có một cái gì đó sai với chính quá trình. Ví dụ, tôi nghĩ rằng nó có thể bỏ qua SIGHUP hoặc SIGINT. Tuy nhiên, khi tôi chạy kill -1 ktserverhoặc kill -2 ktserver, quá trình chết như mong đợi.

EDIT2 : Như Mark Plotnick chỉ ra, vấn đề liên quan đến thực tế là không có giao tiếp lưu thông trên kênh ssh. Tôi đã xác nhận bằng cách chạy ssh -t <host> readvà giết tiến trình ssh sau đó. readvẫn còn sống và đá


Bạn đã thử chưa kill -9 ktserver chưa

@HermanTorjussen Chắc chắn, nó hoạt động. Vấn đề là lệnh này được chạy từ bên trong một quy trình khác và tôi có thể không kiểm soát được tất cả nhiều khả năng có thể khiến quy trình của tôi chết, và do đó phiên ssh với nó. Vì vậy, tôi cần một số cách đáng tin cậy để chắc chắn rằng bất cứ khi nào quá trình của tôi - và do đó xảy ra, ktserver sẽ chết cùng với họ.
GermanK

Kinh nghiệm của tôi với Linux là nếu lệnh từ xa không thực hiện bất kỳ i / o nào đối với kết nối tcp đã chết, nó sẽ tiếp tục chạy. Tôi đã có các ssh example.com dd ...công việc chạy đến hoàn thành thậm chí nhiều giờ sau khi sshkết nối bị chết do sự cố mạng. Nếu bạn có thể thay đổi ktserverđể có một tùy chọn để xuất một cái gì đó một lần trong một thời gian, đó có thể là một cách giải quyết.
Đánh dấu âm mưu

@MarkPlotnick Thật vậy, tôi đã thử chạy read trên máy tính từ xa và sau khi tắt kết nối ssh, readnó đã không chết. Thật không may, tôi không thể thay đổi ktserver để xuất bất cứ thứ gì. Không có giải pháp thì sao?
GermanK

2
Tôi giả sử rằng khi ssh chết mà vỏ của bạn cũng chết. Bạn có thể định cấu hình trình bao của mình để gửi tín hiệu -1 (SIGHUP) khi kết thúc. ( shopt -s huponexit). Bạn có thể kiểm tra nếu điều này làm việc cho bạn?
Hennes

Câu trả lời:


13

Thông thường khi kết nối ssh thì vỏ cũng chết. Bạn có thể định cấu hình vỏ của mình để gửi tín hiệu -1 (SIGHUP) khi nó kết thúc với tất cả các phần tử con của nó.

Đối với bash, bạn có thể định cấu hình tùy chọn này thông qua lệnh dựng sẵn shopt . ( shopt -s huponexit).

Đối với zsh bạn muốn setoptHUP .


Tôi nghĩ rằng đây là câu trả lời cho vấn đề hiện tại của tôi, nhưng nó dường như không hoạt động. Tôi đang chạy: ssh $ host "scp LargeFile.dat $ Otherhost: / tmp" & pid = $! và sau đó cố gắng ngăn chặn việc chuyển tiền đó với: shopt -s huponexit; giết $ pid, nhưng scp không dừng lại khi tôi giết ssh mà tôi bắt đầu. Có suy nghĩ gì không?
David Doria

Bạn có thể kiểm tra với các tùy chọn shell được đặt trước khi bắt đầu lệnh scp không? Hoặc bằng cách bắt đầu một shell, thiết lập shopt và bắt đầu scp?
Hennes

2
Điều này làm việc cho tôi, nhưng trước tiên tôi phải đảm bảo rằng tôi đang sử dụng ssh -t -t, (thông báo -thai lần!), Điều này buộc phải phân bổ tty, thay vì chỉ pty.
Nicolas Wu

13

Tôi thấy rằng chỉ đơn giản là sử dụng -t -tnhư một đối số để sshlàm cho nó hoạt động. Tôi không phải đặt thành huponexitvỏ ban đầu hoặc vỏ từ xa.

Tôi đã thử nghiệm điều này như sau:

Không hoạt động:

ssh user@remote sleep 100
^C

Điều này đã giết phiên ssh, nhưng tôi có thể thấy quá trình ngủ vẫn đang chạy trên máy chủ từ xa ( ps -ef | grep sleephiển thị nó).

Làm việc:

ssh -t -t user@remote sleep 100
^C

Điều này giết chết phiên ssh và quá trình ngủ từ xa cũng bị giết. Tôi cũng đã xác minh rằng tín hiệu được gửi đến quy trình từ xa là SIGINTnếu bạn sử dụng Control- C. Tôi cũng đã xác minh rằng SIGKILL (-9) được áp dụng chossh quy trình cũng sẽ giết quá trình từ xa.

CHỈNH SỬA 1:

Đó đúng đối với sleep... cho các quá trình từ xa bướng bỉnh hơn, tôi thấy rằng sshxử lý ^ C khác nhau mà SIGINT. Ctrl- Cđã làm việc, nhưngkill -INT $pid không

Đây là những gì cuối cùng tôi đã đưa ra mà đã làm việc cho ứng dụng thực tế của tôi (ăn cắp từ các câu trả lời khác).

ssh -t -t -i id_rsa user@mic0 "/bin/sh -O huponexit -c 'sleep 100'"

Lưu ý việc sử dụng lồng nhau của dấu ngoặc kép và dấu ngoặc đơn. Lưu ý rằng quy trình từ xa của bạn PHẢI phản hồi SIGHUP bằng cách thực sự thoát!


Điều này làm việc tốt nhất với tôi, nhưng FYI, nó cũng khiến các nhân vật điều khiển thiết bị đầu cuối bị chảy máu, điều này có thể gây ra đầu ra buồn cười. Vì vậy, cách giải quyết dễ dàng trong trường hợp của tôi là bọc các lệnh được gọi và dẫn đầu ra của chúng đi qua cat. Ví dụ:ssh -ttq user@host '{ cmd; cmd; } | cat'
Droj

Ctrl-CKHÔNG luôn tương đương với kill -INT $pid, xem câu trả lời của tôi trên unix.stackexchange.com/questions/377191/... và khác trên stackoverflow.com/questions/8398845/... cho các chi tiết đẫm máu ;-)
thecarpy

@thecarpy - câu trả lời đầu tiên của bạn cho biết Ctrl-C gần giống với SIGINT và câu trả lời khác nói ^Csẽ gửi SIGINT . Vậy sự khác biệt chính xác là gì nếu chúng không tương đương?
Đánh dấu Lakata

1

Nếu ssh không truyền tín hiệu, nó sẽ nhận được những gì bạn mong đợi từ nó?

CẬP NHẬT. (đặc biệt đối với JosephR): rõ ràng đó là một lỗi trong chính câu hỏi xuất phát từ sự hiểu lầm - "Quá trình tiêu diệt được sinh ra bởi ssh khi ssh chết". SSH không sinh ra các quá trình thường (đôi khi nó xảy ra, nhưng đây là một câu chuyện khác), SSHD thay vào đó, khi chúng ta nhìn vào khía cạnh khác của kết nối. SSH chỉ dựa vào máy chủ từ xa trừu tượng giả. Đó là lý do tại sao điều duy nhất có thể giúp đỡ là khả năng của thiết bị đầu cuối để phát tín hiệu đến các quy trình đính kèm của nó. Điều này hơi cơ bản cho mọi hệ thống giống như UNIX.


1
Điều này không cung cấp một câu trả lời cho câu hỏi. Để phê bình hoặc yêu cầu làm rõ từ một tác giả, hãy để lại nhận xét bên dưới bài đăng của họ.
Anthon

@Anthon, đó là một lời giải thích. Nhưng không ai nói đây là câu trả lời đúng duy nhất. Cảm ơn bình luận của bạn dưới đây.
poige

1
@poige Có thể đưa ra lời giải thích để nó có thể được sử dụng cho OP và những người khác.
Joseph R.

@JosephR., Ok, chỉ dành cho bạn.
poige

1
Nếu tôi nói "Quá trình tiêu diệt được sinh ra bởi sshd khi mất kết nối ssh" thì nó có tốt hơn cho bạn không? Tôi không nghĩ rằng việc chia sẻ lại giải quyết vấn đề của tôi theo bất kỳ cách nào.
GermanK

0

Giải pháp được đăng ở đây không hiệu quả với tôi nhưng vì câu hỏi này xuất hiện đầu tiên khi tôi đang tìm kiếm giải pháp cho vấn đề tương tự và cũng có -t -tmẹo được đề cập ở đây nên tôi sẽ đăng giải pháp giúp tôi cho người khác thử.

ssh -t -t -o ControlMaster=auto -o ControlPath='~/test.ssh' your_remote_ip_goes_here "your_long_running_command" &
sleep 100
ssh -o ControlPath='~/test.ssh' -O exit your_remote_ip_goes_here

Lệnh chạy dài của tôi không chạy nữa khi kết nối bị ngắt như thế này.

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.