Если вы когда-либо читали инструкции от разработчиков, то наверняка видели фразы вроде: «Откройте консоль», «Выполните эту команду в терминале» или «Для этого потребуется командная строка». Эти инструменты часто называют невероятно мощными и полезными, но что это означает на практике? Почему терминал считается незаменимым инструментом разработчика и какие возможности он предоставляет, выходя за рамки привычных графических интерфейсов?
Меня зовут Евгений Бартенев, и я автор и техлид курса «Python-разработчик» в Яндекс Практикуме. В этой статье я расскажу, что стоит за терминами «терминал», «оболочка» и «командная строка», а также разберу их некоторые отличия и особенности. Вы узнаете, как они связаны друг с другом и почему работа через консоль зачастую оказывается быстрее и эффективнее. Мы также рассмотрим некоторые практические примеры, которые трудно реализовать, полагаясь только на графический интерфейс.
Эта статья не является справочником команд или пошаговой инструкцией. Она написана для тех, кто хочет понять, что же такое командная строка, и разобраться в её ключевых возможностях. Материал будет не столь полезен опытным разработчикам, которые используют терминал ежедневно. Однако я сделал фокус на терминологии и ключевых концепциях, которые часто остаются за кадром или вызывают путаницу даже у некоторых опытных пользователей. Но обо всём по порядку.
Разбор в ролике для тех, кто предпочитает видеоформат.
Терминология
Почти в каждой современной операционной системе есть графический интерфейс — это знакомые многим окна, иконки, кнопки и другие графические элементы. С их помощью можно выполнить практически любое действие. Однако в операционных системах обычно доступны и другие интерфейсы, например интерфейс командной строки.
Через интерфейс командной строки можно выполнять те же задачи, что и через графический, а иногда и значительно больше. Например, представить себе графический интерфейс для управления сотнями команд с множеством параметров — с ключами, подкомандами и опциями — довольно сложно. Если попытаться отобразить их все через кнопки и меню, экран быстро окажется перегружен элементами. Командная строка решает эту проблему: одна строка ввода может заменить целый набор сложных графических элементов.
Когда программисты говорят «откройте терминал» или «откройте консоль», они, как правило, имеют в виду именно интерфейс командной строки.
Терминал — это интерфейс для ввода-вывода текста, через который можно взаимодействовать с операционной системой.
В каждой операционной системе по умолчанию есть один или несколько терминалов, например:
в Windows — Windows Terminal, Windows Console Host;
в Linux — GNOME Terminal, Konsole;
в macOS — Terminal.app.
Хотя в обиходе слова «терминал» и «консоль» часто используют как синонимы, технически эти понятия различаются:
терминал — это интерфейс для работы с текстом;
консоль может означать как физическое устройство (например, монитор и клавиатуру в старых компьютерах), так и программу для доступа к терминалу.
При работе с терминалом вы на самом деле взаимодействуете с оболочкой (shell).
Оболочка — это программная среда, которая интерпретирует текстовые команды и выводит результаты. Оболочки можно менять или переключаться между ними, но сам терминал остаётся тем же.
Оболочки по умолчанию:
Windows: Command Prompt, PowerShell.
Linux: большинство дистрибутивов Linux используют bash (Bourne Again SHell) как оболочку по умолчанию. Некоторые новые дистрибутивы начали переходить на zsh (Z shell, произносится как «зет-шелл»).
macOS: до macOS Catalina оболочкой по умолчанию была bash. Начиная с macOS Catalina и позже, Apple перешла на использование zsh в качестве оболочки по умолчанию.
Каждая оболочка может обрабатывать команды, поддерживаемые операционной системой и соответствующим терминалом, но многие оболочки добавляют и свои уникальные возможности.
Обычно оболочки поддерживают сотни, а некоторые даже тысячи команд. Чтобы как-то навести порядок в этом многообразии возможностей, стали появляться различные стандарты. Среди таких стандартов особенно выделяется POSIX (Portable Operating System Interface). Он определяет ключевой набор текстовых команд и их ожидаемые результаты. Если оболочка называется POSIX-совместимой, это означает, что она поддерживает этот установленный набор команд.
Точное количество существующих оболочек определить сложно, поскольку их разработано множество, и новые продолжают появляться. Наиболее известные и популярные POSIX-оболочки — это bash (Bourne-Again SHell), Dash (Debian Almquist shell), ksh (Korn shell), ash (Almquist shell), zsh. А вот оболочки Fish (Friendly interactive shell), PowerShell, Command Prompt, Eshell не поддерживают POSIX, поэтому даже для одноимённых команд в каждой из них можно получить различный результат.
В этой статье я сфокусировался на возможностях именно POSIX-совместимых оболочек на примере zsh в операционной системе macOS.
Переключение между оболочками
Запустить интерфейс командной строки в операционной macOS можно по-разному. Чтобы открыть терминал с помощью Spotlight, достаточно нажать сочетание клавиш Command (⌘) + Пробел и в появившейся строке начать вводить слово Terminal. Как только терминал появится в списке предложений, выберите его нажатием клавиши Enter.
По умолчанию в macOS используется оболочка zsh, но вы можете переключиться на другую, например bash. Для этого выполните в терминале команду bash
— заголовок окна изменится, а в самом окне изменится приглашение для ввода команд.
В macOS по умолчанию предустановлена устаревшая версия bash (3.2), что связано с политикой Apple, направленной на использование лицензий, не обременённых условиями GPLv3. Для использования актуальной версии bash необходимо выполнить дополнительные действия, например установить обновление через менеджер пакетов Homebrew.
Чтобы вернуться в оболочку zsh, введите и выполните команду exit
.
На macOS предустановлены и другие оболочки. Чтобы увидеть все оболочки, доступные в вашей системе, выполните команду:
cat /etc/shells
На стандартной macOS вы увидите что-то вроде:
Для большинства пользователей zsh будет наиболее удобной и функциональной оболочкой, поэтому продолжим именно с ней. Начнём с самых базовых возможностей.
Базовые возможности оболочки
Одна из самых удобных функций большинства оболочек — это возможность быстро перебирать и повторно выполнять ранее введённые команды. Для этого достаточно использовать клавиши стрелка вверх и стрелка вниз.
Клавиши стрелка вправо и стрелка влево перемещают курсор на один символ вправо и влево, а при одновременном удержании клавиши Option — вправо и влево можно перемещаться уже по словам.
Оболочка zsh поддерживает удобное автодополнение. Просто начните вводить команду или путь к файлу, а затем нажмите Tab. Оболочка предложит варианты завершения. Если доступно несколько вариантов, zsh отобразит их список.
Если вы не уверены в том, как использовать ту или иную команду, можно обратиться за справкой. Для этого введите команду man
(англ. manual, «руководство»), которая открывает полное описание команды, например: man ls
.
Выйти из режима просмотра можно, нажав на клавишу q.
Если терминал заполнен текстом и вы хотите начать с чистого экрана, достаточно ввести команду clear
или использовать сочетание клавиш Command + K.
Очистка экрана в терминале, например с помощью команды clear
, не удаляет историю введённых команд — она просто очищает текущее отображение в окне терминала, оставляя всё, что вы вводили ранее, доступным для поиска. Это значит, что вы по-прежнему можете использовать клавиши стрелка вверх и стрелка вниз, чтобы пролистать недавно введённые команды.
Если нужная команда была введена давно, искать её вручную стрелками может быть неудобно. В таком случае поможет команда history
. Она выводит список всех команд, которые вы вводили, вместе с их порядковыми номерами. Например, после выполнения команды history
вы увидите что-то вроде этого:
Теперь, зная номер нужной команды, вы можете выполнить её снова, используя сокращённый синтаксис !<номер>
.
Например, команда !73
повторит команду pwd
(англ. print working directory, «напечатай рабочую папку»).
Псевдонимы
Псевдонимы (алиасы) — это удобный способ сократить часто используемые команды или создать короткие версии для длинных и сложных команд в POSIX-совместимых оболочках.
Для создания псевдонима, который будет доступен только в текущей сессии терминала, используется команда alias
:
alias имя='команда'
Например:
alias ll='ls -la'
Теперь при вводе и выполнении команды ll
будет выполняться команда ls -la
.
Чтобы увидеть все активные псевдонимы, выполните команду alias
.
Для удаления псевдонима используйте команду unalias
:
unalias ll
Чтобы псевдоним сохранялся после перезапуска терминала, его нужно добавить в файл конфигурации оболочки:
echo "alias ll='ls -la'" >> ~/.zshrc
После внесения изменений перезапустите оболочку или выполните source ~/.zshrc
Перенаправление потоков
Потоки в UNIX-подобных операционных системах — это способ работы с данными, которые «текут» между программами, файлами и устройствами. Поток можно представить как канал, через который данные перемещаются, например, из файла в программу, из программы в другой процесс или на устройство, такое как принтер.
Основных потоков три:
Стандартный ввод (stdin) — это поток, откуда программа получает данные. Обычно это клавиатура.
Стандартный вывод (stdout) — это поток, куда программа отправляет свои результаты. Обычно это вывод в окне терминала.
Стандартный поток ошибок (stderr) — это поток для сообщений об ошибках. Он отделён от стандартного вывода, чтобы ошибки не смешивались с обычным результатом программы.
Допустим, вы выполняете команду ls
. Выполнение команды ls
создаёт список файлов и выводит его в стандартный вывод (stdout), то есть на экран. Однако это можно изменить.
Допустим, вам требуется сохранить весь вывод в файл. И самый простой способ сделать это — перенаправить поток. Для этого используется команда >
.
ls > output.txt
Поток будет перенаправлен, и теперь список файлов сохраняется в файл с указанным именем, а не выводится на экран.
Подобным же образом стандартный ввод (stdin) программы можно перенаправить с клавиатуры на файл. Для этого используется символ <
.
python3 myscript.py < input.txt
Программа на Python в файле myscript.py написана так, чтобы получать данные с клавиатуры, но теперь она будет построчно читать указанный файл и брать данные из него, а не ждать ввода от пользователя в терминале.
Конвейеры
Когда вы вводите команду в оболочке, она запускается и выполняется. Результат выполнения команды обычно отображается на экране. Однако в POSIX-совместимых оболочках результат выполнения одной команды вместо вывода на экран можно передать другой команде. Это позволяет создавать последовательности команд для обработки данных. Этот механизм носит название конвейеров (иногда их ещё называют пайплайны) и при написании команд обозначается символом |
.
С помощью конвейеров можно выполнять довольно сложные задачи, разбивая их на последовательность более простых шагов.
Например:
cat input.txt | wc -l
Отдельное выполнение команды cat input.txt
выводит содержимое файла input.txt, а команда wc -l
подсчитывает количество строк в выводе.
Запуск конвейера из этих команд даст только финальный результат — количество строк, минуя промежуточные результаты.
Или вот другой пример:
ls -l | sort -k 5 -n
Команда ls -l
выводит список файлов с подробной информацией, а запуск команды sort -k 5 -n
сортирует вывод по пятому столбцу (размеру файлов). В результате выполнения конвейера мы сразу же получим необходимый результат.
А вот более сложный пример. У нас есть текстовый файл log.txt, содержащий список IP-адресов пользователей, подключавшихся к серверу.
192.168.0.1
192.168.0.2
192.168.0.1
192.168.0.3
192.168.0.2
192.168.0.1
Надо найти IP-адрес хакера, который решил загрузить наш сервер подключениями, вывести этот IP-адрес вместе с количеством подключений, попутно сохранить результат в файл top_user.txt. Из инструментов у нас только оболочка zsh.
В качестве решения задачи можно использовать следующий конвейер:
cat log.txt | sort | uniq -c | sort -nr | awk 'NR==1 {print $2, $1}' | tee top_user.txt
Тут каждая команда выполняет свою задачу, разберём их по порядку.
cat log.txt
— читает содержимое файла log.txt и передаёт его в конвейер.sort
— сортирует IP-адреса, чтобы одинаковые IP-адреса оказались рядом.uniq -с
— подсчитывает количество повторений каждой уникальной строки (IP-адреса). Флаг -c добавляет число повторений перед каждым IP.sort -nr
— сортирует строки по числовым значениям в порядке убывания (флаг-nr: -n
— числовая сортировка,-r
— обратный порядок).awk 'NR==1 {print $2, $1}'
— обрабатывает только первую строку (самый активный IP-адрес) благодаря фильтруNR==1
. Команда{print $2, $1}
выводит второй столбец (IP-адрес) и первый столбец (количество подключений).tee top_user.txt
— записывает результат в файл top_user.txt и одновременно выводит его на экран.
Задачу, конечно, можно было бы решить и меньшим количеством шагов, но я специально хотел показать пример длинного конвейера с разными командами.
В теории количество действий (команд) в конвейере оболочки (например, в bash или zsh) практически не ограничено. Однако на практике существуют технические и системные ограничения, которые определяют максимальную длину конвейера. Например, максимальный размер аргументов командной строки можно получить при помощи команды getconf ARG_MAX
.
Логические операторы
В POSIX-совместимых оболочках логические операторы используются для управления выполнением команд в зависимости от их успешности (возвращаемого кода завершения). Эти операторы позволяют создавать не просто сложные последовательности команд, а последовательности с условиями выполнения.
Например, команда справа от &&
выполняется, только если команда слева завершилась успешно (код завершения 0).
mkdir new_dir && cd new_dir
Если mkdir new_dir
выполнится успешно (директория будет создана), тогда выполнится cd new_dir
— переход в созданную директорию. Если первая команда завершится с ошибкой (например, папка уже существует), вторая команда не будет выполнена.
Команда справа от ||
выполняется, только если команда слева завершилась с ошибкой (код завершения не 0).
mkdir new_dir || echo "Directory already exists"
Если mkdir new_dir
завершится с ошибкой, будет выполнена команда echo
. Если директория успешно создалась, то вторая команда не выполняется.
Можно комбинировать операторы, чтобы создать более сложные условия.
mkdir new_dir && echo "Directory created" || echo "Failed to create directory"
Если команда mkdir new_dir
успешно выполнена — выполняется echo "Directory created". Если же выполнение mkdir new_dir
привело к ошибке — выполняется echo "Failed to create directory"
.
Важный момент заключается в том, что здесь выполняется либо одна из двух веток, либо обе, в зависимости от того, как завершится вторая команда. Чтобы это предотвратить, можно использовать скобки:
(mkdir new_dir && echo "Directory created") || echo "Failed to create directory"
Таким образом логические операторы позволяют строить условия, обрабатывать ошибки и упрощать написание скриптов.
Условия
Современные оболочки терминалов давно вышли за рамки простого ввода и выполнения команд. Они предоставляют инструменты, которые позволяют использовать программные конструкции, знакомые каждому разработчику: переменные, циклы, условия, функции, массивы и многое другое.
Это превращает работу в терминале в процесс, близкий к написанию настоящего кода. Например, вы можете использовать циклы для обработки данных в файлах, условные конструкции для управления потоком выполнения или создавать сложные автоматизации прямо в командной строке.
Давайте рассмотрим, как это выглядит на практике.
Итак, конструкция if
проверяет условие и выполняет определённые команды, если это условие истинно (то есть возвращает код завершения 0). Если условие ложно, можно указать команды для выполнения через else
или дополнительные проверки через elif
.
Например, предположим, что вы работаете с сервером, где нужно ежедневно проверять наличие файла с данными (например, отчёта), и если файла нет, то отправить уведомление администратору, ну или просто вывести сообщение в консоль.
Вот как это можно сделать с помощью конструкции if:
if [ -f input.txt ]; then
echo "File exists"
elif [ -d input.txt ]; then
echo "This is a directory"
else
echo "File does not exist"
fi
Здесь [ -f input.txt ]
проверяет, существует ли файл с именем input.txt. Если файла нет, проверяется условие [ -d input.txt ]
, которое проверяет, является ли объект директорией. Если оба условия ложны, выполняется блок else.
Циклы
В оболочках терминалов, как правило, доступно несколько видов циклов, которые позволяют повторять выполнение команд до достижения определённого условия. Среди них наиболее популярны while, until и, конечно же, for, который особенно часто используется для итерации по элементам, строкам файлов или другим наборам данных. Это делает его универсальным инструментом для автоматизации рутинных задач.
Например, представьте, что вам нужно переименовать все изображения в папке, добавив к их именам текущую дату. Если делать это вручную через графический интерфейс, вам придётся тратить время на каждое изображение. С помощью цикла в терминале это можно автоматизировать буквально одной командой:
for file in *.jpg
do
mv "$file" "$(date +%Y-%m-%d)_$file"
done
Этот цикл перебирает все файлы с расширением .jpg в текущей папке и переименовывает их, добавляя текущую дату перед оригинальным именем.
Такой подход экономит массу времени, особенно если изображений десятки или сотни. Кроме того, вы можете модифицировать цикл для других задач, в основе которых лежит перебор чего-либо, например файлов:
for file in *.txt
do
echo "Processing $file"
done
Здесь переменная file принимает поочерёдно имена всех файлов с расширением .txt в текущей директории и для каждого файла выводится сообщение Processing <имя_файла>
.
Как и в большинстве языков программирования, в циклах, используемых в оболочках терминалов, доступны конструкции break
и continue
. С их помощью можно более гибко управлять выполнением цикла: break
позволяет досрочно завершить выполнение цикла при выполнении определённого условия, а continue
пропускает текущую итерацию и сразу переходит к следующей.
Чем ещё интересны POSIX-совместимые оболочки?
Перечислять возможности POSIX-совместимых оболочек можно практически бесконечно, но формат статьи ограничивает меня в количестве и глубине их рассмотрения. Однако если вас заинтересовала эта тема, то вот ещё несколько направлений, которые вы можете изучить самостоятельно.
Использование регулярных выражений позволит эффективно искать и править текст, обрабатывать логи и анализировать данные.
Создание собственных функций поможет вам персонализировать оболочку и ускорить выполнение часто используемых задач.
Модификация окружения оболочки через написание конфигурационных файлов, таких как ~/.bashrc или ~/.zshrc, позволит настроить автодополнение, цветовые схемы и переменные окружения.
Использование сторонних плагинов, таких как Oh My Zsh, позволит улучшить автодополнение, добавит красивые подсказки и расширенную интеграцию с Git.
Взаимодействие с сетевыми утилитами или с такими инструментами, как curl, wget, ssh и scp, поможет выполнять сетевые операции прямо из командной строки.
Управление процессами даст возможность работать с фоновыми и приостановленными процессами и управлять приоритетами процессов.
Отладка скриптов позволит использовать инструменты вроде
set -x
иtrap
для пошагового анализа выполнения команд.
Это не обязательный к изучению материал для начинающего специалиста, однако понимание и умение применять знания из перечисленных тем даст гораздо больше возможностей для профессионального роста и поможет вам раскрыть весь потенциал POSIX-совместимых оболочек.
Что в итоге?
Я разобрал лишь некоторые из множества возможностей POSIX-совместимых оболочек, которые, на мой взгляд, важно показать тем, кто только начинает знакомство с разработкой и учится работать в командной строке. Мы коснулись основ: работы с историей команд, вызовом справки, построением конвейеров и другими полезными функциями, которые делают консоль мощным инструментом в руках разработчика.
У меня не было цели создать ещё один справочник по командам — таких ресурсов уже достаточно, и они легко доступны через, например, поиск. Вместо этого я сосредоточился на фундаментальных моментах, которые помогают понять суть и возможности работы через интерфейс командной строки. Освоив эти базовые приёмы, вы сможете с уверенностью двигаться дальше, изучать новые команды, автоматизировать рутину и использовать терминал как полноценный инструмент для решения самых разных задач.
Надеюсь, эта статья вдохновит вас на дальнейшее изучение материала и, начав с малого, вы сможете достичь больших результатов и открыть для себя удобство терминала, которое так ценят опытные разработчики.
Комментарии (4)
JBFW
29.01.2025 07:20ИМХО, как-то не с той ноги немного начато, попробую пояснить:
Командная строка - это прежде всего строка для ввода команд, запускающих программы. Не какого-то конкретного набора команд "man, ls, free", а просто для запуска программ, хоть графических, хоть нет.
Тем, кто застал DOS - это пояснять не нужно, а вот тем, кто "впервые решил узнать что такое командная строка" после GUI - как раз нужно: что это не "специальная программа с черным окном и встроенными командами", а тупо интерфейс к компьютеру в обход оболочек.И вот только во вторую очередь - есть простые консольные программы, которые читают и пишут текст, и есть консольные оболочки типа bash, которые умеют еще и встроенные команды, циклы, переменные - вот это всё, которые и запускаются по умолчанию, добавляя что-то кроме "просто запустить программу fyrbyr".
Это, ИМХО, поможет лучше понять в чем "сила" командной строки - примерно то же самое что залезть под капот автомобиля, получив доступ ко всем установленным программам, в том числе служебным, которых "сверху", из пользовательского интерфейса, просто не видно.
Никакой магии и особой силы, просто лючок "Authorized personnel only" в гипсокартонной стене GUI.bartenev_ev Автор
29.01.2025 07:20Спасибо за комментарий и за дополнение. Всё верно, есть интерфейс через который можно вводить команды и есть программы, как консольные, так и графические, которые можно через этот интерфейс запускать.
uuger
Терминалы начинали свой путь как вполне себе
железяки
буквы VT в названии модели VT100 означают VIDEO TERMINAL
bartenev_ev Автор
Ага, всё верно. Я примерно с таких железяк и начинал свой путь в ИТ когда-то.