小白教程

 找回密码
 立即注册
查看: 5303|回复: 2

[已解决] 如何从python脚本中杀死以root身份运行的bash脚本?

[复制链接]

176

主题

185

帖子

663

积分

管理员

Rank: 9Rank: 9Rank: 9

积分
663
发表于 2021-5-17 06:01:09 | 显示全部楼层 |阅读模式
不知道这是否是问这个问题的最佳地点,但是过去一周来我一直在Stack Exchange和其他论坛上查找,但仍然没有找到可行的解决方案。
我需要从python脚本中优雅地杀死bash脚本,到目前为止,我无法使其正常工作。
我在运行最新版本的RasPiOS和Python3的Raspberry Pi Zero W上运行此程序。
我在从init.d启动时自动运行python3脚本(它以root身份运行)。在那个python脚本中,我调用bash脚本也开始(它也以root身份运行)。
python脚本正在运行步进电机,bash脚本正在使用Pi摄像头运行timelapse系列。
目标是创建从日出到日落的全景间隔拍摄视频。我需要两个脚本并行运行,以便彼此独立地控制帧速率和平移速度。
我要完成的工作是:
在启动时,自动启动马达摇摄,然后启动相机拍照。
步进电机完成摇摄后,然后优雅地终止正在运行相机的bash脚本。(这就是我遇到的问题)
然后让电动机返回到其初始位置。
然后关闭Pi。
这是我正在使用的python脚本...请注意,我尝试用来杀死timelapse的2个(许多)解决方案已经删除.sh bash脚本已删除,因为我无法使它们都无法工作... python脚本结束后,timelapse.sh脚本仍在运行。我为这种草率而道歉,我是python编程的新手。
  1. #!/usr/bin/python3

  2. from adafruit_motorkit import MotorKit
  3. from adafruit_motor import stepper
  4. from time import sleep
  5. import subprocess
  6. from subprocess import call
  7. #import psutil
  8. #import os, signal

  9. kit = MotorKit()

  10. # this starts the timelapse.sh script
  11. subprocess.Popen(['/bin/bash', './timelapse.sh'])

  12. #this is the slow east to west pan while pics are taken during timelapse using 5V 28BYJ-48 1:64 gear ratio stepper motor
  13. for j in range(22400):
  14.     for i in range(1):
  15.         kit.stepper1.onestep(direction=stepper.FORWARD, style=stepper.MICROSTEP)
  16. #set time between motor steps
  17.     sleep(2.41)   #timing for 270 degree (22400 steps) 15 hour pan with 16 microstepping

  18. # this kills the timelapse.sh script to stop taking pictures (didn't work)
  19. #PROCNAME = "timelapse.sh"
  20. #for proc in psutil.process_iter():
  21.     # check whether the process name matches
  22. #    if proc.name() == PROCNAME:
  23. #        proc.kill()

  24. #this kills the timelapse.sh script to stop taking pictures (didn't work)
  25. #def check_kill_process(timelapse):
  26. #    for line in os.popen("ps ax | grep " + pstring + " | grep -v grep"):
  27. #        fields = line.split()
  28. #        pid = fields[0]
  29. #        os.kill(int(pid), signal.SIGKILL)

  30. #this returns the stepper motor to starting position
  31. for i in range(1400):
  32.    kit.stepper1.onestep(direction=stepper.BACKWARD, style=stepper.DOUBLE)

  33. #this shuts down the pi to wait for next reboot via the wittypi3 power controller
  34. call("sudo nohup shutdown -h now", shell=True)
复制代码
到目前为止,除了能够在树莓派关闭之前正常地杀死timelapse.sh脚本之外,我已经完成了所有工作。
我宁愿使用脚本名称来执行此操作,而不是尽可能使用它的PID#...只是为了简化操作?
任何帮助或建议,将不胜感激。就像我说的那样,我是python的新手,所以请您在回答和示例中都非常简洁。
谢谢你

本帖寻求最佳方案

 蓝色月光2021-5-17 06:02发表回复被小白教程采纳,幸运的获得奖励 C币 5

在Linux上 详细答案»

回复

使用道具 举报

1

主题

3

帖子

7

积分

新手上路

Rank: 1

积分
7
发表于 2021-5-17 06:02:18 | 显示全部楼层
我试图做的...
  1. import psutil
  2. # this kills the timelapse.sh script to stop taking pictures (didn't work)
  3. PROCNAME = "timelapse.sh"
  4. for proc in psutil.process_iter():
  5.     # check whether the process name matches
  6.     if proc.name() == PROCNAME:
  7.         proc.kill()
复制代码
但这没有用。python脚本结束后,timelapse.sh脚本仍在运行,并且我没有收到任何错误,让我知道它无法结束bash脚本。我意识到它失败的唯一方法是,在python脚本结束后,仍有图片被写入SD卡。我使用“ ps aux”进行了验证,仍然可以看到timelapse.sh进程正在运行。
我在想也许是因为它以root身份在后台运行?我不知道。它需要以root用户身份运行,因为如果我以用户身份运行脚本,然后在一切运行时通过SSH进入Pi,它将导致脚本“暂停”,直到我结束SSH登录会话为止。
回复

使用道具 举报

1

主题

5

帖子

11

积分

新手上路

Rank: 1

积分
11
发表于 2021-5-17 06:02:50 | 显示全部楼层
在Linux上
  1. #! /usr/bin/env python3
  2. import subprocess
  3. import os

  4. def get_pid(name):
  5.     return subprocess.check_output(['pidof', name])

  6. info = get_pid('bash').split()
  7. pid = int(info[0])
  8. print(pid)

  9. os.kill(pid, True)
复制代码


回复

使用道具 举报

您需要登录后才可以回帖 登录 | 立即注册

本版积分规则

Archiver|手机版|小黑屋|小白教程 ( 粤ICP备20019910号 )

GMT+8, 2024-9-20 14:52 , Processed in 0.122597 second(s), 23 queries .

Powered by Discuz! X3.4

© 2001-2017 Comsenz Inc. Template By 【未来科技】【 www.wekei.cn 】

快速回复 返回顶部 返回列表