使用Python制作自定义终端命令
written on Sun 27 March 2016 by importcjj
介绍
首先,拿pip举个例子,pip是我们使用较多的python包管理工具。当我们安装pip之后,直接在终端中就可以使用pip这个命令。那你有没有想过这是如何实现的?
其实,pip这个命令最终调用了python所在文件夹bin目录的pip文件。为什么说最终?因为使用系统默认的python安装pip时,可能会在/usr/local/bin或者/usr/bin下创建软链接。如果使用了virtualenv,那么pip文件就在env/bin下。那么pip文件到底是什么呢?答案就是,是一个具有执行权限的python文件,只不过去掉了.py的后缀.
也许你会兴高采烈的去尝试一发,在bin文件下创建xxx.py,打上一句 print “hello world”, 然后去掉.py的后缀, 再使用chmod a+x xxx来赋予它执行的权限。打开终端,敲下xxx。最后你只会得到print: command not found的错误提示。为什么?因为操作系统不知道这是一个py文件。思考一下,我们平时运行py文件都需要打上python xxx.py形式的命令,其实我们告诉了操作系统这是一个python文件(哪怕是有.py后缀),需要使用python解释器来解释运行该文件。现在,我们没有指定解释器了,自然就无法顺利的作为py脚本来运行了,它被错误的认为是shell脚本了。而shell编程中只有echo,没有print命令。
那么我们要做的就是在文件的第一行为该文件指定它的解释器(通过环境变量来获取当前使用的python解释器的路径):
#!/usr/bin/env python
这是一种常见写法,当然可以写成:
#!/usr/bin/python
这样,我们就为这个脚本指定了一个固定的解释器(它的路径是/usr/bin/python),可能有些时候你需要这样做。但是第一种更加灵活,尤其是在使用virtualenv创建的虚拟环境中,采用第二种写法的脚本将无法导入虚拟环境中安装的依赖包。
拓展
安装自己创建的python项目时,如何让安装工具自动在python目录的bin目录下创建自己的命令文件?在python2中,安装一个包,通常需要setup.py这个文件。大致写法如下:
from setuptools import setup
setup(
name='project_name',
version='0.1',
...
entry_points={
'console_scripts': [
'hello = hello.main:main',
]
}
)
表示hello这个命令执行的是hello包下的main模块中的main函数.
实践
环境: python2.7 + mac osx 举个例子,我们现在有个project,目录如下
example/
- setup.py
- hello/
_ __init__.py
- main.py
其中, main.py
是我们写的命令文件,内容如下:
#!/usr/bin/env python
# -*- coding:utf-8 -*-
def main():
print 'hello word'
setup.py的内容如下:
from setuptools import setup
setup(
name='hello',
version='0.1',
entry_points={
'console_scripts':[
'hello = hello.main:main'
]
}
)
在安装这个简单的项目之前,我们还需要修改一下hello文件到额权限: chmod a+x hello
接着安装, python setup.py
install 或者 pip install
. 这两种方式随便哪种都可以,安装完成后在终端中输入hello命令试试,有没有显示hello world?
结尾
说了这么多,提醒一点,并不是所有的python包都是通过上述方式来提供终端命令的,不过这是一种很普遍很简便的方式!