Процес вбивства, породжений ssh, коли ssh гине


23

Це питання, на яке зверталися кілька разів, не тільки тут, але і на інших сайтах мережі обміну стеками (наприклад, Як змусити ssh вбити віддалений процес, коли я перервав сам ssh? ). Однак я не можу зробити так, щоб жодне з рішень працювало на мене.

Я виконую команду через ssh. Щоразу, коли я виходжу з ssh, я хочу, щоб команда також померла. Ця команда є демоном під назвою ktserver, який працює нескінченно, поки ви не натиснете Ctrl-C.

Я запускаю це наступним чином: ssh -t compute-0-1 ktserverі, дійсно, коли я натискаю Ctrl-C, процес закінчується витончено і сеанс ssh закінчується.

Однак якщо замість натискання клавіші Ctrl-C я вбиваю процес ssh за допомогою killкоманди (наприклад, надсилаючи SIGINT або SIGHUP), ktserverпроцес залишається живим.

Як я можу змусити ktserverзавжди вмирати незалежно від того, як sshвбивають?

EDIT : Якщо замість цього ktserverя запускаю щось зовсім інше, наприклад gedit, все працює як шарм (тобто gedit гине, коли зв’язок помирає). Тому в самому процесі може бути щось не так. Наприклад, я подумав, що це може бути ігнорування SIGHUP або SIGINT. Однак, коли я запускаю kill -1 ktserverабо kill -2 ktserver, процес вмирає так, як очікувалося.

EDIT2 : Як зазначає Марк Плотнік, проблема пов'язана з тим, що на каналі ssh немає циркуляції зв'язку. Я підтвердив, запустивши ssh -t <host> readі вбивши після цього ssh-процес. readвсе ще жив і брикався.


Ви пробували kill -9 ktserver?

@HermanTorjussen Звичайно, це працює. Проблема полягає в тому, що ця команда виконується з іншого процесу, і я, можливо, не маю контролю над усіма багатьма можливостями, які можуть спричинити загибель мого процесу, а отже, і сеанс ssh з ним. Тому мені потрібен якийсь надійний спосіб бути впевненим, що кожен раз, коли мій процес - і тому ssh- вмирає, ktserver помре з ними.
GermanK

Мій досвід роботи з Linux полягає в тому, що якщо віддалена команда не зробить жодного вводу-виводу для мертвого підключення tcp, вона продовжуватиме працювати. У мене ssh example.com dd ...робота закінчилася навіть години після того, як sshзв’язок вмирає через проблеми з мережею. Якщо ви можете змінитиktserver щоб скористатися можливістю вивести щось раз на деякий час, це може бути вирішенням проблеми.
Марк Плотнік

@MarkPlotnick Дійсно, я спробував працювати readна віддаленому комп’ютері, і після вбивства ssh-з'єднання readне помер. На жаль, я не можу змінити ktserver для виведення нічого. Тоді рішення немає?
GermanK

2
Я припускаю, що коли ssh гине, ваша шкаралупа також гине. Ви можете налаштувати оболонку для надсилання сигналу -1 (SIGHUP), коли він закінчується. ( shopt -s huponexit). Чи можете ви перевірити, чи працює це для вас?
Геннес

Відповіді:


13

Зазвичай, коли ssh-з'єднання гине, оболонка також гине. Ви можете налаштувати оболонку для передачі сигналу -1 (SIGHUP), коли він закінчується всім його дітям.

Для bash ви можете налаштувати цю опцію через вбудовану команду shopt . ( shopt -s huponexit).

За zsh ти хочеш .setoptHUP


Я думав, що це відповідь на мою нинішню проблему, але, схоже, це не працює. Я бігаю: ssh $ host "scp LargeFile.dat $ OtherHost: / tmp" & pid = $! а потім намагається зупинити цю передачу за допомогою: shopt -s huponexit; kill $ pid, але scp не припиняється, коли я вбиваю ssh, що я почав. Будь-які думки?
Девід Дорія

Чи можете ви протестувати параметри оболонки, встановлені перед запуском команди scp? Або запустивши оболонку, встановивши shopt і запустивши scp?
Геннес

2
Це працює для мене, але я спершу повинен був переконатися, що я використовую ssh -t -t(помічаю -tдвічі!), Що примушує виділити tty, а не просто pty.
Nicolas Wu

13

Я виявив, що просто використання -t -tв якості аргументу sshзмусило це працювати. Мені не довелося встановлювати huponexitні вихідну, ні віддалену оболонку.

Я перевірив це наступним чином:

Не працює:

ssh user@remote sleep 100
^C

Це знищило ssh-сеанс, але я бачу, що процес сну все ще працює на віддаленому хості ( ps -ef | grep sleepпоказує це).

Чи працює:

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

Це вбиває ssh-сеанс, і процес віддаленого сну також був убитий. Я також перевірив, що сигнал, який надсилається у віддалений процес, - SIGINTякщо ви використовуєте Control- C. Я також перевірив, що SIGKILL (-9) застосовано доssh процесу, також знищить віддалений процес.

EDIT 1:

Це було справедливо для sleep... для більш впертих віддалених процесів я виявив, що sshобробляє ^ C інакше, ніж SIGINT. Ctrl- Cпрацював, алеkill -INT $pid didn'.t

Ось що я нарешті придумав, що працював на мою фактичну заявку (крадучись з інших відповідей).

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

Зверніть увагу на вкладене використання подвійних лапок та одинарних лапок. Зауважте, що ваш віддалений процес ПОВИНЕН відповісти на SIGHUP, фактично закривши його!


Це працювало найкраще для мене, але FYI, це також спричинило кровотечу через символи терміналу, що може спричинити смішний вихід. Отже, найлегшим рішенням у моєму випадку було обгортання команд, що називаються, та передача їх результатів cat. Наприклад,ssh -ttq user@host '{ cmd; cmd; } | cat'
Droj

Ctrl-CНЕ завжди еквівалентно kill -INT $pid, побачити моя відповідь на unix.stackexchange.com/questions/377191 / ... і інший на stackoverflow.com/questions/8398845 / ... для закривавлених деталей ;-)
thecarpy

@thecarpy - у вашій першій відповіді сказано, що Ctrl-C схожий на SIGINT , а в іншій відповіді йдеться про ^Cнадсилання SIGINT . То яка точна різниця, якщо вони не еквівалентні?
Марк Лаката

1

Якщо ssh не поширює сигнали, він отримує, що ви від нього очікуєте?

UPD. (спеціально для JosephR): це, очевидно, сама помилка, яка випливає з нерозуміння - "процес вбивства, породжений ssh, коли ssh гине". SSH зазвичай не породжує процеси (іноді це так, але це вже інша історія), SSHD робить це замість цього, коли ми дивимось на іншу сторону зв'язку. SSH просто покладається на віддалений сервер псевдотермінальної абстракції. Ось чому єдине, що може допомогти, - це здатність термінала випромінювати сигнали до своїх приєднаних процесів. Це дещо дуже базово для кожної системи, схожої на UNIX.


1
Це не дає відповіді на запитання. Щоб критикувати або вимагати роз'яснення у автора, залиште коментар під їх дописом.
Антон

@Anthon, це пояснення. Але ніхто не заявляє, що це має бути єдиною правильною відповіддю. Дякуємо за ваш коментар нижче.
poige

1
@poige Можливо, роз'яснити пояснення, щоб воно могло бути корисним для ОП та інших.
Джозеф Р.

@JosephR., Добре, тільки для вас.
poige

1
Якщо я скажу "Процес вбивства, породжений sshd, коли втрачається ssh-з'єднання", чи буде це вам краще? Я не думаю, що перефразування жодним чином не вирішує мою проблему.
GermanK

0

Розміщене тут рішення не спрацювало для мене, але оскільки це питання виникло першим, коли я шукав рішення подібної проблеми, а також -t -tтут було зазначено хитрість, я опублікую рішення, яке працювало на мене, щоб інші спробували.

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

Моя довга команда, що працює, більше не працює, коли з'єднання припинено так.

Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.