简体   繁体   English

扭曲的脚本问题

[英]Twisted script issue

I have written a Twisted bin file that is deployed on /usr/bin during application deployement, based on the Axiom example provided elsewhere on StackOverflow (I don't remember where), the project can be found here . 我在应用程序部署期间编写了一个部署在/usr/bin上的Twisted bin文件,基于StackOverflow上其他地方提供的Axiom示例(我不记得在哪里),可以在这里找到项目。

My problem is that, during the python setup.py install process, the installed bin file is different than the one from Axiom package: 我的问题是,在python setup.py install过程中,安装的bin文件与Axiom包中的文件不同:

/usr/bin/axiomatic 在/ usr / bin中/不言自明

#!/code/venv/bin/python
from axiom.scripts import axiomatic
axiomatic.main()

/usr/bin/myapp 在/ usr / bin中/ MYAPP

#!/code/venv/bin/python
# EASY-INSTALL-DEV-SCRIPT: 'MyApp==0.0.1','myapp'
__requires__ = 'MyApp==0.0.1'
__import__('pkg_resources').require('MyApp==0.0.1')
exec(compile(open(__file__).read(), __file__, 'exec'))

and the latter doesn't work when invoking it from the bash shell: myapp start 从bash shell调用后者时后者不起作用: myapp start

I get the following error: unknow command myapp 我收到以下错误: unknow command myapp

If I use python setup.py develop instead of python setup.py install everything works smoothly. 如果我使用python setup.py develop而不是python setup.py install一切顺利。


I have setup a little test application that starts a tcp service on port 1234: 我已经设置了一个小测试应用程序,它在端口1234上启动tcp服务:

  • the command twistd finger works , the service starts 命令twistd finger 工作 ,服务启动
  • the command fingerize start (different name on purpose, to be sure not calling the wrong one) doesn't work 命令fingerize startfingerize start不同的名称,以确保不会调用错误的名称) 不起作用

Here is the code: 这是代码:

bin/fingerize 斌/ fingerize

#!/usr/bin/python
from finger import tap
tap.main()

twisted/plugins/finger_plugin.py 扭转/插件/ finger_plugin.py

from twisted.application.service import ServiceMaker
Finger = ServiceMaker('Finger', 'finger.plugins', 'blah', 'finger')

finger/plugins.py 手指/ plugins.py

from twisted.application import internet
from twisted.internet import endpoints
from twisted.python import usage
from twisted.internet import protocol


class Options(usage.Options):
    """ """


def makeService(options):
    from twisted.internet import reactor

    endpoint = endpoints.TCP4ServerEndpoint(reactor, 1234)
    return internet.StreamServerEndpointService(
        endpoint,
        protocol.Factory())

finger/tap.py 手指/ tap.py

import sys

from twisted.python import usage
from twisted.scripts import twistd


class Start(twistd.ServerOptions):
    run = staticmethod(twistd.run)

    def subCommands(self):
        raise AttributeError()

    subCommands = property(subCommands)

    def parseOptions(self, args):
        print(sys.argv)
        print(args)
        a = self.getArguments(args)
        print(a)
        sys.argv[1:] = a
        print(sys.argv)
        print('Starting finger service...')
        self.run()

    def getArguments(self, args):
        args.extend(['--pidfile', self.parent.pid()])
        args.extend(['finger'])
        return args


class Options(usage.Options):
    def subCommands():
        def get(self):
            yield ('start', None, Start, 'Launch finger service')

        return get,

    subCommands = property(*subCommands())

    def pid(self):
        return '/tmp/finger.pid'


def main(argv=None):
    o = Options()
    try:
        o.parseOptions(argv)
    except usage.UsageError, e:
        raise SystemExit(str(e))

setup.py setup.py

from setuptools import find_packages
from setuptools import setup

METADATA = dict(
    name='Finger',
    version='0.0.1',
    packages=find_packages(),
    scripts=['bin/fingerize'],
    install_requires=[
        'Twisted >= 15.5.0',
    ],
    include_package_data=True,
    zip_safe=False,
)

setup(**METADATA)

And when I call fingerize start I get: /code/test/bin/fingerize: Unknown command: finger (test is a virtualenv) 当我调用fingerize start我得到: /code/test/bin/fingerize: Unknown command: finger (test is a virtualenv)

Since you are using setuptools in your setup.py , you can use the newer entry_points keyword, like so: 由于您在setup.py中使用entry_points ,因此可以使用较新的entry_points关键字,如下所示:

entry_points={ 'console_scripts': [ 'fingerize=finger.tap:main', ], },

instead of the scripts keyword. 而不是scripts关键字。

Note if python setup.py install is run in a virtualenv, it will put the script in env/bin/fingerize (assuming your virtualenv folder is env ). 注意如果在virtualenv中运行python setup.py install ,它会将脚本放在env/bin/fingerize (假设你的virtualenv文件夹是env )。

A nice way to make such "python applications" then available globally (for some deployment purpose), while their inner mechanics doesn't interfere with your system python applciations, is to use pipsi ( pip install pipsi ) (made by the guy who developed flask). 使全局可用的“python应用程序”(用于某些部署目的)的一种很好的方法,虽然它们的内部机制不会干扰你的系统python应用程序,但是使用pipsipip install pipsi )(由开发人员制作)烧瓶)。 It's designed to expose just the project's executables to the system and have everything else tucked away in its own virtualenv. 它旨在将项目的可执行文件暴露给系统,并将其他所有内容隐藏在自己的virtualenv中。

You can see more on how to write/configure/distribute python packages at the packaging.python.org guide. 您可以在packaging.python.org指南中看到有关如何编写/配置/分发python包的更多信息。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM