How to use grep to search through the --help output?
When using grep
or egrep
to search through the output from a program with the --help
parameter it prints the complete output instead of the lines that match.
Example:
ssh-keygen --help | grep "known_hosts"
unknown option -- -
usage: ssh-keygen [-q] [-b bits] [-t dsa | ecdsa | ed25519 | rsa | rsa1]
[-N new_passphrase] [-C comment] [-f output_keyfile]
ssh-keygen -p [-P old_passphrase] [-N new_passphrase] [-f keyfile]
ssh-keygen -i [-m key_format] [-f input_keyfile]
ssh-keygen -e [-m key_format] [-f input_keyfile]
ssh-keygen -y [-f input_keyfile]
// etc
When searching for a parameter like ssh-keygen --help | grep "-p"
grep recognizes this parameter for itself. Escaping the dash (i.e. grep "\-p"
) does not help.
Example:
ssh-keygen --help | grep "-p"
grep: invalid option -- 'p'
Usage: grep [OPTION]... PATTERN [FILE]...
Try 'grep --help' for more information.
unknown option -- -
usage: ssh-keygen [-q] [-b bits] [-t dsa | ecdsa | ed25519 | rsa | rsa1]
[-N new_passphrase] [-C comment] [-f output_keyfile]
ssh-keygen -p [-P old_passphrase] [-N new_passphrase] [-f keyfile]
ssh-keygen -i [-m key_format] [-f input_keyfile]
ssh-keygen -e [-m key_format] [-f input_keyfile]
ssh-keygen -y [-f input_keyfile]
ssh-keygen -c [-P passphrase] [-C comment] [-f keyfile]
ssh-keygen -l [-v] [-E fingerprint_hash] [-f input_keyfile]
ssh-keygen -B [-f input_keyfile]
How to solve this? Thanks for any help!
The ssh-keygen
command doesn’t have a --help
option, so it prints the “unknown option” error, silently thinks “RTFM” and outputs the help. It does this not on stdout but on stderr, which is not piped with |
but only with |&
(which is a bash
shorthand for 2>&1 |
):
$ ssh-keygen --help |& grep "known_hosts"
ssh-keygen -F hostname [-f known_hosts_file] [-l]
ssh-keygen -H [-f known_hosts_file]
ssh-keygen -R hostname [-f known_hosts_file]
A totally different issue is grep
recognizing your search expression as an option because it starts with a hyphen. Fortunately grep
is one of the many commands which recognize the “end of options” --
option and takes everything behind it as an argument instead of an option:
$ ssh-keygen --help |& grep -- -p
ssh-keygen -p [-P old_passphrase] [-N new_passphrase] [-f keyfile]
man grep
doesn’t even mention it, but here’s this option’s description from the bash
manual:
A
--
signals the end of options and disables further option processing. Any arguments after the--
are treated as filenames and arguments.
grep
also provides a second way to deal with patterns beginning with “-”: The -e
option takes a pattern as its argument, thus the following is equally possible:
$ ssh-keygen --help |& grep -e -p
ssh-keygen -p [-P old_passphrase] [-N new_passphrase] [-f keyfile]
Further reading
man bash
/SHELL GRAMMAR/Pipelines- What does “--” (double-dash) mean?
man grep
/OPTIONS/Matching Control
You call ssh-keygen
with a non-existent option. That is an error, and error output appears on stderr. It does not appear like ssh-keygen
has a regular option for outputting its usage: if it had (like GNU programs have by default with --help
), that "regular" output would appear on stdout and be accessible to less in the pipe you used.
You can kludge around this using ssh-keygen --help 2>&1 | grep -e "-p"
: the 2>&1
redirects stderr to stdout where the pipe can catch it, and -e
as an option to grep means "the following is the regexp to use even if it looks like an option".
man ssh-keygen
should work better for getting the usage and will pipe into less
by default where you can search regular expressions with /
, and reading in context is usually the better choice.
If what you're looking for is help on the ssh-keygen command try
man ssh-keygen | grep known_hosts
Or, you can do man ssh-keygen
from a command line and then press / and type the search term, eg "kno", press Enter, use n to continue to the next instance of the search term (man man
for more info about using man
). Note the man
search only searches down, so use PgUp or Home to return to the start of the manual entry before starting a new search.