Skip to content

nicat23/explainshell

 
 

Repository files navigation

explainshell.com - match command-line arguments to their help text

explainshell is a tool (with a web interface) capable of parsing man pages, extracting options and explaining a given command-line by matching each argument to the relevant help text in the man page.

How?

explainshell is built from the following components:

  1. man page reader which converts a given man page from raw format to html (manpage.py)
  2. classifier which goes through every paragraph in the man page and classifies it as contains options or not (algo/classifier.py)
  3. an options extractor that scans classified paragraphs and looks for options (options.py)
  4. a storage backend that saves processed man pages to mongodb (store.py)
  5. a matcher that walks the command's AST (parsed by bashlex) and contextually matches each node to the relevant help text (matcher.py)

When querying explainshell, it:

  1. parses the query into an AST
  2. visits interesting nodes in the AST, such as:
    • command nodes - these nodes represent a simple command
    • shell related nodes - these nodes represent something the shell interprets such as '|', '&&'
  3. for every command node we check if we know how to explain the current program, and then go through the rest of the tokens, trying to match each one to the list of known options
  4. returns a list of matches that are rendered with Flask

Project Status

Important

explainshell is actively maintained in terms of keeping it healthy and functional -- issues are addressed, and the core remains stable. All tests are currently passing (59 passed, 9 skipped).

However, please note that the manpages are outdated. The previous system for generating them was unsustainable, and they haven't been updated in some time. There are currently no active plans to revise this mechanism.

If you're relying on manpages, be aware that they may not reflect the latest behavior. Contributions in this area are welcome but would require rethinking the documentation pipeline.

Recent Updates

Unicode Support Fix (Latest)

  • Fixed Unicode character handling in command parsing
  • Non-ASCII characters in command arguments are now properly replaced with ??? in the match field
  • Resolves issues with international character sets in shell commands
  • All tests now pass including the Unicode test case

Python 3.11+ Compatibility

  • Added compatibility shims for Python 3.11+ collections module changes
  • Fixed collections.MutableSet deprecation issues
  • Ensures the project works with modern Python versions

Manpages

Right now explainshell.com contains the entire archive of Ubuntu. It's not possible to directly add a missing man page to the live site (it might be in the future).

Running explainshell locally

Setup a working environment that lets you run the web interface locally using docker:

# download db dump
$ curl -L -o /tmp/dump.gz https://github.com/idank/explainshell/releases/download/db-dump/dump.gz

# Clone Repository
$ git clone https://github.com/idank/explainshell.git

# start containers, load man pages from dump
$ docker-compose build
$ docker-compose up

$ docker-compose exec -T db mongorestore --archive --gzip < /tmp/dump.gz

# run tests
$ docker-compose exec -T web make tests
..SSSSSSSSS.....................................................................
----------------------------------------------------------------------
Ran 80 tests in 0.041s

OK (SKIP=9)
# open http://localhost:5000 to view the ui

Running Tests

To run the test suite and verify everything is working:

# Run all tests
$ docker-compose exec -T web pytest -q ./tests/*.py ./explainshell

# Run specific test
$ docker-compose exec -T web pytest tests/test-matcher.py::test_matcher::test_unicode -v

Processing a man page

Use the manager to parse and save a gzipped man page in raw format:

$ docker-compose exec -T web bash -c "PYTHONPATH=. python explainshell/manager.py --log info /usr/share/man/man1/echo.1.gz"
INFO:explainshell.store:creating store, db = 'explainshell_tests', host = 'mongodb://localhost'
INFO:explainshell.algo.classifier:train on 994 instances
INFO:explainshell.manager:handling manpage echo (from /tmp/es/manpages/1/echo.1.gz)
INFO:explainshell.store:looking up manpage in mapping with src 'echo'
INFO:explainshell.manpage:executing '/tmp/es/tools/w3mman2html.cgi local=%2Ftmp%2Fes%2Fmanpages%2F1%2Fecho.1.gz'
INFO:explainshell.algo.classifier:classified <paragraph 3, DESCRIPTION: '-n     do not output the trailing newlin'> (0.991381) as an option paragraph
INFO:explainshell.algo.classifier:classified <paragraph 4, DESCRIPTION: '-e     enable interpretation of backslash escape'> (0.996904) as an option paragraph
INFO:explainshell.algo.classifier:classified <paragraph 5, DESCRIPTION: '-E     disable interpretation of backslash escapes (default'> (0.998640) as an option paragraph
INFO:explainshell.algo.classifier:classified <paragraph 6, DESCRIPTION: '--help display this help and exi'> (0.999215) as an option paragraph
INFO:explainshell.algo.classifier:classified <paragraph 7, DESCRIPTION: '--version'> (0.999993) as an option paragraph
INFO:explainshell.store:inserting mapping (alias) echo -> echo (52207a1fa9b52e42fb59df36) with score 10
successfully added echo

Note that if you've setup using the docker instructions above, echo will already be in the database.

Contributing

Contributions are welcome! The project is actively maintained and issues are addressed regularly. When contributing:

  1. Ensure all tests pass (pytest -q ./tests/*.py ./explainshell)
  2. Follow the existing code style
  3. Add tests for new functionality
  4. Update documentation as needed

License

See LICENSE file for details.

About

match command-line arguments to their help text

Resources

License

Stars

Watchers

Forks

Releases

No releases published

Packages

 
 
 

Contributors

Languages

  • Python 81.4%
  • JavaScript 13.1%
  • HTML 3.6%
  • Perl 0.9%
  • CSS 0.5%
  • Makefile 0.2%
  • Other 0.3%