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

How to distribute code to be executed by an external command? Bash script?

编辑:根据下面的讨论,我认为我的问题确实适用于任何语言。 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

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

capsall input.txt

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

在脚本文件的顶部添加一个 "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

我建议为此使用 python 打包(例如 [pip])。您也可以使用 OS 特定的打包方法,例如 aptyummsiexec, 无论如何,但除非你必须,否则我不会。您的用户已经安装了 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.pyPython Packaging Authority docs 是无价的。

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

我在上面给出的 console_scripts 定义创建了一个名为 capsall 的脚本,它调用 my project.capsall.main 函数。我会将您的代码重新打包到一个项目中。将脚本捆绑到 capsall.py 模块的 main 函数中。然后生成源码仓库上传到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 将安装您的脚本。