Warning: file_get_contents(/data/phpspider/zhask/data//catemap/8/selenium/4.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
Python 如何在linux中控制后台进程_Python_Linux_Perl_Scripting_Adb - Fatal编程技术网

Python 如何在linux中控制后台进程

Python 如何在linux中控制后台进程,python,linux,perl,scripting,adb,Python,Linux,Perl,Scripting,Adb,我需要在Linux中编写一个脚本,它可以使用一个命令启动后台进程,并使用另一个命令停止进程 具体的应用程序是获取android的用户空间和内核日志 下面的命令应该开始记录日志 $ mylogscript start 以下命令应停止日志记录 $ mylogscript stop 此外,命令不应阻塞终端。例如,一旦我发送start命令,脚本将在后台运行,我应该能够在终端上执行其他工作 任何关于如何在perl或python中实现这一点的指针都会很有帮助 编辑: 已解决:您可以采取以下几种不同的方法

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

具体的应用程序是获取android的用户空间和内核日志

下面的命令应该开始记录日志

$ mylogscript start
以下命令应停止日志记录

$ mylogscript stop
此外,命令不应阻塞终端。例如,一旦我发送start命令,脚本将在后台运行,我应该能够在终端上执行其他工作

任何关于如何在perl或python中实现这一点的指针都会很有帮助

编辑:
已解决:

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

很抱歉,我还没有在Python中实现这两个方面(我还没有真正用perl编写任何东西),但我怀疑这很难——肯定会有一套现成的Python代码来处理命名管道


编辑:另一种让我印象深刻的方法是,您只需在开始时对程序进行后台监控,然后让“停止”版本找到您的非监控进程[例如,通过读取您保存在适当位置的“pidfile”),然后发送一个SIGTERM使其终止。

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

system("sleep 60 &")
这将启动一个后台进程,该进程将在不阻塞终端的情况下休眠60秒。shell中的符号表示在背景中做某事


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

我找到了问题的解决方案。解决方案基本上包括在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)

不确定那会有多大帮助。后台进程将需要对“开始”和“停止”命令作出反应。@MatstPeterson:说得好。我补充了一个如何做的建议。不过,您的方法可能是规范的方法。