OpenSSH a une option appelée LocalCommand
qui exécute une commande côté client lorsque vous établissez une connexion ssh. Malheureusement, il exécute la commande avant l'établissement de la session ssh, pas après. Mais cela m'a donné l'idée que je pourrais d'une manière ou d'une autre obtenir le processus précédent d'attendre la fin de la session ssh. Malgré le fait que le processus ssh soit le PID parent de LocalCommand, il s'avère que ce n'est toujours pas si simple.
Cependant, j'ai trouvé quelque chose qui fonctionne pour moi sous MacOS X, et qui devrait fonctionner sur (d'autres) BSD, sinon Linux. J'ai écrit un petit programme C qui utilise l' kqueue()
interface pour attendre son propre ppid, puis exécuter une commande fournie une fois ce processus terminé. (Liste de code source ci-dessous, pour ceux qui sont intéressés.)
Il ne me reste plus qu'à référencer ce programme dans mon ~/.ssh/config
fichier:
host hp-switch*
PermitLocalCommand yes
LocalCommand ~/bin/wait4parent 'tput smam'
Et cela semble fonctionner très bien. Ceux d'entre vous sous Linux… Je suppose que vous pouvez essayer le même genre de chose en interrogeant LocalCommand
le ppid de et en espérant que ce pid ne soit pas réutilisé. (Voir /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);
}