我有一些通过 ssh 登录的 HP 交换机。交换机发送一个终端命令来禁用换行(terminfo 用语中的“rmam”),但随后无法重新启用它,这在我退出 ssh 会话后搞砸了我的终端。我可以通过运行来修复终端tput smam
。
有没有办法让 ssh 在我的 ssh 会话结束后自动运行该命令?
将它作为 shell 自动命令运行,或ssh
之后始终运行该命令的别名不会杀死我,但我更愿意通过 ssh 解决问题,以便我可以限制命令仅在我连接到后运行-糟糕的主机。
我的 ssh 客户端是 OpenSSH_6.2p2,但如果某处有新功能,我可以更改或更新。
OpenSSH 有一个名为的选项LocalCommand
,当您建立 ssh 连接时,它会在客户端运行命令。不幸的是,它在 ssh 会话建立之前而不是之后运行命令。但这给了我一个想法,我可能会以某种方式让前面的进程等待 ssh 会话结束。尽管 ssh 进程是 LocalCommand 的父 PID,但事实证明它仍然不是那么容易。
但是,我确实找到了在 MacOS X 下对我有用的东西,并且应该在(其他)BSD 上工作,如果不是 Linux。我编写了一个小 C 程序,它使用kqueue()
接口等待自己的 ppid,然后在该进程退出后运行提供的命令。(源代码列表如下,有兴趣的可以看看。)
现在我只需要在我的~/.ssh/config
文件中引用这个程序:
host hp-switch*
PermitLocalCommand yes
LocalCommand ~/bin/wait4parent 'tput smam'
Run Code Online (Sandbox Code Playgroud)
这似乎工作得很好。那些在 Linux 上的人……我想你可以通过轮询LocalCommand
'ppid来尝试同样的事情,并希望该 pid 不会被重用。(见/sf/ask/81039031/)
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);
}
Run Code Online (Sandbox Code Playgroud)
归档时间: |
|
查看次数: |
3442 次 |
最近记录: |