使用 sed 查找并重新格式化登录日期(或者,如何终止空闲的 mosh-server 进程)

使用 sed 查找并重新格式化登录日期(或者,如何终止空闲的 mosh-server 进程)

我有一个杀死空闲 mosh-server 进程的老方法,但它在我的新 VPS 上不起作用。

以下是旧方法,我在 root 的 crontab 中运行该方法来清理已闲置 10 多天的 mosh 进程:

for tty in `w -sf | grep -P '\d\ddays mosh-server' | cut -c 10-15`; do kill -9 `ps -o pid= -t $tty`; done

问题是,在新的 VPS 上,这些进程没有 TTY,所以我无法通过 TTY 匹配并以此方式终止 mosh。以下是我目前得到的结果(顺便说一句,新的 VPS 在 Debian wheezy 上运行内核 3.2,旧 VPS 是之前的 Debian 版本)。

for loginday in `w | grep -P '\d\ddays.* mosh-server' | cut -c 34-40 | sed 's/^\([0-9]*\)\([a-zA-Z]*\).*$/\2 \1/'`; do echo $loginday; done

我尝试从“w”获取登录日期,然后将其与“ps”中的信息关联起来:

ps -C mosh-server -o bsdstart

因此,我可以关联在登录同一天启动的任何空闲 mosh-server 会话(在野外可能占 99.9%),然后通过这种方式使用“ps”获取 pid 来终止它们。

但是,“w”输出的登录日期如下:

03Oct13

我将其简单地剪切为“03Oct”。

'ps' 输出如下:

Oct 3

您可以在上面的 sed 命令中看到,这是不起作用的部分,我试图接收“03Oct”并输出“Oct 03”(当我让它工作时,我会处理零),但我无论如何都无法让 sed 工作在 for 循环内当我用'echo'测试它时它似乎起作用了:

echo 03Oct | sed 's/\([0-9]*\)\([a-zA-Z]*\).*/\2 \1/'

一旦我将 sed 命令粘贴到 for 循环中,会发生什么情况?

更好的是,有没有更好或者更简单的方法来做到这一点?鉴于分离的空闲 mosh-server 进程在 Linux 3.2 上没有我可以轻松关联的 TTY?编辑:另外,在安装了 libutempter 的系统上,mosh-server 将信息写入 utmp我认为它可能会很有用,但我不知道如何得到它。

答案1

您的echo测试与环路测试有两个重要区别:

  • 日期周围没有空格
  • 正则表达式缺少锚点

循环测试不起作用的部分原因是您没有考虑空格。另一个原因是您使用的量词*表示“零个或多个”,这会导致您想要一些数字,但实际上并非如此。要解决这个问题,您可以使用量词表示+“一个或多个”。我们将用它来表示字母字符。但是,由于您想消除前导零,我们可以对数字采取稍微不同的方向。

由于 GNU sed 支持扩展正则表达式,因此我们可以消除转义所有这些特殊字符以及我添加的字符。但请注意,该-r选项不可移植。此外,我将命名字符类替换为字母字符,以使正则表达式更具可读性,并使其与具有不同字符集的语言兼容。

sed -r 's/^ *((0)|([1-9]))([0-9])([[:alpha:]]+).*$/\5 \3\4/'

前导零在组 2 中被捕获并被丢弃。组 1 是两位数的前导数。当组 2 包含零时,组 3 为空(因为使用管道字符创建了交替)。

就目前而言utmplast mosh-server输出对您有用的东西吗(安装了 libutempter)?

另请参阅流程管理看看是否能找到有用的东西。

答案2

要执行比解析日期更精确的操作,您可以查看 /proc 文件系统。在 redhat 上,以下操作对我有用:

⚡ for pid in $(pgrep mosh-server -u $USER); do if [[ $(stat -c %Y /proc/$pid) -lt $(( $(date +%s) - 36000 )) ]]; then echo "$pid is probably stale";fi;  done
27831 is probably stale                                                                                                                                      
38041 is probably stale                                                                                                                                      
38669 is probably stale                                                                                                                                      

⚡ ps fux | grep mosh                                                                                                                                         
1524      2444  0.4  0.0 160352  4752 ?        S    08:27   0:00 mosh-server new -c 256 -s -l LANG=en_US.UTF-8 -- bash -lc use prod                          
1524     27831  0.0  0.0 161648  6288 ?        S    Apr05   0:02 mosh-server new -c 256 -s -l LANG=en_US.UTF-8 -- bash -lc use prod                          
1524     38041  0.0  0.0 159696  4332 ?        S    Apr04   0:03 mosh-server new -c 256 -s -l LANG=en_US.UTF-8 -- bash -lc use prod                          
1524     38669  0.0  0.0 161276  5920 ?        S    Apr04   0:37 mosh-server new -c 256 -s -l LANG=en_US.UTF-8 -- bash -lc use prod 

将 echo 改为 kill,将 36000 改为您想要的超时时间(以秒为单位)。如果您想对所有用户执行此操作,请删除 -u $USER 并以 root 身份运行它。

相关内容