OpenSSHには、LocalCommandssh接続を行うときにクライアント側でコマンドを実行するというオプションがあります。残念ながら、sshセッションが確立される前ではなく、前にコマンドを実行します。しかし、これにより、前のプロセスでsshセッションが終了するのを待つことができたのではないかと考えました。sshプロセスがLocalCommandの親PIDであるという事実にもかかわらず、それはまだそれほど簡単ではないことが判明しました。
ただし、MacOS Xで動作するものを見つけたため、Linuxでなくても(その他の)BSDで動作するはずです。kqueue()インターフェイスを使用して独自のppidを待機し、そのプロセスが終了したら指定されたコマンドを実行する小さなCプログラムを作成しました。(興味のある方のために、以下のソースコードリスト)
今、私は自分の~/.ssh/configファイルでこのプログラムを参照する必要があります:
host hp-switch*
PermitLocalCommand yes
LocalCommand ~/bin/wait4parent 'tput smam'
そして、これはうまく機能するようです。Linuxをお使いLocalCommandの方… のppidをポーリングして同じ種類のことを試すことができ、そのpidが再利用されないことを願っています。(/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);
}