用于监视和警告新的孤立 pid 的脚本

用于监视和警告新的孤立 pid 的脚本

您将如何检测新孤立的 pid 并发出警报?我想要 cron 一个脚本,每天检查一次特定用户的任何孤立 pid (PPID = 1),并且仅在检测到新的孤立进程时发出警报。

例如 ps -efa 输出 grepping 查找“用户”的孤立 pid

第一天

   user  1111111        1   0   Dec 18      -  0:00 command <--- send email about this pid

第二天

   user  1111111        1   0   Dec 18      -  0:00 command
   user  2222222        1   0   Dec 14      -  0:00 command <--- send email about this pid

答案1

我将分两步处理:1. 检测孤儿,2. 在发现新的孤儿时设置警报。

1. 发现孤儿

你可以从这样的事情开始:

ps -eo pid,ppid,ruser,stat,command  

这将为您提供一个列出所有进程的表格,其中包含此处列出的 5 个输出的标题(pid、ppid、ruser、stat、command)。请参阅 部分,了解这 5 个输出字段STANDARD FORMAT SPECIFIERSman ps说明。

输出的连续管道grep可用于过滤列表,或者awk可能更有效地捕获所需的进程;例如:

ps -eo pid,ppid,ruser,stat,command | awk '{ if ($2 == 1 && $3 == "pi") print $0 "\n";}'
  926     1 pi       Ss   /lib/systemd/systemd --user

此处,打印输出的任意行的awk整行/记录 ( )$0ps如果第二个字段 ( $2)ppid的值为1,第三个字段 ( $3) 是用户的字符串(pi在本例中)。在我的系统上运行它产生了上面显示的结果。

但现在它得到了棘手的stat... AFAIK,该字段本身没有任何值来标识孤儿过程;即,其父进程已死亡,但已被该init进程采用 - 其pid= 1。您可以检查PROCESS STATE CODES部分man ps以查看该字段的可能值stat。值为“Z" 表示僵尸进程 - 这是类似于孤儿,但又不同

总而言之,ps无法明确告诉我们一个进程是否是孤儿进程,因此我们必须将上述命令的输出视为嫌疑人名单有待进一步调查。

根据您的用户和系统,您也许能够排除一些过程基于stat代码或command字段的值。例如,上面的命令通过=找到了一个进程 ( systemd) ;这个过程不是一个孤儿。 AFAICT,上述命令输出的 5 个参数为实现您的目标提供了合理的基础。statSsps

2. 当发现新的孤儿时设置警报

以下是建议的方法使用设置警报孤儿检测上面步骤 1 中的命令。

将使用两 (2) 个文件:OrphansOfRecord、 和OrphansOfTheDay. OrphansOfTheDay 将生成如下:

ps -eo pid,ppid,ruser,stat,command | awk '{ if ($2 == 1 && $3 == "pi") print $0 "\n";}' > OrphansOfTheDay

一旦生成, 的每一行OrphansOfTheDay都会与 ; 的每一行进行比较OrphansOfRecord。即对于以下中的每一行OrphansOfTheDay

  • 如果在 中找不到该行OrphansOfRecord,则它是一个新的孤立行,并且设置了警报。
  • 如果没有NEW Orphans,则不设置警报;即清除孤儿后不会发出警报

一个新的孤儿进程定义如下:

  • pid是新的或者command是新的
awk 'NR == FNR{a[$5]b[$1];} !($5 in a)||!($1 in b){print "ALERT" > "alertfile"; close ("alertfile")}' OrphansOfRecord OrphansOfTheDay

解析这个awk命令:

  • NR == FNR是一个状况in awk- 评估 TRUE 的条件第一个文件正在读取参数中列出的内容 -OrphansOfRecord在本例中。读取第一个文件后,条件评估结果为 FALSE。

  • 虽然,NR == FNR这是真的,行动 {a[$5]b[$1];}被执行。此操作将每行的字段$5( command) 和$1( )值分别存储在数组和中。例如,如果文件中有 3 行(或记录),则当此命令完成时,&将分别包含 3 个元素。pidOrphansOfRecordabOrphansOfRecordab

  • 读取 中的所有行后OrphansOfRecordNR == FNR变为 false,并awk开始读取第二个文件OrphansOfTheDayOrphansOfTheDay读取第一行后,读取第二行状况被评价为:!($5 in a)||!($1 in b).此条件$5将该行中的值与数组中的值进行比较a,并将$1同一行中的值与数组中的值进行比较b。请注意,状况测试不匹配$5a 或者A匹配$1b.

  • 这将继续awk测试 的每一行OrphansOfTheDay。当第2次状况为真,第二个行动被执行:{print "ALERT" > "alertfile"; close ("alertfile")}.alertfile如果该操作尚不存在,则通过将其重定向到print "ALERT"并关闭它来创建该操作alertfile以确保刷新输出缓冲区。

“警报”输出可用于表示已发现新的可疑孤儿。 “警报”的存在alertfile或其内容可用于确定是否需要发送电子邮件。

至此,OrphansOfTheDay已处理完毕,如果发现可疑孤儿,则会创建“警报”。仍有两件事需要完成:

  1. 写给:OrphansOfTheDayOrphansOfRecord
mv OrphansOfTheDay OrphansOfRecord
  1. 如果设置了“警报”,则会发送电子邮件并alertfile清除:
if [ -e alertfile ] 
then 
   mail -s "ALERT: NEW ORPHAN FOUND" pi < OrphansOfRecord 
   rm alertfile
fi

圣诞节快到了,我还有几天时间没有时间。我会尽快将脚本放在一起 - 或者您可以自己继续。

相关内容