bash脚本在启动另一个相同的python脚本后终止python脚本
我启动了一个python脚本,然后过了一段时间我想杀死它。但在杀死它之前,我想开始这个脚本的另一个副本,然后在启动新脚本后杀死上一个脚本。我想在循环中这样做 这是我的代码,我只需要一个干净的方法来杀死脚本。我不想使用超时bash脚本在启动另一个相同的python脚本后终止python脚本,python,linux,bash,Python,Linux,Bash,我启动了一个python脚本,然后过了一段时间我想杀死它。但在杀死它之前,我想开始这个脚本的另一个副本,然后在启动新脚本后杀死上一个脚本。我想在循环中这样做 这是我的代码,我只需要一个干净的方法来杀死脚本。我不想使用超时 #!/bin/bash while true do echo "starting FIRST Consumer.py : $(date +"%T")" python3 /home/irum/Desktop/Marketsyc/Consumer.py &
#!/bin/bash
while true
do
echo "starting FIRST Consumer.py : $(date +"%T")"
python3 /home/irum/Desktop/Marketsyc/Consumer.py &
sleep 20
echo "starting SECOND Consumer.py : $(date +"%T")"
python3 /home/irum/Desktop/Marketsyc/Consumer.py &
# Here I want to kill FIRST Consumer.py
sleep 20
# Here I want to kill SECOND Consumer.py
done
每次启动后台进程时,
bash
都会维护一个作业列表,ID从1开始
jobs
builtin列出了后台作业
在您的情况下,您将添加kill%1
以终止第一个启动的后台作业,然后添加kill%2
==编辑==您的脚本变成:
#!/bin/bash
while : ; do
echo "starting FIRST Consumer.py : $(date +"%T")"
python3 /home/irum/Desktop/Marketsyc/Consumer.py &
sleep 20
echo "starting SECOND Consumer.py : $(date +"%T")"
python3 /home/irum/Desktop/Marketsyc/Consumer.py &
kill %1
sleep 20
kill %2
wait
done
您可以获取第一个进程的PID,然后将其终止:
#!/bin/bash
while true
do
echo "starting FIRST Consumer.py : $(date +"%T")"
python3 /home/irum/Desktop/Marketsyc/Consumer.py &
pid=$!
sleep 20
echo "starting SECOND Consumer.py : $(date +"%T")"
python3 /home/irum/Desktop/Marketsyc/Consumer.py &
new_pid=$!
# Here I want to kill FIRST Consumer.py
kill "$pid"
sleep 20
# Here I want to kill SECOND Consumer.py
kill "$new_pid"
done
在
bash
中有两个特殊的后台工作:+
和-
。您可以在作业
命令的输出中看到它们:
$ sleep 10 &
$ sleep 20 &
$ sleep 30 &
$ jobs
[1] Running sleep 10 &
[2]- Running sleep 20 &
[3]+ Running sleep 30 &
+
是最近运行的作业<代码>-是+
之前的最新作业。如果您终止作业或开始新作业,两者都将更新。因此,您可以按如下方式完成脚本:
#!/bin/bash
while true; do
echo "starting FIRST Consumer.py : $(date +%T)"
python3 /home/irum/Desktop/Marketsyc/Consumer.py &
sleep 20
echo "starting SECOND Consumer.py : $(date +%T)"
python3 /home/irum/Desktop/Marketsyc/Consumer.py &
kill %- # kill FIRST Consumer.py
sleep 20
kill %+ # kill SECOND Consumer.py
done
只有当Consumer.py
运行时间始终超过20秒时,此功能才能可靠工作。如果Consumer.py
可以在20秒结束之前终止,那么我们可能会终止错误的作业。要解决此问题,可以使用(python3…/Consumer.py;sleep-inf)和而不是python3…/Consumer.py&
。sleep inf
将阻止作业自行终止 我会这么做的
#!/bin/bash
function check_pid() {
if /bin/ps -p $1 > /dev/null
then
kill $1
else
echo "not running"
fi
}
while true
do
echo "starting FIRST Consumer.py : $(date +"%T")"
python3 /home/irum/Desktop/Marketsyc/Consumer.py &
pid1=$!
sleep 20
echo "starting SECOND Consumer.py : $(date +"%T")"
python3 /home/irum/Desktop/Marketsyc/Consumer.py &
pid2=$!
# Here I want to kill FIRST Consumer.py
check_pid $pid1
sleep 20
# Here I want to kill SECOND Consumer.py
check_pid $pid2
done
这样,仅当进程仍在运行时,进程才会被终止。您不想使用timeout 20 python3?是的,我使用了超时,但有时它不会杀死我的脚本。但是开始新的。一段时间后,我运行了8个脚本。您确定代码示例中的注释吗?(你是否颠倒了第二个和第一个?)我编辑了评论:pClean和kill是一种相互冲突的需求。其中kill的意思是“不惜一切代价停止”,clean的意思是“优雅地退出”。如果您的程序在发出SIGTERM
信号后没有退出,那么它就是行为不正常。在使用SIGKILL
之前修复python脚本。使用SIGKILL
的缺点包括,如果进程无法保存已消耗内容的状态,则会丢失状态。作业ID始终会增加<代码>%1
和%2
仅对第一次迭代正确。在第二次迭代中,您必须使用%3
和%4
。您可以使用$访问上一个作业的PID(而不是作业id)
@Socowi:由于循环结束时没有任何后台作业,因此ID始终为1和2。我的测试证实了这一点,你确定吗?我在bash4.4.19(1)和5.0.0(1)两个不同的系统上测试了我的声明。对于我来说,下面的脚本可以快速打印大于2的数字<代码>while:;执行睡眠10和睡眠20并杀死%1;杀死%2;乔布斯| wc-l;完成
。也许你是对的<代码>睡眠1&杀死%1;休眠2和作业创建作业ID%1和%2,但休眠1和终止%1;睡眠0.5;睡眠2&作业
使用作业id%1两次。似乎kill
是异步的,我们需要在终止一个旧作业和启动一个新作业之间稍作停顿,以便在启动新作业之前释放旧作业id。这是我喜欢在脚本中使用PID的原因。交互式作业管理是另一个怪兽。这个答案对我很有用,但当我添加了-9 to kill命令kill-9“$pid”
时,这个细节取决于你想杀死什么。默认情况下,kill
发送一个SIGTERM
信号(15),该信号可以被捕获和处理。它应该给应用程序一个写下状态并退出的机会。但是如果它没有退出,您可以始终使用SIGKILL
(9),它不能被捕获并强制系统终止应用程序。