0

I have several python scripts that turn my TV on and off. Sometimes the TV does not respond the first time so I use a while loop to continue sending the command until the "success" response is sent. Up to 10 times.

I need to check if one of these programs are running when any of them are started and kill the first process.

This answer uses domain locks and I think this could work but I dont really understand whats happening there: https://stackoverflow.com/a/7758075/2005444

What I dont know is what the process_name would be. The scripts are titles tvon.py, tvoff.py, and tvtoggle.py. Is it just the title? Would it include the extension? How do I get the pid so I can kill the process?

This is running on Ubuntu 14.04.1

EDIT: all I really need is to search for any of these running scripts first. Also, instead of killing the process maybe I could just wait for it to finish. I could just do a loop and break it if none of those processes are running.

The reason I need to do this is if the tv is off and the off script is run it will never succeed. The TV wont respond if it is already off. Which is why I built in the limit of 10 commands. It never really takes over 4 so 10 is overkill. The problem is if the off command is trying to run and I turn the TV on using the tvon script the TV will turn on and back off. Although the TV limits how often commands can be accepted, which reduces the chance of this happening I still want the to be as cleanly working as possible.

EDIT: I found that I can not kill the process because it can lock the tty port up which requires a manual restart. So I think the smarter way is to have the second process wait until the first is done. Or find a way to tell the first process to stop at a specific point in the loop so I know its not transmitting.

Community
  • 1
  • 1
JpaytonWPD
  • 485
  • 1
  • 7
  • 22
  • not quite an answer to your question but this may atleast help you on your way. when you script is running, from the terminal type "ps aux | grep python" this will show you all the processes running using python. It should help you atleast work out what the processes are called – Calum Feb 20 '15 at 01:56
  • `process_name` in that example is an abstract name, whatever you want. `"tv"` might be appropriate for you. As to what is going on, read the link in the first comment under the linked answer. Also, this answer only *locks*, preventing simultaneous execution; you can't kill another process with it. Use the pid file approach in the accepted answer. – Amadan Feb 20 '15 at 02:01
  • This pidfile approach will cause issues since I am actively killing the process before it finishes and has the chance to remove the pid file. I could however maybe only look for a pidfile if a lock is found. I thought about just killing any pid found but since they are recycled that could create problems. – JpaytonWPD Feb 20 '15 at 02:16
  • You could use python to parse the PID from the output of `ps aux | grep tvon.py` or whichever python script you're looking for, and then use `kill PID` to end it. – John Dorian Feb 20 '15 at 04:28

2 Answers2

1

If you have a socket, use it. Sockets provide full-blown bidirectional communication. Just write your script to kill itself if it receives anything on the socket. This can be most easily done by creating a separate thread which tries to do a socket.recv() (for SOCK_DGRAM) or socket.accept() (for SOCK_STREAM/SOCK_SEQPACKET), and then calls sys.exit() once that succeeds.

You can then use socket.send() (SOCK_DGRAM) or socket.connect() (SOCK_STREAM/SOCK_SEQPACKET) from the second script instance to ask the first instance to exit.

Kevin
  • 28,963
  • 9
  • 62
  • 81
  • I did more research on sockets and it seems like they could work. However everything I read is very complex. At least for what I am doing. I did figure out a way to exit my new process if an old one is working. And now that I have a loop that reads the response from the TV and stops when the command is accepted its not really an issue. I am still curious if you maybe have a simple example. Your explanation looks like it should just be a few lines but when I tried I think I was going too far. – JpaytonWPD Dec 24 '15 at 02:36
  • @JpaytonWPD: If you can't get it to work, ask a new question about the specific problem you are having. – Kevin Dec 24 '15 at 13:48
1

This function can kill a python script by name on *nix systems. It looks through a list of running processes, finds the PID of the one associated with your script, and issues a kill command.

import subprocess
def killScript(scriptName):
        # get running processes with the ps aux command
        res = subprocess.check_output(["ps","aux"], stderr=subprocess.STDOUT)

        for line in res.split("\n"):
                # if one of the lines lists our process
                if line.find(scriptName) != -1:
                        info = []

                        # split the information into info[]
                        for part in line.split(" "):
                                if part.strip() != "":
                                        info.append(part)

                        # the PID is in the second slot
                        PID = info[1]

                        #kill the PID
                        subprocess.check_output(["kill",PID], stderr=subprocess.STDOUT)

At the beginning of your tv script you could run something like:

killList = ["tvon.py", "tvoff.py", "tvtoggle.py"]
for script in killList:
        killScript(script)
John Dorian
  • 1,884
  • 1
  • 19
  • 29
  • This works but I found if its killed while transmitting to the TV the tty port becomes un-accessible unless I reset it. – JpaytonWPD Dec 24 '15 at 02:38