Se eu fizer ssh em um servidor remoto do tmux em um único painel, é possível alterar a cor de fundo do painel com base no nome do servidor?
Digamos que todos os meus servidores de produção comecem com prod_XYZ
e um servidor de desenvolvimento comece com dev_XYZ.
Se eu fizer ssh nesses dois servidores, posso colori-los de maneira diferente com base no tipo de servidor em que estou? Ou seja, com base no prefixo do servidor?
Responder1
Se eu fizer ssh nesses dois servidores, posso colori-los de maneira diferente com base no tipo de servidor em que estou?
Sim.
Minha solução básica requer um wrapper ssh
(pode ser uma função shell ou um script), além de um script auxiliar adicional.
A função wrapper deve ser assim:
ssh() {
helper="$HOME/bin/_ssh_tmux_background"
command ssh \
-o PermitLocalCommand=yes \
-o LocalCommand="'$helper' '%h'" \
"$@"
"$helper"
}
E este é o script auxiliar:
#/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"
Salve o script onde $helper
a função aponta ( $HOME/bin/_ssh_tmux_background
no meu código), torne-o executável.
Agora, se você invocar ssh
, a função executará o ssh
comando real com duas opções adicionais: PermitLocalCommand
e LocalCommand
(veja man 5 ssh_config
detalhes). Dessa forma, você executará o script auxiliar com o nome do host remoto como único argumento assim que fizer login no host remoto.
Se você estiver em tmux
, o script herdará a TMUX_PANE
variável de ambiente. O script será encerrado imediatamente se estiver fora de tmux
, portanto não deverá interferir mesmo se você usar a função sem tmux
.
O script compara o nome do host remoto com seus prefixos e escolhe o estilo desejado para tmux
. Você não está limitado a case
, você pode construir sua lógica da maneira que desejar (incluindo correspondência de regex com [[
, mas você precisa bash
então alterar o shebang). No final o estilo é aplicado.
Após ssh
sair, a função chama o script sem argumentos. "$1"
avalia como uma string vazia que não corresponde a nenhum dos nossos padrões, então o estilo padrão de default
é passado para tmux
.
Observe que você pode especificar PermitLocalCommand
and LocalCommand
in /etc/ssh/ssh_config
ou in ~/.ssh/config
. Porém, você não pode se livrar do wrapper tão facilmente, porque precisa alterar a cor de fundo novamente após ssh
sair.
Ainda assim, uma solução sem invólucro pode ser desejada. Imagine um script (invocado com LocalCommand
) que recupera o PID de seu pai ( ssh
's), bifurca-se em segundo plano (assim ssh
continua), monitora o PID e restaura tmux
as configurações após ssh
as saídas. Tal script podesalvaro estilo original do painel, não importa qual fosse, e restaure-o mais tarde, em vez de usar o default
estilo.
Vamos fazê-lo. Esta é minha tentativa:
#/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" ) &
O novo script (digamos $HOME/bin/_ssh_tmux_style
) também deve ser executável. Utiliza tail --pid
o que não é portátil; veressa questãopara abordagens alternativas.
Agora não precisamos da função wrapper antiga (então inicie um novo shell ou unset -f ssh
). Tudo o que precisamos é ~/.ssh/config
. Lembre- man 5 ssh_config
se diz:
Como o primeiro valor obtido para cada parâmetro é usado, mais declarações específicas do host devem ser fornecidas próximo ao início do arquivo e padrões gerais no final.
Tendo isso em mente, coloque o seguinte no lugar certo no seu ~/.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'
As aspas duplas são importantes. Observe que toda a configuração adicional (estilos) agora está incorporada na configuração do ssh
. Faça o seu $PATH
contém $HOME/bin
e depois fica ainda melhor:
LocalCommand=_ssh_tmux_style 'bg=red'
Acho bastante elegante.