Qual è la migliore pratica per la stampa di utilizzo / aiuto (--help)?

11

Durante la scrittura di strumenti per la CLI di UNIX, come posso fare in modo che il programma stampi aiuto e / o utilizzo?

Di solito uso fprintf(stderr, "help text here"); , ma ci sono diversi problemi con questo.

  • In primo luogo, non sono sicuro, se dovrei usare stderr . Va bene, o dovrei usare stdout ?
  • Come puoi immaginare, il testo della guida è piuttosto lungo, a seconda di quante opzioni ha lo strumento. Ora, di solito, metto solo diversi "strings like that\n" nel secondo parametro. Questo, comunque, riempie il mio codice sorgente con cinquanta o più righe di testo di aiuto. Non è affatto facile da gestire. Cosa dovrei fare invece?
  • Quando uno strumento non è scritto in C o in un linguaggio simile a C, tendo a usare here-docs dove possibile (in modo predominante con Perl). Non posso usarlo in C, ma c'è qualcosa di simile, che potrei usare?
  • Stavo considerando di inserirlo in un headerfile.h all'interno di #define HELP "help text here" , non l'ho mai visto in natura, non so se dovrei effettivamente usarlo.

Idealmente, potrei inserire il testo in un file esterno e includerlo. Tuttavia, usare #include per quello sembra sbagliato. Cosa dovrei fare allora?

L'idea è, per avere un testo di aiuto, che sia facilmente gestibile. Averlo nel codice sorgente non è molto comodo.

    
posta polemon 29.02.2012 - 00:27
fonte

6 risposte

8

Ispirati alle parti interne della piattaforma di destinazione

Dai un'occhiata al codice sorgente di BSD. Ad esempio, qui ci sono:

  • usage(void) per lo strumento /usr/bin/uname di NetBSD [ fonte ]:

    usage(void)
    {
        fprintf(stderr, "usage: uname [-amnprsv]\n");
        exit(EXIT_FAILURE);
    }
    
  • usage(void) per /usr/bin/telnet di NetBSD [ fonte ]

  • usage(void) per /bin/ls di OpenBSD [ fonte ]

Dai un'occhiata alle alternative

E decidi tu stesso se stanno meglio o peggio. Puoi utilizzare Google CodeSearch per trovare altri, come:

Come potete vedere, uno stile diverso tra questi e gli strumenti integrati dei sistemi BSD elencati sopra. Ciò non significa che devi seguire l'uno o l'altro. Ma di solito è bene guardarsi intorno e accontentarsi della soluzione coerente.

Una soluzione non standard per le 50 linee di aiuto ...

Se non ti piace evitare 50 righe di testo, puoi semplicemente leggere l'aiuto da un file di testo (in testo normale, o magari analizzare direttamente l'origine di man se ne hai creato uno). Trovo che sia un modo piuttosto elegante (come si può anche consultare il documento di testo), tuttavia per i programmi di sistema di base che li renderebbe intrinsecamente insicuri e introdurrebbero un punto di errore. Altre persone sostengono che è pesante per un messaggio usage o help , ma non è come se fossero chiamati in loop rapidi e stretti ...

In caso di dubbio, segui i giganti.

    
risposta data 29.02.2012 - 10:31
fonte
7

Uso stdout , perché un aiuto non è un errore.

Se questo è un lungo aiuto in C, provo a imitare here-docs:

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

Ma la maggior parte delle volte scrivo una pagina man usando i tag dedicati nroff -man . La guida in-app consiste semplicemente nel riferirsi a quella pagina man .

    
risposta data 29.02.2012 - 10:08
fonte
2

Se fossi in te, avrei semplicemente aperto fonti di grep , tail , cat , your_other_favorite_unix_shell_command per vedere come è fatto lì. Sono abbastanza sicuro che le loro modalità siano ben pensate e possano essere mantenute da molte persone.

Informazioni su stderr o stdout . È davvero semplice, se c'è un errore: scrivi a stderr , se è solo info - stdout . Ad esempio, se eseguo lo strumento con opzioni errate, potresti voler visualizzare un errore, ad esempio Use --help for usage , questo appartiene a stderr . Se eseguo lo strumento con un'opzione valida --help , utilizza stdout .

Se preferisci non avere stringhe di aiuto lunghe vicino al tuo codice, non farlo. #define in un file di intestazione è perfettamente soddisfacente, ma è davvero una preferenza personale. Se dovessi leggere il codice di uno strumento da riga di comando, preferirei che la sua stringa di aiuto fosse all'interno di un file che gestisse le opzioni fornite dall'utente.

    
risposta data 29.02.2012 - 09:36
fonte
1

Se utilizzo C o preferisco non dipendere dalle librerie Boost, quindi rimango con GNU getopt . In caso contrario, preferisco Opzioni del programma di potenziamento che consente di stampare automaticamente.

Ritengo inoltre che l'opzione giusta sia una delle migliori pratiche per quanto riguarda la gestione delle opzioni. L'ho imparato da Git e ora uso lo stesso nei miei progetti. In pratica utilizza la distanza di Damerau-Levenshtein per stampare le corrispondenze migliori se l'utente inserisce qualche opzione della riga di comando sconosciuta.

Ho scritto un piccolo articolo su questo che puoi usare come esempio.

Spero che aiuti:)

    
risposta data 05.12.2013 - 20:43
fonte
1

Ovviamente, scrivere una pagina buca nel codice cout < < o printf () è complicato, in particolare se devi modificare e riempire nuovamente i paragrafi. Quindi, è ovviamente una buona idea modificare quel testo in un file separato, usando ad esempio emacs dove puoi facilmente formattare il testo.

Quindi puoi utilizzare il seguente script sed per convertire quel file di testo in un file di intestazione C legale:

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

Quindi, su #include -inserendo il tuo file di intestazione nel codice sorgente, puoi semplicemente scrivere il tuo testo usando

cout << helpStr;
    
risposta data 17.12.2018 - 22:12
fonte

Leggi altre domande sui tag