如何分发由外部命令执行的代码? Bash脚本?

时间:2016-09-11 01:09:39

标签: python bash shell unix command

编辑:根据以下讨论,我认为我的问题确实适用于任何语言。 Python通过pip自然拥有一个打包系统和安装程序。但是,让我们说这是C代码或perl脚本。用户仍然可以下载程序文件,并可以通过capsall input.txt在命令行中执行代码。

我有一个python脚本,它接受一个输入文件并提供一个输出文件。

对于一个具体示例,此脚本file1.py接收输入文本文件并输出所有字母大写的文本文件:

import sys
inFile = sys.argv[1]
outFile = sys.argv[2]

with open(inFile,'r') as input_file:
    lines = input_file.readlines()

# process the input file somehow
# here we simply capitalize the text, 
# but naturally something more complex is possible

capitalized_lines = []
for line in lines:
    capitalized_lines.append(line.upper())

with open(outFile,'w') as output_file:
    for line in capitalized_lines:
        output_file.write(line)

用户现在使用

执行此代码的方式
python file1.py input.txt output.txt

假设我想分发此代码,以便用户下载tarball并能够在命令行中执行上述代码(例如)

capsall input.txt

将运行python file1.py并输出文件output.txt。有人写一个bash脚本吗?如果是这样,您如何分发代码,以便用户在其PATH中拥有此代码?

2 个答案:

答案 0 :(得分:1)

在脚本文件的顶部添加“hash bang”,告诉bash调用Python解释器。还可以使脚本可执行:

#!/usr/bin/env python
import sys

inFile = sys.argv[1]
outFile = sys.argv[2]
...

使脚本文件可执行:

$ cp file1.py capsall
$ chmod +x capsall

现在您可以使用以下命令运行脚本:

$ ./capsall input.txt output.txt

或者如果capsall在您的路径上:

$ capsall input.txt output.txt

答案 1 :(得分:1)

我建议使用python包装(例如,[pip])。您也可以使用特定于操作系统的打包方法,例如 apt yum msiexec ,无论如何,但我不会这样做,除非你必须。您的用户已经安装了python,因为它们已经用于显式将脚本传递给解释器。如果您对使用python包装感兴趣,请继续阅读。

首先,我会将您的脚本放入一个包中,同时还需要其他任何处理。我们称之为mylibrary。您的项目应该类似于:

myproject
 |-- README.rst
 `-- myproject
  |-- __init__.py
  `-- capsall.py

保持 __ init __。py 简单,并确保您可以导入不带依赖项。我用的是:

version_info = (0, 0, 0)
version = '.'.join(str(v) for v in version_info)

接下来,在根目录中添加名为 setup.py 的文件。这将定义您的包,它的元数据以及要安装到用户$PATH中的脚本。以下将很好地工作:

#!/usr/bin/env python
import setuptools
import myproject

setuptools.setup(
    name='myproject',
    version=myproject.version,
    description='Package of useful utilities.',
    long_description=open('README.rst').read(),
    url='https://github.com/me/myproject',
    author='Me',
    author_email='me@example.com',
    packages=['myproject'],
    entry_points={
        'console_scripts': ['capsall=myproject.capsall:main'],
    },
    license='BSD',
)

如果您打算上传到pypi.python.org,那么您至少需要那么多的元数据。我建议也添加classifiers。编写 setup.py Python Packaging Authority docs非常宝贵。

您最感兴趣的部分是entry_points关键字参数。它定义了可以调用包的各种方法。您正在寻找console_scripts,因为它创建了安装在本地路径中的shell脚本。有关详细信息,请参阅setuptools documentation

我上面给出的console_scripts定义创建了一个名为 capsall 的脚本,用于调用my project.capsall.main函数。我会将您的代码重新打包到一个项目中。将脚本捆绑到 capsall.py 模块的功能中。然后生成一个源存储库并将其上传到pypi.python.org(./setup.py sdist register upload)。上传后,您的用户可以使用pip install myproject安装它。

您可能拥有不想向外界提供的代码。如果是这种情况,那么您可以生成源代码分发并使内部服务器上的tarball可用 - ./setup.py sdist将在 dist 目录中生成tarball。然后pip install whatever/myproject-0.0.0.tar.gz将安装您的脚本。