michael@0: which.py -- a portable GNU which replacement michael@0: ============================================ michael@0: michael@0: Download the latest which.py packages from here: michael@0: (source) http://trentm.com/downloads/which/1.1.0/which-1.1.0.zip michael@0: michael@0: michael@0: Home : http://trentm.com/projects/which/ michael@0: License : MIT (see LICENSE.txt) michael@0: Platforms : Windows, Linux, Mac OS X, Unix michael@0: Current Version : 1.1 michael@0: Dev Status : mature, has been heavily used in a commercial product for michael@0: over 2 years michael@0: Requirements : Python >= 2.3 (http://www.activestate.com/ActivePython/) michael@0: michael@0: michael@0: What's new? michael@0: ----------- michael@0: michael@0: I have moved hosting of `which.py` from my old [Starship michael@0: pages](http://starship.python.net/~tmick/) to this site. These starter michael@0: docs have been improved a little bit. See the [Change Log](#changelog) michael@0: below for more. michael@0: michael@0: **WARNING**: If you are upgrading your `which.py` and you also use my michael@0: [process.py](../process/) module, you must upgrade `process.py` as well michael@0: because of the `_version_/__version__` change in v1.1.0. michael@0: michael@0: michael@0: Why which.py? michael@0: ------------- michael@0: michael@0: `which.py` is a small GNU-which replacement. It has the following michael@0: features: michael@0: michael@0: - it is portable (Windows, Linux, Mac OS X, Un*x); michael@0: - it understands PATHEXT and "App Paths" registration on Windows michael@0: (i.e. it will find everything that `start` does from the command shell); michael@0: - it can print all matches on the PATH; michael@0: - it can note "near misses" on the PATH (e.g. files that match but may michael@0: not, say, have execute permissions); and michael@0: - it can be used as a Python module. michael@0: michael@0: I also would be happy to have this be a replacement for the `which.py` in the michael@0: Python CVS tree at `dist/src/Tools/scripts/which.py` which is michael@0: Unix-specific and not usable as a module; and perhaps for inclusion in michael@0: the stdlib. michael@0: michael@0: Please send any feedback to [Trent Mick](mailto:TrentM@ActiveState.com). michael@0: michael@0: michael@0: Install Notes michael@0: ------------- michael@0: michael@0: Download the latest `which.py` source package, unzip it, and run michael@0: `python setup.py install`: michael@0: michael@0: unzip which-1.1.0.zip michael@0: cd which-1.1.0 michael@0: python setup.py install michael@0: michael@0: If your install fails then please visit [the Troubleshooting michael@0: FAQ](http://trentm.com/faq.html#troubleshooting-python-package-installation). michael@0: michael@0: `which.py` can be used both as a module and as a script. By default, michael@0: `which.py` will be installed into your Python's `site-packages` michael@0: directory so it can be used as a module. On *Windows only*, `which.py` michael@0: (and the launcher stub `which.exe`) will be installed in the Python michael@0: install dir to (hopefully) put `which` on your PATH. michael@0: michael@0: On Un*x platforms (including Linux and Mac OS X) there is often a michael@0: `which` executable already on your PATH. To use this `which` instead of michael@0: your system's on those platforms you can manually do one of the michael@0: following: michael@0: michael@0: - Copy `which.py` to `which` somewhere on your PATH ahead of the system michael@0: `which`. This can be a symlink, as well: michael@0: michael@0: ln -s /PATH/TO/site-packages/which.py /usr/local/bin/which michael@0: michael@0: - Python 2.4 users might want to use Python's new '-m' switch and setup michael@0: and alias: michael@0: michael@0: alias which='python -m which' michael@0: michael@0: or stub script like this: michael@0: michael@0: #!/bin/sh michael@0: python -m which $@ michael@0: michael@0: michael@0: Getting Started michael@0: --------------- michael@0: michael@0: Currently the best intro to using `which.py` as a module is its module michael@0: documentation. Either install `which.py` and run: michael@0: michael@0: pydoc which michael@0: michael@0: take a look at `which.py` in your editor or [here](which.py), or read michael@0: on. Most commonly you'll use the `which()` method to find an michael@0: executable: michael@0: michael@0: >>> import which michael@0: >>> which.which("perl") michael@0: '/usr/local/bin/perl' michael@0: michael@0: Or you might want to know if you have multiple versions on your path: michael@0: michael@0: >>> which.whichall("perl") michael@0: ['/usr/local/bin/perl', '/usr/bin/perl'] michael@0: michael@0: Use `verbose` to see where your executable is being found. (On Windows michael@0: this might not always be so obvious as your PATH environment variable. michael@0: There is an "App Paths" area of the registry where the `start` command michael@0: will find "registered" executables -- `which.py` mimics this.) michael@0: michael@0: >>> which.whichall("perl", verbose=True) michael@0: [('/usr/local/bin/perl', 'from PATH element 10'), michael@0: ('/usr/bin/perl', 'from PATH element 15')] michael@0: michael@0: You can restrict the searched path: michael@0: michael@0: >>> which.whichall("perl", path=["/usr/bin"]) michael@0: ['/usr/bin/perl'] michael@0: michael@0: There is a generator interface: michael@0: michael@0: >>> for perl in which.whichgen("perl"): michael@0: ... print "found a perl here:", perl michael@0: ... michael@0: found a perl here: /usr/local/bin/perl michael@0: found a perl here: /usr/bin/perl michael@0: michael@0: An exception is raised if your executable is not found: michael@0: michael@0: >>> which.which("fuzzywuzzy") michael@0: Traceback (most recent call last): michael@0: ... michael@0: which.WhichError: Could not find 'fuzzywuzzy' on the path. michael@0: >>> michael@0: michael@0: There are some other options too: michael@0: michael@0: >>> help(which.which) michael@0: ... michael@0: michael@0: Run `which --help` to see command-line usage: michael@0: michael@0: $ which --help michael@0: Show the full path of commands. michael@0: michael@0: Usage: michael@0: which [...] [...] michael@0: michael@0: Options: michael@0: -h, --help Print this help and exit. michael@0: -V, --version Print the version info and exit. michael@0: michael@0: -a, --all Print *all* matching paths. michael@0: -v, --verbose Print out how matches were located and michael@0: show near misses on stderr. michael@0: -q, --quiet Just print out matches. I.e., do not print out michael@0: near misses. michael@0: michael@0: -p , --path= michael@0: An alternative path (list of directories) may michael@0: be specified for searching. michael@0: -e , --exts= michael@0: Specify a list of extensions to consider instead michael@0: of the usual list (';'-separate list, Windows michael@0: only). michael@0: michael@0: Show the full path to the program that would be run for each given michael@0: command name, if any. Which, like GNU's which, returns the number of michael@0: failed arguments, or -1 when no was given. michael@0: michael@0: Near misses include duplicates, non-regular files and (on Un*x) michael@0: files without executable access. michael@0: michael@0: michael@0: Change Log michael@0: ---------- michael@0: michael@0: ### v1.1.0 michael@0: - Change version attributes and semantics. Before: had a _version_ michael@0: tuple. After: __version__ is a string, __version_info__ is a tuple. michael@0: michael@0: ### v1.0.3 michael@0: - Move hosting of which.py to trentm.com. Tweaks to associated bits michael@0: (README.txt, etc.) michael@0: michael@0: ### v1.0.2: michael@0: - Rename mainline handler function from _main() to main(). I can michael@0: conceive of it being called from externally. michael@0: michael@0: ### v1.0.1: michael@0: - Add an optimization for Windows to allow the optional michael@0: specification of a list of exts to consider when searching the michael@0: path. michael@0: michael@0: ### v1.0.0: michael@0: - Simpler interface: What was which() is now called whichgen() -- it michael@0: is a generator of matches. The simpler which() and whichall() michael@0: non-generator interfaces were added. michael@0: michael@0: ### v0.8.1: michael@0: - API change: 0.8.0's API change making "verbose" output the default michael@0: was a mistake -- it breaks backward compatibility for existing michael@0: uses of which in scripts. This makes verbose, once again, optional michael@0: but NOT the default. michael@0: michael@0: ### v0.8.0: michael@0: - bug fix: "App Paths" lookup had been crippled in 0.7.0. Restore that. michael@0: - feature/module API change: Now print out (and return for the module michael@0: interface) from where a match was found, e.g. "(from PATH element 3)". michael@0: The module interfaces now returns (match, from-where) tuples. michael@0: - bug fix: --path argument was broken (-p shortform was fine) michael@0: michael@0: ### v0.7.0: michael@0: - bug fix: Handle "App Paths" registered executable that does not michael@0: exist. michael@0: - feature: Allow an alternate PATH to be specified via 'path' michael@0: optional argument to which.which() and via -p|--path command line michael@0: option. michael@0: michael@0: ### v0.6.1: michael@0: - first public release michael@0: