tmux kill-window не убивает дочерние процессы

Вы были рядом, чтобы найти, и вам нужно было только добавить опцию -z, также вы можете сделать ее короче, как показано ниже.

sed -Ez 's/(ssl:\n\s*enabled: )false/\1true/g' infile
1
21.02.2020, 06:06
2 ответа

Ctrl + c противkill-window

С помощью Ctrl + c вы обычно (, когда stty -aпоказывает intr = ^C), отправляете SIGINT процессам в группе процессов переднего плана . Кажется, вы предполагаете, что любой процесс, который получает выходы SIGINT (, уничтожается ), но в целом это может быть не так.

Вы упомянули Ctrl + d , поэтому, вероятно, есть интерактивная оболочка между сервером tmux и процессом, который вы хотите завершить. В этом случае SIGINT отправляется процессу, а не оболочке; но даже если бы оболочка его получила, она не вышла бы. (Я не говорю, что так всегда; Я говорю, что это соответствует вашему описанию ).

Таким образом, кажется, что после завершения процесса по Ctrl + c вы нажимаете Ctrl + d , чтобы выйти из оболочки.

Когда вы уничтожаете окно в tmux, соответствующие псевдотерминалы -закрываются, и процессы, использующие их в качестве своих управляющих терминалов, получают SIGHUP. Такой процесс может отправить SIGHUP своим потомкам, тогда (для оболочки см. этот ответ). Процесс может игнорировать сигнал (, см. nohup). Даже если он игнорирует сигнал, он может (или не может )умереть позже, если попытается использовать псевдо-терминал -, которого больше нет.

Итак, вкратце:

  • вы отправляете SIGINT или SIGHUP рассматриваемому процессу;
  • От процесса зависит, как он будет реагировать на SIGINT или SIGHUP .

Отправка сообщений SIGINT

Процесс может игнорировать SIGINT. Если Ctrl + c делает то, что вы хотите для процессов, с которыми вы имеете дело,тогда, возможно, достаточно отправить им SIGINT до закрытия окна и отправки SIGHUP; как если бы вы нажали Ctrl + c на каждой панели.

Следующая команда перечисляет процессы (непосредственных потомков сервера tmux )в панелях текущего окна, получает соответствующие группы процессов переднего плана и отправляет SIGINT каждому:

tmux list-panes -F "#{pane_pid}" | xargs ps -o tpgid= | xargs -I{} kill -s SIGINT -{}

Проблема в том, что этот самый конвейер также будет получать сигнал SIGINT и может завершиться преждевременно. Чтобы справиться с этим

  • запустите команду из другого места и используйте -tдля указания окна,
  • или реализовать некоторую логику, чтобы группа процессов переднего плана конвейера была исключена,
  • или запустить конвейер в фоновом режиме:

    tmux list-panes -F "#{pane_pid}" | xargs ps -o tpgid= | xargs -I{} kill -s SIGINT -{} &
    
  • или заставить команду игнорировать сигнал:

    sh -c '
    trap "" SIGINT
    tmux list-panes -F "#{pane_pid}" | xargs ps -o tpgid= | xargs -I{} kill -s SIGINT -{}
    '
    

Я думаю, что этот подход склонен к гонке; между psи killвсе может измениться. Лучше (? )Альтернативой является отправка Ctrl + c на каждую панель:

tmux list-panes -F "#{pane_id}" | xargs -I {} tmux send-keys -t {} C-c &

Крюк

Используйте этот хук, чтобы заставить tmux отправлять Ctrl + c на каждую панель в окне, которое должно быть kill-windowed:

tmux set-hook before-kill-window 'run-shell "
   tmux list-panes -t \"#{window_id}\" -F \"##{pane_id}\" | xargs -I {} tmux send-keys -t {} C-c
"'

Это выглядит ужасно, потому что есть три уровня цитирования, но, тем не менее, это работает в моих тестах (Хотя я не проверял тщательно ). Цель ##— отложить расширение #{pane_id}. Суть в том, что #{window_id}необходимо расширять, когда run-shellработает, но #{pane_id}должен сохраняться и расширяться только тогда, когда list-panesгенерирует свой вывод.

Обратите внимание на крышки крюков kill-window, но не на kill-pane, kill-sessionили kill-server. Кроме того, kill-window— это , а не , просто kill-paneповторяется несколько раз, так что хук before-kill-paneточно не покроет все случаи принудительного уничтожения панели. А еще есть команды respawn-pane -kи respawn-window -k.


Что, если этого недостаточно?

Процесс не может завершиться после SIGINT. Используя tmux list-panes -F "#{pane_pid}"в качестве отправной точки, вы можете попытаться получить список PID (и/или PGID ), которым вы хотите отправить SIGTERM (или даже SIGKILL ). Основная проблема с этим общим подходом заключается в том, что можно породить процесс и полностью разорвать его связь с его предками и tty.

Поэтому, как правило, вы не сможете отследить все процессы, исходящие из данного окна tmux.

3
28.04.2021, 23:22

Вы не даете достаточно информации.

C-b %разбивает окно, ничего не уничтожает, так что вы, должно быть, изменили привязку клавиш. С чем он у вас связан? Или вы имеете в виду C-b &?

Уничтожение панели приведет к закрытию pty, и ядро ​​отправит всем процессам, у которых pty является управляющим терминалом, SIGHUP, что должно заставить их выйти, если только они не проигнорируют его.

Что именно вы запускаете в панели? Процессы вообще не завершаются или становятся зомби?

Также было бы полезно знать, какую версию tmux вы используете.

1
28.04.2021, 23:22

Теги

Похожие вопросы