LoginSignup
2
1

More than 5 years have passed since last update.

tmux の複数の window を安全に終了させる

Posted at

tmux では kill-session でセッション内の window を終了させることができるが、この場合、問答無用で HUP シグナルが送られる。

しかし、アプリケーションによっては INT シグナルを送ったり、exit とタイプしないと正常な終了処理が行われない場合がある。

現在のセッションのすべての window について、名前に基づいて適切な終了処理を行う tmkill という Ruby スクリプトを作成した。

#!/usr/bin/env ruby
# tmux のウィンドウを安全に kill する
# ウィンドウ名にもとづいて exit [Enter] か control-c を送る

# セッション名・ウィンドウ名の取得
# #{} は tmux のフォーマット文字列
session = `tmux display-message -p "\#{session_name}"`.strip
window_names = `tmux list-windows -F "\#{window_name}"`.strip.each_line.map{|l| l.strip }

commands = []
window_names.each do |window|
  # ウィンドウ名に基づいて、送信するキー入力を決定する
  # ウィンドウ名の最初に [test] とついていれば、それを省く
  keys = case window.gsub(/^\[test\]/, "")
  when "guard", "rails-sh"
    %w(exit Enter)
  when "rails", "resque", "solr", "wordpress"
    %w(C-c)
  else
    # ignore
    next
  end
  commands << ["tmux", "send-keys", "-t", "#{session}:#{window}"] + keys
end

if (ARGV & %w(-n --dry-run)).any?
  require "shellwords"
  commands.each{|cmd| puts cmd.shelljoin }
else
  commands.each{|cmd| system *cmd }
end

kill-session と違ってセッション自体は終了させない。
また名前がマッチしない場合は何もしないようにして、シェルは終了させないようにしている。

解説

tmuxinator を使ってる場合にだいたい同様の事を実現している記事 (Exit Tmuxinator Session Safely) を参考にした。

まず、現在のセッション名を取得する。

# tmux display-message は status line の表示
# -p で標準出力へ表示
# #{session_name} はセッション名を示すフォーマット文字列
$ tmux display-message -p '#{session_name}'
0

ウィンドウ名を取得する。

# tmux list-windows は現在のセッションのウィンドウ一覧の表示
# -F でフォーマットが指定できる
# #{window_name} はウィンドウ名を示すフォーマット文字列
$ tmux list-window -F '#{window_name}'
zsh
rails
guard

tmux send-keys コマンドでそれぞれのウィンドウにキー入力を送る。

# tmux send-keys -t セッション名:ウィンドウ名 キー入力1 キー入力2 ...
$ tmux send-keys -t 0:rails C-c
$ tmux send-keys -t 0:guard exit Enter
2
1
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
2
1