web-dev-qa-db-ja.com

リモートホスト名に応じてtmuxペインの背景色を変更します

単一のペインでtmuxからリモートサーバーにSSH接続した場合、サーバー名に基づいてペインの背景色を変更することはできますか?

すべての本番サーバーがprod_XYZで始まり、開発サーバーがdev_XYZ.で始まるとしましょう。これら2つのサーバーにSSH接続した場合、使用しているサーバーのタイプに基づいて色を変えることはできますか?つまり、サーバープレフィックスに基づいていますか?

1
Scott Skiles

これらの2つのサーバーにSSH接続した場合、使用しているサーバーのタイプに基づいて色を変えることはできますか?

はい。

基本的なソリューションには、sshのラッパー(これはシェル関数またはスクリプトの場合があります)と、追加のヘルパースクリプトが必要です。


ラッパー関数は次のようになります。

ssh() {
  helper="$HOME/bin/_ssh_tmux_background"
  command ssh \
    -o PermitLocalCommand=yes \
    -o LocalCommand="'$helper' '%h'" \
    "$@"
  "$helper"
}

そしてこれはヘルパースクリプトです:

#/bin/sh

[ -z "$TMUX_PANE" ] && exit
style=default
case "$1" in
    prod_* )
        style='bg=red'
        ;;
    dev_* )
        style='bg=blue'
        ;;
esac   
tmux select-pane -P "$style" -t "$TMUX_PANE"

関数の$helperが指すスクリプトを保存し(私のコードでは$HOME/bin/_ssh_tmux_background)、実行可能にします。

ここで、sshを呼び出すと、関数は実際のsshコマンドを実行します。2つの追加オプションはPermitLocalCommandLocalCommandです(詳細はman 5 ssh_configを参照)。このようにして、リモートホストにログインするとすぐに、リモートホスト名を唯一の引数としてヘルパースクリプトを実行します。

tmuxにいる場合、スクリプトはTMUX_PANE環境変数を継承します。スクリプトはtmuxの外にある場合はすぐに終了するため、tmuxなしで関数を使用しても干渉しないはずです。

スクリプトは、リモートホスト名をプレフィックスと照合し、tmuxに必要なスタイルを選択します。 caseに限定されず、任意の方法でロジックを構築できます([[と一致する正規表現を含みますが、bashが必要です。その後、Shebangを変更します)。最後にスタイルが適用されます。

sshが終了した後、関数は引数なしでスクリプトを呼び出します。 "$1"は、どのパターンにも一致しない空の文字列に評価されるため、defaultのデフォルトスタイルがtmuxに渡されます。


/etc/ssh/ssh_configまたは~/.ssh/configPermitLocalCommandおよびLocalCommandを指定できることに注意してください。ただし、sshの終了後に背景色を再度変更する必要があるため、ラッパーを簡単に削除することはできません。

それでも、ラッパーのないソリューションが望ましい場合があります。親(LocalCommand)のPIDを取得し、バックグラウンドにフォークし(sshが継続する)、PIDを監視し、sshの終了後にtmux設定を復元するスクリプト(sshで呼び出される)を想像してみてください。このようなスクリプトは、defaultスタイルを使用する代わりに、ペインの元のスタイルを保存し、後で復元する場合があります。

やってみましょう。これは私の試みです:

#/bin/sh

[ -z "$TMUX_PANE" ] && exit
[ "$#" -eq 1 ] || exit 1

newstyle="$1"
oldstyle="$(tmux select-pane -g -t "$TMUX_PANE")"

tmux select-pane -P "$newstyle" -t "$TMUX_PANE"

( tail --pid="$PPID" -f /dev/null
  tmux select-pane -P "$oldstyle" -t "$TMUX_PANE" ) &

新しいスクリプト(たとえば$HOME/bin/_ssh_tmux_style)も実行可能である必要があります。ポータブルではないtail --pidを使用します。別のアプローチについては、 この質問 を参照してください。

これで、古いラッパー関数は必要なくなりました(したがって、新しいシェルまたはunset -f sshを開始します)。必要なのは~/.ssh/configだけです。 man 5 ssh_configが言うことを忘れないでください:

各パラメーターに対して最初に取得された値が使用されるため、ファイルの先頭近くにホスト固有の宣言を追加し、最後に一般的なデフォルトを指定する必要があります。

これを念頭に置いて、次を~/.ssh/configの適切な場所に配置します。

Host prod_*
PermitLocalCommand=yes
LocalCommand="$HOME/bin/_ssh_tmux_style" 'bg=red'

Host dev_*
PermitLocalCommand=yes
LocalCommand="$HOME/bin/_ssh_tmux_style" 'bg=blue'

二重引用符は重要です。追加の構成(スタイル)全体がsshの構成に埋め込まれていることに注意してください。 $PATH$HOME/binを含めると、さらに良くなります。

LocalCommand=_ssh_tmux_style 'bg=red'

とてもエレガントだと思います。

1