Melissa’s co-worker needed to write some Python code to kill an external process. There are some third-party modules, like psutil that can solve that problem, but companies like Initech tend to put lots of obstacles along the path of bringing third-party code into your applications.
Without third-party tools, you’re stuck “shelling out”. Using built-in Python functions like os.system
or the subprocess
module. This lets you run commands like ps
and kill
from inside of your Python program. It’s inelegant, but it works just fine. There’s certainly nothing wrong with it.
Melissa’s co-worker saw the inelegant solution, and said to themselves, “Can I make that more ineleganter?”
This code searches for every process that’s a “server” for their application, and then kills them.
def kill_process(self):
server_pid_count_str = ""
server_pid_count_str = subprocess.check_output(
"ps -e -opid,args | grep SERVER | grep " + self.server_name +
" | sed '/grep/d' | wc -l", shell=True).strip()
if server_pid_count_str.isdigit():
server_pid_count = int(server_pid_count_str)
for i in range(0, server_pid_count):
pid_server = subprocess.check_output(
"ps -e -opid,args | grep SERVER | grep " +
self.server_name + " | sed '/grep/d' | sort | head -1 | tail -1 | awk '{print $1}'",
shell=True).strip()
if pid_server.isdigit():
subprocess.check_call("kill -9 " + pid_server, shell=True)
Look at that thing of beauty. It counts the number of server processes using wc -l
, then it does a for-loop that number of times. Inside the for-loop, it calls out to ps
again, but this time it sorts the results and passes them through head -1 | tail -1
to get a single line, which it then picks the PID out of to kill. Also, I don’t know where the variable self.server_name
gets its value from, but I hope it’s not from some external source, because the use of shell=True
makes this vulnerable to shell injection.