0

why defunct process generate when call exec in shell script?

Because some extra configure and sharelib should be set and preload before starting snmpd,

so I use shell script like bellow, but the problem is that a zombie process was generated every time when start the shell script.

as far as I know, exec will replace the original shell process 26452, why a child process 26453 generate and become zombie?

$# 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>

how to avoid the zombie process, pls help!

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
jackxie
  • 33
  • 1
  • 10

1 Answers1

1

It's a parent process' responsibility to wait for any child processes. The child process will be a zombie from the time it dies until the parent waits for it.

You started a child process, but then you used exec to replace the parent process. The new program doesn't know that it has children, so it doesn't wait. The child therefore becomes a zombie until the parent process dies.

Here's a MCVE:

#!/bin/sh
sleep 1 &      # This process will become a zombie
exec sleep 30  # Because this executable won't `wait`

You can instead do a 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
that other guy
  • 116,971
  • 11
  • 170
  • 194