OpenSSH tiene una opción llamada LocalCommand
que ejecuta un comando en el lado del cliente cuando realiza una conexión ssh. Desafortunadamente, ejecuta el comando antes de que se establezca la sesión ssh, no después. Pero eso me dio la idea de que de alguna manera podría lograr que el proceso anterior espere a que termine la sesión ssh. A pesar de que el proceso ssh es el PID principal del LocalCommand, resulta que todavía no es tan fácil.
Sin embargo, encontré algo que funciona para mí en MacOS X, y debería funcionar en (otros) BSD, si no en Linux. Escribí un pequeño programa en C que usa la kqueue()
interfaz para esperar en su propio ppid y luego ejecuta un comando provisto una vez que el proceso finaliza. (Código fuente a continuación, para aquellos que estén interesados).
Ahora solo tengo que hacer referencia a este programa en mi ~/.ssh/config
archivo:
host hp-switch*
PermitLocalCommand yes
LocalCommand ~/bin/wait4parent 'tput smam'
Y esto parece funcionar bien. Aquellos de ustedes en Linux ... Supongo que pueden probar el mismo tipo de sondeo buscando LocalCommand
el ppid y esperando que ese pid no se reutilice. (Ver /programming/1157700/how-to-wait-for-exit-of-non-children-processes )
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);
}