为什么在 shell 脚本中调用 exec 时会生成失效进程?
why defunct process generate when call exec in shell script?
为什么在 shell 脚本中调用 exec 时会生成失效进程?
因为在启动 snmpd 之前应该设置和预加载一些额外的配置和 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
对于任何 child 进程,parent 进程对 wait
负责。 child 进程从它死亡到它的 parent wait
秒将成为僵尸。
您启动了一个 child 进程,但随后您使用 exec
替换了 parent 进程。新程序不知道它有children,所以它没有wait
。 child 因此成为僵尸,直到 parent 进程死亡。
这是一个 MCVE:
#!/bin/sh
sleep 1 & # This process will become a zombie
exec sleep 30 # Because this executable won't `wait`
您可以改为 double fork:
#!/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
为什么在 shell 脚本中调用 exec 时会生成失效进程?
因为在启动 snmpd 之前应该设置和预加载一些额外的配置和 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
对于任何 child 进程,parent 进程对 wait
负责。 child 进程从它死亡到它的 parent wait
秒将成为僵尸。
您启动了一个 child 进程,但随后您使用 exec
替换了 parent 进程。新程序不知道它有children,所以它没有wait
。 child 因此成为僵尸,直到 parent 进程死亡。
这是一个 MCVE:
#!/bin/sh
sleep 1 & # This process will become a zombie
exec sleep 30 # Because this executable won't `wait`
您可以改为 double fork:
#!/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