获取一个以自身为后台的 ssh 进程的 pid

dla*_*lin 13 shell-script background-process

所以我想调用两个后台ssh进程:

ssh -D localhost:8087 -fN aws-gateway-vpc1
ssh -D localhost:8088 -fN aws-gateway-vpc2
Run Code Online (Sandbox Code Playgroud)

这些网关没有让我设置authorized_keys 文件的好处,因此必须提示我输入交互式密码。这就是为什么我使用-f标志而不是 shell 的原因&,它只会在我交互式身份验证后才将进程后台运行。

在这种情况下,我似乎无法使用$!bash 变量来获取最近 [self] 后台进程的 pid。

如果被中断,我还有什么其他选择可以找到正确的 pid 以便稍后杀死?

小智 28

通过 grepping 查找 pid 可能容易出错。另一种选择是使用SSHControlPathControlMaster选项。通过这种方式,您将能够让 ssh 命令侦听控制套接字并等待来自后续 ssh 调用的命令。

尝试这个

ssh -D localhost:8087 -S /tmp/.ssh-aws-gateway-vpc1 -M -fN aws-gateway-vpc1
# (...)
# later, when you want to terminate ssh connection
ssh -S /tmp/.ssh-aws-gateway-vpc1 -O exit aws-gateway-vpc1
Run Code Online (Sandbox Code Playgroud)

exit命令可让您在不知道 PID 的情况下终止进程。如果您确实需要任何 PID,您可以使用以下check命令来显示它:

$ ssh -S /tmp/.ssh-aws-gateway-vpc1 -O check aws-gateway-vpc1
Master running (pid=1234)
Run Code Online (Sandbox Code Playgroud)

  • +1,比基于 ps 的解决方案可靠得多。“exit”命令消除了对 PID 来终止进程的需要,但我冒昧地在提到“check”命令时进行了编辑,这也回答了“如何获取 PID?”的问题。正如最初所问的那样。 (2认同)

ter*_*don 7

$!不工作,就像你说的,因为它并没有被当前shell中背景。事实上,该ssh进程甚至不是您启动它的 shell 的子进程。在我的拱门系统,至少,它运行作为PID的孩子1,该init过程。

因此,要获得 PID,您可以简单地使用ps

$ ssh -f  localhost sleep 100
$ ps aux | grep '[s]sh.*-f'
terdon   20648  0.0  0.0  43308   680 ?        Ss   12:15   0:00 ssh -f localhost sleep 100
Run Code Online (Sandbox Code Playgroud)

这告诉我 PID 是20648*

或者,更简单地,使用pgrep -f

$ pgrep -f 'ssh.*-f'
20648
Run Code Online (Sandbox Code Playgroud)

而且,杀死它(他们):

pkill -f 'ssh.*-f'
Run Code Online (Sandbox Code Playgroud)

*如果您想知道命令中的,请参阅问题。[s]grep