Правильна величина величини величини сценарію Bash та оболонки


193

Я зіткнувся з багатьма скриптами оболонки зі змінними у всіх заголовках, і я завжди вважав, що з цим виникає серйозне непорозуміння. Я розумію, що за умовою (а можливо, вже давно) мінливі середовища містяться у великій ліміті.

Але в сучасних сценаріях середовища, таких як Bash, я завжди віддав перевагу конвенції малих імен для тимчасових змінних, а великих регістрів лише для експортованих (тобто середовищ) змінних . Наприклад:

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

Це завжди було моїм сприйняттям речей. Чи є авторитетні джерела, які або згодні або не згодні з таким підходом, або це суто питання стилю?

Відповіді:


262

За угодою, змінні оточення ( PAGER, EDITOR, ...) і внутрішніх змінних оболонки ( SHELL,BASH_VERSION , ...) капіталізуються. Усі інші назви змінних мають бути малими літерами.

Пам'ятайте, що назви змінних залежать від регістру; ця конвенція дозволяє уникнути випадкових переваг екологічних та внутрішніх змінних.

Дотримуючись цієї конвенції, ви можете бути впевнені, що вам не потрібно знати всю змінну середовища, яка використовується інструментами або оболонками UNIX, щоб уникнути їх перезапису. Якщо це ваша змінна, її малі регістри. Якщо ви експортуєте його, великі регістри.


8
+1. Хороший момент про випадкове перезапис. Я забув згадати, але тепер, коли ви це згадуєте, я думаю, що вирішив використовувати малі регістри, тому що я читав або чув про цю проблему.
JasonSmith

5
Я вважав, що основною причиною використання великих імен змінних є уникання конфліктів з командними оболонками. Нещодавно у нас було ім'я хоста одного з наших серверів, яке випадково було змінено на '=', оскільки в сценарії була використана змінна 'ім'я хоста'.
ThisSuitIsBlackNot

25
@ThisSuitIsBlackNot Ігнорування шаленого коду, змінні мають префікс із доларом при розширенні та використанні в тому місці, де їх не можна плутати з назвою команди, коли їх немає. Очевидно, що імені хоста = moo приведуть вас у біду. Не тому, що ви використовуєте "ім'я хоста" з нижчим регістром, а тому, що не використовуєте правильний синтаксис призначення. Присвоєння виконується з ім'ям хоста = moo, без пробілів. Якщо припустити правильний код, вам не потрібно турбуватися про імена змінних, що суперечать іменам команд.
lhunath

3
Усі текстові книги, які я переглянув у верхньому регістрі користувачів для всіх змінних оболонок. Незважаючи на те, що імена змінних малих регістрів є допустимими, велика література - це умовна умова.
Брайан С. Вілсон

3
Я цього не знав, і я просто втратив пару годин. над використанням USER="username"у bash-скрипті автоматизації деяких віддалених команд над ssh замість user="username". Тьфу! Радий, що зараз я знаю!
Габріель Степлес

28

Будь-які конвенції про іменування, що дотримуються послідовно, завжди допоможуть. Ось декілька корисних порад щодо іменування змінної оболонки:

  • Використовуйте всі обмеження та підкреслення для експортованих змінних та констант, особливо коли вони поділяються на кілька сценаріїв або процесів. Використовуйте загальний префікс, коли це застосовано, щоб пов'язані змінні виділялися і не стикалися з внутрішніми змінними Bash які є всіма великими літерами.

    Приклади:

    • Експортуються змінні із загальним префіксом: JOB_HOME JOB_LOG JOB_TEMP JOB_RUN_CONTROL
    • Константи: LOG_DEBUG LOG_INFO LOG_ERROR STATUS_OK STATUS_ERROR STATUS_WARNING
  • Використовуйте "футляр для змій" ( усі малі та підкреслені літери) ) для всіх змінних, які відносяться до одного сценарію чи блоку.

    Приклади: input_file first_value max_amount num_errors

    Використовуйте змішаний випадок, коли локальна змінна має певний зв’язок із змінною середовища, наприклад: old_IFS old_HOME

  • Використовуйте провідне підкреслення для "приватних" змінних та функцій. Це особливо актуально, якщо ви коли-небудь пишете бібліотеку оболонок, де функціям у файлі бібліотеки або в усіх файлах потрібно ділитися змінними, не зіткнувшись ні з чим, що може бути подібним чином названо в головному коді.

    Приклади: _debug _debug_level _current_log_file

  • Уникайте випадку з верблюдами . Це зведе до мінімуму помилки, спричинені помилками записів. Пам'ятайте, що змінні оболонки залежать від регістру .

    Приклади: inputArray thisLooksBAD, numRecordsProcessed,veryInconsistent_style


Дивитися також:


1
Це умовність , але воно навряд чи загальновизнане. Обґрунтування справи верблюда не зовсім переконливе. Рекомендація щодо використання SHOUTING для експортованих змінних м'яко суперечлива.
tripleee

3
Я не стверджував, що це звичайна конвенція. Я бачив, що більшість програмістів не замислюються серйозно про дотримання чітких умов у скриптах оболонок і думають про те, щоб записати свої думки на основі того, що я робив.
codeforester

8

Якщо змінні оболонки збираються експортувати в навколишнє середовище, варто врахувати, що POSIX (випуск 7, видання 2018 р.) Визначення змінної середовища середовища визначає:

Назви змінних оточуючих середовищ, які використовуються утилітами в томі Shell and Utilities POSIX.1-2017, складаються виключно з великих літер, цифр та підкреслення ( _) з символів, визначених у Portable Character Set, і не починаються з цифри.

...

Простір імен змінних імен середовища, що містять малі літери, зарезервовано для додатків. Програми можуть визначати будь-які змінні середовища з іменами з цього простору імен без зміни поведінки стандартних утиліт.


6

Я роблю те, що ти робиш. Я сумніваюсь, що є авторитетне джерело, але це здається досить поширеним де-факто стандартом.


1
Я згоден. Це тому, що ALL_CAPS некрасивий, але добре зробити так, щоб ЕКОЛОГІЧНІ ВАРІАБЛИВИ виділялися некрасивими.
струнка

1
Я погоджуюся з вами щодо стилю кодування, але я точно не погоджуюся з тим, що він широко поширений! Сценарії оболонки - одна з тих бічних мов, яку люди просто неформально вивчають, і тому я відчуваю, що всі завжди говорять МІСЦЕ =cat /tmp/location.txt
JasonSmith

@jhs - Мені, очевидно, пощастило в сценаріях оболонок, з якими мені довелося працювати!
Draemon

4
"Простір імен змінних імен середовища, що містять малі літери, зарезервовано для додатків." - POSIX IEEE Std 1003.1-2008 розділ 8.1
трійка

5

Насправді, термін "змінні середовища", здається, є досить недавнім видобутком. Керніган і Пайк у класичній книзі "Програмування UNIX програми", опублікованій у 1984 році, говорять лише про "змінні оболонки" - в індексі навіть немає запису "оточення"!


8
Я думаю, що це упущення книги. getenv (), setenv () та середовище були представлені у версії UNIX 7 (1979). en.wikipedia.org/wiki/Version_7_Unix
Джуліано

3
Ця книга хоче зазначити, що великі великі регістри мають особливе значення.
ashawley

3

Це просто дуже поширена конвенція, я сумніваюся, що для цього є якесь "авторитетне" джерело.


1

я схильний використовувати ALL_CAPS як для змінних середовищ, так і глобальних. Звичайно, у Bash немає реальної області змінної області, тому є гарна частина змінних, що використовуються як глобальні (в основному налаштування та відстеження стану), і відносно небагато "локальних" (лічильники, ітератори, частково побудовані рядки та часопис)


Так, я начебто концептуально думаю про неекспортовані змінні як місцевих жителів, оскільки Баш так часто змушує дочірніх процесів робити все, що йому завдано.
JasonSmith
Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.