简体   繁体   English

陷阱 docker 信号并停止 bash 中的进程不起作用

[英]Trap docker signal and stop process in bash not working

I have already read and try this我已经阅读并尝试了这个

I'm not able to gracefully stop my docker container, the container just stop and kill everything inside instead of run my trap handler, I have been trying to solve this 1 year or more.我无法优雅地停止我的 docker 容器,容器只是停止并杀死里面的所有东西而不是运行我的陷阱处理程序,我一直试图解决这个问题 1 年或更长时间。

This is my entrypoint这是我的入口点

ENTRYPOINT ["/home/sdtdserver/user.sh", "/home/sdtdserver/install.sh"]

This is one of the script that do preparations and then continue to other, user.sh这是做准备然后继续其他的脚本之一, user.sh

    #!/bin/bash
    exit_handler() {
            # Execute the  shutdown commands
            echo "[INFO] Stopping 7 Days To Die Server" >> /home/sdtdserver/log/console/sdtdserver-console.log
            su-exec sdtdserver /home/sdtdserver/sdtdserver stop
            exit
    }
    
    set -eu
    
    # Print info
    echo "
            =======================================================================
            USER INFO:
    
            UID: $PUID
            GID: $PGID
    
            MORE INFO:
    
            If you have permission problems remember to use same user UID and GID.
            Check it with "id" command
            If problem persist check:
            https://github.com/vinanrra/Docker-7DaysToDie/blob/master/README.md
            =======================================================================
    "
    
    # Set user and group ID to sdtdserver user
    groupmod -o -g "$PGID" sdtdserver  > /dev/null 2>&1
    usermod -o -u "$PUID" sdtdserver  > /dev/null 2>&1
    
    # Locale, Timezone
    localedef -i en_US -c -f UTF-8 -A /usr/share/locale/locale.alias en_US.UTF-8 && \
    ln -snf /usr/share/zoneinfo/$TimeZone /etc/localtime && echo $TimeZone > /etc/timezone
    
    # Apply owner to the folder to avoid errors
    chown -R sdtdserver:sdtdserver /home/sdtdserver
    
    # Start cron
    service cron start
    
    # Change user to sdtdserver
    su-exec sdtdserver "$@"
    
    # Trap specific signals and forward to the exit handler
    trap exit_handler SIGTERM
    
    # Keep script alive to trap SIGTERM
    while true; do
            sleep 10
    done

I think my problem come here: su-exec sdtdserver "$@" - Line 43我想我的问题出在这里: su-exec sdtdserver "$@" - 第 43 行

I'm using su-exec to execute the swap the user and execute the next scripts as other user, and maybe that's the problem, I have been thinking too to move the user.sh script to somewhere where the script will be executed when it's started without using the entrypoint in the Dockerfile and instead swap to my other script install.sh and even remove the use of su-exec and reformat everything in one script (I don't like this idea tbh)我正在使用 su-exec 执行交换用户并以其他用户身份执行下一个脚本,也许这就是问题所在,我也一直在考虑将 user.sh 脚本移动到脚本将在其执行时执行的地方开始时不使用 Dockerfile 中的入口点,而是切换到我的其他脚本install.sh甚至删除 su-exec 的使用并在一个脚本中重新格式化所有内容(我不喜欢这个想法 tbh)

#!/bin/bash
rootDir=$(dirname "$(readlink -f "${BASH_SOURCE[0]}")")
scriptsDir="${rootDir}/scripts"

# Show log function
show_log () {
   i="0"
      # -F = --follow=name --retry
      tail -F /home/sdtdserver/log/console/sdtdserver-console.log
}

test_alert () {
   if [ "${TEST_ALERT,,}" == 'yes'  ]; then
      source $scriptsDir/server_alerts.sh
   fi
}

# Check requeriments

# Check if script is missing
if [ ! -f sdtdserver ]; then
   source $scriptsDir/check_script.sh
fi

# Check if server have been installed
if [ ! -f serverfiles/DONT_REMOVE.txt ]; then
   source $scriptsDir/first_install.sh
fi

# Crontab
echo "# Crontab file" > crontab.txt

if [ "${BACKUP,,}" == 'yes'  ]; then
   source $scriptsDir/crontab/backup.sh
fi

if [ "${MONITOR,,}" == 'yes'  ]; then
   source $scriptsDir/crontab/monitor.sh
fi

echo "# Don't remove the empty line at the end of this file. It is required to run the cron job" >> crontab.txt

crontab crontab.txt

rm crontab.txt

# Use of case to avoid errors if used wrong START_MODE
case $START_MODE in
   0)
      exit
   ;;
   1)
      source $scriptsDir/server_start.sh
      test_alert
      show_log
   ;;
   2)
      source $scriptsDir/server_update.sh
      exit
   ;;
   3)
      source $scriptsDir/server_update.sh
      source $scriptsDir/server_start.sh
      test_alert
      show_log
   ;; 
   4)
      source $scriptsDir/server_backup.sh
      exit
   ;;
   *)
      source $scriptsDir/check_startMode.sh
      exit
   ;;
esac

This is top command inside the container:这是容器内的顶级命令:

TOP-命令

This is the GitHub branch where I'm doing the testing: fix-exit这是我正在进行测试的 GitHub 分支: fix-exit

First thanks to everyone that try to help me and second I just don't want to copy and paste a code, I want to understand why isn't working, because that's the issue I have, I'm clueless and that's why I'm unable to fix it, even documentation it's appreciated.首先感谢所有试图帮助我的人,其次我不想复制和粘贴代码,我想了解为什么不起作用,因为这是我遇到的问题,我一无所知,这就是为什么我我无法修复它,即使是文档也值得赞赏。

The problem was that I wasn't running the script asynchronous, and bash was waiting to end the tail command at the end of install.sh (which was "endless"), here is the part of the code that was changed:问题是我没有异步运行脚本,并且 bash 正在等待在 install.sh 结束时结束 tail 命令(这是“无休止的”),这是更改的代码部分:

# Change user to sdtdserver
su-exec sdtdserver bash /home/sdtdserver/install.sh &
# If bash is waiting for a command to complete and receives a signal for which a trap has been set, the trap will not be executed until the command completes.
# When bash is waiting for an asynchronous command via the wait builtin,
# the reception of a signal for which a trap has been set will cause the 'wait' builtin to return immediately with an exit status greater than 128,
# immediately after which the trap is executed.
wait $!

Also, this man had the same problem, but I didn't know that the tail was the problem.另外,这个人也有同样的问题,但我不知道尾巴是问题所在。

SIGTERM signal not caught when the last process is tail 最后一个进程为尾时未捕获 SIGTERM 信号

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM