我需要让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
}