Corriger la capitalisation des variables de script Bash et shell

200

Je rencontre de nombreux scripts shell avec des variables en majuscules, et j'ai toujours pensé qu'il y avait un grave malentendu à ce sujet. Je crois comprendre que, par convention (et peut-être par nécessité il y a longtemps), les variables d'environnement sont en majuscules.

Mais dans les environnements de script modernes comme Bash, j'ai toujours préféré la convention des noms en minuscules pour les variables temporaires et en majuscules uniquement pour les variables exportées (c'est-à-dire d'environnement) . Par exemple:

#!/usr/bin/env bash
year=`date +%Y`
echo "It is $year."
export JAVA_HOME="$HOME/java"

Cela a toujours été ma vision des choses. Existe-t-il des sources faisant autorité qui sont en accord ou en désaccord avec cette approche, ou est-ce purement une question de style?

JasonSmith
la source

Réponses:

273

Par convention, les variables d'environnement ( PAGER, EDITOR...) et des variables shell internes ( SHELL, BASH_VERSION, ...) sont capitalisés. Tous les autres noms de variables doivent être en minuscules.

N'oubliez pas que les noms de variables sont sensibles à la casse; cette convention évite de surcharger accidentellement les variables environnementales et internes.

En respectant cette convention, vous pouvez être assuré que vous n'avez pas besoin de connaître toutes les variables d'environnement utilisées par les outils ou les shells UNIX pour éviter de les écraser. Si c'est votre variable, mettez-la en minuscule. Si vous l'exportez, mettez-le en majuscule.

lhunath
la source
9
+1. Bon point sur l'écrasement accidentel. J'ai oublié de mentionner, mais maintenant que vous le mentionnez, je pense que j'ai décidé d'utiliser des minuscules parce que j'ai lu ou entendu parler de ce problème.
JasonSmith
5
Je pensais que la principale raison d'utiliser des noms de variables en majuscules était d'éviter les conflits avec les commandes shell. Récemment, le nom d'hôte de l'un de nos serveurs a été accidentellement changé en '=' car un script utilisait une variable 'hostname'.
ThisSuitIsBlackNot
25
@ThisSuitIsBlackNot Ignorant le code merdique, les variables sont précédées d'un dollar lorsqu'elles sont développées et utilisées à un endroit où elles ne peuvent pas être confondues avec un nom de commande lorsqu'elles ne le sont pas. De toute évidence, faire hostname = moo va vous poser des problèmes. Non pas parce que vous utilisez un "nom d'hôte" en minuscules, mais parce que vous n'utilisez pas la syntaxe d'affectation correcte. L'affectation se fait avec hostname = moo, sans espaces. En supposant que le code soit correct, vous n'avez pas à vous soucier des noms de variables en conflit avec les noms de commandes.
lhunath
3
Tous les manuels que j'ai consultés utilisent toujours des majuscules pour toutes les variables du shell. Alors que les noms de variables en minuscules sont autorisés, les majuscules sont la convention.
Brian S. Wilson
3
Je ne le savais pas et je viens de perdre quelques heures. sur l'utilisation USER="username"dans un script bash automatisant certaines commandes distantes via ssh au lieu de user="username". Pouah! Heureux je sais maintenant!
Gabriel Staples
30

Toutes les conventions de dénomination suivies de manière cohérente seront toujours utiles. Voici quelques conseils utiles pour la dénomination des variables shell:

  • Utilisez toutes les majuscules et les traits de soulignement pour les variables et les constantes exportées, en particulier lorsqu'elles sont partagées entre plusieurs scripts ou processus. Utilisez un préfixe commun chaque fois que cela est applicable afin que les variables liées se démarquent et ne se heurtent pas aux variables internes Bash qui sont toutes en majuscules.

    Exemples:

    • Variables exportées avec un préfixe commun: JOB_HOME JOB_LOG JOB_TEMP JOB_RUN_CONTROL
    • Constantes: LOG_DEBUG LOG_INFO LOG_ERROR STATUS_OK STATUS_ERROR STATUS_WARNING
  • Utilisez "snake case" ( tout en minuscules et traits de soulignement ) pour toutes les variables qui sont limitées à un seul script ou à un bloc.

    Exemples: input_file first_value max_amount num_errors

    Utilisez des cas mixtes lorsque la variable locale a une relation avec une variable d'environnement, comme: old_IFS old_HOME

  • Utilisez un trait de soulignement pour les variables et fonctions "privées". Ceci est particulièrement pertinent si jamais vous écrivez une bibliothèque shell dans laquelle les fonctions d'un fichier de bibliothèque ou d'un fichier à l'autre doivent partager des variables, sans jamais entrer en conflit avec tout ce qui pourrait être nommé de la même manière dans le code principal.

    Exemples: _debug _debug_level _current_log_file

  • Évitez le cas de chameau . Cela minimisera les bogues causés par les fautes de frappe. N'oubliez pas que les variables shell sont sensibles à la casse .

    Exemples: inputArray thisLooksBAD, numRecordsProcessed,veryInconsistent_style


Voir également:

codeforester
la source
1
Il s'agit d' une convention mais elle n'est guère acceptée universellement. La justification de l'affaire chameau n'est pas entièrement convaincante. La recommandation d'utiliser SHOUTING pour les variables exportées est légèrement controversée.
tripleee
3
Je n'ai pas prétendu que c'était une convention couramment suivie. J'ai vu que la plupart des programmeurs ne pensent pas sérieusement à suivre les conventions fortes dans les scripts shell et ont pensé à noter mes pensées en fonction de ce que j'ai fait.
codeforester
9

Si les variables shell doivent être exportées vers l'environnement, il convient de considérer que la définition de variable d'environnement POSIX (numéro 7, édition 2018) spécifie:

Les noms de variables d'environnement utilisés par les utilitaires dans le volume Shell and Utilities de POSIX.1-2017 se composent uniquement de lettres majuscules, de chiffres et du trait de soulignement ( _) des caractères définis dans Portable Character Set et ne commencent pas par un chiffre.

...

L'espace de nom des noms de variable d'environnement contenant des lettres minuscules est réservé aux applications. Les applications peuvent définir toutes les variables d'environnement avec des noms provenant de cet espace de nom sans modifier le comportement des utilitaires standard.

Anthony Geoghegan
la source
6

Je fais ce que tu fais. Je doute qu'il existe une source faisant autorité, mais cela semble une norme de facto assez répandue.

Draemon
la source
1
Je suis d'accord. C'est parce que ALL_CAPS est moche, mais il est bon de faire en sorte que les VARIABLES D'ENVIRONNEMENT se démarquent en étant laides.
slim
1
Je suis d'accord avec vous sur le style de codage, mais je ne suis absolument pas d'accord pour dire qu'il est répandu! Les scripts shell sont l'un de ces langages secondaires que les gens apprennent simplement de manière informelle, et j'ai donc l'impression que tout le monde dit toujours LOCATION =cat /tmp/location.txt
JasonSmith
@jhs - J'ai évidemment eu de la chance dans les scripts shell avec lesquels j'ai dû travailler!
Draemon
4
"L'espace de nom des noms de variables d'environnement contenant des lettres minuscules est réservé aux applications." - POSIX IEEE Std 1003.1-2008 section 8.1
tripleee
5

En fait, le terme «variables d'environnement» semble être d'une monnaie assez récente. Kernighan et Pike dans leur livre classique "L'environnement de programmation UNIX", publié en 1984, ne parlent que de "variables shell" - il n'y a même pas d'entrée pour "environnement" dans l'index!


la source
8
Je pense que c'est une omission du livre. getenv (), setenv () et environ ont été introduits dans UNIX version 7 (1979). en.wikipedia.org/wiki/Version_7_Unix
Juliano
4
Ce livre cherche à noter que les variables majuscules ont une signification particulière.
ashawley
3

C'est juste une convention très répandue, je doute qu'il y ait une source "faisant autorité" pour cela.

Alnitak
la source
2

J'ai tendance à utiliser ALL_CAPS à la fois pour l'environnement et les variables globales. bien sûr, dans Bash, il n'y a pas de vraie portée de variable, donc il y a une bonne partie des variables utilisées comme globales (principalement les paramètres et le suivi d'état), et relativement peu de `` locaux '' (compteurs, itérateurs, chaînes partiellement construites et temporaires)

Javier
la source
Oui, je considère en quelque sorte conceptuellement les variables non exportées comme des variables locales, car Bash oblige si souvent les processus enfants à faire tout ce qu'il est chargé de faire.
JasonSmith