0

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

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

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

$ mylogscript start

以下命令应该停止记录

$ mylogscript stop

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

有关如何在 perl 或 python 中实现这一点的任何指示都会有所帮助。

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

4

3 回答 3

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)
于 2013-01-30T03:51:17.933 回答
0

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

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

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

于 2013-01-30T00:47:08.377 回答
0

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

system("sleep 60 &")

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

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

于 2013-01-30T00:47:09.690 回答