How to distribute code to be executed by an external command? Bash script?
<p>EDIT: Based on discussions below, I think my question really code apply to any language. Python naturally has a packaging system and installation procedure via <code>pip</code>. But let's say this was C code or a perl script. Users still would download the program files, and have a way to execute the code in the command line via <code>capsall input.txt</code>. </p>

<p>I have a python script that takes an input file and gives an output file.</p>

<p>For a concrete example, this script <code>file1.py</code> takes in an input text file and outputs a text file with all letters capitalized:</p>

<pre><code>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)
</code></pre>

<p>The way users execute this code now with </p>

<pre><code>python file1.py input.txt output.txt
</code></pre>

<p>Let's say I wanted to distribute this code such that users would download a tarball and be able to execute the above in the command line with (for example)</p>

<pre><code>capsall input.txt
</code></pre>

<p>which would run <code>python file1.py</code> and output the file <code>output.txt</code>. Does one write a bash script? If so, how do you distribute the code such that users will have this in their PATH? </p>

<p>I would recommend using python packaging (e.g., [pip]) for this.  You could use the OS specific packaging method as well, something like <em>apt</em>, <em>yum</em>, <em>msiexec</em>, whatever, but I wouldn't unless you have to.  Your users already have python installed since they are used to explicitly passing your script to the interpreter already.  If you are interested in using python packaging, then read on.</p>

<p>First, I would put your script into a package along with whatever other processing is necessary.  Let's call it <code>mylibrary</code>.  Your project should look something like:</p>

<pre><code>myproject
 |-- README.rst
 `-- myproject
  |-- __init__.py
  `-- capsall.py
</code></pre>

<p>Keep <em>__init__.py</em> simple and make sure that you can import it <strong>without</strong> dependencies.  I use something like:</p>

<pre><code>version_info = (0, 0, 0)
version = '.'.join(str(v) for v in version_info)
</code></pre>

<p>Next, add a file named <em>setup.py</em> at the root.  This is what will define your package, it's metadata, and the scripts to install into your user's <code>$PATH</code>.  The following will work nicely:</p>

<pre><code>#!/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',
)
</code></pre>

<p>If you plan on uploading to pypi.python.org, then you will need at least that much metadata. I would recommend adding <code>classifiers</code> as well.  The <a href="https://packaging.python.org/distributing/" rel="nofollow">Python Packaging Authority docs</a> on writing a <em>setup.py</em> are invaluable.</p>

<p>The part that you are most interested in is the <code>entry_points</code> keyword parameter.  It defines various ways that your package can be invoked.  You are looking for <code>console_scripts</code> since it creates shell scripts that are installed into the local path.  See the <a href="https://setuptools.readthedocs.io/en/latest/setuptools.html#automatic-script-creation" rel="nofollow">setuptools documentation</a> for more details.</p>

<p>The <code>console_scripts</code> definition that I gave above creates a script named <em>capsall</em> that invokes the <code>my project.capsall.main</code> function.  I would repackage your code into a project.  Bundle your script into the <em>main</em> function of the <em>capsall.py</em> module.  Then generate a source repository and upload it to pypi.python.org (<code>./setup.py sdist register upload</code>).  Once you have it uploaded, your users can install it using <code>pip install myproject</code>.</p>

<p>Chances are that you have code that you don't want to give to the outside world.  If that is the case, then you can generate a source distribution and make the tarball available on an internal server -- <code>./setup.py sdist</code> will generate a tarball in the <em>dist</em> directory.  Then <code>pip install whatever/myproject-0.0.0.tar.gz</code> will install your script.</p>

python bash shell unix command