Что такое Shell
Если вы пользуетесь Linux, то рано или поздно, поиски решения какой-либо задачи приводили вас к терминалу. Это очень эффективное средство взаимодействия с операционной системой. Вы можете быстро выполнять нужные команды, получать результат и объединять несколько команд в цепочку. Один из самых основных компонентов терминала — это командная оболочка или Shell.
В этой статье мы поговорим о том, что такое Shell в Linux, зачем нужна командная оболочка, какие функции она выполняет и как развивались командные оболочки за последнее время.
Что такое Shell
Shell или командная оболочка — это программа, которая организовывает среду для выполнения других программ и команд Командная оболочка имеет свои встроенные команды, арифметические операторы и другие синтаксические выражения, но основная её задача упрощать запуск других программ. Именно командная оболочка занимается поиском программ в текущем каталоге и в путях, указанных в переменной среды PATH, управляет сменой текущего каталога и переменными окружения. Таким образом, основная задача оболочки — интерпретировать команды пользователя и выполнять их не зависимо от того внешние ли это программы или внутренние команды.
Чтобы понять с чем вы имеете дело, командой оболочки или внешней программой можно воспользоваться командой whereis. Например команда cd, это не программа, а встроенная команда оболочки, как и bg и fg:
А вот команда ls — уже внешняя программа, исполняемый файл которой расположен в файловой системе.
Командная оболочка — это традиционный способ ввода данных в Unix подобных операционных системах. Командные оболочки появились почти сразу же после появления Unix и привычных нам интерфейсов взаимодействия с компьютером. Первой командной оболочкой была Thompson Shell, разработанная Кеном Томсоном в Bell Labs в 1971 году. Уже тогда поддерживалось перенаправление ввода-вывода команд с помощью туннелей, а также поддерживались простые условные операторы.
Циклы while в командных оболочках появились чуть позже, в оболочке PWB Shell, разработанной Джоном Машеу на основе Thompson Shell. Но современный вид командная оболочка приобрела только с выходом оболочки Борна (Bourne Shell) в 1979 году. В ней было уже автодополнение имен файлов и команд, стандартные переменные окружения и привычные управляющие структуры. Исполняемый файл этой оболочки имел такой путь в системе — /bin/sh. В современных системах это обычно ссылка на используемую оболочку.
Именно вдохновляясь идеями этой оболочки потом была разработана оболочка Bash (Bourne Again Shell) используемая сейчас по умолчанию в большинстве дистрибутивов Linux. Она уже была разработана Браеном Фоксом в рамках проекта GNU в 1989 году. С тех пор прошло много времени и эта оболочка сильно устарела. Поэтому были разработаны и другие более современные командные оболочки, такие как ZSH и Fish.
Оболочка Zsh появилась незадолго после Bash в 1990 году, но она уже имеет намного больше функций, например, есть автодополнение для cd, когда выводится список папок из которого можно выбрать нужную:
Поддерживается автодополнение для параметров команд, например, для git можно вывести доступные команды вместе со справкой:
И это только несколько из всех преимуществ оболочки, кроме того она поддерживает цветные темы для вывода приглашения, а также довольно сильно расширяется с помощью плагинов.
Ещё более современная оболочка fish (Friendly Interactive Shell), появившаяся в 2005 году. Она поддерживает все стандартные возможности командной оболочки, но кроме того имеет удобную подсветку синтаксиса команд во время введения, удобный поиск команд, как Ctrl+R только по умолчанию, но самое удобное здесь это скрипты. Они намного проще для начинающих пользователей.
Если вы не меняли командную оболочку, то очень высока вероятность, что у вас используется Bash. Самый простой способ узнать какая оболочка у вас используется на данный момент, посмотреть содержимое переменной окружения SHELL:
Ещё один способ узнать текущую оболочку — воспользоваться командной ps. Если ей передать опцию -p и идентификатор процесса, то она покажет информацию о нём. Вывести идентификатор процесса текущей оболочки можно с помощью символов $$. Поэтому выполните:
В данном случае видно, что используется ZSH. Для того чтобы посмотреть все оболочки, установленные в вашей системе, просто выведите содержимое файла /etc/shells:
Все эти оболочки можно использовать выполнения команд от пользователей. Оболочка настраивается в файле /etc/passwd, для каждого пользователя отдельно. Поэтому посмотреть какая оболочка настроена для того или иного пользователя можно в этом файле. Например, для текущего пользователя команда будет выглядеть так:
grep «^$USER» /etc/passwd | awk -F: ‘< print $7>‘
Выводы
В этой статье вы узнали что такое Shell, а также как развивались командные оболочки от момента их появления до наших дней. Как видите, это очень удобный инструмент, и даже графический интерфейс не может его полностью заменить.
Обнаружили ошибку в тексте? Сообщите мне об этом. Выделите текст с ошибкой и нажмите Ctrl+Enter.
О разных командных оболочках Linux и Unix
Наверняка почти все читатели Хабра знают оболочки sh и bash. Так же большинство из нас что-то слышали про zsh и tcsh. Однако на этом список существующих оболочек не заканчивается. Условно можно разделить их на три группы:
- Клоны Bourne shell (bash, zsh)
- C shell (csh, tcsh)
- Базирующиеся на популярных языках программирования(psh, ipython, scsh)
- Экзотические, специфические и все остальные
Наибольшее распространение получили POSIX-совместимые оболочки, ведущие родословную от Bourne shell (шелл Борна), поэтому с него и начнем
Bourne shell и его клоны
Bourne shell, исполняемый файл: sh. Командная оболочка названная в честь своего создателя Стивена Борна. Большая часть операторов была заимствована им из языка Алгол 68. Вышла в 7-м издании операционной системы UNIX, где была оболочкой по умолчанию. До сих пор подавляющее большинство Unix-подобных систем имеют /bin/sh — символическую или жесткую ссылку на sh-совместимую оболочку.
Bourne again shell, исполняемый файл: bash. Название можно перевести, как «Возрождённый шел Борна». Скорее всего самая популярная оболочка на сегодняшний день. Де-факто стандарт для Linux. Не буду на ней останавливаться, т.к. в интернете много хороших статей про bash. Например вот и вот.
Z shell, исполняемый файл: zsh. Свободная современная sh-совместимая оболочка. Имеет ряд преимуществ перед bash касающихся в основном работы в интерактивном режиме. О ней на Хабре писали тут и тут
Кроме того существует довольно много оболочек попадающих в эту группу: Korn shell (ksh) и Almquist shell (ash) etc но не будем подробно на них останавливаться.
C shell
C shell, исполняемый файл: csh Командная оболочка разработанная автором vi Биллом Джоем. За основу для скриптового языка csh был взят, как понятно из названия, язык C. Т.к. на тот момент, в 1978 г., это был наиболее популярный язык программирования среди разработчиков и пользователей BSD UNIX. В настоящий момент более популярна свободная реализация csh — tcsh.
TENEX C Shell, исполняемый файл: tcsh. Именно в tcsh когда-то впервые появилось автодополнение. Является оболочкой по умолчанию в FreeBSD. Подробнее о ней почитать можно здесь.
Для того чтоб наглядно показать разницу в синтаксисе приведу несколько примеров скриптов делающих одно и то же для csh и sh-совместимого командного интерпретатора.
#!/bin/sh if [ $days -gt 365 ] then echo This is over a year. fi
#!/bin/csh if ( $days > 365 ) then echo This is over a year. endif
#!/bin/sh for i in d* do case $i in d?) echo $i is short ;; *) echo $i is long ;; esac done
#!/bin/csh foreach i ( d* ) switch ( $i ) case d?: echo $i is short breaksw default: echo $i is long endsw end
#!/bin/sh i=2 j=1 while [ $j -le 10 ]; do echo '2 **' $j = $i i=`expr $i '*' 2` j=`expr $j + 1` done
#!/bin/csh set i = 2 set j = 1 while ( $j
Однако список фичь поддерживаемых свежими версиями bash, zsh и tcsh очень похож и выбор конкретной оболочки по большей части дело вкуса. С менее распространенными оболочками дело обстоит иначе. Тут различия существеннее.
Командные оболочки, базирующиеся на популярных языках программирования.
Perl Shell, исполняемый файл: psh. Оболочка сочетающая в себе функции вышеупомянутых оболочек и мощь языка Perl. Т.к. psh написана на perl она может запускаться даже на Windows. Несколько примеров использования psh:
ls | s/y/k/ # Замена c помощью регулярных выражений ls | < print ++$i, ": $_"; >q # Быстрые фильтр. Внутри фигурных скобок выражение на perl, где $_ содержит одну строку вывода. netstat | < $_[1]>2; >g # grep-фильтры. Выводятся только те строки для которых выражение в скобках возвращает true command >[=FOO] # Перенаправление по дескриптору открытого файла command >[2] file # Эквивалентно command 2> file на bash. Перенаправляет в файл поток вывода и ошибок grep foo lib/**/*.pm # Использование **, что означает текущий каталог и все подкаталоги
Scsh, исполняемый файл scsh. Командный интерпретатор с открытым кодом использующий в качестве скриптового языка Scheme 48. Не поддерживает стандартные для других оболочек функции (история команд, редактирование текста в командной строке, дополнение путей/команд). Рекомендуется написания скриптов, но не для интерактивной работы. Может прийтись по вкусу любителям функционального программирования. Ниже приведен пример скрипта, который выводит имена всех исполняемых файлов находящихся в каталогах из переменной окружения PATH
#!/usr/local/bin/scsh -s !# (define (executables dir) (with-cwd dir (filter file-executable? (directory-files dir #t)))) (define (writeln x) (display x) (newline)) (for-each writeln (append-map executables ((infix-splitter ":") (getenv "PATH"))))
IPython. Это интерактивная оболочка для языка программирования Python, имеющая ряд дополнительных функций. IPython имеет специальный профиль для работы в качестве системной командной оболочки. Способ запуска этого режима зависит, как я понял, от версии, но на моей машине это выглядит так:
ipython3 --profile=pysh
- Кросплатформенность. Есть даже версия под Windows
- Python версий 2.x или 3.x в качестве скриптового языка, расширенные возможности интроспекции
- Автодополнение кода Python а так же имен файлов и системных команд.
- История команд и макросы на ее основе
- Механизм ускоряющий навигацию по каталогам, закладки и многое другое
# Допустим нам захотелось посчитать сумарный размер файлов логов dpkg: In [58]: cd /var/log/ /var/log In [59]: log_files = !ls -l dpkg.log* In [60]: log_files[0] Out[60]: '-rw-r--r-- 1 root root 1824 нояб. 3 16:41 dpkg.log' In [61]: for line in log_files: . size += int(line.split()[4]) . In [62]: size Out[62]: 1330009 # . или последовательно пингануть десяток хостов In [67]: for i in range(100,110): . !ping -c 1 192.168.0.$i .
Остальные
Конечно это не полный список даже популярных оболочек. Помимо вышеперечисленных категорий существуют ещё использующие собственный синтаксис, не совместимый с sh и не копирующий существующие ЯП . Примером может служить friendly interactive shell (fish). Но на последок хотел бы рассказать не о ней, а более специфической sleepshell.
Sleep Dummy Shell, исполняемый файл: sleepshell. Строго говоря командным процессором sleepshell назвать нельзя, т.к. он не умеет обрабатывать команды. И вообще не умеет ничего, кроме как периодически записывать в стандартный вывод звёздочки "*". Однако используется она именно в качестве командной оболочки и вот для чего: Допустим мы хотим предоставить кому-то возможность делать тоннели ssh через наш сервер под управлением Linux или Unix. Подробнее про ssh-туннелирование читаем тут. Но нам не нужно при этом, что этот кто-то получил доступ к командной строке и файловой системе нашего сервера. Для такого случая и предназначена sleepshell. Создаем на сервере аккаунт в качестве шела для него устанавливаем sleepshell. Владелец аккаунта сможет подключаться и пробрасывать порты, но не сможет выполнять команды.
На этом всё. Надеюсь, что было интересно. Буду рад любым замечаниям и советам по тексту статьи.