Какая переменная окружения определяет файл истории команд
Перейти к содержимому

Какая переменная окружения определяет файл истории команд

  • автор:

Какая переменная окружения определяет файл истории команд

Команда history является встроенной командой командных оболочек C shell, csh и bash (но не sh), предназначенной для повторного исполнения ранее исполненных команд. Обычно история команд хранится в отдельном файле, например, командная оболочка bash хранит ее в файле .bash_history, расположенном в домашней директории пользователя. Это очень полезная команда, позволяющая сэкономить время, требующееся для повторного ввода длинных команд.

Базовый синтаксис команды выглядит следующим образом:

Команда поддерживает различные параметры, позволяющие модифицировать файл, а также историю команд текущей сессии, которые, впрочем, используются крайне редко. В частности, параметр -c позволяет очистить историю команд, параметр -d позволяет удалить команду с заданным идентификатором из истории, параметр -a позволяет добавить команды из текущей сессии в файл истории команд с заданным именем, параметр -n позволяет прочитать новые команды из файла истории команд с заданным именем и добавить их в историю команд текущей сессии, параметр -r позволяет прочитать все команды из файла истории команд с заданным именем и добавить их в историю команд текущей сессии, параметр -w позволяет записать всю историю команд в файл с заданным именем, параметр -p позволяет раскрыть аргументы и вывести результаты без добавления в историю и параметр -s позволяет добавить аргументы в качестве единственной команды истории текущей сессии.

Команда учитывает значения переменных окружения. Например, переменные окружения FILENAME и HISTFILE позволяют задать имя файла истории команд, переменная окружения HISTTIMEFORMAT — установить формат вывода даты и времени, переменные окружения HISTSIZE и HISTFILESIZE — установить максимальное количество строк файла истории команд, переменная окружения HISTCONTROL — задать правила обработки команд перед помещением их в историю текущей сессии.

Примеры использования

Работа с историей команд

Для вывода истории команд, выполненных с помощью командной оболочки, следует использовать команду history без каких-либо параметров:

$ history
1 mc
2 nano /etc/apt/sources.list
3 apt-get update

Команда выведет длинный список команд с их номерами. Для исполнения команды с заданным номером достаточно записать этот номер после восклицательного знака. Например, следующая команда позволит выполнить команду mc:

Если использовать два восклицательных знака, будет повторена предыдущая команда:

Если же нужно найти определенные команды, достаточно задействовать утилиту grep:

$ history | grep kwboot
196 apt search kwboot
200 kwboot
203 kwboot -t -B 115200 /dev/ttyUSB0 -b u-boot.kwb -p

Также в bash существует сочетание клавиш CTRL+R, позволяющее искать команды в истории команд в интерактивном режиме:

(reverse-i-search)`kwboot -t’: kwboot -t -B 115200 /dev/ttyUSB3 -b u-boot.kwb -p

Блокировка механизма записи команд

Если вы не хотите, чтобы исполняемые команды записывались в историю, вы можете использовать переменную окружения HISTSIZE. По сути, вам нужно лишь экспортировать эту переменную с нулевым значением, после чего команды перестанут записываться в историю:

$ export HISTSIZE=0
$ history
$

Очевидно, что после этого команда history не выводит никаких результатов.

Блокировка записи отдельных команд

Если вы хотите использовать историю команд командной оболочки, но не желаете, чтобы в нее записывались все исполняемые команды, вы можете воспользоваться переменной окружения HISTCONTROL. К примеру, вы можете экспортировать эту переменную с значением ignorespace, после чего все команды, начинающиеся с символа пробела, не будут записываться в историю команд:

$ export HISTCONTROL=ignorespace
$ history
1 mc

344 export HISTCONTROL=ignorespace
345 history
$ ls
$ history
1 mc

344 export HISTCONTROL=ignorespace
345 history
346 history

Очевидно, что команда ls с начальным символом пробела не была записана в историю.

Игнорирование дублей команд

Для того, чтобы вывести историю команд с игнорированием дублей достаточно использовать значение erasedups переменной окружения HISTCONTROL:

$ export HISTCONTROL=ignoreboth:erasedups
$ history
1 mc

344 export HISTCONTROL=ignoreboth:erasedups
345 history

Очистка истории команд

Для очистки истории команд достаточно использовать параметр -c команды history:

Как читать и определять переменные окружения и оболочки на Linux

Как читать и определять переменные окружения и оболочки на Linux главное изображение

В этой статье будет описано взаимодействие с окружением, а также чтение и установка переменных окружения и оболочки напрямую и через конфигурационные файлы. Все дальнейшие действия должны быть релевантны на любой системе Linux.

Введение

Когда происходит взаимодействие через сессию оболочки, имеется множество информации, которую консольная оболочка обрабатывает для определения своего поведения и доступа к сторонним ресурсам. Некоторые из этих настроек находятся в конфигурационных настройках, а другие определены самим пользователем.

Место, в котором оболочка держит пути всех этих настроек, называется окружением. Окружение — это место, которое оболочка определяет каждый раз, когда запускается сессия. В ней заключены переменные, созданные свойствами системы.

Бесплатные курсы по программированию в Хекслете

  • Освойте азы современных языков программирования
  • Изучите работу с Git и командной строкой
  • Выберите себе профессию или улучшите навыки

Как работает окружение и его переменные

Окружение обеспечивает набор переменных, через которые оболочка может получать или определять настройки, и пропускать их через дочерние процессы. Различные системные и пользовательские файлы могут обращаться к окружению.

Окружение реализовано как строка, состоящая из пары ключ-значение. Если определяется несколько значений, то они последовательно разделены знаком двоеточия. Каждая пара будет выглядеть как:

Если значение содержит пробелы, тогда используют кавычки
KEY="value with spaces" 

Ключами в данных примерах являются переменные. Они могут быть одним из двух типов: переменной окружения и переменной оболочки.

Переменные окружения это переменные, определенные для текущей оболочки — они наследуются любым потомком оболочки и запущенного процесса. Эти переменные используются, чтобы пропускать информацию в процессы, которые образуются от самой оболочки.

Переменные оболочки это переменные, которые содержатся исключительно в оболочке, где они были определены или установлены. Они часто используются для хранения путей, например, как текущая рабочая директория.

По правилам — эти типы переменных определяются, используя заглавные символы. Эта особенность помогает пользователям определять контекст употребления переменных.

Вывод переменных оболочки и окружения

Каждая сессия оболочки хранит пути своих собственных переменных и переменных окружения. Их достигнуть можно разными способами.

Можно распечатать список всех переменных окружения используя env или printenv . По умолчанию они должны делать все то же самое:

Как правило, этот вывод довольно типичен для обоих команд. Различия между ними в функциональности. Например, в printenv можно запрашивать значения определенной переменной.

С другой стороны env позволяет изменять окружение, указывая определение переменной. Например:

Дочерние процессы, как правило, наследуют переменные окружения от родительского процесса, и это дает возможность переписывать значения или добавлять дополнительные переменные для потомков.

Если посмотреть на вывод команды printenv , то там есть несколько переменных окружения, которые установлены через нашу файловую систему и процессов без нашего ввода.

Это были переменные окружения, но выглядят как переменные консольной оболочки.

Существует команда set , которую можно использовать для отображения. Если ввести set без дополнительных параметров, будет выводиться список всех переменных консольной оболочки, переменные окружения, локальные переменные и функции оболочки:

Вывод этой команды довольно огромен. Для удобства работы с этими переменными можно использовать пейджеры more или less .

В принципе, отсутствует особая необходимость знать все функции, определенные для bash . Поэтому — можно очистить вывод, указав, что set должен проводить операции в режиме POSIX , которые опускают отображение функций консольной оболочки. Это можно выполнить в дочерней оболочке, чтобы наше текущее окружение оставалось прежним:

Возникнет список всех определенных переменных окружения и оболочки.

Можно попробовать сравнить этот вывод с выводом команд env или printenv , тем самым получив список только переменных оболочки. Возможно, вывод будет довольно кривым:

Отображение будет до сих пор включать несколько переменных окружения, в связи с тем фактом, что set команда выводит значения в кавычках, в то время как команды printenv и env показывают значения, опуская их.

Все это должно давать правильное понимание переменных окружения и оболочки.

Эти переменные используются для всех необходимых вещей. Они обеспечивают альтернативный способ определения постоянных значений для сессии — между процессами, тем самым избегая изменений в файле.

Общие переменные окружения и консольной оболочки

Некоторые переменные окружения и оболочки очень полезны и к ним часто обращаются. Здесь перечислены общие переменные окружения, которые зачастую используются:

  • SHELL: отображает путь к оболочке, которая занимается интерпретацией тех или иных команд, которые вводит пользователь. Как правило, по умолчанию, это будет интерпретатор bash , но возможно и применение других значений, которые можно указать.
  • TERM: указывает тип терминала, который эмулируется, когда запускается консольная оболочка. Могут эмулироваться различные терминалы для необходимых операционных требований.
  • USER: имя текущего пользователя оболочки.
  • PWD: переменная отображает значение текущей рабочей директории.
  • OLDPWD: предыдущая рабочая директория. Оболочка держит эту переменную для обратного переключения, когда запускается команда cd — .
  • LS_COLORS: определяет цвет кодов, которые используются для вывода команды ls . Чтобы различать типы файлов и директорий.
  • MAIL: отображает электронную почту текущего пользователя.
  • PATH: список директорий, которые будет проверять система, когда будет идти обращение к той или иной команде. Когда пользователь вводит команду, система смотрит указанные директории, в последовательном порядке.
  • LANG: текущий язык и локализационные настройки, включая кодировку символов.
  • HOME: текущая домашняя директория пользователя.
  • _: отображает вывод последней запущенной команды.

В дополнение к этим переменным окружения, имеются некоторые переменные оболочки, которые также будут часто встречаться:

  • BASHOPTS: список опций, которые используются при запуске bash . Это может быть полезно для выяснения, каким конкретно способом будет оперировать консольная оболочка.
  • BASH_VERSION: отображает конкретную версию bash .
  • BASH_VERSINFO: мажорная версия bash .
  • COLUMNS: число колон, используемых для отображения вывода в оболочке.
  • DIRSTACK: директории, которые доступны для команд pushd и popd .
  • HISTFILESIZE: количество линий, хранящиеся в файле истории набранных команд.
  • HISTSIZE: количество линий, которые можно хранить в памяти.
  • HOSTNAME: имя компьютера системы на данный момент.
  • IFS: внутренний разделитель поля в командной строке. По умолчанию — это пробел.
  • PS1: строка приглашения на ввод. Эта переменная используется для того, чтобы определить, как будет выглядеть эта строка. Еще есть вторая строка PS2 которая используется, когда команда многострочная.
  • SHELLOPTS: опции оболочки, которые можно определять с помощью команды set .
  • UID: идентификатор текущего пользователя.

Установка переменных окружения и оболочки

Для лучшего понимания различий между двумя видами переменных и представления синтаксиса их определения, мы покажем примеры этого процесса.

Создание переменной оболочки

Определение этой переменной будет происходить в пределах текущей сессии консольной оболочки.

Кавычки здесь используются, поскольку значение переменной содержит пробел. В дальнейшем будут использоваться одинарные кавычки — это позволит сделать так, что особые знаки в bash будут правильно отображаться.

Определенная выше переменная теперь доступна в текущей сессии, но в дочернем процессе она будет отсутствовать. Увидеть ее можно при помощи команды grep на вывод set :

Если запустить команду exit , тогда оболочка выходит на родительскую сессию, в которой уже определена данная работающая переменная. Также можно убедиться в отсутствии данной переменной в окружении, сделав ту же проверку:

Чтобы получить значение той или иной переменной, используется следующая конструкция:

Команда echo делает вывод введенной строки как аргумента. Но, в данном случае применяется знак $ , в совокупности с ключом переменной, который возвращает ее значение.

Создание переменной окружения

Чтобы обернуть созданную переменную оболочки в переменную окружения, можно ее экспортировать:

Если создать новую дочернюю сессию, то можно увидеть, что в ней также существует эта переменная:

Дочерний процесс принял переменную, созданную предыдущей сессией. Также можно попробовать определить переменную в текущем процессе и проверить ее наличие в родительском:

Переменные окружения проходят только в дочерние процессы. Переменная NEW_VAR была определена в дочернем окружении переменных. Она была бы также доступна любым другим дочерним сессиям от этой текущей. Вернувшись обратно — в основную сессию, — через команду exit , предыдущее окружение вместе с этой переменной было стерто.

Отвязка переменных

На данный момент переменная TEST_VAR находится в окружении. По необходимости можно делать отвязку переменных.

Теперь, если посмотреть в окружение, то удаленная переменная там будет отсутствовать.

При этом она до сих пор существует в переменной оболочки:

Если возникает потребность окончательно сделать отвязку переменной из оболочки и окружения, то можно применить команду unset :

Проверить результат команды можно с помощью echo :

Отсутствует какое-либо возвращаемое значение, потому что переменная была отвязана.

Установка переменных окружения по логину

Как упоминалось выше, множество программ используют переменные окружения, чтобы решать, как конкретно производить операции. И вместо того, чтобы каждый раз делать вручную определение всех переменных, лучше определять переменные автоматически.

На самом деле, это более сложная проблема, чем кажется сперва, поскольку различные конфигурационные файлы, которые bash читает при запуске — и это зависит от того, как все запущено.

Различие между логин, не-логин, интерактивной и не-интерактивной сессией оболочки

Bash оболочка читает различные конфигурационные файлы в зависимости от того, какая сессия запущена.

Логин-сессия оболочки запускается по аутентификации пользователя. Если пользователь входит в сессию терминала или через SSH и аутентифицируется, тогда эта сессия оболочки будет определена как логин-оболочка.

Если начинается новая сессия bash-оболочки в пределах аутентифицированной сессии, подобно вызову команды bash из консоли, тогда такая оболочка определяется без логина и сразу запускается.

Помимо этих типов сессий, существуют интерактивный и не-интерактивный подход. Первый прикрепляется к терминалу, второй же — наоборот.

Таким образом сессии оболочки могут различаться по этим двум типам.

Обычная сессия, начинающаяся с SSH, обычно является интерактивной оболочкой с логином. Скрипты, запускающиеся из командной строки, обычно являют собой не-интерактивной и не-логин оболочкой. Терминальная сессия может быть составлена из любых комбинаций этих двух свойств.

В независимости от того, какая сессия определена как логин или не-логин, существуют некоторые заявления, по которым происходит инициализация сессии оболочки.

Логин сессия при запуске в первую очередь будет читать конфигурационные заявления из файла /etc/profile . Затем она будет смотреть данные в первом конфигурационном файле и пользовательской домашней директории, чтобы получить особые настройки пользователя.

Читаются исключительно файлы, которые располагаются в ~/.bash_profile , ~/.bash_login и ~/.profile .

В не-логин сессии оболочка читает файл /etc/bash.bashrc и пользовательский ~/.bashrc файл для построения своего окружения.

Не-интерактивные оболочки читают переменную окружения под названием BASH_ENV и читают указанный файл, чтобы определить новое окружение.

Реализация переменных окружения

Как можно увидеть выше, существуют различные отдельные файлы для настроек.

Это обеспечивает гибкость, которая может помочь в особых ситуациях, где будут необходимы конкретные настройки для логин и не-логин оболочки. Хотя, обычно, настройки одинаковы в обоих ситуациях.

Большинство Linux-дистрибутивов производят конфигурацию файлов к источнику не-залогиненых конфигурационных файлов. Это значит, что можно определять окружение переменных внутри них. И они будут прочитаны в обоих случаях.

Обычно в конфигурациях указываются особые переменные окружения для пользовательских нужд. Эти настройки указываются в ~/.bashrc файле.

Внутри этого файла будет уже содержаться определенные данные. Большинство из определений нужны для настройки bash-опций, которые мало связаны с окружением переменных. Переменные внутри файла устанавливаются так же, как и в командной оболочке:

Любое новое окружение переменных может быть добавленно в этот файл. Желательно добавлять новые данные в конец файла — это позволит быстрее их найти в случае, если нужно что-либо изменить. При следующем запуске оболочки, после изменения этого файла, указанные переменные будут прочитаны и пропущены в окружение оболочки. Возможно также и текущую сессию обновить, прочитав файл, введя следующую команду:

Если необходимо установить системные переменные, то можно добавить их в /etc/profile , /etc/bash.bashrc или /etc/environment .

Заключение

Переменные окружения и оболочки всегда представляются в сессиях оболочки и могут быть довольно полезными. Они являются интересным способом установки конфигурационных деталей родительских процессов для их дочерних, а также позволяют удобно производить настройку через внешние файлы.

Существуют различные сценарии, по которым необходимо читать окружение на системе. Эти инструменты и приемы должны дать хорошее основание для создания этих изменений и корректное их использование.

Статья была переведена отсюда .

Бесплатные курсы по программированию в Хекслете

  • Освойте азы современных языков программирования
  • Изучите работу с Git и командной строкой
  • Выберите себе профессию или улучшите навыки

Фундаментальные основы Linux. Часть III. Раскрытие команд командной оболочкой

Оригинал: Linux Fundamentals
Автор: Paul Cobbaut
Дата публикации: 16 октября 2014 г.
Перевод: А.Панин
Дата перевода: 13 декабря 2014 г.

Глава 14. История команд командной оболочки

В командной оболочке реализован механизм для упрощения повторного ввода команд, который в подробностях описан в данной главе.

Повторение последней выполненной команды

Для повторения последней выполненной команды в командной оболочке bash следует использовать команду !! . Данная последовательность символов носит имя bang bang (бэнг-бэнг).

paul@debian5:~/test42$ echo данная команда будет повторно исполнена > file42.txt paul@debian5:~/test42$ !! данная команда будет повторно исполнена > file42.txt paul@debian5:~/test42$

Повторение других команд

Вы можете повторить другие команды, воспользовавшись символом ! , после которого должен быть введен один или несколько начальных символов команды. В результате командная оболочка повторит последнюю команду, начинающуюся с введенных символов.

paul@debian5:~/test42$ touch file42 paul@debian5:~/test42$ cat file42 paul@debian5:~/test42$ !to touch file42 paul@debian5:~/test42$

Команда history

Для просмотра списка исполненных ранее команд следует использовать команду history , которая позволяет вывести информацию об истории команд, выполненных в рамках данной командной оболочки (или использовать команду history n для ознакомления со списком из n последних выполненных команд).

paul@debian5:~/test$ history 10 38 mkdir test 39 cd test 40 touch file1 41 echo привет > file2 42 echo Сегодня очень холодно > winter.txt 43 ls 44 ls -l 45 cp winter.txt summer.txt 46 ls -l 47 history 10

Команда !n

При вводе символа ! с последующим вводом номера команды для повторения, командная оболочка выведет строку соответствующей команды и исполнит ее.

paul@debian5:~/test$ !43 ls file1 file2 summer.txt winter.txt

Сочетание клавиш Ctrl-r

Другой вариант методики осуществления поиска в истории команд заключается в использовании сочетания клавиш ctrl-r . В примере ниже я использовал сочетание клавиш ctrl-r и ввел четыре символа apti , после чего в файле истории команд командной оболочки был осуществлен поиск последней команды, содержащей последовательность из этих четырех символов.

paul@debian5:~$ (reverse-i-search)`apti': sudo aptitude install screen

Переменная окружения $HISTSIZE

Переменная $HISTSIZE устанавливает количество команд, которые будут сохраняться при работе в вашем текущем окружении. Большинство дистрибутивов устанавливает стандартное значение данной переменной, равное 500 или 1000.

paul@debian5:~$ echo $HISTSIZE 500

Вы можете изменить значение данной переменной на любое желаемое.

paul@debian5:~$ HISTSIZE=15000 paul@debian5:~$ echo $HISTSIZE 15000

Переменная окружения $HISTFILE

Переменная $HISTFILE указывает на файл, который содержит данные истории команд вашей командной оболочки. В командной оболочке bash стандартным значением данной переменной является путь к файлу ~/.bash_history .

paul@debian5:~$ echo $HISTFILE /home/paul/.bash_history

Данные истории команд для сессии работы с командной оболочкой сохраняются в данном файле в момент, когда вы завершаете сессию !

При закрытии эмулятора терминала gnome-terminal с помощью мыши или команды reboot в случае работы с учетной записью пользователя root, история команд вашего терминала НЕ БУДЕТ сохранена.

Переменная окружения $HISTFILESIZE

Количество команд, сохраняемых в вашем файле истории команд, может быть установлено с помощью переменной окружения $HISTFILESIZE.

paul@debian5:~$ echo $HISTFILESIZE 15000

Предотвращение сохранения команд

Вы можете предотвратить запись команды в файл истории , использовав пробел в качестве префикса команды.

paul@debian8:~/github$ echo abc abc paul@debian8:~/github$ echo def def paul@debian8:~/github$ echo ghi ghi paul@debian8:~/github$ history 3 9501 echo abc 9502 echo ghi 9503 history 3

Регулярные выражения (дополнительная информация)

Имеется возможность использования регулярных выражений в случае использования символа ! для повтора команд. В примере ниже перед повторным исполнением команды производится замена символа 1 на символ 2 в строке этой команды.

paul@debian5:~/test$ cat file1 paul@debian5:~/test$ !c:s/1/2 cat file2 hello paul@debian5:~/test$

История команд оболочки Korn Shell (дополнительная информация)

Повторение команды при работе с командной оболочкой Korn Shell осуществляется похожим образом. Командная оболочка Korn Shell точно так же поддерживает команду history , но для извлечения команд из списка ранее исполненных команд в данной командной оболочке используется символ r .

В примере ниже продемонстрирована работа команды history. Обратите внимание на различие в назначении параметра команды.

$ history 17 17 clear 18 echo hoi 19 history 12 20 echo world 21 history 17

При повторении команд с использованием символа r в качестве аргумента могут быть использованы как номера команд, возвращенные командой history, так и последовательности начальных символов команд.

$ r e echo world world $ cd /etc $ r cd /etc $

Практическое задание: история команд командной оболочки

1. Выполните команду echo Ответом на вопросы о смысле жизни, вселенной и всем сущем является 42 .

2. Повторите предыдущую команду, использовав только два символа (существуют два решения!)

3. Выведите список из 5 последних исполненных вами команд.

4. Повторно выполните длинную команду echo из вопроса 1, воспользовавшись номерами команд, которые вы получили вместе с выводом команды из вопроса 3.

5. Сколько команд может храниться в файле истории команд в рамках текущей сессии вашей командной оболочки?

6. В какой файл сохраняются команды при при завершении сессии командной оболочки?

7. Сколько команд может быть записано в файл истории команд при завершении вашей текущей сессии командной оболочки?

8. Сделайте так, чтобы ваша командная оболочка bash сохранила 5000 введенных вами впоследствии команд.

9. Откройте более одной консоли (используйте сочетание клавиш Ctrl-shift-t в эмуляторе терминала gnome-terminal) с использованием одной и той же учетной записи пользователя. Когда данные истории команд запишутся в файл истории команд?

Корректная процедура выполнения практического задания: история команд командной оболочки

1. Выполните команду echo Ответом на вопросы о смысле жизни, вселенной и всем сущем является 42 .

echo Ответом на вопросы о смысле жизни, вселенной и всем сущем является 42

2. Повторите предыдущую команду, использовав только два символа (существуют два решения!)

!! или !e

3. Выведите список из 5 последних исполненных вами команд.

paul@ubu1010:~$ history 5 52 ls -l 53 ls 54 df -h | grep sda 55 echo Ответом на вопросы о смысле жизни, вселенной и всем сущем является 42 56 history 5

В вашем случае номера команд будут отличаться.

4. Повторно выполните длинную команду echo из вопроса 1, воспользовавшись номерами команд, которые вы получили вместе с выводом команды из вопроса 3.

paul@ubu1010:~$ !56

5. Сколько команд может храниться в файле истории команд в рамках текущей сессии вашей командной оболочки?

echo $HISTSIZE

6. В какой файл сохраняются команды при при завершении сессии командной оболочки?

echo $HISTFILE

7. Сколько команд может быть записано в файл истории команд при завершении вашей текущей сессии командной оболочки?

echo $HISTFILESIZE

8. Сделайте так, чтобы ваша командная оболочка bash сохранила 5000 введенных вами впоследствии команд.

HISTSIZE=5000

9. Откройте более одной консоли (используйте сочетание клавиш Ctrl-shift-t в эмуляторе терминала gnome-terminal) с использованием одной и той же учетной записи пользователя. Когда данные истории команд запишутся в файл истории команд?

В момент исполнения команды exit .

Предыдущий раздел: Оглавление Следующий раздел:
Глава 13. Встраивание и параметры командных оболочек Глава 15. Формирование списков имен файлов на основе шаблонов

Считывание и настройка переменных оболочки и окружения в Linux

Считывание и настройка переменных оболочки и окружения в Linux

При взаимодействии с вашим сервером в сеансе оболочки существует большое количество элементов информации, которые ваша оболочка использует для определения своего поведения и обеспечения доступа к ресурсам. Некоторые из этих настроек хранятся внутри настроек конфигурации, в то время как другие определяются с помощью пользовательского ввода.

Одним из способов, с помощью которого оболочка следит за всеми этими настройками и данными, состоит в использовании области, которая называется окружением. Окружение — это область, которую оболочка создает каждый раз при запуске сеанса, где содержатся переменные, определяющие свойства системы.

В этом руководстве мы обсудим вопрос взаимодействия с окружением и считывания или настройки переменных окружения и оболочки в интерактивном режиме и с помощью файлов конфигурации.

Как работают окружение и переменные окружения

Каждый раз при запуске сеанса оболочки запускается процесс сбора и компиляции информации, которая должна быть доступной процессу оболочки и его дочерним процессам. Он получает данные для этих настроек из самых разнообразных файлов и настроек в системе.

Окружение предоставляет среду, через которую процесс оболочки может получать или задавать настройки и, в свою очередь, передавать эти настройки его дочерним процессам.

Окружение реализуется в виде строк, которые содержат пары ключ-значение. Если передается несколько значений, они обычно разделяются двоеточием ( : ). Каждая пара, как правило, выглядит следующим образом:

KEY=value1:value2. 

Если значение содержит значительное количество пробелов, используются кавычки:

KEY="value with spaces" 

Ключи в этих случаях являются переменными. Они могут относиться к одному из двух типов: переменные окружения или переменные оболочки.

Переменные окружения — это переменные, определяемые для текущей оболочки и наследуемые любыми дочерними оболочками или процессами. Переменные окружения используются для передачи информации процессам, которые запущены в оболочке.

Переменные оболочки — это переменные, содержащиеся исключительно в оболочке, внутри которой они были заданы или определены. Часто они используются для отслеживания кратковременных данных, например текущего рабочего каталога.

Согласно конвенции эти типы переменных обычно определяются с помощью заглавных букв. Это помогает пользователям различать переменные окружения внутри других контекстов.

Вывод переменных оболочки и окружения

Каждый сеанс оболочки отслеживает собственные переменные оболочки и окружения. Мы можем получить доступ к этим переменным разными способами.

Мы можем просмотреть список всех наших переменных окружения с помощью команд env или printenv . В состоянии по умолчанию они должны работать одинаково:

Output
SHELL=/bin/bash TERM=xterm USER=demouser LS_COLORS=rs=0:di=01;34:ln=01;36:mh=00:pi=40;33:so=01;35:do=01;35:bd=40;33;01:cd=40;33;01:or=40;31;01:su=37;41:sg=30;43:ca. MAIL=/var/mail/demouser PATH=/usr/local/bin:/usr/bin:/bin:/usr/local/games:/usr/games PWD=/home/demouser LANG=en_US.UTF-8 SHLVL=1 HOME=/home/demouser LOGNAME=demouser LESSOPEN=| /usr/bin/lesspipe %s LESSCLOSE=/usr/bin/lesspipe %s %s _=/usr/bin/printenv

Ниже представлен приблизительный стандартный вывод для обеих команд: printenv и env . Разница между двумя командами становится заметна только при использовании более специфического функционала. Например, с помощью printenv вы можете запрашивать значения для отдельных переменных:

Output
/bin/bash

С другой стороны, env позволяет изменять окружение, в котором запущены программы, с помощью передачи набора определений переменных в следующей команде:

Поскольку, как мы узнали ранее, дочерние процессы обычно наследуют переменные окружения родительского процесса, это дает вам возможность переопределить значения или добавить дополнительные переменные для дочернего процесса.

Как вы можете видеть в выводе команды printenv , в системных файлах и процессах существует небольшое количество переменных окружения, доступных без нашего ввода.

Эти команды отображают переменные окружения, но как мы можем просмотреть переменные оболочки?

Для этого вы можете использовать команду set . Если мы введем команду set без каких-либо дополнительных параметров, то получим список всех переменных оболочки, переменных окружения, локальных переменных и функций оболочки:

Output
BASH=/bin/bash BASHOPTS=checkwinsize:cmdhist:expand_aliases:extglob:extquote:force_fignore:histappend:interactive_comments:login_shell:progcomp:promptvars:sourcepath BASH_ALIASES=() BASH_ARGC=() BASH_ARGV=() BASH_CMDS=() . . .

Обычно это очень большой список. Вы, скорее всего, захотите преобразовать его в более компактный вид для удобства просмотра выводимых данных:

Количество дополнительной информации, которую мы получаем, немного ошеломляет. Нам, скорее всего, не нужно знать, например, все функции bash, которые определены.

Мы можем очистить вывод, указав, что команда set должна работать в режиме POSIX, которые не подразумевает вывода функций оболочки. Также эту команду можно выполнить в субоболочке, чтобы не менять наше текущее окружение:

Она будет выводить список всех определенных переменных окружения и оболочки.

Мы можем попытаться сравнить данный вывод с выводом команд env или printenv , чтобы получить список исключительно переменные оболочки, но этот список будет несовершенен из-за того, что эти команды отображаются информацию по-разному:

Он все равно будет включать несколько переменных окружения из-за того, что команда set выводит значения в кавычках, а команды printenv и env не помещают строковые значения в кавычки.

Однако он все равно может дать неплохое представление о том, какие переменные окружения и оболочки настроены в вашем сеансе.

Эти переменные используются в самых разных случаях. Они предоставляют альтернативный способ настройки постоянных значений для сеанса, действующих в разных процессах, без необходимости записи изменений в файл.

Стандартные переменные окружения и оболочки

Некоторые переменные окружения и оболочки очень полезны и используются довольно часто. Ниже представлены некоторые распространенные переменные окружения, которые вам, скорее всего, придется использовать:

  • SHELL : описывает оболочку, где будет выполняться интерпретация любых команд, которые вы вводите. В большинстве случаев по умолчанию будет использоваться bash, но другие значения можно установить, если вы предпочитаете использовать другие варианты.
  • TERM : указывает тип терминала, который будет использоваться при запуске оболочки. Различные аппаратные терминалы могут имитироваться согласно различным операционным требованиям. Скорее всего вам не придется думать об этом.
  • USER : текущий пользователь, для которого выполнен вход.
  • PWD : текущий рабочий каталог.
  • OLDPWD : предыдущий рабочий каталог. Эта информация сохраняется оболочкой, чтобы выполнять переход к предыдущему каталогу с помощью команды cd — .
  • LS_COLORS : цветовые коды, которые используются для опционального добавления цветного вывода для команды ls . Эта команда используется для выделения различных типов файлов и предоставления пользователю большего количества информации при беглом просмотре.
  • MAIL : путь к почтовому ящику текущего пользователя.
  • PATH : список каталогов, которые система будет проверять при поиске команд. Когда пользователь вводит команду, система будет проверять каталоги в указанном здесь порядке при поиске исполняемого файла.
  • LANG : текущий язык и настройки локализации, включая кодирование символов.
  • HOME : домашний каталог текущего пользователя.
  • _ : последняя предыдущая выполненная команда.

Помимо этих переменных окружения существует ряд переменных оболочки, с которыми вы будете часто встречаться:

  • BASHOPTS : список опций, которые использовались при исполнении bash. Это может быть полезно, если вам нужно узнать, будет ли окружение оболочки работать так, как вы хотите.
  • BASH_VERSION : используемая версия bash, описанная в понятной человеку форме.
  • BASH_VERSINFO : версия bash в машиночитаемом виде.
  • COLUMNS : количество столбцов, используемых для отображения вывода на экране.
  • DIRSTACK : стек каталогов, доступных с помощью команд pushd и popd .
  • HISTFILESIZE : количество строк истории команды, хранящейся в файле.
  • HISTSIZE : количество строк истории команды, допустимое для хранения в памяти.
  • HOSTNAME : имя хоста компьютера в настоящий момент.
  • IFS : внутренний разделитель поля для выделения ввода в командной строке. По умолчанию используется пробел.
  • PS1 : определение первичного приглашения ввода. Эта опция используется для определения того, как будет выглядеть ваше приглашение при запуске сеанса оболочки. PS2 используется для объявления вторичного приглашения для случаев, когда команда использует несколько строк.
  • SHELLOPTS : опции оболочки, которые можно задать с помощью опции set .
  • UID : уникальный идентификатор текущего пользователя.

Настройка переменных оболочки и окружения

Чтобы лучше понять разницу между переменными оболочки и окружения, а также для знакомства с синтаксисом, используемым для настройки этих переменных, мы воспользуемся небольшой демонстрацией.

Создание переменных оболочки

Мы начнем с определения переменной оболочки внутри нашего текущего сеанса. Сделать это достаточно просто; нам нужно указать только имя и значение. Мы будем придерживаться конвенции по использованию исключительно заглавных букв в имени и зададим для него в качестве значения простую строку.

Здесь мы использовали кавычки, поскольку значение нашей переменной содержит пробел. Кроме того, мы использовали одинарные кавычки, потому что восклицательный знак — это специальный символ оболочки bash, который обычно использует историю bash, если не воспользоваться экранированием или одинарными кавычками.

Теперь у нас есть переменная. Эта переменная доступна в нашем текущем сеансе, но она не будет передаваться дочерним процессам.

Мы можем увидеть это, выполнив с помощью команды grep поиск новой переменной в выводе set :

Output
TEST_VAR='Hello World!'

Мы можем убедиться, что это не переменная окружения, попробовав выполнить то же самое действие для команды printenv :

Вывод должен быть пустой.

Давайте воспользуемся этим как возможностью продемонстрировать способ получения доступа к значению любой переменной оболочки или окружения.

Output
Hello World!

Как вы можете видеть, сослаться на значение переменной можно, добавив перед ее именем знак $ . Оболочка в результате понимает, что при обнаружении этой конструкции следует подставить значение переменной.

Теперь у нас есть переменная оболочки. Она не должна передаваться каким-либо дочерним процессам. Мы можем развернуть новую оболочку bash, используя для этого текущую оболочку, чтобы продемонстрировать это:

Если мы введем bash , чтобы развернуть дочернюю оболочку, а затем попробуем получить доступ к содержимому переменной, значение не будет возвращено. Именно этого мы и ожидали.

Вернитесь к нашей оригинальной оболочке, введя exit :

Создание переменных окружения

Теперь давайте превратим нашу переменную оболочки в переменную окружения. Мы можем сделать это с помощью экспорта переменной. Команда для выполнения этой задачи имеет соответствующее название:

Наша переменная будет превращена в переменную окружения. Мы можем убедиться в этом, снова проверив наш список переменных окружения:

Output
TEST_VAR=Hello World!

В этот раз наша переменная отображается в списке. Давайте повторим наш эксперимент с дочерней оболочкой:

Output
Hello World!

Отлично! Наша дочерняя оболочка получила переменную, настроенную в родительской оболочке. Перед тем как выйти из дочерней оболочки, давайте попробуем экспортировать другую переменную. Мы можем задать переменные окружения за один шаг, например:

Проверьте, что переменная успешно была экспортирована в окружение:

Output
NEW_VAR=Testing export

Теперь давайте вернемся в нашу оригинальную оболочку:

Давайте посмотрим, доступна ли наша новая переменная:

Ничего не возвращается.

Это связано с тем, что переменные окружения передаются только дочерним процессам. Это не является встроенным способом настройки переменных окружения для родительской оболочки. Это хорошо в большинстве случаев, так как программы не могут влиять на операционное окружение, из которого они были вызваны.

Переменная NEW_VAR была установлена в качестве переменной окружения в нашей дочерней оболочке. Эта переменная будет доступна из своей оболочки и любой из ее дочерних оболочек и процессов. Когда мы вышли обратно в нашу основную оболочку, это окружение было уничтожено.

Понижение и сброс переменных

Наша переменная TEST_VAR все еще определена в качестве переменной окружения. Мы можем превратить ее обратно в переменную оболочки, введя следующую команду:

Она больше не является переменной окружения:

Однако она все еще сохранила статус переменной оболочки:

Output
TEST_VAR='Hello World!'

Если мы хотим полностью сбросить переменную, как оболочки, так и окружения, мы можем сделать это с помощью команды unset :

Мы можем убедиться, что эта переменная больше не задана:

Ничего не возвращается, потому что переменная была сброшена.

Настройка переменных окружения во время входа

Мы уже упоминали, что многие программы используют переменные окружения для определения специфики своей работы. Мы не хотим задавать важные переменные каждый раз при запуске нового сеанса оболочки, и мы уже видели, сколько переменных уже задано при входе. Так как же мы можем создавать и определять переменные автоматически?

Это действительно более сложная проблема, чем это может показаться изначально, из-за множества файлов конфигурации, которые считывает оболочка bash в зависимости от того, как она запускается.

Разница между сеансами оболочки входа, без входа, интерактивными и неинтерактивными сеансами

Оболочка bash считывает разные файлы конфигурации в зависимости от того, как запускается сеанс.

Одно из различий между сеансами заключается в том, что оболочка запускается в рамках сеанса входа или без входа.

Оболочка входа — это сеанс оболочки, начинающийся с аутентификации пользователя. Если вы выполняете вход в сеанс терминала или через SSH с аутентификацией, ваш сеанс оболочки будет настроен в виде оболочки со входом.

Если вы запускаете новый сеанс оболочки внутри аутентифицированного сеанса, как мы уже делали, вызывая команду bash из терминала, запускается сеанс оболочки без входа. При запуске вашей дочерней оболочки вам не потребовалось вводить данные для аутентификации.

Еще одним отличием, которое можно отметить, является интерактивный или неинтерактивный характер сеанса оболочки.

Интерактивный сеанс оболочки — это сеанс оболочки, прикрепленный к терминалу. Неинтерактивный сеанс оболочки не прикреплен к сеансу терминала.

Таким образом, каждый сеанс оболочки классифицируется либо как сеанс входа или без входа, либо как интерактивный или неинтерактивный.

Обычный сеанс, который начинается с SSH, как правило, представляет собой интерактивный сеанс входа. Скрипт, запускаемый из командной строки, обычно запускается в неинтерактивном сеансе без входа. Сеанс терминала может быть иметь любое сочетание этих двух параметров.

То, относится ли сеанс оболочки к оболочке входа или без входа, определяет то, какие файлы будут считываться при инициализации сеанса оболочки.

Сеанс, запускаемый в виде сеанса входа, будет считывать данные конфигурации сначала из файла /etc/profile . Затем он будет искать первый файл конфигурации сеанса входа в домашнем каталоге пользователя, чтобы получить данные конфигурации для конкретного пользователя.

Сеанс считывает первый из файлов ~/.bash_profile , ~/.bash_login и ~/.profile , который ему удается найти, и не считывает остальные файлы.

В отличие от этого сеанс, определенный в оболочке без входа, будет читать файл /etc/bash.bashrc и затем использовать файл ~/.bashrc конкретного пользователя для создания окружения.

Неинтерактивные оболочки считывают значение переменной окружения BASH_ENV и указанный в нем файл для определения нового окружения.

Реализация переменных окружения

Как вы можете видеть, существует множество разных файлов, которые часто требуется просмотреть при определении наших настроек.

Эта возможность предоставляет большую гибкость, которая может быть полезна в определенных ситуациях, когда нам нужны определенные настройки при использовании оболочки входа и другие настройки для оболочки без входа. Однако большую часть времени мы будем использовать одни и те же настройки в обеих ситуациях.

К счастью, большинство дистрибутивов Linux позволяют настраивать файлы конфигурации входа для использования файлов конфигурации без входа. Это означает, что вы можете определить переменные окружения, которые вы хотите использовать в обоих случаях, только в файлах конфигурации без входа. Затем эти файлы будут считываться в обоих сценариях.

Чаще всего мы будем настраивать переменные окружения для конкретного пользователя, и наши настройки, как правило, будут доступны в оболочках как со входом, так и без входа. Это означает, что лучше всего использовать для определения этих переменных файл ~/.bashrc .

Откройте этот файл:

Скорее всего, он уже содержит довольно большое количество данных. Большинство определений здесь предназначены для настройки опций bash, которые не имеют отношения к переменным окружения. Вы можете задать переменные окружения таким же образом, как вы делали это в командной строке:

Любые новые переменные окружения можно добавить в любое место файла ~/.bashrc при условии, что они не помещаются внутри другой команды или цикла. Сохраните и закройте файл. В следующий раз при запуске сеанса оболочки ваше объявление переменной окружения будет считываться и передаваться в среду оболочки. Вы можете заставить ваш текущий сеанс считать файл прямо сейчас, введя следующую команду:

Если вам потребуется задать общесистемные переменные, вы можете рассмотреть возможность их добавления в файлы /etc/profile , /etc/bash.bashrc или /etc/environment .

Заключение

Переменные окружения и оболочки всегда присутствуют в сеансах оболочки и могут быть очень полезны. Они представляют собой интересный способ настройки данных конфигурации родительского процесса для его дочерних процессов, а также позволяют задавать опции вне файлов.

Такой подход обладает множеством преимуществ в определенных ситуациях. Например, некоторые механизмы развертывания используют переменные окружения для настройки информации аутентификации. Это полезно, потому что данный способ позволяет избежать необходимости сохранения этих данных в файлах, которые могут быть видны третьим сторонам.

Существует много других, более простых, но очень распространенных сценариев, где вам может потребоваться считывать или изменять окружение вашей системы. Эти инструменты и техники могут послужить хорошей основой для внесения этих изменений и их корректного использования.

Thanks for learning with the DigitalOcean Community. Check out our offerings for compute, storage, networking, and managed databases.

Добавить комментарий

Ваш адрес email не будет опубликован. Обязательные поля помечены *