Команда «.» (точка) часто используется в шелл-скриптах, однако не все знают, что это синоним команды source, встроенной в оболочку bash. Обычно говорят, что она используется для включения (подключения, «инклудинга») неких внешних файлов внутри скрипта. Рассмотрим в чём заключается суть такого подключения на примере файла .bash_profile:
На второй строчке с помощью оператора «.» выполняется содержимое файла
/.bashrc . Может возникнуть вопрос, почему нельзя было для этого использовать, например, sh или просто сам bash.
Дело в том, что при использовании точки не создаётся копии bash-процесса — скрипт выполняется в текущем экземпляре bash, причём все переменные окружения, инициализированные в данном скрипте после его завершения не исчезают, а передаются в окружение системы. Вот в этом и состоит суть «включения». Наоборот, если скрипт запускается явным образом с помощью sh или bash, то создаётся локальная копия (форк) bash, и по завершении скрипта в родительский bash ничего не возвращается — все переменные окружения, созданные в скрипте безвозвратно теряются.
Проиллюстрируем сказанное на простом примере. Создадим файл script следующего содержания:
Если теперь запустить скрипт с помощью sh, то на экран будет выведено значение внутренней переменной скрипта:
# sh script # Внутренняя переменная testenv = Hi there!
Однако эта переменная не сохранится после завершения работы скрипта и не будет присутствовать в текущем окружении bash:
Если же запустить скрипт точкой, то он выполнится с тем же результатом:
# . script # Внутренняя переменная testenv = Hi there!
Только переменная testenv будет доступна среди переменных окружения текущей системной оболочки:
# echo $testenv; # Hi there!
Дочерняя копия bash при использовании оператора точка создаётся только в том случае, когда процесс запускается в фоновом режиме. Это единственное исключение из общего правила.
Источник
Глава 3. Служебные символы
Служебные символы, используемые в текстах сценариев.
Комментарии. Строки, начинающиеся с символа # (за исключением комбинации #! ) — являются комментариями.
Комментарии могут располагаться и в конце строки с исполняемым кодом.
Комментариям могут предшествовать пробелы (пробел, табуляция).
Исполняемые команды не могут следовать за комментарием в той же самой строке. Пока что еще не существует способа отделения комментария от «исполняемого кода» , следующего за комментарием в той же строке.
Само собой разумеется, экранированный символ # в операторе echo не воспринимается как начало комментария. Более того, он может использоваться в операциях подстановки параметров и в константных числовых выражениях.
Кавычки » ‘ и \ экранируют действие символа #.
В операциях поиска по шаблону символ # так же не воспринимается как начало комментария.
Разделитель команд. [Точка-с-запятой] Позволяет записывать две и более команд в одной строке.
Следует отметить, что символ » ; » иногда так же как и # необходимо экранировать.
Ограничитель в операторе выбора case . [Двойная-точка-с-запятой]
команда «точка» . Эквивалент команды source (см. Пример 11-18). Это встроенная команда bash.
«точка» может являться частью имени файла . Если имя файла начинается с точки, то это «скрытый» файл, т.е. команда ls при обычных условиях его не отображает.
Если подразумевается имя каталога, то одна точка означает текущий каталог и две точки — каталог уровнем выше, или родительский каталог.
Символ точка довольно часто используется для обозначения каталога назначения в операциях копирования/перемещения файлов.
Символ «точка» в операциях поиска. При выполнении поиска по шаблону , в регулярных выражениях, символ «точка» обозначает одиночный символ.
Двойные кавычки . В строке «STRING» , ограниченной двойными кавычками не выполняется интерпретация большинства служебных символов, которые могут находиться в строке. см. Глава 5.
Одинарные кавычки . [Одинарные кавычки] ‘STRING’ экранирует все служебные символы в строке STRING . Это более строгая форма экранирования. Смотрите так же Глава 5.
Запятая . Оператор запятая используется для вычисления серии арифметических выражений. Вычисляются все выражения, но возвращается результат последнего выражения.
escape. [обратный слэш] Комбинация \X «экранирует» символ X . Аналогичный эффект имеет комбинация с «одинарными кавычками» , т.е. ‘X’ . Символ \ может использоваться для экранирования кавычек » и ‘ .
Более детальному рассмотрению темы экранирования посвящена Глава 5.
Разделитель, используемый в указании пути к каталогам и файлам. [слэш] Отделяет элементы пути к каталогам и файлам (например /home/bozo/projects/Makefile).
Подстановка команд. [обратные кавычки] Обратные кавычки могут использоваться для записи в переменную команды `command` .
пустая команда. [двоеточие] Это эквивалент операции «NOP» ( no op, нет операции). Может рассматриваться как синоним встроенной команды true. Команда » : » так же является встроенной командой Bash, которая всегда возвращает «true» ( 0 ).
Символ-заполнитель в условном операторе if/then:
Как символ-заполнитель в операциях, которые предполагают наличие двух операндов, см. Пример 8-2 и параметры по-умолчанию.
Как символ-заполнитель для оператора вложенного документа. См. Пример 17-9.
В комбинации с оператором > (оператор перенаправления вывода), усекает длину файла до нуля. Если указан несуществующий файл — то он создается.
В комбинации с оператором >> — оператор перенаправления с добавлением в конец файла и обновлением времени последнего доступа ( : >> new_file). Если задано имя несуществующего файла, то он создается. Эквивалентно команде touch.
Вышеизложенное применимо только к обычным файлам и неприменимо к конвейерам, символическим ссылкам и другим специальным файлам.
Символ : может использоваться для создания комментариев, хотя и не рекомендуется. Если строка комментария начинается с символа # , то такая строка не проверяется интерпретатором на наличие ошибок. Однако в случае оператора : это не так.
Символ » : » может использоваться как разделитель полей в /etc/passwd и переменной $PATH.
инверсия (или логическое отрицание) используемое в условных операторах. Оператор ! инвертирует код завершения команды, к которой он применен. (см. Пример 6-2). Так же используется для логического отрицания в операциях сравнения, например, операция сравнения «равно» ( = ), при использовании оператора отрицания, преобразуется в операцию сравнения — «не равно» ( != ). Символ ! является зарезервированным ключевым словом BASH.
В некоторых случаях символ ! используется для косвенного обращения к переменным.
Кроме того, из командной строки оператор ! запускает механизм историй Bash (см. Приложение F). Примечательно, что этот механизм недоступен из сценариев (т.е. исключительно из командной строки).
символ-шаблон. [звездочка] Символ * служит «шаблоном» для подстановки в имена файлов. Одиночный символ * означает любое имя файла в заданном каталоге.
В регулярных выражениях токен * представляет любое количество (в том числе и 0) символов.
арифметический оператор. В арифметических выражениях символ * обозначает операцию умножения.
Двойная звездочка (два символа звездочки, следующих подряд друг за другом — ** ), обозначает операцию возведения в степень.
Оператор проверки условия. В некоторых выражениях символ ? служит для проверки выполнения условия.
В конструкциях с двойными скобками, символ ? подобен трехместному оператору языка C. См. Пример 9-28.
сивол-шаблон. Символ ? обозначает одиночный символ при подстановке в имена файлов. В регулярных выражениях служит для обозначения одиночного символа.
Символ $ , предшествующий имени переменной, указывает на то, что будет получено значение переменной.
end-of-line (конец строки). В регулярных выражениях, символ «$» обозначает конец строки.
код завершения. Переменная $? хранит код завершения последней выполненной команды, функции или сценария.
id процесса. Переменная $$ хранит id процесса сценария.
группа команд.
Команды, заключенные в круглые скобки исполняются в дочернем процессе — subshell-е.
Переменные, создаваемые в дочернем процессе не видны в «родительском» сценарии. Родительский процесс-сценарий, не может обращаться к переменным, создаваемым в дочернем процессе.
инициализация массивов.
Фигурные скобки.
Команда интерпретируется как список команд, разделенных точкой с запятой, с вариациями, представленными в фигурных скобках. [1] При интерпретации имен файлов (подстановка) используются параметры, заключенные в фигурные скобки.
Использование неэкранированных или неокавыченных пробелов внутри фигурных скобок недопустимо.
file1 : A file1 : B file1 : C file2 : A file2 : B file2 : C
Блок кода. [фигурные скобки] Известен так же как «вложенный блок» , эта конструкция, фактически, создает анонимную функцию. Однако, в отличии от обычных функций, переменные, создаваемые во вложенных блоках кода, доступны объемлющему сценарию.
Код, заключенный в фигурные скобки, может выполнять перенаправление ввода-вывода.
Пример 3-1. Вложенные блоки и перенаправление ввода-вывода
Пример 3-2. Сохранение результата исполнения вложенного блока в файл
В отличие от групп команд в (круглых скобках), описаных выше, вложенные блоки кода, заключенные в <фигурные скобки>исполняются в пределах того же процесса, что и сам скрипт (т.е. не вызывают запуск дочернего процесса — subshell). [2]
pathname — полное имя файла (т.е. путь к файлу и его имя). Чаще всего используется совместно с командой find.
Обратите внимание на то, что символ » ; » , которым завершается ключ -exec команды find, экранируется обратным слэшем. Это необходимо, чтобы предотвратить его интерпретацию.
test.
Проверка истинности выражения, заключенного в квадратные скобки [ ]. Примечательно, что [ является частью встроенной команды test (и ее синонимом), И не имеет никакого отношения к «внешней» утилите /usr/bin/test.
test.
Проверка истинности выражения, заключенного между [[ ]] (зарезервированное слово интерпретатора).
См. описание конструкции [[ . ]] ниже.
элемент массива.
При работе с массивами в квадратных скобках указывается порядковый номер того элемента массива, к которому производится обращение.
Конструкция scriptname >filename перенаправляет вывод scriptname в файл filename. Если файл filename уже существовал, то его прежнее содержимое будет утеряно.
Конструкция command &>filename перенаправляет вывод команды command, как со stdout, так и с stderr, в файл filename.
Конструкция command >&2 перенаправляет вывод со stdout на stderr.
Конструкция scriptname >>filename добавляет вывод scriptname к файлу filename. Если задано имя несуществующего файла, то он создается.
(command)>
» » и » > » обозначают операции сравнения строк .
перенаправление ввода на встроенный документ.
bash$ grep ‘\ ‘ textfile
конвейер. Передает вывод предыдущей команды на ввод следующей или на вход командного интерпретатора shell. Этот метод часто используется для связывания последовательности команд в единую цепочку.
Конвейеры (еще их называют каналами) — это классический способ взаимодействия процессов, с помощью которого stdout одного процесса перенаправляется на stdin другого. Обычно используется совместно с командами вывода, такими как cat или echo, от которых поток данных поступает в «фильтр» (команда, которая на входе получает данные, преобразует их и обрабатывает).
cat $filename | grep $search_word
В конвейер могут объединяться и сценарии на языке командной оболочки.
А теперь попробуем объединить в конвейер команду ls -l с этим сценарием.
Выход stdout каждого процесса в конвейере должен читаться на входе stdin последующим, в конвейере, процессом. Если этого не делается, то поток данных блокируется , в результате конвейер будет работать не так как ожидается.
Конвейер исполняется в дочернем процессе, а посему — не имеет доступа к переменным сценария.
Если одна из команд в конвейере завершается аварийно, то это приводит к аварийному завершению работы всего конвейера.
принудительное перенаправление, даже если установлен ключ noclobber option.
логическая операция OR (логическое ИЛИ). В опрециях проверки условий, оператор || возвращает 0 (success), если один из операндов имеет значение true (ИСТИНА).
Выполнение задачи в фоне. Команда, за которой стоит & , будет исполняться в фоновом режиме.
В сценариях команды, и даже циклы могут запускаться в фоновом режиме.
Пример 3-3. Запуск цикла в фоновом режиме
Команда, исполняемая в пределах сценария в фоне, может подвесить сценарий, ожидая нажатия клавиши. К счастью, это легко «лечится».
Логическая операция AND (логическое И). В операциях проверки условий, оператор && возвращает 0 (success) тогда, и только тогда, когда оба операнда имеют значение true (ИСТИНА).
префикс ключа. С этого символа начинаются опциональные ключи команд.
COMMAND -[Option1][Option2][. ]
ls -al
sort -dfu $filename
set — $variable
перенаправление из/в stdin или stdout. [дефис]
Обратите внимание, что в этом контексте «-» — не самостоятельный оператор Bash, а скорее опция, распознаваемая некоторыми утилитами UNIX (такими как tar, cat и т.п.), которые выводят результаты своей работы в stdout.
В случае, когда ожидается имя файла, тогда «-» перенаправляет вывод на stdout (вспомните пример с tar cf) или принимает ввод с stdin.
Сама по себе команда file без параметров завершается с сообщением об ошибке.
Добавим символ «-» и получим более полезный результат. Это заставит командный интерпретатор ожидать ввода от пользователя.
Теперь команда принимает ввод пользователя со stdin и анализирует его.
Используя передачу stdout по конвейеру другим командам, можно выполнять довольно эффектные трюки, например вставка строк в начало файла.
С помощью команды diff — находить различия между одним файлом и частью другого:
grep Linux file1 | diff file2 —
И наконец пример использования служебного символа «-« с командой tar.
Пример 3-4. Резервное архивирование всех файлов, которые были изменены в течение последних суток
Могут возникнуть конфликтные ситуации между опреатором перенаправления «-» и именами файлов, начинающимися с символа «-» . Поэтому сценарий должен проверять имена файлов и предаварять их префиксом пути, например, ./-FILENAME, $PWD/-FILENAME или $PATHNAME/-FILENAME.
Если значение переменной начинается с символа «-» , то это тоже может быть причиной появления ошибок.
предыдущий рабочий каталог. [дефис] Команда cd — выполнит переход в предыдущий рабочий каталог, путь к которому хранится в переменной окружения $OLDPWD .
Не путайте оператор «-» (предыдущего рабочего каталога) с оператором «-» (переназначения). Еще раз напомню, что интерпретация символа «-» зависит от контекста, в котором он употребляется.
Минус. Знак минус в арифметических операциях.
В зависимости от контекста применения, символ » = » может выступать в качестве оператора сравнения.
Плюс. Оператор сложения в арифметических операциях.
В зависимости от контекста применения, символ + может выступать как оператор регулярного выражения.
Ключ (опция). Дополнительный флаг для ключей (опций) команд.
Отдельные внешние и встроенные команды используют символ » + » для разрешения некоторой опции, а символ » — » — для запрещения.
модуль. Модуль (остаток от деления) — арифметическая операция.
В зависимости от контекста применения, символ % может выступать в качестве шаблона.
домашний каталог. [тильда] Соответствует содержимому внутренней переменной $HOME.
bozo — домашний каталог пользователя bozo, а команда ls
bozo выведет содержимое его домашнего каталога.
/ — это домашний каталог текущего пользователя, а команда ls
/ выведет содержимое домашнего каталога текущего пользователя.
текущий рабочий каталог. Соответствует содержимому внутренней переменной $PWD.
предыдущий рабочий каталог. Соответствует содержимому внутренней переменной $OLDPWD.
начало-строки. В регулярных выражениях символ «^» задает начало строки текста.
изменяет поведение терминала или управляет выводом текста. Управляющий символ набирается с клавиатуры как комбинация CONTROL + .
Ctl-C
Завершение выполнения процесса.
Ctl-D
Выход из командного интерпретатора (log out) (аналог команды exit).
«EOF» (признак конца файла). Этот символ может выступать в качестве завершающего при вводе с stdin.
Ctl-G
«BEL» (звуковой сигнал — «звонок»).
Ctl-H
Backspace — удаление предыдущего символа.
Ctl-J
Ctl-L
Перевод формата (очистка экрана (окна) терминала). Аналогична команде clear.
Ctl-M
Ctl-U
Стирание строки ввода.
Ctl-Z
используется как разделитель команд или переменных. В качестве пробельного символа могут выступать — собственно пробел (space), символ табуляции, символ перевода строки, символ возврата каретки или комбинация из вышеперечисленных символов. В некоторых случаях, таких как присваивание значений переменным, использование пробельных символов недопустимо.
Пустые строки никак не обрабатываются командным интерпретатором и могут свободно использоваться для визуального выделения отдельных блоков сценария.
$IFS — переменная специального назначения. Содержит символы-разделители полей, используемые некоторыми командами. По-умолчанию — пробельные символы.
Примечания
Интерпретатор, встретив фигурные скобки, раскрывает их и возвращает полученный список команд, которые затем и исполняет.
Исключение: блок кода, являющийся частью конвейера, может быть запущен в дочернем процессе (subshell-е).