Ubuntu – How to use grep to search through the –help output

bashcommand linegrep

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!

Best Answer

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

Related Question