Como posso executar um script imediatamente após a conexão via SSH?

24

Comecei a fazer essa pergunta, mas respondi enquanto a estava aberta. Vou postar esta pergunta, acompanhar a minha solução e deixá-la aberta para outras soluções em potencial.

<história de fundo>

Eu sou um usuário tmux e vim. Eu gosto do trabalho com o vim remoto, pois não preciso me preocupar com as máquinas de desenvolvimento do Ubuntu que surgem quando um filme em flash me dá um pânico no kernel. Executar o tmux significa que os arquivos abertos estão esperando por mim após a reinicialização e posso continuar de onde parei. Eu tive problemas com o vim executando em uma sessão tmux quando me conecto da seguinte forma:

ssh example.com -t 'tmux attach'

Surgem problemas de UTF-8 que não surgem quando se descascam normalmente e apenas se conectam manualmente a uma sessão do tmux.

</ história de fundo>

Então, eu quero um método reutilizável de iniciar algo no login ssh, que não afete nenhuma das outras coisas que configurei no meu .zshrc(ou no seu, .bashrcse você ainda usa o bash) que pode ser necessário para o meu ambiente de desenvolvimento, que não afeta aparece quando ocasionalmente estou trabalhando localmente na mesma máquina.

connrs
fonte

Respostas:

13

Quando você executa ssh example.com, o daemon ssh inicia um shell de login para você e o shell de login lê o seu ~/.profile(ou ~/.bash_profileou ~/.zprofileou ~/.logindependendo do seu shell de login). Quando você especifica um comando para executar remotamente (com ou sem -t), o daemon ssh inicia um shell comum, para que você .profilenão seja lido. Remédio:

ssh example.com -t '. /etc/profile; . ~/.profile; tmux attach'

A maioria dos daemons ssh está configurada para recusar a transmissão de variáveis ​​de ambiente, exceto LC_*. Se o daemon ssh on example.compermitir, você pode abusar de uma LC_*variável personalizada para iniciar o tmux automaticamente - coloque isso em seu ~/.profile:

if [ -n "$LC_tmux_session" ] && tmux has -t "$LC_tmux_session"; then
  exec tmux attach -t "$LC_tmux_session"
elif [ -n "${LC_tmux_session+1}" ] && tmux has; then
  exec tmux attach
fi

depois faça login com LC_tmux_session= ssh example.comou LC_tmux_session=session_name ssh example.com.

Esta resposta tem mais informações sobre a passagem de variáveis ​​de ambiente pelo ssh.

Gilles 'SO- parar de ser mau'
fonte
O motivo pelo qual não estou usando não ssh example.com -t 'tmux attach'é porque há problemas ao carregar meu ambiente, mas porque tive problemas com a exibição de caracteres UTF-8; esse problema não existe ao conectar da maneira convencional. É por isso que esta pergunta é sobre a execução de scripts imediatamente após a conexão pelo SSH.
connrs 23/03
Eu amo sua solução embora. Elegantes
connrs
@connrs: Você tem problemas com o UTF-8, mesmo quando executa o seu .profile? Presumi que o problema ocorreu devido à definição incorreta de localidades na máquina de destino, que você /etc/profileou .profilecorrigiu. O problema da localidade provavelmente é corrigível com mais informações.
Gilles 'SO- stop being evil'
Eu queria voltar ao escritório para testar isso. Você está totalmente correto, o fornecimento do perfil / etc / dispara o comportamento adequado. Você agora realmente resolveu o problema que me motivou a fazer esta pergunta mais genérica
connrs
6

Eu previamente recomendadas configuração PermitUserEnvironment yese adicionar uma variável de ambiente em sua ~/.ssh/environmentaté computador Eli Heady entrasse com uma sugestão melhor nos comentários abaixo.

Abra seu .zlogin(bash: .bash_profileetc.) e coloque o seguinte:

if [[ "$SSH_CONNECTION" != "" && "$MY_SSH_CONNECTION" != "yes" ]]; then
    while true; do
        echo -n "Do you want to attach to a tmux session? [y/n]"
        read yn
        case $yn in
            [Yy]* ) MY_SSH_CONNECTION="yes" tmux attach; break;;
            [Nn]* ) break;;
            * ) echo "Please answer y/n";;
        esac
    done
fi

Inspiração retirada de: Como solicitar entrada em um script de shell do Linux?

Observe que eu usei o .zloginarquivo, mas você pode usá-lo, .zshrcmas eu gosto de manter meus arquivos de ponto organizados e o separa para que eu possa usá-lo em outras máquinas.

Substitua a pergunta por algo apropriado para si e substitua MY_SSH_CONNECTION="yes" tmux attachpelo que você deseja executar nesse momento.

Observe como o script é configurado MY_SSH_CONNECTION="yes"antes tmux attachpara transmiti-lo ao tmux, pois também abrirá um shell que acessará o mesmo script acima e evitará qualquer recursão.

connrs
fonte
2
O uso de PermitUserEnvironment não será possível em alguns ambientes devido às implicações potenciais de segurança. O SSH define a variável $ SSH_CONNECTION, que pode ser usada no lugar do seu $ SSH_LOGIN no seu .zlogin, evitando a necessidade de usar ~ / .ssh / environment. Algo como if [[ "$SSH_CONNECTION" != "" ]]deveria fazê-lo.
Eli Heady
3

Eu mesmo, adiciono isso aos meus arquivos .bash_profile:

if [ -z "$STY" ]; then
    reattach() { exec screen -A -D -RR ${1:+"$@"} ; }
fi
if [ -t 0 ]; then
    screen -wipe
    echo 'starting screen... (type Ctrl-C to abort)'
    sleep 5 && reattach
fi

Isso me dá algum tempo para interromper a reconexão ou criação de uma sessão de tela. Ele não funciona nos formatos 'ssh system command' (que não chama o perfil ~ /.*). Uma função shell é configurada para reconectar se eu abortar.

Arcege
fonte
Ótimo! Eu consegui consertar isso colocando bashrc e depois em cada nova janela da tela - ao mudar para .profile, funcionou bem.
Hugo
0

Você pode considerar correr

ssh remotehost -t screen -DR

e execute sua sessão de terminal lá. Você pode desanexar ( ^A^D) e reconectar posteriormente (de um cliente diferente). Isso fará com que o problema com a inicialização não interativa desapareça, pois a tela mantém sessões de terminal interativas completas (opcionalmente também shells de logon, man screen(1) ou ^A?)

ver
fonte
Como mencionado na minha pergunta, estou usando o tmux em vez da tela GNU para gerenciar minhas sessões. E quando carregado -t 'tmux attach', tenho problemas com o vim que não estão presentes normalmente. É por isso que a verdadeira questão é sobre a execução de scripts no ssh connect, em vez do gerenciamento de tela / sessão. Desculpas para não ser mais claro na minha pergunta
connrs
Desculpe, você mencionou o tmux, mas isso não significou nada para mim. Obrigado por mencionar uma nova ferramenta!
sehe
0

Para falar especificamente sobre os problemas UTF-8, se você adicionar

SendEnv LANG

E $LANGestá definido para algo como en_US.UTF-8na extremidade local e seu sshd na extremidade remota permite a SendEnvdiretiva (com AcceptEnvin sshd_config), o tmux na outra extremidade deve respeitá-la. Eu tive esse problema por um tempo e foi difícil solucioná-lo.

Chris W.
fonte
0

Se você deseja que ele seja executado sempre que se conectar, você pode simplesmente adicionar tmux attachà parte inferior da sua ~/.profilemáquina remota.

linesarefuzzy
fonte