干净地杀死进程

干净地杀死进程

我需要让Linux Ubuntu平台自动启动并杀死一个进程,例如,如果时间是早上8点进程启动,如果时间是晚上7点进程被杀死,而且必须每天都这样,应该没问题,如果时间间隔容易改变。

我尝试在 crontab 中使用简单的代码:

28 12 * * * /home/pi/Desktop/start.sh
50 11 * * * pkill led.py

不要看时间,我尝试过更改它们,start.sh启动led.py脚本,但如果我使用pkill -9 -f led.py.该进程被终止,但 LED 不会关闭。如果我手动启动程序,然后用Ctrl+终止它c,LED 就会关闭。哪里有问题?为什么我不能终止进程并同时关闭 LED?

答案1

当您键入Ctrl+时c,通常会向进程发送“INT”信号。从signal(7)

  Signal     Value     Action   Comment
  ──────────────────────────────────────────────────────────────────────
  ...
  SIGINT        2       Term    Interrupt from keyboard

进程通常为此信号安装一个处理程序,允许它们在退出之前执行一些清理操作。就您的脚本而言led.py,听起来该处理程序关闭了 LED。

默认情况下,pkill发送kill“TERM”(15)信号。 (您还尝试发送“KILL”(9)。)这些信号导致led.py死机不太优雅,没有机会运行其整理功能。

为了led.py干净地完成,您应该发送“INT”(2)信号,

pkill -2 [process specifier]

pkill您的命令也crontab可能无法找到该进程,因为您提供的名称不是它正在搜索的名称。从pkill(1)

-f,--完整

图案通常仅与进程名称匹配。什么时候-F设置后,将使用完整的命令行。

由于您的脚本 ,led.py可能是一个 python 脚本,因此进程名称很简单python(或python3,或类似)。完整的命令行类似于python led.py,因此-f选项可以让您进行匹配。

pkill -2 -f led.py

答案2

我多年前就使用过这个函数:

function killit () {
for process in "$@"; do
    kill -0 $process &>/dev/null
    if [[ $? == 0 ]] ; then
        sudo kill $process #(sends a TERM, wait 5 seconds)
        sleep 5
        RUNNING=$(ps aux | tr -s " " "\t" | cut -f 2 | grep $process)
        if [[ $RUNNING ]] ; then
            echo "$0 WARNING: process $process still running, trying kill again"
            sudo kill $process #(yes, try again, wait 5 seconds)
            sleep 5
            RUNNING=$(ps aux | tr -s " " "\t" | cut -f 2 | grep $process)
            if [[ $RUNNING ]] ; then
                echo "$0 WARNING: process $process still running, trying kill -INT"
                sudo kill -INT $process  #(wait for it)
                sleep 5
                RUNNING=$(ps aux | tr -s " " "\t" | cut -f 2 | grep $process)
                if [[ $RUNNING ]] ; then
                    echo "$0 WARNING: process $process still running, trying kill -INT again"
                    sudo kill -INT $process  #(damn, still not dead?)
                    sleep 5
                    RUNNING=$(ps aux | tr -s " " "\t" | cut -f 2 | grep $process)
                    if [[ $RUNNING ]] ; then
                        echo "$0 WARNING: process $process still running, trying kill -KILL"
                        sudo kill -KILL $process #(same thing as -9)
                        sleep 5
                        RUNNING=$(ps aux | tr -s " " "\t" | cut -f 2 | grep $process)
                        if [[ $RUNNING ]] ; then
                            echo "$0 WARNING: process $process still running, trying kill -KILL again"
                            sudo kill -KILL $process #(something is wrong)
                            sleep 5
                            RUNNING=$(ps aux | tr -s " " "\t" | cut -f 2 | grep $process)
                            if [[ $RUNNING ]] ; then
                                echo "$0 WARNING: Can't kill process $process"
                                logger "$0 WARNING: Can't kill process $process"
                            fi
                        fi
                    fi
                fi
            fi
        fi
    fi
done
}

相关内容