【问题标题】:How to control background process in linux如何在linux中控制后台进程
【发布时间】:2013-01-13 16:44:20
【问题描述】:

我需要在 Linux 中编写一个脚本,它可以使用一个命令启动后台进程并使用另一个命令停止该进程。

具体应用是为android取用户空间和内核日志。

以下命令应该开始记录日志

$ mylogscript start

以下命令应该停止记录

$ mylogscript stop

此外,命令不应阻塞终端。例如,一旦我发送启动命令,脚本在后台运行,我应该能够在终端上做其他工作。

任何关于如何在 perl 或 python 中实现它的指针都会有所帮助。

编辑: 已解决:https://stackoverflow.com/a/14596380/443889

【问题讨论】:

    标签: python linux perl scripting adb


    【解决方案1】:

    您可以采取以下几种不同的方法: 1. 信号 - 您使用信号处理程序,并且通常使用“SIGHUP”来指示进程重新启动(“start”),使用 SIGTERM 来停止它(“stop”)。 2. 使用命名管道或其他 IPC 机制。后台进程有一个单独的线程,它只是从管道中读取数据,当有东西进来时,就对其进行操作。这种方法依赖于有一个单独的可执行文件来打开管道并发送消息(“start”、“stop”、“set loglevel 1”或任何你喜欢的)。

    对不起,我还没有在 Python 中实现这些 [perl 我还没有真正写过任何东西],但我怀疑这很难 - 肯定会有一套现成的 Python 代码处理命名管道。

    编辑:另一种让我印象深刻的方法是,您只需在启动时将程序守护,然后让“停止”版本找到您的守护进程 [例如通过读取您存放在合适位置的“pidfile”],然后发送一个 SIGTERM 让它终止。

    【讨论】:

      【解决方案2】:

      我不知道这是否是在 perl 中执行此操作的最佳方式,但例如:

      system("sleep 60 &")
      

      这将启动一个后台进程,该进程将在不阻塞终端的情况下休眠 60 秒。 shell 中的 & 表示在后台做某事。

      告诉进程何时停止的一个简单机制是让它定期检查某个文件是否存在。如果文件存在,则退出。

      【讨论】:

      • 不确定这有多大帮助。后台进程需要对“开始”和“停止”命令做出反应。
      • @MatsPetersson:好点。我添加了一个关于如何做的建议。不过,您的方法可能是规范的方法。
      【解决方案3】:

      我找到了解决问题的方法。解决方案本质上包括在 python 中启动一个子进程,并在完成后发送一个信号以终止该进程。 以下是参考代码:

      #!/usr/bin/python
      
      import subprocess
      import sys
      import os
      import signal
      
      U_LOG_FILE_PATH = "u.log"
      K_LOG_FILE_PATH = "k.log"
      U_COMMAND = "adb logcat > " + U_LOG_FILE_PATH
      K_COMMAND = "adb shell cat /proc/kmsg > " + K_LOG_FILE_PATH
      
      LOG_PID_PATH="log-pid"
      
      def start_log():
          if(os.path.isfile(LOG_PID_PATH) == True):
              print "log process already started, found file: ", LOG_PID_PATH
              return
          file = open(LOG_PID_PATH, "w")
          print "starting log process: ", U_COMMAND
          proc = subprocess.Popen(U_COMMAND,
              stdout=subprocess.PIPE, stderr=subprocess.PIPE,
              shell=True, preexec_fn=os.setsid)
          print "log process1 id = ", proc.pid
          file.write(str(proc.pid) + "\n")
          print "starting log process: ", K_COMMAND
          proc = subprocess.Popen(K_COMMAND,
              stdout=subprocess.PIPE, stderr=subprocess.PIPE,
              shell=True, preexec_fn=os.setsid)
          print "log process2 id = ", proc.pid
          file.write(str(proc.pid) + "\n")
          file.close()
      
      def stop_log():
          if(os.path.isfile(LOG_PID_PATH) != True):
              print "log process not started, can not find file: ", LOG_PID_PATH
              return
          print "terminating log processes"
          file = open(LOG_PID_PATH, "r")
          log_pid1 = int(file.readline())
          log_pid2 = int(file.readline())
          file.close()
          print "log-pid1 = ", log_pid1
          print "log-pid2 = ", log_pid2
          os.killpg(log_pid1, signal.SIGTERM)
          print "logprocess1 killed"
          os.killpg(log_pid2, signal.SIGTERM)
          print "logprocess2 killed"
          subprocess.call("rm " + LOG_PID_PATH, shell=True)
      
      def print_usage(str):
          print "usage: ", str, "[start|stop]"
      
      # Main script
      if(len(sys.argv) != 2):
          print_usage(sys.argv[0])
          sys.exit(1)
      
      if(sys.argv[1] == "start"):
          start_log()
      elif(sys.argv[1] == "stop"):
          stop_log()
      else:
          print_usage(sys.argv[0])
          sys.exit(1)
      
      sys.exit(0)
      

      【讨论】:

        猜你喜欢
        • 2010-11-08
        • 2015-01-11
        • 2012-03-14
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2013-05-25
        • 2012-12-28
        相关资源
        最近更新 更多