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

Python 如何分发要由外部命令执行的代码?Bash脚本?,python,bash,shell,unix,command,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 op

编辑:基于下面的讨论,我认为我的问题真的可以适用于任何语言。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,并能够在命令行中使用(例如)

它将运行
pythonfile1.py
并输出文件
output.txt
。是否编写bash脚本?如果是这样,您如何分发代码,以便用户在其路径中拥有这些代码

在脚本文件的顶部添加一个“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
使脚本文件可执行:

#!/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])。您也可以使用特定于操作系统的打包方法,比如apt、yum、msiexec等等,但除非您必须这样做,否则我不会这么做。您的用户已经安装了python,因为他们已经习惯于显式地将脚本传递给解释器。如果您对使用python打包感兴趣,请继续阅读

首先,我会将您的脚本与任何其他必要的处理一起放入一个包中。我们把它叫做
mylibrary
。您的项目应该如下所示:

myproject
 |-- README.rst
 `-- myproject
  |-- __init__.py
  `-- capsall.py
version_info = (0, 0, 0)
version = '.'.join(str(v) for v in version_info)
保持_init_uuy.py的简单性,并确保您可以导入它而不必依赖项。我用的是:

myproject
 |-- README.rst
 `-- myproject
  |-- __init__.py
  `-- capsall.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,那么您至少需要这么多元数据。我还建议添加
分类器
。编写setup.py时所需的时间非常宝贵

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

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


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

您应该阅读本指南,更具体地阅读相关内容,请查看本网站。您可以构建独立的软件包,它不需要任何依赖项,这对于您的用户大多是非技术性的情况是非常有效的。如果你需要参数,那么在执行ie.print“输入文件名:”后,在程序中获取文件详细信息,infle=raw_input()这是可行的,但是如果他们希望将其打包给其他用户,那么在这里使用标准打包/分发技术不是最好的吗?@idjaw我理解你的意思。当然,最好将要通过pip安装并导入的包包装起来。我在问上面的一个理论问题。@mhawke那么,用户将下载脚本文件
.py
和一个bash脚本
.sh
,其中将包含
chmod
命令?您如何要求用户将
capsall
放在路径中?@idjaw:是的,您是对的。问题是使用哪种标准包装方法?选项包括
pip
rpm
、debian-pkg以及独立二进制文件,如由
cxFreeze
生成的二进制文件。这是一个大话题-+