SSH para dois endereços, use o que se conecta primeiro

5

Eu tenho um computador em casa (chame-o de franklin porque é assim que eu o chamo) que frequento do meu laptop de trabalho. Quando estou em casa, ssh para franklin.local e, quando estou no trabalho ou em qualquer outro lugar, ssh para remote.address.of.franklin.

Eu quero ter uma função no meu perfil que sempre se conecta da maneira correta para a situação. Minhas condições de rede geralmente mudam (com fio vs. sem fio, diferentes SSIDs, etc.), então prefiro não fazer isso detectando o estado da rede, mas sim:

  1. Se o franklin estiver disponível localmente, conecte-se localmente,
  2. else, conecte-se remotamente

Veja o que eu uso agora:

function franklin () {
    ping -c 5 "franklin.local" > /dev/null
    if [[ $? != 0 ]]
        then
        echo "franklin not available on local, so trying remote connection"
        ssh -p 22 remote.address.of.franklin
    else
        echo "franklin available on local network, so trying local connection"
        ssh [email protected]
    fi
}

O problema é que o ping leva tempo. A minha pergunta é: posso executar ambos os comandos ssh em simultâneo e, em seguida, utilizar automaticamente o que ligar primeiro?

    
por Zev Eisenberg 19.12.2012 / 16:50

3 respostas

4

Que tal experimentar um simples OR do seu shell?

ssh [email protected] || ssh -p 22 remote.address.of.franklin

Eu não estou realmente familiarizado com o ZSH, mas acho que a lógica de avaliação ainda seria preguiçosa, o que significa que a segunda parte só é avaliada se a primeira parte falhar. É claro que o primeiro comando pode parar por algum tempo tentando descobrir se franklin.local está disponível.

Você poderia atribuir esse comando a um alias para encurtá-lo (como você fez com a função).

    
por 19.12.2012 / 17:41
2

Eu uso nc em vez de ping:

franklin() {
    local host=franklin.local
    if nc -w1 $host 22 &>/dev/null; then
        echo "connecting locally"
    else
        echo "connecting remotely"
        host=remote.address.of.franklin
    fi
    ssh username@$host "$@"
}

Adicionei "$@" à chamada ssh. Isso permite que você execute rapidamente comandos remotos como

franklin uptime
    
por 19.12.2012 / 20:23
1

Acontece que eu estava mais perto da solução do que pensava. Eu tive uma suposição incorreta sobre como funciona a parte de pesquisa de endereço do ping. Eu pensei que, se eu tivesse um problema na rede, e o franklin.local não retornasse os pings, ele falharia e se conectaria remotamente. Acontece que, se franklin.local estiver na rede, ping -c 1 franklin.local retornará 0 e, se não, retornará 68, ambos imediatamente. Então a única mudança é a contagem do ping de 5 para 1 (eu também ajustei a ordem do script para fazer mais sentido):

function franklin
{
    ping -c 1 franklin.local &> /dev/null
    if [[ $? == 0 ]]; then
        echo "Connecting locally."
        ssh "[email protected]"
    else
        echo "Connecting remotely."
        ssh "remote.address.of.franklin"
    fi
}

Isso é significativamente mais rápido do que antes, e não muito mais lento do que apenas usar o comando ssh apropriado diretamente.

    
por 19.12.2012 / 17:41