linux - 为什么在 shell 脚本中调用 exec 时会生成已失效的进程?
问题描述
为什么在 shell 脚本中调用 exec 时会生成已失效的进程?
因为在启动 snmpd 之前应该设置和预加载一些额外的 configure 和 sharelib,
所以我像下面这样使用shell脚本,但问题是每次启动shell脚本时都会生成一个僵尸进程。
据我所知,exec会替换原来的shell进程26452,为什么会生成一个子进程26453变成僵尸?
$# ps -ef | grep snmpd
root 26452 12652 0 10:24 pts/4 00:00:00 snmpd udp:161,udp6:161 -f -Ln -I -system_mib ifTable -c /opt/snmp/config/snmpd.conf
root 26453 26452 0 10:24 pts/4 00:00:00 [snmpd_wapper.sh] <defunct>
如何避免僵尸进程,请帮助!
cat /home/xpeng/snmpd_wapper.sh
#!/bin/bash
( sleep 2;/opt/snmp/bin/snmpusm -v 3 -u myuser -l authNoPriv -a MD5 -A xpeng localhost create top myuser >/dev/null 2>&1; \
/opt/snmp/bin/snmpvacm -v 3 -u myuser -l authNoPriv -a MD5 -A xpeng localhost createSec2Group 3 top RWGroup >/dev/null 2>&1; \
/opt/snmp/bin/snmpvacm -v 3 -u myuser -l authNoPriv -a MD5 -A xpeng localhost createView all .1 80 >/dev/null 2>&1; \
/opt/snmp/bin/snmpvacm -v 3 -u myuser -l authNoPriv -a MD5 -A xpeng localhost createAccess RWGroup 3 1 1 all all none >/dev/null 2>&1 ) &
LIBRT=/usr/lib64
if [ "$(. /etc/os-release; echo $NAME)" = "Ubuntu" ]; then
LIBRT=/usr/lib/x86_64-linux-gnu
fi
echo $$>/tmp/snmpd.pid
export LD_PRELOAD=$LD_PRELOAD:$LIBRT/librt.so:/opt/xpeng/lib/libxpengsnmp.so
exec -a "snmpd" /opt/snmp/sbin/snmpd udp:161,udp6:161 -f -Ln -I -system_mib,ifTable -c /opt/snmp/config/snmpd.conf
解决方案
这是父进程wait
对任何子进程的责任。子进程从它死亡到父进程为它服务时将是一个僵尸wait
。
您启动了一个子进程,但随后您用于exec
替换父进程。新程序不知道它有孩子,所以它没有wait
。因此,子进程成为僵尸,直到父进程死亡。
这是一个 MCVE:
#!/bin/sh
sleep 1 & # This process will become a zombie
exec sleep 30 # Because this executable won't `wait`
您可以改为使用双叉:
#!/bin/sh
( # Start a child shell
sleep 1 & # Start a grandchild process
) # Child shell dies, grandchild is given to `init`
exec sleep 30 # This process now has no direct children
推荐阅读
- reactjs - 在没有外部依赖的情况下反应本机去抖钩子
- c# - 带有 id 的 ASP.NET WebAPI 2 版本控制 POST
- c# - 在 C# .NET Core 中检查文件权限
- xcode - 如何快速访问其他类中的变量?
- mongodb - mongodb - 集合的唯一字段覆盖文档
- python - Python Selenium:如何设置基于 DIV 的编辑器的文本?
- html - 如何修改包含在角度变量中并以 html 显示的字符串
- azure-data-factory - 长时间排队的复制活动
- c++ - 从照片中计算 3D 对象位置
- loops - 在嵌套的 for 循环中遍历特定的名称组合