Search code examples
pythonlinuxperlscriptingadb

How to control background process in linux


I need to write a script in Linux which can start a background process using one command and stop the process using another.

The specific application is to take userspace and kernel logs for android.

following command should start taking logs

$ mylogscript start

following command should stop the logging

$ mylogscript stop

Also, the commands should not block the terminal. For example, once I send the start command, the script run in background and I should be able to do other work on terminal.

Any pointers on how to implement this in perl or python would be helpful.

EDIT: Solved: https://stackoverflow.com/a/14596380/443889


Solution

  • I got the solution to my problem. Solution essentially includes starting a subprocess in python and sending a signal to kill the process when done. Here is the code for reference:

    #!/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)