Executar comando local após a conclusão da sessão ssh

5

Eu tenho alguns switches da HP em que eu faço login via ssh. Os switches enviam um comando de terminal para desabilitar a quebra de linha ("rmam" no jargão do terminfo), mas depois não reativam, o que estraga meu terminal depois que eu saio da sessão ssh. Eu posso consertar o terminal executando tput smam .

Existe alguma maneira de fazer o ssh executar automaticamente esse comando depois que minha sessão ssh termina?

Ele não me mataria para executá-lo como um autocommand shell, ou alias ssh para sempre executar esse comando depois, mas eu prefiro resolver o problema via ssh para que eu possa limitar o comando para ser apenas executar depois de me conectar a hosts conhecidos como ruins.

Meu cliente ssh é OpenSSH_6.2p2, mas posso mudar ou atualizar se houver um novo recurso em algum lugar.

    
por wfaulk 30.10.2014 / 17:35

2 respostas

5

O OpenSSH tem uma opção chamada LocalCommand que executa um comando no lado do cliente quando você faz uma conexão ssh. Infelizmente, ele executa o comando antes de a sessão ssh ser estabelecida, não depois. Mas isso me deu a ideia de que eu poderia, de alguma forma, conseguir que o processo precedente esperasse que a sessão ssh terminasse. Apesar do fato de que o processo ssh é o PID pai do LocalCommand, verifica-se que ainda não é tão fácil assim.

No entanto, eu encontrei algo que funciona para mim no MacOS X, e deveria funcionar em (outros) BSDs, se não no Linux. Eu escrevi um pequeno programa C que usa a interface kqueue() para esperar em seu próprio ppid e, em seguida, executar um comando fornecido uma vez que o processo saia. (Código fonte abaixo, para quem estiver interessado.)

Agora, basta referenciar este programa no meu arquivo ~/.ssh/config :

host hp-switch*
 PermitLocalCommand yes
 LocalCommand ~/bin/wait4parent 'tput smam'

E isso parece funcionar bem. Aqueles de vocês no Linux… Eu acho que você pode tentar o mesmo tipo de coisa pesquisando o ppid de LocalCommand e esperando que aquele pid não seja reutilizado. (Veja link )

wait4parent.c:

#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#include <sys/types.h>
#include <sys/event.h>
#include <sys/time.h>

int main(int argc, char **argv) {
    pid_t ppid, fpid;
    struct kevent kev;
    int kq;
    int kret;
    struct timespec timeout;

    if ( argc > 2 ) {
        fprintf(stderr, "Please quote the command you want to run\n");
        exit(-1);
    }

    ppid = getppid();

    fpid = fork();
    if ( fpid == -1 ) {
        perror("fork");
        exit(-1);
    }

    if ( fpid != 0 ) {
        exit(0);
    }

    EV_SET(&kev, ppid, EVFILT_PROC, EV_ADD, NOTE_EXIT, 0, 0);

    kq = kqueue();
    if ( kq == -1 ) {
        perror("kqueue");
        exit(-1);
    }

    kret = kevent(kq, &kev, 1, NULL, 0, NULL);
    if ( kret == -1 ) {
        perror("kevent");
        exit(-1);
    }

    timeout.tv_sec = ( 8 /*hours*/ * 60 /*minutes per hour*/ * 60 /*seconds per minute*/ );
    timeout.tv_nsec = 0;

    kret = kevent(kq, NULL, 0, &kev, 1, &timeout);
    if ( kret == -1 ) {
        perror("kevent");
        exit(-1);
    }

    if ( kret > 0 ) {
        system(argv[1]);
    }
    /* ( kret == 0 ) means timeout; don't do anything */

    exit(0);
}
    
por 30.10.2014 / 23:03
4

Você pode criar um simples wrapper ssh para isso e especificar comandos para serem executados após o ssh, por exemplo

nox:~$ fssh foo
foo:~$ id
uid=0(root) gid=0(root) groups=0(root)
foo:~$ exit
logout
Connection to 1.2.3.4 closed.
Thu Oct 30 19:01:35 CET 2014
nox:~$ cat bin/fssh 
#!/bin/bash

eval ssh '$@'
rc=$?
date
exit "$rc"
    
por 30.10.2014 / 19:02

Tags