Tenho cerca de dez servidores aos quais me conecto com SSH regularmente. Cada um tem uma entrada no ~/.ssh/config
arquivo do meu computador local .
Para evitar perder o controle do meu processo de execução quando minha conexão com a Internet inevitavelmente cai, sempre trabalho dentro de uma tmux
sessão. Eu gostaria de ter uma maneira de fazer o tmux conectar-se automaticamente toda vez que uma conexão SSH for iniciada, então eu não tenho que digitar sempre tmux attach || tmux new
após fazer SSH.
Infelizmente, isso não está sendo tão simples quanto eu esperava.
- Não quero adicionar nenhum comando aos
~/.bashrc
servidores porque só quero isso para sessões SSH, não para sessões locais. - Adicionar
tmux attach || tmux new
aos~/.ssh/rc
servidores simplesmente resulta no erronot a terminal
sendo lançado após a conexão, mesmo quando aRequestTTY force
opção é adicionada à linha desse servidor em meu arquivo de configuração SSH local.
~/.ssh/config
. A resposta que a maioria das pessoas provavelmente precisará é, portanto, stackoverflow.com/a/52838493/5354137 .Respostas:
Configuração do lado do servidor:
Para iniciar automaticamente o tmux em seu servidor remoto ao fazer login normalmente via SSH (e apenas SSH), edite o
~/.bashrc
do seu usuário ou root (ou ambos) no servidor remoto de acordo:Este comando cria uma sessão tmux chamada
ssh_tmux
se nenhuma existir, ou reanexa a uma sessão já existente com aquele nome. No caso de sua conexão cair ou quando você esquecer uma sessão semanas atrás, todo login SSH automaticamente o leva de volta à sessão tmux-ssh que você deixou para trás.Conecte-se a partir do seu cliente:
Nada de especial, apenas
ssh user@hostname
.fonte
ssh_tmux
para$USER
)$SSH_TTY
vs$SSH_CONNECTION
também.tmux new-session -A -s ssh_tmux
para substituirtmux attach-session -t ssh_tmux || tmux new-session -s ssh_tmux
muito mais curto, se um pouco mais confuso,-A
diz ao tmux para anexar a sessão se ela já existirif [[ -n "$PS1" ]] && [[ -z "$TMUX" ]] && [[ -n "$SSH_CONNECTION" ]];
$PS1
, use em[[ $- == *i* ]]
vez disso, pois o PS1 pode ser definido mesmo quando não é um shell interativo.Tudo bem, encontrei uma solução bastante satisfatória. No meu local
~/.bashrc
, escrevi uma função:que basicamente sobrescreve a função de terminal ssh para chamar o programa ssh embutido com os argumentos fornecidos, seguido por
"tmux attach || tmux new"
.(O
$@
denota todos os argumentos fornecidos na linha de comando, entãossh -p 123 user@hostname
será expandido parassh -t -p 123 user@hostname "tmux attach || tmux new"
)(O
-t
argumento é equivalenteRequestTTY Force
e necessário para o comando tmux.)fonte
tmux
suportar, considere usar otmux new -A foo
qual será anexado a uma sessão existente chamada,foo
se possível, criando-a, se necessário. Isso permite que você simplifique sua função para/usr/bin/ssh -t "$@" tmux new -A
(e certifique-se de citar$@
!).function ssht
ou algo parecido para que possa continuar a usarssh
normalmente. Caso contrário, basta digitar/usr/bin/ssh
no prompt de comando sempre que se conectar a uma máquina sem tmux :)ssht
para~/bin
.ssh -t user@hostname "LANG=$LANG tmux attach || tmux new"
Conectar:
Durante a sessão:
Use
Ctrl+d
para terminar a sessão (a janela do tmux fecha) ouCtrl+b d
para desconectar temporariamente da sessão e conectar-se a ela novamente mais tarde.Quando você estiver dentro do tmux a qualquer momento, você pode usar
Ctrl+b s
para ver a lista de sessões e mudar a atual para outra.Corrija seu .bashrc:
Eu recomendo que você defina a função universal em seu
.bashrc
:Ele usa a
22
porta por padrão. Defina também seus aliases de conexão rápida:Login sem senha:
E se você não quiser digitar a senha todas as vezes, gere
.ssh
chaves para fazer o login automaticamente :Coloque sua chave pública no host remoto:
Dicas adicionais:
Se você deseja usar o id de sessão temporário que corresponde a uma sessão bash local, use como id do tmux :
fonte
||
, em alguns casos de uso é a de incluirnew-session
no.tmux.conf
e apenas usar sempretmux a -t 0
.tmux new-session -A
qual anexará se existir, caso contrário, criará um novo.tmux 3.1 ou mais recente¹ na máquina remota
Em seu local
~/.ssh/config
, coloque²:Não relacionado, mas se você estiver lidando com caracteres não ASCII, recomendo mudar para
tmux -u …
para habilitar explicitamente o suporte Unicode, mesmo em máquinas que não têm as variáveis de ambiente adequadas definidas.tmux 3.0a ou mais antigo na máquina remota
Quase o mesmo que acima, mas altere a última linha para³:
¹ Em 2020-10-29, a lista de distribuições enviadas com tmux 3.1 ou mais recente já é bastante longa.
²
new
é a abreviação denew-session
.³
at
é a abreviação deattach-session
.Método alternativo usando o
authorized_keys
arquivo do controle remoto :Se você preferir não ter um
~/.ssh/config
arquivo por qualquer motivo, ou deseja que a máquina remota force a máquina conectada a se conectar / abrir a sessão, adicione ao seu controle remoto~/.ssh/authorized_keys
:Isso, é claro, funcionará com todos os clientes que tenham a chave privada correspondente instalada, o que pode ser uma vantagem ou uma desvantagem, dependendo do que você deseja. Existe o risco de que, caso algo dê errado, não seja mais possível conectar.
fonte
tmux at
vez detmux a
? Também seria sensato usar uma sessão nomeada para isso ou o tmux seria anexado a sessões "aleatórias" existentes ao se logar no host.Ctrl+A
Ctrl+Z
.Ctrl-B
D
funciona o tratamento em comparação comCtrl-B
Ctrl-Z
. Obrigado!Usei linhas de @kingmeffisto (não tenho permissão para comentar essa resposta) e adicionei uma saída para encerrar o tmux também encerrar a conexão ssh. No entanto, isso quebrou as sessões de SFTP, então tive que verificar em
$SSH_TTY
vez de$SSH_CONNECTION
.EDITAR 4/2018: Adicionado teste para terminal interativo via
[[ $- =~ i ]]
para permitir que ferramentas como o Ansible funcionem.fonte
Conforme descrito nesta postagem do blog, você pode fazer o ssh e depois anexar a uma sessão tmux existente com um único comando:
fonte
tmux attach || tmux new
para que uma nova sessão do tmux não seja criada para cada conexão). A parte complicada é que o comando correto éssh -t user@host tmux attach || tmux new
e a única maneira de criar um alias para algo que precisa de um argumento dentro da string de comando é criar uma nova função, como fiz acima.ssh [hostname] -t tmux attach -t [sessionName]
byobu é um wrapper muito útil para tmux / screen. Conecta-se a uma sessão existente, se houver, ou cria uma nova.
Eu o uso com autossh, que reconecta a sessão ssh de maneira elegante. Altamente recomendado em caso de problemas de conectividade intermitente.
fonte
Você pode achar isto útil - usa ssh em um loop e se reconecta ou se conecta a uma sessão tmux existente para que você tenha uma maneira fácil e confiável de se reconectar após uma queda de rede
fonte
Este é o que realmente cria uma ótima experiência do usuário. Ele inicia automaticamente o tmux sempre que você abre o terminal (tanto fisicamente quanto ssh). Você pode iniciar seu trabalho em um dispositivo, sair do terminal e retomar no outro. Se ele detectar alguém já conectado à sessão, ele criará uma nova sessão. Coloque-o no servidor , dependendo do seu shell
~/.zshrc
ou~/.bashrc
.if [[ -z "$TMUX" ]] ;then ID="$( tmux ls | grep -vm1 attached | cut -d: -f1 )" # get the id of a deattached session if [[ -z "$ID" ]] ;then # if not available attach to a new one tmux new-session else tmux attach-session -t "$ID" # if available attach to it fi fi
fonte
Sei que estou revivendo um tópico antigo, mas fiz alguns trabalhos na solução bashrc e acho que tem alguma utilidade:
Há um limite de 10 (11) sessões por enquanto - eu não queria matar meu servidor com um loop infinito em bashrc. Parece funcionar de forma bastante confiável, exceto o erro de falha do tmux em clientes de lista se a sessão não existir.
fonte
Essa maneira permite que você se reconecte a uma instância antiga do tmux se sua sessão ssh cair. O
exec
salva um garfo é claro.fonte
Acrescentar ao fundo do seu servidor remoto de
~/.bashrc
, (ou, eventualmente, a sua/etc/.bashrc.shared
(1)) :Muitas dicas boas acima combinadas aqui , por exemplo,
$-
e$SSH_TTY
são melhores, eu acho.E gosto de adicionar alguns comentários para ajudar esse velho a se lembrar do que está acontecendo sem ter que procurar.
E, finalmente, gosto de um
exit
final para voltar para casa de forma limpa quando terminar.Obrigado a todos.
Note que eu forneço um compartilhado
/etc/.bashrc.shared
no final do usuário e do root.bashrc
, para coisas comuns usadas em ambos, como colorizedls
, vários aliases, funções e extensões de caminho, ou seja, não quero código redundante em meu root / .bashrc nem usuário /.bashrc.fonte