您将如何检测新孤立的 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 SPECIFIERS
的man 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
整行/记录 ( )$0
ps
如果第二个字段 ( $2
)ppid
的值为1
,和第三个字段 ( $3
) 是用户的字符串(pi
在本例中)。在我的系统上运行它产生了上面显示的结果。
但现在它得到了棘手的stat
... AFAIK,该字段本身没有任何值来标识孤儿过程;即,其父进程已死亡,但已被该init
进程采用 - 其pid
= 1。您可以检查PROCESS STATE CODES
部分man ps
以查看该字段的可能值stat
。值为“Z" 表示僵尸进程 - 这是类似于孤儿,但又不同。
总而言之,ps
无法明确告诉我们一个进程是否是孤儿进程,因此我们必须将上述命令的输出视为嫌疑人名单有待进一步调查。
根据您的用户和系统,您也许能够排除一些过程基于stat
代码或command
字段的值。例如,上面的命令通过=找到了一个进程 ( systemd
) ;这个过程不是一个孤儿。 AFAICT,上述命令输出的 5 个参数为实现您的目标提供了合理的基础。stat
Ss
ps
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
是一个状况inawk
- 评估 TRUE 的条件第一个文件正在读取参数中列出的内容 -OrphansOfRecord
在本例中。读取第一个文件后,条件评估结果为 FALSE。虽然,
NR == FNR
这是真的,行动{a[$5]b[$1];}
被执行。此操作将每行的字段$5
(command
) 和$1
( )值分别存储在数组和中。例如,如果文件中有 3 行(或记录),则当此命令完成时,&将分别包含 3 个元素。pid
OrphansOfRecord
a
b
OrphansOfRecord
a
b
读取 中的所有行后
OrphansOfRecord
,NR == FNR
变为 false,并awk
开始读取第二个文件OrphansOfTheDay
。OrphansOfTheDay
读取第一行后,读取第二行状况被评价为:!($5 in a)||!($1 in b)
.此条件$5
将该行中的值与数组中的值进行比较a
,并将$1
同一行中的值与数组中的值进行比较b
。请注意,状况测试不匹配的$5
在a
或者A匹配的$1
在b
.这将继续
awk
测试 的每一行OrphansOfTheDay
。当第2次状况为真,第二个行动被执行:{print "ALERT" > "alertfile"; close ("alertfile")}
.alertfile
如果该操作尚不存在,则通过将其重定向到print "ALERT"
并关闭它来创建该操作alertfile
以确保刷新输出缓冲区。
“警报”输出可用于表示已发现新的可疑孤儿。 “警报”的存在alertfile
或其内容可用于确定是否需要发送电子邮件。
至此,OrphansOfTheDay
已处理完毕,如果发现可疑孤儿,则会创建“警报”。仍有两件事需要完成:
- 写给:
OrphansOfTheDay
OrphansOfRecord
mv OrphansOfTheDay OrphansOfRecord
- 如果设置了“警报”,则会发送电子邮件并
alertfile
清除:
if [ -e alertfile ]
then
mail -s "ALERT: NEW ORPHAN FOUND" pi < OrphansOfRecord
rm alertfile
fi
圣诞节快到了,我还有几天时间没有时间。我会尽快将脚本放在一起 - 或者您可以自己继续。