我正在尝试编写一个使用 ssh 连接进行“心跳”的 shell 脚本。我想在某个超时后(连接断开后)终止该连接的客户端和服务器端。
到目前为止我发现了什么:
要更改“ClientAliveCountMax”,我必须修改每台目标计算机上的 sshd_config(默认情况下禁用此选项)。
所以我的问题是 - 我是否也可以将“TCPKeepAlive”用于我的目的(无需更改源/目标机器上的任何其他内容)?
目标操作系统是 SLES11 SP2 - 但我认为这与此处无关。
我有时会对进程可以接收的所有信号感到困惑。据我了解,一个进程对这些信号中的每一个都有一个默认处理程序(信号处置),但它可以通过调用sigaction()
.
所以这是我的问题:是什么导致每个信号被发送?我意识到您可以通过-s
参数 to手动向正在运行的进程发送信号kill
,但是发送这些信号的自然情况是什么?例如,什么时候SIGINT
发送?
另外,对可以处理哪些信号有任何限制吗?甚至SIGSEGV
可以处理信号并将控制权返回给应用程序吗?
我希望能够通过 ssh 发送信号(SIGINT 是最重要的)。
这个命令:
ssh server "sleep 1000;echo f" > foo
Run Code Online (Sandbox Code Playgroud)
将在服务器上开始睡眠,并在 1000 秒后将 'f\n' 放在我本地机器上的文件 foo 中。如果我按 CTRL-C(即向 ssh 发送 SIGINT),它将终止 ssh,但不会终止远程服务器上的 sleep。我希望它杀死远程服务器上的睡眠。
所以我试过:
ssh server -t "sleep 1000;echo f" > foo
Run Code Online (Sandbox Code Playgroud)
但如果 stdin 不是终端,我会收到此错误:
Pseudo-terminal will not be allocated because stdin is not a terminal.
Run Code Online (Sandbox Code Playgroud)
然后 SIGINT 仍然没有转发。
所以我试过:
ssh server -t -t "sleep 1000;echo f" > output
Run Code Online (Sandbox Code Playgroud)
但是 foo 中的输出不是 'f\n' 而是 'f\r\n' 这在我的情况下是灾难性的(因为我的输出是二进制数据)。
在上面我使用“sleep 1000;echo f”,但实际上它是由用户提供的,因此它可以包含任何内容。然而,如果我们可以让它适用于“sleep 1000;echo f”,我们很可能让它适用于所有现实情况。
我真的不关心在另一端获得伪终端,但我一直无法找到任何其他方式让 ssh 转发我的 SIGINT。
还有其他方法吗?
编辑:
用户可以给出从 …