ssh 会话结束后运行本地命令

ssh 会话结束后运行本地命令

我有一些 HP 交换机,我通过 ssh 登录。交换机发送终端命令来禁用换行(terminfo 用语中为“rmam”),但无法重新启用它,这导致我退出 ssh 会话后终端出现问题。我可以通过运行 来修复终端tput smam

有什么方法可以让 ssh 在会话结束后自动运行该命令?

将其作为 shell 自动命令运行或以别名始终在之后运行该命令不会杀死我ssh,但我更愿意通过 ssh 解决问题,以便我可以限制该命令仅在我连接到已知的坏主机后运行。

我的 ssh 客户端是 OpenSSH_6.2p2,但如果某处有新功能,我可以更改或更新。

答案1

OpenSSH 有一个名为的选项,LocalCommand当你建立 ssh 连接时,它会在客户端运行一个命令。不幸的是,它运行命令ssh 会话建立时,而不是之后。但这让我想到,我可能能够以某种方式让前面的进程等待 ssh 会话结束。尽管 ssh 进程是 LocalCommand 的父 PID,但事实证明这仍然不是那么容易。

但是,我确实找到了在 MacOS X 下可以运行的东西,如果不是 Linux,它应该可以在(其他)BSD 上运行。我编写了一个小型 C 程序,该程序使用该kqueue()接口等待其自己的 ppid,然后在该进程退出后运行提供的命令。(源代码列表如下,供有兴趣的人参考。)

现在我只需要在我的~/.ssh/config文件中引用该程序:

host hp-switch*
 PermitLocalCommand yes
 LocalCommand ~/bin/wait4parent 'tput smam'

这似乎工作得很好。那些使用 Linux 的人……我想你可以尝试同样的事情,通过轮询LocalCommandppid 并希望该 pid 不会被重复使用。(参见https://stackoverflow.com/questions/1157700/how-to-wait-for-exit-of-non-children-processes

等待4父母.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);
}

答案2

您可以为此制作简单的 ssh 包装器,并在其中指定在 ssh 之后运行的命令,例如

nox:~$ fssh foo
foo:~$ id
uid=0(根) gid=0(根) groups=0(根)
foo:~$ 退出
登出
与 1.2.3.4 的连接已关闭。
2014 年 10 月 30 日星期四 19:01:35 CET
nox:〜$ cat bin/fssh
/bin/bash #!/bin/bash

评估 ssh'$@'
rc=$?
日期
退出“$rc”

相关内容