Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

#! /usr/bin/env and process names: portability at a price?

There are lots of good reasons to use #! /usr/bin/env. Bottom line: It makes your code more portable. Well, sorta. Check this out....


I have two nearly identical scripts, bintest.py

#! /usr/bin/python
import time
time.sleep(5*60)

and envtest.py

#! /usr/bin/env python
import time
time.sleep(5*60)

Note that they are only different in their shebangs.


bintest.py runs as expected

br@carina:~$ ./bintest.py & ps && killall bintest.py
[1] 15061
  PID TTY          TIME CMD
14625 pts/0    00:00:00 bash
15061 pts/0    00:00:00 bintest.py
15062 pts/0    00:00:00 ps
br@carina:~$ 
[1]+  Terminated              ./bintest.py

but envtest.py does something less-than-optimal

br@carina:~$ ./envtest.py & ps && killall envtest.py
[1] 15066
  PID TTY          TIME CMD
14625 pts/0    00:00:00 bash
15066 pts/0    00:00:00 python
15067 pts/0    00:00:00 ps
envtest.py: no process found
br@carina:~$ killall python
br@carina:~$ 
[1]+  Terminated              ./envtest.py

What we've seen is that using #! /usr/bin/env caused the process to receive the name "python" rather than "envtest.py", thus rendering our killall ineffective. On some level it seems like we've traded one kind of portability for another: we can now swap out python interpreters easily, but we've lost "kill-ability" on the command line. What's up with that? If there's a best-practice here for achieving both, what is it?

like image 868
BrianTheLion Avatar asked Jun 27 '11 16:06

BrianTheLion


1 Answers

"kill-ability" on the command line can by addressed portably and reliably using the PID of the backgrounded process obtained from shell $! variable.

$ ./bintest.py & bg_pid=$! ; echo bg_pid=$bg_pid ; ps && kill $bg_pid
[1] 2993
bg_pid=2993
  PID TTY          TIME CMD
 2410 pts/0    00:00:00 bash
 2993 pts/0    00:00:00 bintest.py
 2994 pts/0    00:00:00 ps
$ 
[1]+  Terminated              ./bintest.py
$ 

and envtest.py

$ ./envtest.py & bg_pid=$! ; echo bg_pid=$bg_pid ; ps && kill $bg_pid
[1] 3016
bg_pid=3016
  PID TTY          TIME CMD
 2410 pts/0    00:00:00 bash
 3016 pts/0    00:00:00 python
 3017 pts/0    00:00:00 ps
$ 
[1]+  Terminated              ./envtest.py
$ 

As @Adam Bryzak points out, neither script cause the process title to be set on Mac OS X. So, if that feature is a firm requirement, you may need to install and use python module setproctitle with your application.

This Stackoverflow post discusses setting process title in python

like image 62
Brian Swift Avatar answered Nov 18 '22 16:11

Brian Swift