Poprawna wielkość liter w zmiennych skryptu Bash i powłoki

193

Natrafiam na wiele skryptów powłoki ze zmiennymi we wszystkich wielkich literach i zawsze myślałem, że istnieje poważne nieporozumienie z tym. Rozumiem, że zgodnie z konwencją (a być może z konieczności dawno temu) zmienne środowiskowe są pisane wielkimi literami.

Ale w nowoczesnych środowiskach skryptowych, takich jak Bash, zawsze wolałem konwencję nazw małych liter dla zmiennych tymczasowych i wielkich liter tylko dla eksportowanych zmiennych (tj. Środowiskowych) . Na przykład:

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

To zawsze było moje zdanie na ten temat. Czy są jakieś wiarygodne źródła, które zgadzają się lub nie zgadzają z tym podejściem, czy jest to wyłącznie kwestia stylu?

JasonSmith
źródło

Odpowiedzi:

262

Umownie, zmiennych środowiskowych ( PAGER, EDITOR...) oraz wewnętrznych zmiennych powłoki ( SHELL, BASH_VERSION...) są aktywowane. Wszystkie pozostałe nazwy zmiennych powinny być pisane małymi literami.

Pamiętaj, że w nazwach zmiennych rozróżniana jest wielkość liter; Konwencja ta pozwala uniknąć przypadkowego zastąpienia zmiennych środowiskowych i wewnętrznych.

Trzymając się tej konwencji, możesz mieć pewność, że nie musisz znać każdej zmiennej środowiskowej używanej przez narzędzia UNIX lub powłoki, aby uniknąć ich zastąpienia. Jeśli jest to twoja zmienna, wpisz ją małymi literami. Jeśli go eksportujesz, wielkie litery.

lhunath
źródło
8
+1. Dobra uwaga na temat przypadkowego zastąpienia. Zapomniałem wspomnieć, ale teraz, kiedy o tym wspominasz, myślę, że zdecydowałem się na pisanie małymi literami, ponieważ czytałem lub słyszałem o tym problemie.
JasonSmith
5
Myślałem, że głównym powodem używania nazw zmiennych pisanych dużymi literami było unikanie konfliktów z poleceniami powłoki. Niedawno zmieniliśmy nazwę hosta jednego z naszych serwerów na „=”, ponieważ skrypt używał zmiennej „nazwa hosta”.
ThisSuitIsBlackNot
25
@ThisSuitIsBlackNot Ignorując kiepski kod, zmienne są poprzedzane dolarem po rozwinięciu i używane w miejscu, w którym nie można ich pomylić z nazwą polecenia, gdy nie są. Oczywiście zrobienie hostname = moo wpędzi cię w kłopoty. Nie dlatego, że używasz małej litery „nazwa hosta”, ale dlatego, że nie używasz prawidłowej składni przypisania. Przypisanie odbywa się za pomocą nazwy hosta = muczenie, bez spacji. Zakładając poprawny kod, nie musisz się martwić o konflikt nazw zmiennych z nazwami poleceń.
lhunath,
3
Wszystkie podręczniki, na które patrzyłem, zawsze zawierają wielkie litery dla wszystkich zmiennych powłoki. Chociaż nazwy zmiennych pisane małymi literami są dopuszczalne, konwencja jest pisana wielkimi literami.
Brian S. Wilson
3
Nie wiedziałem o tym i właśnie straciłem kilka godzin. nad używaniem USER="username"w skrypcie bash automatyzującym niektóre zdalne polecenia za pomocą ssh zamiast user="username". Ugh! Cieszę się, że teraz wiem!
Gabriel Staples
28

Wszelkie konsekwentnie przestrzegane konwencje nazewnictwa zawsze pomogą. Oto kilka pomocnych wskazówek dotyczących nazewnictwa zmiennych powłoki:

  • Użyj wszystkich wielkich liter i znaków podkreślenia dla eksportowanych zmiennych i stałych, zwłaszcza gdy są one współużytkowane przez wiele skryptów lub procesów. W stosownych przypadkach używaj wspólnego przedrostka, aby pokrewne zmienne wyróżniały się i nie kolidowały ze zmiennymi wewnętrznymi Bash, które są dużymi literami.

    Przykłady:

    • Wyeksportowane zmienne ze wspólnym prefiksem: JOB_HOME JOB_LOG JOB_TEMP JOB_RUN_CONTROL
    • Stałe: LOG_DEBUG LOG_INFO LOG_ERROR STATUS_OK STATUS_ERROR STATUS_WARNING
  • Użyj „węża” ( wszystkie małe i podkreślenia ) dla wszystkich zmiennych, których zakres obejmuje pojedynczy skrypt lub blok.

    Przykłady: input_file first_value max_amount num_errors

    Użyj zmiennej mieszanej, gdy zmienna lokalna ma jakiś związek ze zmienną środowiskową, na przykład: old_IFS old_HOME

  • Użyj wiodącego podkreślenia dla „prywatnych” zmiennych i funkcji. Jest to szczególnie istotne, jeśli kiedykolwiek napiszesz bibliotekę powłoki, w której funkcje w pliku biblioteki lub między plikami muszą współdzielić zmienne, bez kolizji z czymkolwiek, co mogłoby być podobnie nazwane w głównym kodzie.

    Przykłady: _debug _debug_level _current_log_file

  • Unikaj futerału wielbłąda . Pozwoli to zminimalizować błędy spowodowane literówkami. Pamiętaj, że w zmiennych powłoki rozróżniana jest wielkość liter .

    Przykłady: inputArray thisLooksBAD, numRecordsProcessed,veryInconsistent_style


Zobacz też:

codeforester
źródło
1
To konwencja, ale jest prawie powszechnie akceptowane. Uzasadnienie przeciwko sprawie wielbłądów nie jest całkowicie przekonujące. Zalecenie użycia SHOUTING dla eksportowanych zmiennych jest nieco kontrowersyjne.
tripleee
3
Nie twierdziłem, że jest to konwencja powszechnie stosowana. Widziałem, że większość programistów nie myśli poważnie o przestrzeganiu silnych konwencji w skryptach powłoki i myślała o zanotowaniu moich myśli w oparciu o to, co robiłam.
codeforester
8

Jeśli zmienne powłoki mają zostać wyeksportowane do środowiska, warto wziąć pod uwagę, że POSIX (wydanie 7, wydanie 2018) Definicja zmiennej środowiskowej określa:

Nazwy zmiennych środowiskowych używane przez narzędzia w tomie Shell and Utilities POSIX.1-2017 składają się wyłącznie z wielkich liter, cyfr i podkreślenia ( _) ze znaków zdefiniowanych w przenośnym zestawie znaków i nie zaczynają się od cyfry.

...

Przestrzeń nazw nazw zmiennych środowiskowych zawierających małe litery jest zarezerwowana dla aplikacji. Aplikacje mogą definiować dowolne zmienne środowiskowe o nazwach z tej przestrzeni nazw bez modyfikowania zachowania standardowych narzędzi.

Anthony Geoghegan
źródło
6

Robię to co ty. Wątpię, by istniało wiarygodne źródło, ale wydaje się ono dość powszechnym de facto standardem.

Draemon
źródło
1
Zgadzam się. To dlatego, że ALL_CAPS jest brzydki, ale dobrze jest, aby ZMIENNE ŚRODOWISKA wyróżniały się brzydkością.
szczupły
1
Zgadzam się z tobą w stylu kodowania, ale zdecydowanie nie zgadzam się, że jest on powszechny! Skrypty powłoki są jednym z tych dodatkowych języków, których ludzie uczą się nieformalnie, więc wydaje mi się, że wszyscy zawsze mówią LOKALIZACJA =cat /tmp/location.txt
JasonSmith
@jhs - oczywiście miałem szczęście w skryptach powłoki, z którymi musiałem pracować!
Draemon
4
„Przestrzeń nazw nazw zmiennych środowiskowych zawierających małe litery jest zarezerwowana dla aplikacji”. - POSIX IEEE Std 1003.1-2008 sekcja 8.1
tripleee
5

W rzeczywistości termin „zmienne środowiskowe” wydaje się mieć dość nowy termin. Kernighan i Pike w swojej klasycznej książce „The UNIX Programming Environment”, wydanej w 1984 r., Mówią tylko o „zmiennych powłoki” - w indeksie nie ma nawet hasła „środowisko”!


źródło
8
Myślę, że to pominięcie książki. getenv (), setenv () i środowisko zostały wprowadzone w wersji UNIX 7 (1979). en.wikipedia.org/wiki/Version_7_Unix
Juliano
3
Ta książka przypomina, że ​​zmienne pisane wielkimi literami mają specjalne znaczenie.
ashawley
3

Jest to po prostu bardzo szeroko stosowana konwencja, wątpię, by było dla niej „wiarygodne” źródło.

Alnitak
źródło
1

Zwykle używam ALL_CAPS zarówno dla zmiennych środowiskowych, jak i globalnych. oczywiście w Bash nie ma rzeczywistego zakresu zmiennych, więc jest duża część zmiennych wykorzystywanych jako globale (głównie ustawienia i śledzenie stanu) oraz stosunkowo niewiele „locals” (liczniki, iteratory, częściowo skonstruowane łańcuchy i tymczasowe)

Javier
źródło
Tak, trochę koncepcyjnie myślę o nieeksportowanych zmiennych jako lokalach, ponieważ Bash tak często zmusza procesy potomne do robienia tego, do czego jest przeznaczony.
JasonSmith