Korrigieren Sie die Groß- und Kleinschreibung von Bash- und Shell-Skriptvariablen

191

Ich stoße auf viele Shell-Skripte mit Variablen in Großbuchstaben und habe immer gedacht, dass dies ein schwerwiegendes Missverständnis darstellt. Mein Verständnis ist, dass Umgebungsvariablen gemäß Konvention (und möglicherweise aufgrund der Notwendigkeit vor langer Zeit) in Großbuchstaben angegeben sind.

In modernen Skriptumgebungen wie Bash habe ich jedoch immer die Konvention von Kleinbuchstaben für temporäre Variablen und Großbuchstaben nur für exportierte Variablen (dh Umgebungsvariablen) bevorzugt . Beispielsweise:

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

Das war schon immer meine Einstellung. Gibt es maßgebliche Quellen, die diesem Ansatz entweder zustimmen oder nicht zustimmen, oder ist es nur eine Frage des Stils?

JasonSmith
quelle

Antworten:

262

Per Konvention Umgebungsvariablen ( PAGER, EDITOR, ...) und innere Schale Variablen ( SHELL, BASH_VERSION, ...) werden aktiviert. Alle anderen Variablennamen sollten in Kleinbuchstaben geschrieben werden.

Denken Sie daran, dass bei Variablennamen zwischen Groß- und Kleinschreibung unterschieden wird. Diese Konvention vermeidet das versehentliche Überschreiben von Umgebungsvariablen und internen Variablen.

Wenn Sie diese Konvention einhalten, können Sie sicher sein, dass Sie nicht jede Umgebungsvariable kennen müssen, die von UNIX-Tools oder -Shells verwendet wird, um ein Überschreiben zu vermeiden. Wenn es Ihre Variable ist, schreiben Sie sie in Kleinbuchstaben. Wenn Sie es exportieren, schreiben Sie es in Großbuchstaben.

lhunath
quelle
8
+1. Guter Punkt zum versehentlichen Überschreiben. Ich habe vergessen zu erwähnen, aber jetzt, wo Sie es erwähnen, habe ich mich für Kleinbuchstaben entschieden, weil ich nur dieses Problem gelesen oder gehört habe.
JasonSmith
5
Ich dachte, der Hauptgrund für die Verwendung von Variablennamen in Großbuchstaben sei die Vermeidung von Konflikten mit Shell-Befehlen. Wir haben kürzlich den Hostnamen eines unserer Server versehentlich in '=' geändert, weil ein Skript eine Variable 'Hostname' verwendet hat.
ThisSuitIsBlackNot
25
@ThisSuitIsBlackNot Wenn man beschissenen Code ignoriert, wird Variablen beim Erweitern ein Dollar vorangestellt und an einer Stelle verwendet, an der sie nicht mit einem Befehlsnamen verwechselt werden können, wenn dies nicht der Fall ist. Wenn Sie hostname = moo ausführen, werden Sie offensichtlich in Schwierigkeiten geraten. Nicht weil Sie einen "Hostnamen" in Kleinbuchstaben verwenden, sondern weil Sie nicht die richtige Zuweisungssyntax verwenden. Die Zuweisung erfolgt mit Hostname = moo, keine Leerzeichen. Unter der Annahme eines korrekten Codes müssen Sie sich keine Gedanken über Variablennamen machen, die mit Befehlsnamen in Konflikt stehen.
lhunath
3
Alle Lehrbücher, die ich mir angesehen habe, verwenden für alle Shell-Variablen immer Großbuchstaben. Während Variablennamen in Kleinbuchstaben zulässig sind, ist Großbuchstaben die Konvention.
Brian S. Wilson
3
Ich wusste das nicht und habe nur ein paar Stunden verloren. über die Verwendung USER="username"in einem Bash-Skript zur Automatisierung einiger Remote-Befehle über ssh anstelle von user="username". Pfui! Ich bin froh, dass ich es jetzt weiß!
Gabriel Staples
28

Alle konsequent befolgten Namenskonventionen helfen immer. Hier einige hilfreiche Tipps zur Benennung von Shell-Variablen:

  • Verwenden Sie alle Groß- und Kleinschreibung für exportierte Variablen und Konstanten, insbesondere wenn sie von mehreren Skripten oder Prozessen gemeinsam genutzt werden. Verwenden Sie nach Möglichkeit ein gemeinsames Präfix, damit verwandte Variablen hervorstechen und nicht mit internen Bash-Variablen kollidieren , die alle in Großbuchstaben geschrieben sind.

    Beispiele:

    • Exportierte Variablen mit einem gemeinsamen Präfix: JOB_HOME JOB_LOG JOB_TEMP JOB_RUN_CONTROL
    • Konstanten: LOG_DEBUG LOG_INFO LOG_ERROR STATUS_OK STATUS_ERROR STATUS_WARNING
  • Verwenden Sie "Snake Case" ( alle Klein- und Unterstriche ) für alle Variablen, die sich auf ein einzelnes Skript oder einen Block beziehen.

    Beispiele: input_file first_value max_amount num_errors

    Verwenden Sie Groß- und Kleinschreibung, wenn die lokale Variable eine Beziehung zu einer Umgebungsvariablen hat, z. old_IFS old_HOME

  • Verwenden Sie einen führenden Unterstrich für "private" Variablen und Funktionen. Dies ist besonders relevant, wenn Sie jemals eine Shell-Bibliothek schreiben, in der Funktionen innerhalb einer Bibliotheksdatei oder zwischen Dateien Variablen gemeinsam nutzen müssen, ohne jemals mit etwas in Konflikt zu geraten, das im Hauptcode möglicherweise ähnlich benannt ist.

    Beispiele: _debug _debug_level _current_log_file

  • Vermeiden Kamel Fall . Dadurch werden die durch Tippfehler verursachten Fehler minimiert. Denken Sie daran, dass bei Shell-Variablen zwischen Groß- und Kleinschreibung unterschieden wird .

    Beispiele: inputArray thisLooksBAD, numRecordsProcessed,veryInconsistent_style


Siehe auch:

Codeforester
quelle
1
Dies ist eine Konvention, die jedoch kaum allgemein akzeptiert wird. Die Begründung gegen den Kamelfall ist nicht ganz überzeugend. Die Empfehlung, SHOUTING für exportierte Variablen zu verwenden, ist leicht umstritten.
Tripleee
3
Ich habe nicht behauptet, dass es sich um eine allgemein verfolgte Konvention handelt. Ich habe gesehen, dass die meisten Programmierer nicht ernsthaft darüber nachdenken, strenge Konventionen in Shell-Skripten zu befolgen, und daran gedacht haben, meine Gedanken basierend auf dem, was ich getan habe, aufzuschreiben.
Codeforester
8

Wenn Shell-Variablen in die Umgebung exportiert werden sollen, sollten Sie berücksichtigen, dass in der Definition der Umgebungsvariablen für POSIX (Ausgabe 7, Ausgabe 2018) Folgendes angegeben ist:

Umgebungsvariablennamen, die von den Dienstprogrammen im Shell- und Dienstprogramm-Volume von POSIX.1-2017 verwendet werden, bestehen ausschließlich aus Großbuchstaben, Ziffern und dem Unterstrich ( _) der im tragbaren Zeichensatz definierten Zeichen und beginnen nicht mit einer Ziffer.

...

Der Namensraum von Umgebungsvariablennamen mit Kleinbuchstaben ist für Anwendungen reserviert. Anwendungen können beliebige Umgebungsvariablen mit Namen aus diesem Namensraum definieren, ohne das Verhalten der Standarddienstprogramme zu ändern.

Anthony Geoghegan
quelle
6

Ich mache was du machst. Ich bezweifle, dass es eine maßgebliche Quelle gibt, aber es scheint ein ziemlich weit verbreiteter De-facto-Standard zu sein.

Draemon
quelle
1
Genau. Das liegt daran, dass ALL_CAPS hässlich ist, aber es ist gut, UMWELTVARIABLEN durch Hässlichkeit hervorzuheben.
schlank
1
Ich stimme Ihnen in Bezug auf den Codierungsstil zu, aber ich bin definitiv nicht der Meinung, dass er weit verbreitet ist! Shell-Skripte sind eine dieser cat /tmp/location.txt
Nebensprachen
@jhs - Ich hatte offensichtlich Glück mit den Shell-Skripten, mit denen ich arbeiten musste!
Draemon
4
"Der Namensraum von Umgebungsvariablennamen mit Kleinbuchstaben ist für Anwendungen reserviert." - POSIX IEEE Std 1003.1-2008 Abschnitt 8.1
Tripleee
5

Tatsächlich scheint der Begriff "Umgebungsvariablen" relativ neu zu sein. Kernighan und Pike sprechen in ihrem 1984 veröffentlichten klassischen Buch "The UNIX Programming Environment" nur von "Shell-Variablen" - es gibt nicht einmal einen Eintrag für "Environment" im Index!


quelle
8
Ich denke, das ist eine Auslassung des Buches. getenv (), setenv () und environ wurden in UNIX Version 7 (1979) eingeführt. en.wikipedia.org/wiki/Version_7_Unix
Juliano
3
In diesem Buch wird darauf hingewiesen, dass Variablen in Großbuchstaben eine besondere Bedeutung haben.
Ashawley
3

Es ist nur eine sehr weit verbreitete Konvention, ich bezweifle, dass es eine "maßgebliche" Quelle dafür gibt.

Alnitak
quelle
1

Ich neige dazu, ALL_CAPS sowohl für Umgebungsvariablen als auch für globale Variablen zu verwenden. Natürlich gibt es in Bash keinen wirklichen Variablenbereich, daher gibt es einen großen Teil der Variablen, die als Globale verwendet werden (hauptsächlich Einstellungen und Statusverfolgung), und relativ wenige "Einheimische" (Zähler, Iteratoren, teilweise konstruierte Zeichenfolgen und Temporäre).

Javier
quelle
Ja, ich stelle mir nicht exportierte Variablen konzeptionell als Einheimische vor, da Bash so oft untergeordnete Prozesse dazu zwingt, alles zu tun, womit es beauftragt ist.
JasonSmith