#!/ usr/bin/env和进程名称:价格可移植性?

Bri*_*ion 6 command-line portability kill shebang environment-variables

使用#有很多好的 理由!在/ usr/bin中/ env的.底线:它使您的代码更具可移植性.好吧,有点儿.看一下这个....


我有两个几乎相同的脚本, bintest.py

#! /usr/bin/python
import time
time.sleep(5*60)
Run Code Online (Sandbox Code Playgroud)

envtest.py

#! /usr/bin/env python
import time
time.sleep(5*60)
Run Code Online (Sandbox Code Playgroud)

请注意,他们只是在他们的shebangs不同.


bintest.py 按预期运行

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

envtest.py做的事情不是最优的

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

我们看到的是使用#! /usr/bin/env导致进程接收名称"python"而不是"envtest.py",从而使我们killall无效.在某种程度上,似乎我们已经为另一种交换了一种可移植性:我们现在可以轻松地换掉python解释器,但是我们在命令行上丢失了"kill-ability".那是怎么回事?如果这里有实现两者的最佳实践,它是什么?

Bri*_*ift 2

命令行上的“kill-ability”可以通过使用从 shell 变量获得的后台进程的 PID 可移植且可靠地进行寻址$!

$ ./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
$ 
Run Code Online (Sandbox Code Playgroud)

和 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
$ 
Run Code Online (Sandbox Code Playgroud)

正如 @Adam Bryzak 指出的那样,这两个脚本都不会导致在 Mac OS X 上设置进程标题。因此,如果该功能是硬性要求,您可能需要在应用程序中安装和使用 python 模块setproctitle 。

这篇 Stackoverflow 文章讨论了在 python 中设置进程标题