Was wird als Best Practice für die Drucknutzung / -hilfe (--help) angesehen?


12

Wie soll ich beim Schreiben von Tools für die CLI von UNIX das Programm zum Ausdrucken der Hilfe und / oder Verwendung verwenden?

Ich benutze normalerweise fprintf(stderr, "help text here");, aber es gibt mehrere Probleme damit.

  • Erstens bin ich mir nicht sicher, ob ich verwenden soll stderr. Ist das in Ordnung oder soll ich verwenden stdout?
  • Wie Sie sich vorstellen können, ist der Hilfetext ziemlich lang, je nachdem, über wie viele Optionen das Tool verfügt. Jetzt setze ich normalerweise nur mehrere "strings like that\n"in den zweiten Parameter. Dies füllt meinen Quellcode jedoch mit fünfzig oder mehr Zeilen Hilfetext. Es ist überhaupt nicht einfach zu handhaben. Was soll ich stattdessen tun?
  • Wenn ein Tool nicht in C oder einer C-ähnlichen Sprache geschrieben ist, verwende ich hier nach Möglichkeit Here-Docs (am bekanntesten bei Perl). Ich kann das nicht in C verwenden, aber gibt es so etwas, das ich verwenden könnte?
  • Ich habe darüber nachgedacht, es in ein headerfile.hInneres zu stecken #define HELP "help text here". Ich habe es noch nie in freier Wildbahn gesehen. Ich weiß nicht, ob ich das tatsächlich verwenden soll.

Im Idealfall könnte ich den Text in eine externe Datei einfügen und einfügen. Die Verwendung #includedafür scheint jedoch falsch zu sein. Was sollte ich dann tun?

Die Idee ist, einen Hilfetext zu haben, der leicht zu handhaben ist. Es ist nicht wirklich praktisch, es im Quellcode zu haben.


1
Was ist so schlimm an 50 Zeilen in Ihrem Quellcode? Setzen Sie es einfach am Ende. Es ist nicht so, dass Sie sich regelmäßig damit anlegen müssen.
Whatsisname

2
@whatsisname Verwendung, Hilfe für normale und Longopts. Am Ende habe ich ungefähr 200 Zeichenfolgen im Sourcode. Abgesehen davon denke ich einfach nicht, dass dies eine bewährte Methode ist usw. Es muss eine effizientere Möglichkeit geben, Hilfetexte usw.
einzufügen

Antworten:


8

Lassen Sie sich von den Interna Ihrer Zielplattform inspirieren

Schauen Sie sich den Quellcode des BSD an. Zum Beispiel sind hier die:

  • usage(void)für das NetBSD- /usr/bin/unameTool [ Quelle ]:

    usage(void)
    {
        fprintf(stderr, "usage: uname [-amnprsv]\n");
        exit(EXIT_FAILURE);
    }
    
  • usage(void)für NetBSDs /usr/bin/telnet[ Quelle ]

  • usage(void)für OpenBSDs /bin/ls[ Quelle ]

Schauen Sie sich Alternativen an

Und entscheiden Sie selbst, ob sie besser oder schlechter sind. Sie können Google CodeSearch verwenden, um andere zu finden, z.

  • Verwendung von SkyLoad [ Quelle ]

Wie Sie sehen können, unterscheiden sich die oben aufgeführten Tools zwischen diesen und den integrierten BSD-Systemen. Es bedeutet nicht , Sie haben das eine oder andere zu folgen. Aber normalerweise ist es gut, sich umzuschauen und sich mit der konsistenten Lösung zufrieden zu geben.

Eine nicht standardmäßige Lösung für die 50 Hilfslinien ...

Wenn Sie 50 Textzeilen nicht vermeiden möchten, können Sie einfach die Hilfe aus einer Textdatei lesen (im Klartext oder die manQuelle des Textes direkt analysieren , wenn Sie eine erstellt haben). Ich finde das eine ziemlich elegante Art (wie Sie sogar das Textdokument nachschlagen können), jedoch für Kernsystemprogramme, die sie von Natur aus unsicher machen und einen Fehlerpunkt einführen würden. Andere Leute werden argumentieren, dass es schwer für eine usageoder eine helpNachricht ist, aber es ist nicht so, dass diese in schnellen engen Schleifen aufgerufen werden ...

Wenn Sie Zweifel haben, folgen Sie den Riesen.


8

Ich benutze stdout, weil eine Hilfe kein Fehler ist.

Wenn dies eine lange Hilfe in C ist, versuche ich, die folgenden Dokumente nachzuahmen:

printf("This is the help for MyWonderfulApp\n"
       "Options are:\n"
       "    --help: display what you are reading now\n"
       "    --quiet: output nothing\n");

Aber die meiste Zeit schreibe ich eine manSeite mit nroff -mandedizierten Tags. Die In-App-Hilfe besteht einfach darin, auf diese manSeite zu verweisen .


Aber Hilfe ist nicht unbedingt eine wünschenswerte Standardausgabe, oder? Wie wäre es stdlog?
Greyfade

@ Greyfade: Ist stdlogStandard C?
Mouviciel

@mouviciel: ... ich dachte es wäre. Ich denke nicht. C ++ einen verwandten Standard Strom hat ( cin, cout, cerrund clog), so dass ich glaube , ich dachte stdlogin dem C - Standard war. Mein Fehler.
Greyfade

2

Wenn ich Sie wäre , würde ich gerade eröffnet auf Quellen grep, tail, cat, your_other_favorite_unix_shell_commandum zu sehen , wie es dort getan hat. Ich bin mir ziemlich sicher, dass ihre Wege ziemlich gut durchdacht sind und von vielen Menschen gepflegt werden können.

Über stderroder stdout. Es ist wirklich einfach, wenn es einen Fehler gibt - schreiben Sie an stderr, wenn es nur Informationen sind - stdout. Wenn ich beispielsweise Ihr Tool mit falschen Optionen ausführe, möchten Sie möglicherweise einen Fehler anzeigen, z. B. Use --help for usagediesen gehört dazu stderr. Wenn ich Ihr Tool mit einer gültigen Option ausführe --help, verwenden Sie bitte stdout.

Wenn Sie keine langen Hilfezeichenfolgen in der Nähe Ihres Codes bevorzugen, tun Sie dies nicht. #define in einer Header-Datei ist vollkommen in Ordnung, aber es ist wirklich eine persönliche Präferenz. Wenn ich den Code eines Befehlszeilentools lesen müsste, würde ich es vorziehen, wenn sich die Hilfezeichenfolge in einer Datei befindet, die die vom Benutzer bereitgestellten Optionen verarbeitet.


2
Das beantwortet seine Frage nicht.
Mavrik

Hm, was ist mit dem Minus? Wozu?
devmiles.com

@Mavrik: Der erste Absatz tut es.
Haylem

1

Ich benutze die gnu getopts Bibliothek. Ein Beispiel mit Hilfe finden Sie in diesem Beispielprojekt , insbesondere in der Hauptmethode am Ende von parser.y .

Da es in geschweiften Klammern eingeschlossen ist, kann der von mir verwendete Vim-Editor die Linien zusammenfalten, und ich bemerke sie nicht einmal, wenn ich es nicht brauche.


1

Wenn ich C verwende oder mich nicht auf Boost-Bibliotheken verlassen möchte, bleibe ich bei GNU getopt. Ansonsten bevorzuge ich Boost-Programmoptionen, bei denen die Hilfe automatisch gedruckt wird.

Ich halte es auch für eine der besten Methoden, die richtige Option zu erraten, wenn es um die Handhabung von Optionen geht. Ich habe es von Git gelernt und verwende es jetzt in meinen Projekten. Grundsätzlich wird der Abstand Damerau - Levenshtein verwendet, um die besten Übereinstimmungen zu drucken, wenn der Benutzer eine unbekannte Befehlszeilenoption eingibt.

Ich habe einen kleinen Artikel darüber geschrieben , den Sie als Beispiel verwenden können.

Ich hoffe es hilft :)


1

Das Schreiben einer Lochseite in cout << oder printf () Code ist natürlich umständlich, insbesondere wenn Sie Ihre Absätze ändern und neu füllen müssen. Daher ist es natürlich eine gute Idee, diesen Text in einer separaten Datei zu bearbeiten, z. B. mit Emacs, mit denen Sie Ihren Text einfacher formatieren können.

Anschließend können Sie das folgende sed- Skript verwenden, um diese Textdatei in eine legale C-Header-Datei zu konvertieren:

s/\"/\\\"/g
s/$/\\n"/
s/^/"/
1i\
const char *helpStr = 
$a\
;

Dann wird bei # include Headerdatei in Ihrem Quellcode -ing, können Sie einfach schreiben Sie Ihren Text mit

cout << helpStr;
Durch die Nutzung unserer Website bestätigen Sie, dass Sie unsere Cookie-Richtlinie und Datenschutzrichtlinie gelesen und verstanden haben.
Licensed under cc by-sa 3.0 with attribution required.