Работа интерпретатора bash (развертывание параметров)

8 сентября, 2010 Рубрики: bash, Linux, основы Linux

Приветствую всех, кто пришел на мой блог. В данной статье, хочу предоставить небольшое введение в принцип (последовательность) работы командного интерпретатора bash. То есть как шелл оболочка bash понимает (читай: интерпретирует) где команда, где параметры команды, где опции и вообще какие они, эти опции, и в итоге, что с командой и ее опциями и параметрами нужно сделать…

Итак, после ввода команды и нажатия Enter, оболочка bash:

  1. После ввода команды и нажатия клавиши Enter производится развертывание (подстановка) параметров в строке команды. Развертываниепроисходит в строго определенной последовательности:
    1. Развертывание фигурных скобок. При указании в фигурных скобках нескольких значений через запятую, итоговое значение разворачивается в список строк, содержащих каждое значение в скобках, например значение file{12,13,14}.txt будет развернуто в file12.txt file12.txt file14.txt.
    2. Развертывание тильды. Знак тильды заменяется значением переменной $HOME, при условии, что строка образует правильный логин. Если имя пользователя не является зарегистрированным в системе, то тильда не заменяется. Пример:
      $ echo $HOME
      /home/mc-sim
      $ echo ~
      /home/mc-sim
      $ echo ~123
      ~123
    3. Развертывание параметров. На данном этапе происходит замена позиционных переменных.
    4. Развертывание переменных. На данном этапе происходит подстановка значений переменных. (если переменная пустая или на задана, то и значение ее будет пустым). Чтобы запретить bash’у подстановку значений переменных, их необходимо экранизировать (литерализировать):
      $ echo $person
      McSim
      $ echo "$person"
      McSim
      $ echo '$person'
      $person
      $ echo \$person $person

      одинарные кавычки запрещают подстановку переменных, а символ \ экранирует $, которые указывает на то что $person – это переменная.

    5. Подстановка команды. Команду, заключенную в между $( и ) (аналог этой комбинации – заключение в обратные кавычки (`)) выполняет и ее результат передается интерпертатору/предыдущей команде.
    6. Развертывание арифметических выражений. Происходит поиск и вычисление арифметического выражения и заменяется результатом выражения. Выражение имеет формат: $[сумма+или+разность+или+еще=результат].
    7. Разбиение на слова. Шелл разбирает на элементы (слова) – строку команды. Какие символы оболочка будет использовать для разделения элементов команды, определяются в переменной $IFS.
    8. Развертывание путей (или Globbing). Более подробно о Globbing написано в man 7 glob. Развертывание путей заключается в подстановке файловых шаблонов (неоднозначных имен путей) по следующим правилам:
      1. * – вся строка (включая пустую строку)
      2. ? – любой один символ
      3. [abc…] или [a-c] – любой символ в квадратных скобках (при этом: символы ‘*’ и ‘?’ означают сами себя, а символ ‘!’ означает первый символ диапазона)
      4. [^abc…] или [^a-c] – НЕ символ в квадратных скобках (отрицание)
      5. спецсимволы, предваренные \ (обратной косой чертой) считаются как обычные и не обрабатываются как спецсимволы (экранируются)
  2. Далее bash проверяет наличие алиасов команд в /home/user_name/.bashrc (список имеющихся алиасов можно посмотреть командой alias)
  3. Ищет команду в следующем порядке:
    1. Среди встроенных в интерпретатор команд
    2. Ищет команду в каталогах, указанных в переменной $PATH (список каталогов можно получить командой echo $PATH
      Примечание: если в имени команды есть символ “/”, то интерпретатор запускает команду по пути (без поиска в $PATH)
  4. Выполняет инетерпертированную команду, при этом:
    1. При разделении команд знаками &&, следующая команда выполняется, только если предыдущая завершилось с кодом 0 (ноль), то есть без ошибок.
    2. При разделении команд знаками ||, следующая команда выполняется, только если предыдущая завершилось с НЕ нулевым значением.
    3. При разделении команд знаком ; (точка с запятой), следующая команда выполняется после завершения предыдущей, не зависимо от результата.
    4. При объединении команд в () (круглые скобки),  команды группируются и обрабатываются отдельной копией шелла, соответственно со своими переменными и окружением, которое может отличаться от остальных, не включенных в скобки.
    5. Если после команды или группы команд, заключенных в скобки, стоит символ &, то команда выполняется в фоновом режиме.
    6. Если в строке команды используются символы < или >, то выполняется перенаправление потоков.

Хочу заметить, что при запуске, bash последовательно читает следующие конфигурационные файлы: /etc/profile, /home/Linux_user/.bash_profile, /home/Linux_user/.bash_login, /home/Linux_user/.profile, /home/Linux_user/.bashrc (данный файл читается только не логин-оболочкой). В данных файлах хранятся настройки окружения bash (переменные, локаль и др.). Если есть необходимость изменить значение ключевых переменных, описанных в файлах $HOME/.bash_profile и др., без повторного входа в систему, необходимо выполнить команду:

$ . .bash_profile # точка пробел .bash_profile

Вот собственно и вся схема работы.

Upd 2010.10.11: дополнил 5 пункт.
Upd 2011.01.18: дополнил пункт 5.6-5.7, а так же конфигурационные файлы.
Upd 2011.01.20: переработаны полностью и объединены 1 и 2 пункты.

С Уважением, Mc.Sim!




Теги: , , ,
Комментариев пока нет.

Написать комментарий