Lors de l'écriture d'outils pour la CLI d'UNIX, comment dois-je faire pour que le programme imprime l'aide et / ou l'utilisation?
J'utilise habituellement fprintf(stderr, "help text here");
, mais il y a plusieurs problèmes avec cela.
- Tout d'abord, je ne sais pas si je devrais utiliser
stderr
. Est-ce correct ou dois-je utiliserstdout
? - Comme vous pouvez l'imaginer, le texte d'aide est assez long, selon le nombre d'options de l'outil. Maintenant, j'ai l'habitude d'en mettre plusieurs
"strings like that\n"
dans le deuxième paramètre. Cependant, cela remplit mon code source de cinquante lignes ou plus de texte d'aide. Ce n'est pas facile à gérer du tout. Que dois-je faire à la place? - Lorsqu'un outil n'est pas écrit en C ou dans un langage de type C, j'ai tendance à utiliser ici-docs lorsque cela est possible (surtout avec Perl). Je ne peux pas utiliser ça en C, mais y a-t-il quelque chose comme ça, que je pourrais utiliser?
- J'envisageais de le mettre dans un
headerfile.h
intérieur#define HELP "help text here"
, je ne l'ai jamais vu dans la nature, je ne sais pas si je devrais vraiment l'utiliser.
Idéalement, je pourrais mettre le texte dans un fichier externe et l'inclure. Utiliser #include
pour cela semble cependant mal. Que dois-je faire alors?
L'idée est d'avoir un texte d'aide facilement gérable. L'avoir dans le code source n'est pas vraiment pratique.
Réponses:
Inspirez-vous des composants internes de votre plateforme cible
Jetez un œil au code source du BSD. Par exemple, voici:
usage(void)
pour l'/usr/bin/uname
outil de NetBSD [ source ]:usage(void)
pour NetBSD/usr/bin/telnet
[ source ]usage(void)
pour OpenBSD/bin/ls
[ source ]Jetez un œil aux alternatives
Et décidez vous-même s'ils sont meilleurs ou pires. Vous pouvez utiliser Google CodeSearch pour en trouver d'autres, comme:
Comme vous pouvez le voir, style différent entre ceux-ci et les outils intégrés aux systèmes BSD répertoriés ci-dessus. Cela ne signifie pas que vous devez suivre l'un ou l'autre. Mais généralement, il est bon de regarder autour de soi et de se contenter d'une solution cohérente.
Une solution non standard aux 50 lignes d'aide ...
Si vous n'aimez pas éviter 50 lignes de texte, vous pouvez simplement lire l'aide d'un fichier texte (en texte brut, ou peut-être analyser directement la
man
source du si vous en avez créé un). Je trouve que c'est une manière plutôt élégante (comme vous pouvez même rechercher le document texte), cependant pour les programmes de systèmes de base qui les rendraient intrinsèquement dangereux et introduiraient un point d'échec. D'autres personnes diront que c'est lourd pour unusage
ou unhelp
message, mais ce n'est pas comme si on les appelait en boucles serrées rapides ...En cas de doute, suivez les géants.
la source
J'utilise
stdout
, car une aide n'est pas une erreur.Si c'est une longue aide en C, j'essaie d'imiter ici-docs:
Mais la plupart du temps, j'écris une
man
page à l'aide denroff -man
balises dédiées. L'aide intégrée à l'application consiste simplement à se référer à cetteman
page.la source
stdlog
?stdlog
norme C?cin
,cout
,cerr
etclog
), donc je suppose que je pensaisstdlog
était dans la norme C. Ma faute.Si je serais vous , je viens d' ouvrir des sources de
grep
,tail
,cat
,your_other_favorite_unix_shell_command
pour voir comment il est fait là - bas. Je suis sûr que leurs méthodes sont assez bien pensées et peuvent être entretenues par de nombreuses personnes.À propos de
stderr
oustdout
. C'est vraiment simple, s'il y a une erreur - écrivez àstderr
, si c'est juste des informations -stdout
. Par exemple, si j'exécute votre outil avec de mauvaises options, vous souhaiterez peut-être afficher une erreur, par exempleUse --help for usage
, celle-ci appartientstderr
. Si je lance votre outil avec une option valide--help
, veuillez utiliserstdout
.Si vous préférez ne pas avoir de longues chaînes d'aide près de votre code, ne le faites pas. #define dans un fichier d'en-tête est parfaitement bien, mais c'est vraiment une préférence personnelle. Si je devais lire le code d'un outil de ligne de commande, je préférerais que sa chaîne d'aide soit dans un fichier qui gère les options fournies par l'utilisateur.
la source
J'utilise la bibliothèque gnu getopts . Pour un exemple d'aide, consultez cet exemple de projet , en particulier la méthode principale au bas de parser.y .
Puisqu'il est entouré d'accolades, l'éditeur de vim que j'utilise peut plier les lignes ensemble, et je ne les remarque même pas quand je n'en ai pas besoin.
la source
Si j'utilise C ou préfère ne pas dépendre des bibliothèques Boost, je m'en tiens à GNU
getopt
. Sinon, je préfère les options du programme Boost qui impriment l'aide automatiquement.Je considère également que deviner la bonne option est l'une des meilleures pratiques en matière de gestion des options. Je l'ai appris de Git et j'utilise maintenant la même chose dans mes projets. Il utilise essentiellement la distance Damerau – Levenshtein pour imprimer les meilleures correspondances si l'utilisateur entre une option de ligne de commande inconnue.
J'ai écrit un petit article à ce sujet que vous pouvez utiliser comme exemple.
J'espère que ça aide :)
la source
De toute évidence, écrire une page de trou dans le code cout << ou printf () est fastidieux, en particulier si vous devez modifier et remplir à nouveau vos paragraphes. Par conséquent, c'est évidemment une bonne idée de modifier ce texte dans un fichier séparé, en utilisant par exemple emacs où vous pouvez plus facilement formater votre texte.
Ensuite, vous pouvez utiliser le script sed suivant pour convertir ce fichier texte en un fichier d'en-tête C légal:
Ensuite, lors de l' inclusion de votre fichier d'en-tête dans votre code source, vous pouvez simplement écrire votre texte en utilisant
la source