OpenSSH memiliki opsi yang disebut LocalCommandyang menjalankan perintah di sisi klien ketika Anda membuat koneksi ssh. Sayangnya, ia menjalankan perintah sebelum sesi ssh dibuat, bukan sesudahnya. Tapi itu memberi saya ide bahwa saya mungkin bisa mendapatkan proses sebelumnya untuk menunggu sesi ssh berakhir. Terlepas dari kenyataan bahwa proses ssh adalah induk PID dari LocalCommand, ternyata itu masih tidak mudah.
Namun, saya memang menemukan sesuatu yang bekerja untuk saya di bawah MacOS X, dan harus bekerja pada BSD (lainnya), jika bukan Linux. Saya menulis sebuah program C kecil yang menggunakan kqueue()antarmuka untuk menunggu pada ppid sendiri dan kemudian menjalankan perintah yang disediakan setelah proses itu keluar. (Daftar kode sumber di bawah ini, untuk mereka yang tertarik.)
Sekarang saya hanya perlu merujuk program ini di ~/.ssh/configfile saya :
host hp-switch*
PermitLocalCommand yes
LocalCommand ~/bin/wait4parent 'tput smam'
Dan ini sepertinya bekerja dengan baik. Bagi Anda di Linux ... Saya kira Anda dapat mencoba hal yang sama dengan polling untuk LocalCommandppid dan berharap pid itu tidak dapat digunakan kembali. (Lihat /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);
}