Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Command line version #4

Open
OndroNR opened this issue Aug 31, 2013 · 21 comments
Open

Command line version #4

OndroNR opened this issue Aug 31, 2013 · 21 comments

Comments

@OndroNR
Copy link

OndroNR commented Aug 31, 2013

I would appreciate command line version, so I could write explain tar xzvf archive.tar.gz or even explain !!.

@xiongchiamiov
Copy link

I was going to attempt that this weekend. :)

@xiongchiamiov
Copy link

So the first major difficulty I've run into is that explainshell uses lexgrog for parsing. lexgrog is part of man-db, an alternative man implementation that's only used on a few Linux distros. Notably, this doesn't include CentOS (though perhaps it will eventually, since it's in Fedora), or any non-Linux Unixes (the BSDs, OS X).

I think you can do the same thing with groff, given enough work, but the simpler option is to just use whatis - it seems to give us the same sort of output, albeit only for installed manpages (but that's what we're working off of for a local version, right?).

@idank
Copy link
Owner

idank commented Aug 31, 2013

I think we should start with a client that queries explainshell.com, so it can be as thin as possible and require none of the dependencies needed to run explainshell locally.

So the only thing missing is an API at explainshell.com/api/?command=... that returns the structure exposed by the matcher, who given a command string returns a list of (start-index, end-index, help-text) that we found a matching argument for in the man page.

Then a client simply calls this API and can do cool things like colorize each argument(s) with its help text, like the web interface does with the lines.

@xiongchiamiov
Copy link

Although the dependencies are a bitch, the advantage of doing a purely-client implementation is that it gets the info for the man pages on the system, rather than some arbitrary other system. This irons out problems with version mismatches between Linux distros (the packages on CentOS are significantly older than Ubuntu), implementation mismatches (e.g. bsd ls vs. gnu ls), and miscellaneous locally-installed programs (that aren't global enough to be included in explainshell.com).

That being said, an API-querying thin client is probably easier to create (and certainly to install). I think there's motivation for both existing.

@petems
Copy link

petems commented Sep 2, 2013

This would be an awesome feature, I can imagine the cross-platform-ness being a bit of a headache though...

@weakish
Copy link

weakish commented Sep 2, 2013

A quick and dirty wrapper using command line browser (w3m) to view explainshell pages: https://gist.github.com/weakish/733022#file-explainshell-rc

@idank
Copy link
Owner

idank commented Sep 7, 2013

I agree it could get messy if the man page the site has is different than the one you have locally (perhaps in the future, you could submit your copy to explainshell.com and it will remember it?). But I think over time as more man pages will be added, the problem might become smaller and smaller. I'm not particularly keen on keeping multiple versions of the same program, besides different variants such as gnu/bsd/etc.

The main argument for working with the live site as I see it is that it contains manual corrections that I've done, and in the future I expect these corrections to be done by users too, resulting in more accuracy than that provided by the automatic extractor algorithm.

Having said that, I'll help in any way I can to get a nice fully local explainshell.

@OndroNR
Copy link
Author

OndroNR commented Sep 14, 2013

As beginner user of linux I would be satisfied with thin client, that queries explainshell.com for quick lookup of simple commands. But sometime I work offline, so I would use standalone version as well.

@patcon
Copy link

patcon commented Dec 2, 2013

+1 for api

@drewcrawford
Copy link

+1 for API

If the API supports man page submission, then the CLI application could just upload the local manpage if an acceptable one isn't available on the server. By this solution, you have the advantage desired by @xiongchiamiov of providing output for all local manpages, and the advantage desired by @idank for relying on manually-moderated information if it is available. Further, the output of explainshell.com improves, both reducing the need for and streamlining the manpage submission process.

@idank idank mentioned this issue Dec 5, 2013
@idank
Copy link
Owner

idank commented Dec 5, 2013

That sounds like a nice solution @drewcrawford. I haven't really started thinking of an API for submitting man pages, that would be quite tricky, but it's definitely something I'd like to do at some point.

@joyrexus
Copy link

@xiongchiamiov In lieu of a RESTful API, one can replicate the backend (mongorestore dump/explainshell) and hack up a little CLI interface. FWIW, here's an elementary proof-of-concept.

The classification collection could of course be munged for easier querying.

@troydm
Copy link

troydm commented Jan 28, 2014

Here is my command line version perl script #76
Needs only vanila perl and curl to run

@idank idank mentioned this issue Aug 6, 2014
@bfr
Copy link

bfr commented Jan 25, 2015

https://github.com/bfr/explainshellcli

@idank
Copy link
Owner

idank commented Jan 25, 2015

Nice, small and simple :).

@troydm
Copy link

troydm commented Jan 25, 2015

Here is link for mine https://github.com/troydm/exp

@diimdeep
Copy link

#!/bin/bash
w3m "http://explainshell.com/explain?cmd="`echo $@ | tr ' ' '+'}`

@bfr
Copy link

bfr commented Jan 26, 2015

Good solution if you have w3m available. I would maybe dump the page to stdout and cut out the top of the page. Something like this(Maybe replace the sed line with something more flexible, but you get the point):

w3m -dump "http://explainshell.com/explain?cmd="`echo $@ | tr ' ' '+'}` | sed '1,16d'

@bradparks
Copy link

bradparks commented Aug 18, 2017

Thanks for the idea @bfr - I wrapped your approach up a wee bit more to remove some cruft like double blank lines, any lines that mentioned explainshell or had "bullets" in them generated by html. So this doesnt use sed to find the offset, it just removes all the other stuff.

explain_shell

OUT=$(w3m -dump "http://explainshell.com/explain?cmd="`echo $@ | tr ' ' '+'}`)
echo
echo "$OUT"| grep -v explainshell | grep -v • | grep -v "source manpages" | sed '/./,$!d' | cat -s 
$ explain_shell ls -ltr    

ls(1)

-ltr

list directory contents

-l     use a long listing format

-t     sort by modification time, newest first

-r, --reverse
       reverse order while sorting

@shivansh
Copy link

shivansh commented Jan 2, 2018

@bradparks I made a few changes to your version to make it a little bit faster.

#!/bin/bash

set -euo pipefail

# Here strings are noted to be faster for a small amount of
# data as compared to pipes where the setup cost dominates.
# https://unix.stackexchange.com/a/219806/158139
response=$(w3m -dump "http://explainshell.com/explain?cmd="$(echo $@ | tr ' ' '+'}))
cat -s <(grep -v -e explainshell -e • -e □ -e "source manpages" <<< "$response")

Gist

Benchmarks

Before:

explain-shell ls -ltr  0.02s user 0.00s system 1% cpu 1.849 total

After:

explain-shell ls -ltr  0.02s user 0.00s system 1% cpu 1.728 total

@CMCDragonkai
Copy link

Having a command line version would be like an extension to man itself. In fact it is the better version of man like as if having man explain '...'.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests