Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/linux/22.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
bash脚本在启动另一个相同的python脚本后终止python脚本_Python_Linux_Bash - Fatal编程技术网

bash脚本在启动另一个相同的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 &

我启动了一个python脚本,然后过了一段时间我想杀死它。但在杀死它之前,我想开始这个脚本的另一个副本,然后在启动新脚本后杀死上一个脚本。我想在循环中这样做

这是我的代码,我只需要一个干净的方法来杀死脚本。我不想使用超时

#!/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),它不能被捕获并强制系统终止应用程序。