Configuration utilisateur d'un script shell. Les meilleures pratiques?

13

J'écris un script shell avec quelques variables qui devraient être configurées par l'utilisateur. Il y aura un programme d'installation pour télécharger et configurer le script, éventuellement en posant une série de questions. Le script en question s'adresse à d'autres développeurs.

Cela peut être mis en œuvre de plusieurs manières:

  1. Utilisez des espaces réservés dans le script lui-même et utilisez-les sedpour les remplacer lors de l'installation (quelque chose comme ceci: /programming/415677/how-to-replace-placeholders-in-a-text-file )

    • Avantages: Toutes les définitions de variables sont contenues dans le script. Il est facile de télécharger le script manuellement et de configurer les variables pour les utilisateurs qui préfèrent un éditeur à l'installateur.

    • Inconvénients: il est difficile de reconfigurer les variables via le programme d'installation une fois qu'elles sont en place. À moins que je ne crée une expression rationnelle plus complexe qui serait sujette à des erreurs.

  2. Utilisez un fichier de configuration , essentiellement un autre script shell avec des affectations, et utilisez-le sourcepour l'inclure. (Et probablement le placer dans ~/.scriptname? Le script principal est copié /usr/local/bin)

    • Avantages: Il est facile de reconfigurer le script. Pourrait même ajouter un paramètre pour le faire à partir du script principal (fonctionnerait probablement dans la première solution également, mais l'édition d'un script à partir de lui-même ne semble pas être une très bonne idée)

    • Inconvénients: le script dépend maintenant de deux fichiers et l'utilisateur doit exécuter le programme d'installation pour que le fichier de configuration soit créé. Cela peut être résolu en générant automatiquement un fichier de configuration s'il n'en existe pas. Mais localiser un fichier de configuration externe sera toujours plus lourd pour les utilisateurs qui souhaitent simplement télécharger le script, le modifier et en finir avec.

En outre, quelques options concernant la façon dont la configuration doit être gérée par l'utilisateur après l'installation:

  1. Git comme
    $ myscript config server.host example.org $ myscript config server.proxypath / home / johndoe / proxy $ myscript config server.httppath / home / johndoe / web

  2. Interactive
    $ myscript config
    Entrez le nom d'hôte du serveur: example.org
    Entrez le chemin d'accès au proxy sur le serveur: / home / johndoe / proxy
    Entrez le chemin d'accès au répertoire http sur le serveur: / home / johndoe / web

  3. getopts avec de longues options
    $ myscript --host example.org --proxypath / home / johndoe / proxy --httppath / home / johndoe / web


  4. Config $ myscript simple example.org / home / johndoe / proxy / home / johndoe / web

Y a-t-il d'autres façons de procéder que vous envisageriez?
Des bonnes pratiques, quelque chose d'élégant?

Charlie Rudenstål
la source
2
Je ne doute pas que vous puissiez écrire un script shell qui fait tout cela, mais la question est de savoir pourquoi vous voulez écrire quelque chose d'aussi complexe que cela nécessite un programme d'installation dans un script shell. Quoi qu'il en soit, regardez comment le système de configuration du noyau Linux gère son fichier de configuration.
Bien. Le script 'installer' ne téléchargerait que le vrai script, le copierait à son bon emplacement et poserait une série de questions pour la configuration (3-4 variables). De cette façon, je peux donner aux utilisateurs une seule ligne de commande, en ignorant le script d'installation et en le redirigeant vers / bin / sh. Bien sûr, je pouvais ignorer le programme d'installation et ajouter simplement un paramètre «install» au script principal. Peut-être une meilleure solution, qu'en pensez-vous?
Charlie Rudenstål
"mais la question est de savoir pourquoi vous voulez écrire quelque chose de si complexe", voici le script en question: github.com/charlie-rudenstal/depo J'essaie de réduire le nombre d'étapes que les nouveaux utilisateurs doivent effectuer, en particulier pendant la installation. Envisager d'automatiser également la configuration requise du serveur.
Charlie Rudenstål

Réponses:

6

Qu'attendrais-je d'un programme sain (un script shell ou non):

  • Je n'ai jamais à modifier l'exécutable pour le configurer. Ce n'est pas un noyau OS.
  • Je peux passer n'importe quel paramètre en utilisant la ligne de commande. C'est un must pour chaque élément d'information qui n'a pas de défaut raisonnable. La seule exception est un mot de passe qui nécessite une saisie interactive.
  • Facultativement, je peux passer un paramètre à l'aide d'une variable d'environnement.
  • Je peux écrire les paramètres dans un fichier de configuration, et ce fichier sera utilisé s'il est présent sous un nom bien connu, ou s'il est explicitement indiqué d'utiliser les deux méthodes ci-dessus.
  • Le fichier de configuration utilise les mêmes noms de paramètres et syntaxe que la ligne de commande.
9000
la source
Très bon conseil. Serait-ce votre commande préférée? (1) Vérifier les paramètres passés en ligne de commande (2) Vérifier le paramètre dans un .scriptnameConfig dans le même répertoire (3) Vérifier le paramètre dans une variable d'environnement (4) Vérifier le paramètre dans un .scriptnameConfig dans ~ / .scriptnameConfig (5) Utiliser la valeur par défaut cadre
Charlie Rudenstål
"Le fichier de configuration utilise les mêmes noms de paramètres et syntaxe que la ligne de commande." - À quoi cela devrait-il ressembler? J'allais utiliser la syntaxe d'affectation pour les scripts shell réguliers: SETTING = VALUE. La commande comme la syntaxe ne serait-elle pas un peu étrange dans un fichier de configuration?
Charlie Rudenstål
Voyez comment mountou sshpermettez-vous d'utiliser la même syntaxe sur la ligne de commande et dans la configuration. Vous n'avez pas besoin de copier totalement la syntaxe de la ligne de commande; au lieu de «--foo = bar», vous pouvez utiliser «foo = bar». Si vous utilisiez plutôt 'BarOption: Foo', ce serait beaucoup moins pratique: la nécessité de se rappeler si la casse est importante, quel mot clé est accepté dans le fichier et lequel en ligne de commande, et l'impossibilité de copier-coller une commande qui fonctionne ligne dans un fichier de configuration avec seulement une édition cosmétique.
9000
3

Lorsque j'ai besoin d'écrire un script élaboré avec diverses options de configuration, j'utilise Python avec les bibliothèques argparse et ConfigParser . Ceux-ci aident à l'implémentation mais le processus s'applique à tout script shell:

  1. Recherchez un fichier de configuration. S'il existe, lisez tous les paramètres qu'il contient dans une table de dictionnaire / recherche.
  2. Analyser les arguments de ligne de commande nommés. Pour chaque argument fourni, remplacez la valeur chargée à partir du fichier de configuration si elle existe. Pour tout argument non passé dans la ligne de commande et pas dans la configuration, utilisez une valeur par défaut.
  3. Exécute la fonction principale du script
  4. Si le fichier de configuration n'existe pas, écrivez-y les valeurs transmises et / ou par défaut.

Ma préférence est pour un fichier de configuration pour contenir les options préférées lorsque le script va être utilisé à plusieurs reprises, mais laissez les arguments de ligne de commande remplacer. Écrivez le fichier de configuration en utilisant ces paramètres lors de sa première exécution. Le fichier de configuration peut ensuite être partagé et validé dans un référentiel de code.

Dans mon cas le plus récent, j'ai également écrit les valeurs par défaut dans la [DEFAULT]section en haut du fichier de configuration, puis j'avais une section pour chaque "environnement" avec des remplacements appropriés pour chacun. L '"environnement" est le premier paramètre sans nom du script. Ainsi, dans ce cas, les paramètres sont choisis comme défaut par défaut -> fichier de configuration par défaut -> valeur de section du fichier de configuration -> paramètre de ligne de commande . Un paramètre de ligne de commande supplémentaire donne la possibilité de remplacer la configuration existante par la dernière valeur de l'exécution. Ce fichier de configuration est écrit dans le répertoire courant, il s'applique donc par projet et peut être validé avec le reste du code. Quiconque extrait le même projet démarre alors avec la même configuration.

Matt S
la source
"Un paramètre de ligne de commande supplémentaire donne la possibilité de remplacer la configuration existante par la dernière valeur d'exécution." Il s'agit d'une approche intéressante. Un moyen pratique de combiner les paramètres avec la configuration.
Charlie Rudenstål
+1, je recommanderais également de définir les valeurs par défaut dans un default.configfichier situé dans le même répertoire que le script, puis de rechercher un fichier de configuration à ~/.scriptnamepour remplacer ces valeurs. De cette façon, chaque valeur a une valeur par défaut valide et est plus facile à maintenir.
Aaron
2

La modification des espaces réservés est sujette aux erreurs.

J'irais avec l'aide d'un fichier de configuration.

Votre préoccupation concernant la dépendance est valide, cependant, je ne me souviens pas d'avoir utilisé trop d'outils composés d'un seul fichier. Donc, théoriquement, vous avez raison, mais en pratique, cela devrait être tout à fait correct.

Une troisième option consiste à faire écrire au logiciel de configuration une nouvelle version sur mesure spécifique aux options et paramètres sélectionnés. Cela peut être plus difficile à écrire et à tester bien sûr :)

Aucune chance
la source