如何在Python中获取调用shell的名称?
我有一个Python脚本,它总是通过命令行来运行,这个命令行可以是zsh或者bash。
我该怎么知道是哪个命令行调用了这个脚本呢?
3 个回答
-3
os.system("echo $0")
这个命令在我的系统上运行得非常顺利:
cat shell.py:
#!/ms/dist/python/PROJ/core/2.5/bin/python
import os
print os.system("echo $0")
bash-2.05b$ uname -a
Linux pi929c1n10 2.4.21-32.0.1.EL.msdwhugemem #1 SMP Mon Dec 5 21:32:44 EST 2005 i686 athlon i386 GNU/Linux
pi929c1n10 /ms/user/h/hirscst 8$ ./shell.py
/bin/ksh
pi929c1n10 /ms/user/h/hirscst 9$ bash
bash-2.05b$ ./shell.py
/bin/ksh
bash-2.05b$
0
你不能以可靠的自动化方式做到这一点。
环境变量可能会让人误解(用户可以恶意地更改它们)。大多数自动生成的shell变量并不会“泄露”,也就是说,它们只在当前的shell进程中可见,而在子进程中不可见。
你可以找到父进程的PID,然后在进程列表中查找这个ID。但是如果你的程序在后台运行,这个方法就不管用了(在这种情况下,父进程的PID总是1)。
用户可以通过脚本启动你的程序。那么在这种情况下,哪个shell是正确的呢?是启动脚本的那个shell,还是脚本本身的shell?
其他程序可以通过系统调用来运行你的脚本。在这种情况下,你要么得到他们的shell,要么什么都得不到。
如果你对用户的环境有绝对的控制权,可以在他们的配置文件中放一个变量(查看BASH和ZSH的手册,找一个在启动时总是读取的文件。记得没错的话,BASH的文件是.profile
)。
[编辑] 创建一个别名,使其在两个shell中都能调用。在这个别名中,使用
env SHELL_HINT="x$BASH_VERSION" your_script.py
这样在zsh中应该会得到“x”,而在bash中会得到其他东西。
11
在Linux系统中,你可以使用procfs这个工具:
>>> os.readlink('/proc/%d/exe' % os.getppid())
'/bin/bash'
os.getppid()
这个命令可以返回父进程的PID(进程ID)。这个方法是通用的,在哪个系统上都能用。但是,要获取进程名称就没那么简单了,不能用同样的方法。你可以解析一下ps
命令的输出,这个命令在所有Unix系统上都可以使用,比如可以用psutil这个库来帮助你。