如何安装Python程序,使其具有命令行快捷方式

时间:2017-07-03 15:10:08

标签: python setuptools

我试图编写一个我可以pip install的Python程序,以便它有一个特定的命令行别名,类似于' aws'使用awscli包的命令(参见https://pypi.python.org/pypi/awscli/1.11.115)。

setup.py中的awscli似乎包含类似

的内容
setuptools.setup(console='bin/aws')

这可能是命令行'别名'工作。但是,在http://setuptools.readthedocs.io/en/latest/setuptools.html,我无法轻松找到有关如何使用此console选项的文档或示例。

我的简化用例如下。我有一个目录sayhello,其中包含以下内容:

.
├── sayhello.py
└── setup.py

其中sayhello.py同时定义了函数(say_hello)和调用此函数的if __name__ == "__main__"块:

def say_hello():
    print("Hello, world!")

if __name__ == "__main__":
    say_hello()

我尝试的setup.py

from setuptools import setup, find_packages

setup(name="sayhello", version="1.0", packages=find_packages(), console="/bin/sayhello")

然后在sayhello目录中,我做

pip install .

(在virtualenv venvsource venv/bin/activate之后在虚拟环境中执行此操作)。在此之后,我可以在Python shell中import sayhellosayhello.say_hello(),但我尝试定义的键盘快捷键sayhello不起作用。

如何修改setup.py以使命令sayhello触发if __name__ == "__main__"中的sayhello.py阻止?

2 个答案:

答案 0 :(得分:2)

假设您的软件包的根目录中有sayhello.py。然后只需在setup.py中添加scripts

setup(
    ...
    scripts=['sayhello.py']
)

习惯上将所有脚本放在scripts/ dir中,使它们可执行,并在第一行放置hashbang(#!/usr/bin/env python)。

第二种方法是通过console_scripts

setup(
    ...
    entry_points = {
        'console_scripts': ['sayhello=sayhello:say_hello'],
    }
    ...
)

最小的例子

sayhello.py put:

#!/usr/bin/env python
print "Hello!"

setup.py

from setuptools import setup
setup(
    name="sayhello",
    version="0.0.1",
    scripts=['sayhello.py']
)

运行pip install .后,您应该将sayhello.py脚本复制到虚拟环境的bin目录(位于PATH中)。

测试脚本:

$ sayhello.py
Hello!

答案 1 :(得分:1)

首先,我认为您需要将sayhello.py放入__init__.py的目录中,以便find_packages找到它(这是entry_points方法的要求)。我不确定(我从来没有尝试过),但我现在一直在努力,没有它就无法让它工作。

我知道有两种创建命令行可运行脚本的方法:entry_pointsscripts

entry_points是更强大的选项,但要求脚本的功能成为您的包的一部分(意味着它位于包中的模块中。如果您将sayhello.py移动到{{1}带有sayhello文件的目录,它看起来像这样:

__init__.py

更简单的选项是entry_points={ 'console_scripts': [ 'say_hello = sayhello.sayhello:say_hello' ] } 。只需添加:

scripts

以下是我的工作:

scripts=['sayhello.py']

来自setuptools导入设置,find_packages

setup.py

目录结构:

setup(
    name="sayhello",
    version="1.0",
    packages=find_packages(),
    entry_points = {
        'console_scripts': [
            "sayhello = sayhello.sayhello:say_hello"
        ]
    }
)

. ├── sayhello │   ├── __init__.py │   └── sayhello.py └── setup.py

sayhello.py