Wie verwende ich grep, um die Ausgabe --help zu durchsuchen?

7

Wenn Sie die Ausgabe eines Programms mit dem Parameter verwenden grepoder egrepdurchsuchen, wird --helpanstelle der übereinstimmenden Zeilen die gesamte Ausgabe gedruckt.

Beispiel:

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

Bei der Suche nach einem Parameter wie ssh-keygen --help | grep "-p"grep erkennt dieser Parameter diesen für sich. Es grep "\-p"hilft nicht, dem Bindestrich (dh ) zu entkommen.

Beispiel:

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]

Wie kann man das lösen? Vielen Dank für jede Hilfe!

Rapstacke
quelle

Antworten:

15

Der ssh-keygenBefehl hat keine --helpOption, gibt also den Fehler "Unbekannte Option" aus, denkt stillschweigend an "RTFM" und gibt die Hilfe aus. Dies geschieht nicht auf stdout, sondern auf stderr , das nicht mit, |sondern nur mit |&(was eine bashAbkürzung für ist 2>&1 |) versehen ist:

$ 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]

Ein völlig anderes Problem besteht grepdarin, Ihren Suchausdruck als Option zu erkennen, da er mit einem Bindestrich beginnt. Glücklicherweise grepist dies einer der vielen Befehle, die die --Option "Ende der Optionen" erkennen und alles dahinter als Argument anstelle einer Option verwenden:

$ ssh-keygen --help |& grep -- -p
       ssh-keygen -p [-P old_passphrase] [-N new_passphrase] [-f keyfile]

man greperwähnt es nicht einmal, aber hier ist die Beschreibung dieser Option aus dem bashHandbuch:

A --signalisiert das Ende von Optionen und deaktiviert die weitere Optionsverarbeitung. Alle Argumente nach dem --werden als Dateinamen und Argumente behandelt.

grepbietet auch eine zweite Möglichkeit, mit Mustern umzugehen, die mit „-“ beginnen: Die -eOption verwendet ein Muster als Argument, daher ist Folgendes ebenfalls möglich:

$ ssh-keygen --help |& grep -e -p
       ssh-keygen -p [-P old_passphrase] [-N new_passphrase] [-f keyfile]

Weiterführende Literatur

Dessert
quelle
toller Beitrag, aber warum sollte das grep-Handbuch Ihrer Meinung nach erwähnen, wie die Shell funktioniert --? Andere Shell-Funktionen wie Dateinamenerweiterung, Variablenerweiterung und Befehlssubstitution werden ebenfalls nicht erwähnt. Es gibt viele Dinge, die die Shell tut, bevor der Befehl ausgeführt wird. Ich denke, das grep-Handbuch ist nicht der richtige Ort für solche Details.
Wunder173
@ miracle173 bashund einige seiner Builtins verstehen --, aber die Shell macht nichts damit grep -- -p(was wäre das?). Es ist grepallein, der diese Option und ihre besondere Bedeutung versteht, daher sollte ihre Handbuchseite sie als Option auflisten.
Dessert
Du hast recht. Ich sehe jetzt, dass es auf einige der eingebauten beschränkt ist. Es ist also eigentlich eine Grep-Funktion.
Wunder173
@ miracle173 Durch die Implementierung grepfolgte POSIX Utility Syntax Guideline 10 , so ist es nicht ihre Idee, aber immer noch ...
Dessert
2

Sie rufen ssh-keygenmit einer nicht vorhandenen Option an. Dies ist ein Fehler, und die Fehlerausgabe wird auf stderr angezeigt. Es sieht nicht so aus, als hätte ssh-keygenes eine reguläre Option für die Ausgabe seiner Verwendung: Wenn dies der Fall wäre (wie dies bei GNU-Programmen standardmäßig der --helpFall ist), würde diese "reguläre" Ausgabe auf stdout erscheinen und für weniger in der von Ihnen verwendeten Pipe zugänglich sein.

Sie können dies umgehen, indem Sie ssh-keygen --help 2>&1 | grep -e "-p": 2>&1stderr nach stdout umleiten, wo die Pipe es fangen kann, und -eals Option für grep bedeutet "Folgendes ist der reguläre Ausdruck, der verwendet werden soll, auch wenn er wie eine Option aussieht".

man ssh-keygensollte besser funktionieren, um die Verwendung zu erhalten, und wird lessstandardmäßig weitergeleitet, wo Sie nach regulären Ausdrücken suchen können /, und das Lesen im Kontext ist normalerweise die bessere Wahl.

Eliah Kagan
quelle
2

Wenn Sie Hilfe zum Befehl ssh-keygen suchen, versuchen Sie es

man ssh-keygen | grep known_hosts

Sie können dies auch man ssh-keygenüber eine Befehlszeile tun und dann /den Suchbegriff drücken und eingeben, z. B. "kno". Drücken Sie Enter, verwenden Sie n, um mit der nächsten Instanz des Suchbegriffs fortzufahren ( man manweitere Informationen zur Verwendung man). Beachten Sie, dass die manSuche nur nach unten sucht. Verwenden Sie daher PgUpoder Home, um zum Anfang des manuellen Eintrags zurückzukehren, bevor Sie eine neue Suche starten.

Stephen Boston
quelle