Execute o comando no servidor remoto através do SSH - sem sair

5

Eu me conecto frequentemente ao Laboratório Linux da minha escola para trabalhar remotamente nas minhas atribuições de programação. Às vezes, quando há muitos outros alunos conectados ao servidor, a conexão é lenta e eu perdi o trabalho durante os tempos limite de conexão. Há vários servidores para escolher no laboratório e quero poder executar automaticamente who assim que a conexão for feita, para que eu possa ver o quão lotado é o servidor e usar outro se ele estiver muito cheio. No momento, eu uso uma função no meu arquivo .bash_aliases para agilizar a entrada de conexão e senha:

No arquivo ~/.bash_aliases :

#!/bin/bash

# ssh to the Linux lab. Takes hostnames defined in ~/.ssh/config as 
# parameters
function sshll()
{
    if [ "$@" ]
      echo "Connecting to hostname $@";
      sshpass -f <password_file> ssh $@;
    else
      echo "Connecting to default host";
      sshpass -f <password_file> ssh <user@ipaddress>;
    fi
}

Isso funciona, então adicionei who ao final dos comandos ssh :

No arquivo ~/.bash_aliases :

#!/bin/bash

# ssh to the linux lab. Takes hostnames defined in ~/.ssh/config as 
# parameters
function sshll()
{
    if [ "$@" ]
      echo "Connecting to hostname $@";
      sshpass -f <password_file> ssh $@ 'who';
    else
      echo "Connecting to default host";
      sshpass -f <password_file> ssh <user@ipaddress> 'who';
    fi
}

Isso conecta, insere minha senha automaticamente e executa who , mas fecha a conexão. Existe uma maneira de executar who automaticamente, sem fechar a conexão depois?

    
por Michael Hoffmann 13.10.2015 / 21:01

4 respostas

2

TL; DR : a resposta da int_ua é o caminho a seguir, mais simples e sem esforço.

Por que isso funciona da maneira como funciona

Isso volta ao comportamento básico de qualquer shell. Quando você faz login como ssh [email protected] , você obtém a versão interativa do shell. Quando você executa ssh [email protected] -t "command1;command2" , basicamente obtém /bin/sh -c 'command1;command2' . O primeiro permite executar o que você colocar no stdin enquanto obtém os arquivos de pontos, enquanto o segundo apenas executa esses comandos e saídas. Essencialmente, não há como executar um comando antes do uso interativo (a menos que esteja em um dos arquivos de ponto) ou obter um shell interativo do comando single-shot sh -c (ou qualquer shell que seja, não necessariamente sh ).

Idéias com falha ou incompletas

Minha primeira idéia que tive é a seguinte: se o shell usa o local do servidor .bashrc , alguém poderia usar o arquivo local do cliente no servidor? Bem, não . Não, a menos que você copie o arquivo de pontos para o servidor remoto com scp ou rsync.

A segunda ideia que eu tive é a PROMPT_COMMAND . Esta% nice bash variável executa o comando toda vez antes de mostrar seu prompt PS1 , então por que não definir essa variável antes de gerar bash to PROMPT_COMMAND="who; unset PROMPT_COMMAND" para que seja executada como single-shot?

O problema é que essa variável precisa ser exportada para o servidor remoto, e resposta do Gilles me ajudou a fazer algo parecido com isso :

ssh -o SendEnv=PS1 ssh localhost -t bash

ou

ssh localhost -t " PROMPT_COMMAND='who; unset PROMPT_COMMAND' bash  "

Problema? -o opção SendEnv deve permitir que a variável específica que você está tentando enviar em /etc/ssh/sshd_config , e, além disso, em qualquer caso, você ainda pode executar todas essas coisas com /bin/sh -c

Melhoria ligeira da resposta da int_ua

Então, agora, podemos ver que o padrão ssh user@server -t 'command1;shell' funciona melhor. Exceto por haver um pequeno detalhe: /bin/sh -c process ainda está lá, então por que não executar bash com exec para substituir esse processo?

 ssh [email protected] -t 'who;exec bash'
    
por Sergiy Kolodyazhnyy 21.02.2016 / 08:22
5

Apenas a execução de bash deve ser suficiente:

 sshpass -f <password_file> ssh <user@ipaddress> 'who; bash';
    
por int_ua 21.02.2016 / 04:43
3

Esta é uma resposta, mas definitivamente não é a resposta.

Descobri que sshd (o daemon para serviços ssh no host remoto) executará comandos em ~ / .ssh / rc na conexão. Acabei de criar esse arquivo e adicionei who , e agora uma lista de usuários é exibida toda vez que faço uma conexão remota e ainda recebo um shell de login.

No host remoto:

File ~/.ssh/rc:

#!/bin/bash

# This file is executed by sshd when a remote connection is started over ssh
who

No cliente:

In file ~/.bash_aliases:

#!/bin/bash

# ssh to the linux lab. Takes hostnames defined in ~/.ssh/config as 
# parameters
function sshll()
{
    if [ "$@" ]
      echo "Connecting to hostname $@";
      sshpass -f <password_file> ssh $@;
    else
      echo "Connecting to default host";
      sshpass -f <password_file> ssh <user@ipaddress>;
    fi
}

Ainda estou interessado em saber como fazer isso do lado do cliente, para outros usuários com problemas semelhantes que não podem usar o ~ / .ssh / rc por falta de permissões, ou qualquer outra razão.

    
por Michael Hoffmann 13.10.2015 / 21:24
3

a resposta do int_ua é o que eu usaria. Apenas para completar, se você pode editar seu próprio .profile ou .bashrc no servidor remoto, você pode acrescentar isto a qualquer um:

if [[ -n $SSH_TTY ]]
then
    who
fi

O SSH define várias variáveis, uma das quais é SSH_TTY - você pode testar essas variáveis para determinar se você está conectado via SSH. Restrições em ~/.ssh/rc não devem impedir você de usar isso.

Eu uso isso para definir o meu prompt (note como eu pulo o nome do host para shells locais):

if [[ -n $SSH_TTY ]]
then
    PS1="\u@\h:\w $ "
else
    PS1="\u:\w $ "
fi
    
O
por muru 21.02.2016 / 04:59