0

我有一个在后台运行的脚本。它打开与服务器的 SSH 连接并无限期地跟踪文件。当我让我的 mac 进入睡眠状态时,SSH 连接关闭。这是有问题的脚本:

#!/bin/sh

(ssh <user>@<ip> -o PermitLocalCommand=no  \
 ": > .irssi/fnotify ; tail -f .irssi/fnotify " | \
 while read heading message; do                   \
 growlnotify -s -t "${heading}" -m "${message}";  \
 done)&

那时,我必须运行ps aux | grep ssh,找到正确的进程并手动杀死它;这很乏味。所以我有几个问题和可能的答案:

  1. 有没有办法重命名脚本的进程名称,以便每次再次运行时都可以按名称杀死它?
  2. 否则,有没有办法pid在我执行脚本时存储它,然后在我再次运行它时将其杀死?

我相信第一个解决方案是不可能的,但值得一问。

对于第二个解决方案,我做了一些研究,我去了某个地方但还不够远......这是我所拥有的:

我设法获得pid了脚本本身,而不是特定的 SSH 连接。但据我所见,pid脚本的始终是<pid of ssh connection> - 1.

所以我需要将 1 添加到pid脚本中,但我无法做到这一点。但无论如何,这是一个可行的解决方案吗?

否则,请问有什么替代解决方案?

4

2 回答 2

1

你不需要做任何PID跟踪,让shell句柄ssh在一个循环中断开。

#!/bin/sh
while true ; do
    ssh -o BatchMode=yes user@host '
        : > ~/.irssi/notify
        tail -f ~/.irssi/notify
    ' | while read -r title message ; do
        growlnotify -s -t "$title" -m "$message"
    done
    sleep 5  # retry timeout
done

调整user@host并重试超时以品尝,保存在您的路径中,chmod +x 它,并在方便时运行,例如从xinitrc/后台运行,xsession或者如果您想观看输出则在一个术语中运行。

为了防止出现多个实例,您可以预先添加如下内容。

if [ -e /tmp/sshnotify.pid ] ; then
    read pid < /tmp/sshnotify.pid
    if kill -0 $pid > /dev/null 2>&1 ; then
        echo >&2 already running
        exit 1
    fi
fi
echo $$ > /tmp/sshnotify.pid
于 2013-10-17T13:35:17.297 回答
0

由于您使用的是 zsh,因此您可以通过设置ARGV0参数来设置 ssh 进程的名称。您可以通过将,ARGV0=WhateverNameYouWant放在ssh括号内来做到这一点。

在后台运行的最后一个进程的 PID 可用作$!,但由于您没有一个简单的命令来说明您正在后台运行,因此该命令不会是 ssh 进程的 PID。但是,我怀疑这可能是您用来查找脚本 PID 的内容。

您可以通过将其包装在外壳中来在外壳中进行数学运算$(( )),例如$(($! + 1)). 您可以在这些表达式中保留$一些变量引用,但这似乎不适用于$!. 但是,将 PID 加 1 并不是获取子进程 PID 的可靠方法;只需要一个不同的过程在错误的时间产生一个孩子就可以摆脱它。

于 2013-10-17T12:03:18.997 回答