Executando Comandos Remotos de Forma Interativa com SSH

Muitas vezes, eu preciso executar um comando em um servidor remoto, mas não desejo iniciar uma sessão interativa completa. Quero que o programa mantenha todas as características de um processo local, porém seja executado no servidor remoto.

Inicialmente, eu apenas usava o comando ssh especificando o servidor e o comando que desejo executar:

ssh servidor comando

Esse método não funciona bem para programas que exigem um pseudo terminal, como o Neovim. Para resolver isso, eu tentei a opção -t para forçar a alocação de um pseudo terminal. Assim, programas como o ls exibem cores, mas o ambiente de usuário não é carregado. Nesse caso, eu preciso usar a opção --color no ls. Mesmo assim, programas como o Neovim falham porque o shell não se comporta como interativo e códigos ANSI não são processados corretamente.

ssh -t servidor comando

Para que o shell funcione completamente e carregue as configurações, eu informo ao shell que ele deve ser interativo. No zsh, isso ocorre com a opção -i. Eu também uso a opção -c para executar o comando desejado:

ssh -t servidor "zsh -ic 'comando'"

Assim, eu executo comandos complexos de minha máquina local sem abrir uma sessão remota interativa, aumentando a praticidade e a segurança. Esse método é útil em scripts que precisam manipular o servidor, pois não deixa a sessão aberta.

O único inconveniente é que o comando roda em um shell novo, sem carregar variáveis de ambiente e outras configurações após a finalização. Posso conectar a uma sessão do tmux ou do screen, mas isso dificulta a identificação do início e do fim do comando, impedindo a captura de saída.

De qualquer forma segue o comando para criar uma sessão do tmux ou se conectar a uma existente e então executar o comando:

ssh -t servidor "tmux new-session -d -s persistent || true; \
tmux send-keys -t persistent \"zsh -ic 'comando'\" Enter; \
tmux attach -t persistent"

Para obter um shell remoto com todas as configurações e variáveis de ambiente mantendo o estado entre as sessões, precisaríamos de um novo shell. Mas esse é um projeto para outro dia.

Vídeo com a explicação detalhada:

Cesar Gimenes

Última modificação