如何在linux中控制后台进程

时间:2013-01-29 23:55:26

标签: python linux perl scripting adb

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

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

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

$ mylogscript start

以下命令应该停止记录

$ mylogscript stop

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

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

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

3 个答案:

答案 0 :(得分:1)

您可以采用以下几种方法:  1.信号 - 你使用一个信号处理程序,并使用,通常是“SIGHUP”来指示进程重启(“启动”),SIGTERM停止它(“停止”)。  2.使用命名管道或其他IPC机制。后台进程有一个单独的线程,它只是从管道读取,当有东西进入时,就会对它起作用。此方法依赖于具有打开管道的单独可执行文件,并发送消息(“开始”,“停止”,“设置日志级别1”或您想要的任何内容)。

对不起,我没有在Python中实现这些[和perl我还没有写过任何内容],但我怀疑它很难 - 必然会有一套现成的python代码处理命名管道。

编辑:另一个令我印象深刻的方法是你只是在开始时守护程序,然后让“停止”版本找到你的deamonized进程[例如通过读取你藏在适当位置的“pidfile”,然后发送一个SIGTERM来终止它。

答案 1 :(得分:1)

我得到了解决问题的方法。解决方案主要包括在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)

答案 2 :(得分:0)

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

system("sleep 60 &")

这将启动后台进程,该进程将在不阻塞终端的情况下休眠60秒。 shell中的&符表示在后台执行某些操作。

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