Tout en développant l'application, j'ai commencé à me demander: comment concevoir des arguments en ligne de commande?
Beaucoup de programmes utilisent une formule comme celle-ci -argument value
ou /argument value
. La solution qui m'est venue à l’esprit était argument:value
. Je pensais que c'était une bonne chose, car sans espaces blancs, il était impossible de brouiller valeurs et arguments. En outre, il est facile de scinder une chaîne en deux sur le premier à partir du :
caractère de gauche .
Mes questions sont:
- La
-argument value
formule populaire est-elle meilleure queargument:value
(plus lisible, plus facile à écrire, sans bug, plus facile à comprendre pour les développeurs experts)? - Existe-t-il des règles connues que je devrais suivre lors de la conception des arguments en ligne de commande (autre que si ça marche, c'est OK)?
Demandé pour plus de détails je vais le fournir. Cependant, je pense qu'ils ne devraient pas affecter les réponses. La question concerne les bonnes habitudes en général. Je pense qu'ils sont tous les mêmes pour toutes sortes d'applications.
Nous travaillons sur une application qui sera utilisée dans des lieux publics (totems tactiles, tableaux). Les applications sont écrites avec Qt Quick 5 (C ++, QML, JS). Windows 8.1 / 10 sera installé sur les périphériques. Nous allons fournir une interface frontale pour gérer les appareils. Cependant, certains administrateurs avancés peuvent vouloir configurer eux-mêmes l'application. Ce n'est pas très important du point de vue de l'entreprise, mais comme je suis d'accord avec ce que Kilian Foth a dit, je ne veux pas que mon application soit pénible pour un utilisateur. Ne trouvant pas dans Internet ce que je veux, j'ai demandé ici.
Aux utilisateurs plus avancés de Stack Exchange: Je voulais que cette question soit générale. Peut-être qualifie-t-il le wiki de la communauté (je ne sais pas si la question existante peut être convertie avec des réponses). Comme je veux que cette question soit indépendante du système d'exploitation et du langage de programmation, les réponses qui apparaissent ici peuvent constituer une leçon précieuse pour les autres développeurs.
la source
ls -ltr
pour combiner les options-l
,-t
et-r
. Les programmes de style GNU autorisent également les options basées sur les mots avec un double trait d'union,--reverse
au lieu de-r
. Il existe d'autres conventions populaires comme-h
afficher l'aide,--
signaler la fin des options, spécifier-
un nom de fichier pour autoriser la lecture à partir de stdin, etc.-argument value
pas-argument:value
communs. Communs sont-a value
,-avalue
et--argument=value
.getopt(s)
) où vous pouvez.Réponses:
Sur les systèmes POSIX (par exemple Linux, MacOSX), du moins pour les programmes éventuellement démarrés dans un terminal shell (par exemple, la plupart d'entre eux), je recommanderais d'utiliser les conventions de codage GNU (qui répertorie également les noms d'arguments courants) et de consulter les instructions relatives aux utilitaires POSIX. , même pour les logiciels propriétaires:
toujours manipuler
--version
et--help
(même les/bin/true
accepte !!). Je maudis les auteurs de logiciels qui ne comprennent pas--help
, je les déteste (carprog --help
c'est la première commande que j'essaye d'un nouveau programme)! Souvent,--help
peut être abrégé en-h
Demandez au
--help
message de répertorier toutes les options (sauf si vous en avez trop ... dans ce cas, listez les plus courantes et référez-vous explicitement à uneman
page ou à une URL) et aux valeurs par défaut des options, et peut-être important (et spécifique au programme). ) Variables d'environnement. Afficher ces listes d'options en cas d'erreur d'argument.accepter l'
-a
argument court (lettre simple) et avoir un équivalent--long-argument
, donc-a2
--long-argument=2
,--long-argument 2
; bien sûr, vous pourriez avoir (pour les options rarement utilisées) un--only-long-argument
nom; pour les arguments modaux sans options supplémentaires-cf
est généralement traité comme-c -f
, etc., donc votre-argument:value
proposition est étrange, et je ne recommande pas de le faire.utilisez GLIBC getopt_long ou mieux (par exemple, argp_parse , dans OCaml c'est son
Arg
module , ...)utilisez souvent
-
pour une entrée ou une sortie standard (si vous ne pouvez pas faire cela, manipulez/dev/stdin
et/dev/stdout
même sur les rares systèmes d'exploitation qui n'en ont pas)imitez le comportement de programmes similaires en réutilisant la plupart de leurs conventions d'options; en particulier
-n
pour les essais à secmake
,-h
à l'aide,-v
pour la verbosité, etc ...utiliser
--
comme séparateur entre les options et le fichier ou d'autres argumentssi votre programme utilise
isatty
pour tester alors que stdin est un terminal (et se comporte de manière "interactive" dans ce cas), fournissez une option pour forcer le mode non interactif, de même si votre programme dispose d'une interface graphique (et effectue des testsgetenv("DISPLAY")
sur le bureau X11), mais peut également être utilisé en batch ou en ligne de commande.Certains programmes (par exemple
gcc
) acceptent les listes d'arguments indirects, ce qui@somefile.txt
signifie que les arguments de programme lus sont lussomefile.txt
; cela peut être utile lorsque votre programme peut accepter un très grand nombre d'arguments (plus que ceux de votre noyauARG_MAX
)BTW, vous pouvez même ajouter des fonctionnalités de saisie automatique pour votre programme et les shells habituels (comme
bash
ouzsh
)Certaines anciennes commandes Unix (par exemple
dd
, ou mêmesed
) ont des arguments de commande étranges pour la compatibilité historique. Je recommanderais de ne pas suivre leurs mauvaises habitudes (à moins que vous ne leur donniez une meilleure variante).Si votre logiciel est une série de programmes de ligne de commande connexes, se inspirer de git (que vous utilisez sûrement comme un outil de développement), qui accepte
git help
etgit --help
et ont beaucoupgit
subcommand
etgit
subcommand
--help
Dans de rares cas, vous pouvez également utiliser
argv[0]
(en utilisant des liens symboliques dans votre programme), par exemplebash
invoqué sousrbash
un comportement différent ( shell restreint ). Mais je ne recommande généralement pas de faire cela; il pourrait être judicieux d'utiliser votre programme comme interpréteur de script en utilisant shebang, c'est-#!
à- dire sur la première ligne interprétée par execve (2) . Si vous faites de telles astuces, assurez-vous de les documenter, y compris dans les--help
messages.Rappelez - vous que sur la POSIX shell est englobement arguments ( avant l' exécution de votre programme!), Donc éviter d' exiger des caractères (comme
*
ou$
ou~
) dans les options qui doivent être coquille échappé.Dans certains cas, vous pouvez intégrer un interpréteur tel que GNU guile ou Lua dans votre logiciel (évitez d’inventer votre propre langage de script Turing-complete si vous n’êtes pas expert en langages de programmation). Cela a de profondes conséquences sur la conception de votre logiciel (il faut donc y penser tôt!). Vous devriez alors pouvoir facilement passer un script ou une expression à cet interprète. Si vous prenez cette approche intéressante, concevez votre logiciel et ses primitives interprétées avec soin; vous pourriez avoir un utilisateur étrange codant de gros scripts pour votre truc.
Dans d'autres cas, vous pouvez laisser vos utilisateurs avancés charger leur plug-in dans votre logiciel (en utilisant des techniques de chargement dynamiques à la
dlopen
&dlsym
). Là encore, il s’agit d’une décision de conception très importante (définissez et documentez donc soigneusement l’interface du plug-in) et vous devrez définir une convention permettant de transmettre les options de programme à ces plug-ins.Si votre logiciel est complexe, faites-le accepter certains fichiers de configuration (en plus du remplacement des arguments du programme) et possédez probablement un moyen de tester (ou tout simplement d’analyser) ces fichiers de configuration sans exécuter tout le code. Par exemple, un agent de transfert de courrier (comme Exim ou Postfix) est assez complexe et il est utile de pouvoir le "sécher à moitié" (par exemple, observer comment il gère une adresse email donnée sans envoyer réellement d'email).
Notez que le
/option
est une chose Windows ou VMS. Ce serait insensé sur les systèmes POSIX (car la hiérarchie des fichiers est utilisée/
comme séparateur de répertoires et parce que le shell effectue la suppression). Toute ma réponse est principalement pour Linux (et POSIX).PS Si possible, faites de votre programme un logiciel libre , certains utilisateurs et développeurs vous apporteront des améliorations (et ajouter une nouvelle option à un programme est souvent l’une des choses les plus faciles à ajouter à un logiciel libre existant). De plus, votre question dépend beaucoup du public visé : un jeu pour adolescents ou un navigateur pour grand-mère n’a probablement pas besoin du même type et du même nombre d’options qu’un compilateur, ou un inspecteur de réseau pour les systèmes de centre de traitement des données, ou un logiciel de CAO pour un microprocesseur. architectes ou pour les concepteurs de ponts. Un ingénieur familiarisé avec la programmation et les scripts aime probablement beaucoup plus que votre grand-mère d'avoir beaucoup d'options paramétrables, et voudra probablement pouvoir exécuter votre application sans X11 (peut-être dans un
crontab
travail).la source
git
est un meilleur exemple. Je ne recommanderai même pas de regarder encvs
2016.dd -h
.--help
généralement mais ne reconnaissent pas souvent ce-h
qui est ennuyeux. Je tape habituellement -h quand j'oublie une option dans un programme, il est ennuyeux de devoir ressaisir la commande avec l'option la plus longue--help
. Après tout, j'ai tapé -h parce que j'avais oublié quelque chose. Pourquoi devrait-on s’attendre à ce que l’utilisateur se souvienne des programmes qui nécessitent «--help» et des programmes qui nécessitent «-h» pour afficher l’écran d’aide? Incluez simplement une option pour -h et --help.Le fait qu'une convention de format de données soit populaire constitue son avantage.
Vous pouvez facilement voir que l'utilisation de = ou: ou même '' comme séparateur est une différence triviale qui pourrait être convertie en un autre ordinateur sans effort. Qu'est-ce qui constituerait un gros effort pour un être humain à se rappeler "Maintenant, voyez-vous, ce programme rarement utilisé délimite-t-il les choses avec
:
ou avec=
? Hmmm ..."En d'autres termes, pour l'amour de Dieu, ne déviez pas de conventions extrêmement enracinées sans raison impérieuse. Les gens se souviendront de votre programme comme "celui avec la syntaxe étrange et ennuyeuse de cmdline" au lieu de "celui qui a sauvé ma dissertation universitaire".
la source
dd
utilise unekey=value
syntaxe. La raison de cette décision de conception est que cet outil (pseudo: d ata d estroyer) peut causer beaucoup de dommages s’il n’est pas utilisé correctement. En obligeant l'utilisateur à abandonner son habitude habituelle, il l'oblige à réfléchir de plus près à ce qu'il fait.dd
? Je crois qu'il a tout simplement été codé à un moment (dans les années 1970?) Où le fichier ARG_MAX du noyau était petit, les shells n'avaient pas d'auto-complétion et--long-arguments
n'existaient pas. Depuis lors, mieuxdd
est resté compatible avec lesdd
provient d'un autre système d'exploitation (qu'UNIX) - un langage de script (JCL) sous IBM / 360 - où les conventions étaient différentes, avant d'être porté plus ou moins inchangé vers UNIX - en partie parce que ceux qui étaient susceptibles de l'utiliser système précédent.En termes simples
A Rome, fais comme les Romains.
-p value
ou--parameter value
. Linux dispose d'outils pour analyser facilement ces paramètres et ces indicateurs.Je fais habituellement quelque chose comme ça:
Si votre application CLI est destinée à Windows, utilisez
/flag
et/flag:value
conventions.Certaines applications comme Oracle n'utilisent ni l'une ni l'autre. Utilisation des utilitaires Oracle
PARAMETER=VALUE
.Une chose que j’aime faire est, en plus d’accepter des paramètres dans la ligne de commande, de fournir la possibilité d’utiliser un parfait , qui est un fichier de paire clé-valeur pour éviter de longues chaînes de paramètres. Pour cela, vous devez fournir un
--parfile mifile.par
paramètre supplémentaire . Évidemment, si--parfile
est utilisé, tous les autres paramètres sont ignorés au profit de ce qui est à l'intérieur du parfait.Une suggestion supplémentaire consiste à autoriser l'utilisation de certaines variables d'environnement personnalisées . Par exemple, définir une variable d'environnement
MYAPP_WRKSPACE=/tmp
rendrait inutile la définition de toujours--wrkspace /tmp
.TAB
et le shell le complétera pour eux.la source
gcc
) gèrent@mifile.par
comme vos--parfile mifile.par
suggestions.fooCmd -opt1 -opt2 $(cat more_options.opts)
. Par conséquent, je m'attendrais à ce qu'une option "paramètre de fichier de configuration", si elle est fournie, fonctionne fondamentalement de la même manière.Une chose qui n'est pas encore apparue:
Essayez de concevoir votre logiciel à partir des arguments de la ligne de commande . Sens:
Avant de concevoir la fonctionnalité, concevez l'interface utilisateur.
Cela vous permettra de faire une analyse approfondie des cas critiques et des cas courants dès le début. Bien sûr, vous allez toujours faire abstraction de l'extérieur et de l'intérieur, mais cela donnera de bien meilleurs résultats que d'écrire tout le code et de claquer une CLI.
En outre, consultez docopt ( http://docopt.org/ ).
docopt est une aide précieuse dans de nombreuses langues, en particulier pour Python où les analyseurs d'arguments indésirables tels que argparse sont très limités et toujours considérés comme "OK". Au lieu d'avoir des analyseurs syntaxiques, des sous-vendeurs et des dictionnaires conditionnels, vous définissez simplement l' aide de la syntaxe et le reste.
la source
argparse
ne pas être programmeur, utilisateur ou convivial.Quelques commentaires précieux déjà fournis (@ Florian, Basile), mais permettez-moi d'ajouter ... OP dit,
Mais aussi des remarques:
Vous devez tenir compte de votre public cible - les administrateurs avancés . Sur quelle plate-forme travaillent-ils normalement - Win / Unix / Mac? Et sur quelle plate-forme vous exécutez l'application? Suivez les conventions CLI déjà établies pour cette plate-forme. Est-ce que vos administrateurs "avancés" veulent / ont besoin d'un outil basé sur une interface graphique?
Vous voulez que l'interface soit cohérente en interne et avec les autres outils d'administration. Je ne veux pas m'arrêter et penser c'est
cmd -p <arg>
oucmd -p:<arg>
oucmd /p <arg>
. Ai-je besoin de citations, car il y a un espace? Puis-jecmd -p <val1> <val2>
oucmd -p <val1> -p <val2>
pour plusieurs cibles? Sont-ils spécifiques à la commande? Surchargeable? Est-ce que çacmd -p2 <arg> -p1 <arg>
marche aussi? Est-ce quels -l -r -t dir1 dir2
==ls -trl dir1 dir2
?Pour mes outils d'administration Unix, j'ai toujours gardé à l'esprit les conseils fournis par Shelldorado de Heiner, ainsi que les autres références mentionnées.
Aussi important que de concevoir la CLI, vous devez vous assurer que votre application est conçue pour fonctionner avec des arguments de ligne de commande identiques à ceux de l’interface graphique, c’est-à-dire qu’aucune logique métier n’est utilisée dans l’interface graphique ou que vous utilisez la commande commune appelée à partir de la GUI et de la CLI.
La plupart des outils d'administration basés sur UNIX sont en fait conçus en premier lieu comme des outils de ligne de commande et l'interface graphique fournie facilite simplement le "remplissage" des options pour la ligne de commande. Cette approche permet l’automatisation, l’utilisation de fichiers de réponses, etc., ainsi que la gestion pratique (moins de travail pour moi!)
Tcl / Tk est le jeu d’outils classique utilisé avec cette approche . Ne pas suggérer de changer d’outil; il suffit de considérer une approche de conception consistant à écrire une application administrative basée sur une interface graphique pour la première fois en tant qu'outil de ligne de commande; superposez ensuite l'interface graphique pour plus de commodité. À un moment donné, vous découvrirez probablement que l'interface graphique est un problème (et source d'erreurs) si vous devez effectuer plusieurs configurations et ressaisir les mêmes options à plusieurs reprises et que vous rechercherez une approche automatisée.
N'oubliez pas que votre administrateur doit probablement saisir les valeurs correctes dans les zones correctes de toute façon, alors combien d'efforts relâchez-vous quand même avec l'interface graphique?
la source