## Основы командной строки ### **Настройка лабораторной среды** Для практики команд, рассматриваемых в этом курсе, можно использовать **онлайн-интерпретатор Bash**. Это позволит вам получить практический опыт работы с различными командами Linux, даже без установки ОС. Один из популярных онлайн-интерпретаторов Bash — это **REPL**. В рамках курса мы будем использовать именно его для выполнения всех примеров команд. *** ### **Что такое команда** **Команда** — это программа, которая даёт операционной системе указание выполнить определённую задачу. В Linux программы хранятся в виде файлов, следовательно, команда — это тоже файл, расположенный где-то на диске. Команды могут принимать **дополнительные аргументы** от пользователя. Эти аргументы называются **аргументами командной строки**. Умение правильно использовать команды — это важный навык. В Linux существует множество способов получить справку по командам. Почти каждая команда сопровождается документацией. Чаще всего, можно использовать аргументы `-h` или `--help`, чтобы получить краткое описание команды и доступных параметров. Но самым популярным способом получения справки являются так называемые **man-страницы** (*manual pages*) — встроенная система документации в Linux. *** **Пример: использование `-help` для команды `ls`** ``` ls --help ``` Эта команда выведет краткую справку по использованию `ls`, включая список доступных опций. ### **Структура файловой системы в Linux** Файловая система Linux имеет **иерархическую (древовидную) структуру**, где самый верхний уровень — это **корневой каталог**, обозначаемый как `/`. Внутри корневого каталога находятся другие каталоги, в которых хранятся файлы, относящиеся к различным частям системы. Эти каталоги могут содержать: * **системные файлы** * **файлы приложений** * **файлы, относящиеся к пользователю** Каждый из этих подкаталогов может, в свою очередь, содержать другие каталоги и файлы, образуя дерево, в котором всё начинается с корня `/`. | **Каталог** | **Описание** | | ------- | -------- | | `/bin` | Содержит исполняемые файлы наиболее часто используемых команд | | `/dev` | Содержит файлы устройств, установленных в системе | | `/etc` | Содержит все конфигурационные файлы системы | | `/home` | Содержит пользовательские файлы и каталоги | | `/lib` | Содержит все системные библиотеки | | `/mnt` | Содержит точки монтирования для внешних устройств | | `/proc` | Содержит файлы, связанные с запущенными в системе процессами | | `/root` | Домашний каталог пользователя root (суперпользователя) | | `/sbin` | Содержит системные утилиты для администрирования | | `/tmp` | Используется для временных файлов | | `/usr` | Используется для хранения программ и данных пользовательского уровня | ## **Команды для навигации по файловой системе** В Linux есть три базовые команды, которые чаще всего используются для перемещения по файловой системе: * `ls` * `pwd` * `cd` Давайте разберём, что делает каждая команда и как с ними работать. Рекомендуется практиковаться, выполняя примеры в онлайн-интерпретаторе Bash. *** ### **`pwd` (print working directory)** В любой момент времени вы находитесь в каком-то каталоге. Чтобы узнать, в каком именно каталоге вы сейчас находитесь, используйте команду: ``` pwd ``` Эта команда выведет **полный путь текущего рабочего каталога**. Например: ``` /home/username/projects ``` Это особенно полезно, когда вы перемещаетесь по разным директориям и хотите убедиться, где именно вы находитесь. Теперь мы воспользуемся командой `cd`, чтобы **перейти в другой каталог**, а затем с помощью команды `pwd` **выведем текущий путь**, чтобы убедиться, что переход прошёл успешно. Пример: переход в каталог с помощью `cd` и проверка с `pwd` Результат: ``` /etc/python ``` Команда `cd` (change directory) позволяет перемещаться по файловой системе. После перехода можно использовать `pwd`, чтобы увидеть, в каком каталоге вы сейчас находитесь. Если ввести `cd` без аргументов, вы вернётесь в домашний каталог: ### **cd (change directory)** Команда `cd` используется для **смены рабочего каталога**. С помощью этой команды вы можете перемещаться из одного каталога в другой. В приведённом ниже примере мы изначально находимся в **корневом каталоге**. Затем используем команду `cd`, чтобы перейти в другой каталог. **Пример** Допустим, вы находитесь в корневом каталоге `/`: ``` pwd ``` Результат: ``` / ``` Теперь используем `cd`, чтобы перейти, например, в каталог `/home/user`: ``` cd /home/user pwd ``` Результат: ``` /home/user ``` Таким образом, команда `cd` позволяет вам перемещаться по структуре каталогов, а команда `pwd` подтверждает, где именно вы сейчас находитесь. ### **`ls` (просмотр файлов и каталогов)** Команда `ls` используется для **отображения содержимого каталога**. Она выводит список всех файлов и папок, находящихся в указанном каталоге. Если просто ввести `ls` в командной строке, без дополнительных аргументов, то команда покажет **все файлы и каталоги в текущем рабочем каталоге**. Эта команда особенно полезна для того, чтобы быстро просмотреть, какие файлы и папки находятся в каталоге, где вы сейчас находитесь. Мы также можем указать **имя каталога** в качестве аргумента для команды `ls`. В этом случае команда выведет **все файлы и каталоги**, находящиеся **в указанном каталоге**. Эта команда отобразит содержимое папки `/usr`, даже если вы сейчас находитесь в другом каталоге. ## **Команды для работы с файлами** Существует пять базовых команд, которые часто используются для создания, копирования, перемещения и удаления файлов: * `touch` * `mkdir` * `cp` * `mv` * `rm` Сейчас мы разберём, что делает каждая из этих команд и как ими пользоваться. Рекомендуется попробовать приведённые примеры в онлайн-интерпретаторе Bash. *** ### **`touch` — создание нового файла** Команда `touch` используется для **создания нового пустого файла**. Хотя у неё есть и другие применения, здесь мы рассмотрим самый простой случай — создание файла. **Общий синтаксис команды `touch`:** ``` touch ``` ### **`mkdir` — создание новых каталогов** Команда `mkdir` используется для **создания новых каталогов**. После выполнения команды можно использовать `ls`, чтобы убедиться, что каталог был успешно создан. **Общий синтаксис команды `mkdir`:** ``` mkdir <имя_каталога> ``` Пример: ``` mkdir new_folder ``` Эта команда создаст каталог с именем `new_folder` в текущем рабочем каталоге. Вот еще пример: ### **`rm` — удаление файлов и каталогов** Команда `rm` используется для **удаления файлов и каталогов**. Важно помнить, что эта команда **удаляет данные без возможности восстановления** — после успешного выполнения `rm` вернуть удалённые файлы и папки практически невозможно. Поэтому используйте её **с особой осторожностью**. **Общий синтаксис команды `rm`:** ``` rm <имя_файла> ``` **Пример:** Допустим, вы ранее создали файл с помощью команды `touch` и каталог с помощью `mkdir`. Теперь вы можете удалить их с помощью команды `rm`. ``` rm myfile.txt ``` Для удаления пустого каталога: ``` rmdir new_folder ``` Если нужно удалить каталог с содержимым — используется флаг `-r`: ``` rm -r folder_name ``` Будьте осторожны при использовании `rm -r`, особенно в сочетании с `sudo`. Еще пример: ### **`cp` (копирование файлов и каталогов)** Команда `cp` используется для **копирования файлов и каталогов** из одного места в другое. Важно отметить, что команда `cp` **не изменяет оригинальные файлы или каталоги**. После успешного выполнения команды оригинал и копия **существуют одновременно**. **Общий синтаксис команды `cp`:** ``` cp <путь_к_источнику> <путь_к_назначению> ``` В данный момент мы находимся в каталоге `/home/runner`. Сначала мы создадим новый каталог с именем `test_directory` с помощью команды `mkdir`. Затем попробуем скопировать файл `_test_runner.py` в только что созданный каталог. После этого файл `_test_runner.py` появится внутри `test_directory`, а оригинал останется на месте. Обратите внимание, что **оригинальный файл \_test\_runner.py не был изменён**. Он по-прежнему находится в текущем каталоге. Просто была создана **новая копия этого файла** внутри каталога `test_directory`. Мы также можем использовать команду `cp`, чтобы **скопировать целый каталог** из одного места в другое. Давайте разберём это на примере. Мы снова использовали команду `mkdir`, чтобы создать новый каталог с именем `another_directory`. Затем мы использовали команду `cp` с **дополнительным флагом `-r`**, чтобы скопировать каталог `test_directory`. **Дополнение:** Флаг `-r` (или `--recursive`) нужен для **рекурсивного копирования**, т.е. копируются и вложенные файлы, и папки. **Пример выполнения:** ``` mkdir another_directory cp -r test_directory another_directory/ ``` В результате каталог `test_directory` со всем его содержимым будет скопирован внутрь `another_directory`. ### **`mv` (перемещение файлов и каталогов)** Команда `mv` может использоваться как для **перемещения файлов и каталогов** из одного места в другое, так и для **переименования** файлов или каталогов. Обратите внимание, что **перемещение и копирование — это разные действия**. При перемещении **оригинал удаляется** с исходного места — остаётся только перемещённая версия. Общий синтаксис команды `mv`: ``` mv <путь_к_источнику> <путь_к_назначению> ``` В этом примере мы используем команду `mv`, чтобы переместить файл `_test_runner.py` в каталог `test_directory`. Поскольку в этом каталоге уже есть файл с таким именем, команда `mv` **заменит** его новым файлом. Обратите внимание: после выполнения команды `mv` **исходный файл больше не существует в текущем каталоге** — он перемещён. Если в каталоге `test_directory` уже был файл с именем `_test_runner.py`, он будет **перезаписан без предупреждения**. Мы также можем использовать команду `mv` для **перемещения каталогов** из одного места в другое. В отличие от команды `cp`, здесь **не нужно использовать флаг `-r`**. Важно помнить: после выполнения `mv` **оригинальный каталог исчезнет** с прежнего места, так как он был перемещён. Одна из важных возможностей команды `mv` — это **переименование файлов и каталогов**. Давайте посмотрим, как использовать эту команду для переименования. Сначала мы **перешли в каталог `test_directory`**, а затем использовали команду `mv`, чтобы **переименовать файл `_test_runner.py` в `test.py`**. ``` mv _test_runner.py test.py ``` Эта команда просто изменит имя файла. Теперь в каталоге `test_directory` вместо файла `_test_runner.py` будет `test.py`. Файл был **переименован**, но не перемещён. ## **Команды для просмотра содержимого файлов** Существует пять основных команд, которые часто используются для **просмотра содержимого файлов**: * `cat` * `head` * `tail` * `more` * `less` Сейчас мы разберём, что делает каждая команда и как её использовать. Рекомендуется отработать приведённые примеры в онлайн-интерпретаторе Bash. В качестве подготовки мы создадим новый файл с именем `numbers.txt` и **вставим в него числа от 1 до 100**, по одному числу на каждой строке. Не беспокойтесь о приведённой выше команде — это **продвинутая команда**, которая используется для генерации чисел. Затем мы использовали **оператор перенаправления**, чтобы **записать эти числа в файл**. Подробнее о **перенаправлении ввода/вывода (I/O redirection)** мы поговорим в следующих разделах. **Но если очень хочется узнать сейчас:** ``` seq 1 100 > numbers.txt ``` 🔹 **Что делает:** Команда `seq 1 100` генерирует последовательность чисел от 1 до 100, по одному числу на строку. 🔹 **Оператор `>`** Перенаправляет вывод команды в файл `numbers.txt`. Если файла не существует — он будет создан. Если файл уже есть — его содержимое будет **перезаписано**. 📄 В результате создаётся файл `numbers.txt` со следующим содержимым: ``` 1 2 3 ... 100 ``` ### **`cat`** Самое простое применение команды `cat` — это **вывод содержимого файла на экран**. Это очень полезная команда, у неё есть и другие возможности, о которых мы поговорим позже. ``` cat numbers.txt ``` Вы можете выполнить эту команду, и увидите, как на экране отобразятся числа от 1 до 100. Скорее всего, вам придётся **прокрутить вверх**, чтобы увидеть все строки. **Дополнение:** `cat` — сокращение от *concatenate* (объединить). Позже мы увидим, как она может использоваться для объединения нескольких файлов, записи в файлы и других операций. ### **`head`** Команда `head` по умолчанию **отображает первые 10 строк файла**. При необходимости можно добавить аргументы, чтобы вывести любое нужное количество строк с начала файла. В приведённом примере, при использовании команды: ``` head numbers.txt ``` Вывод будет следующим: ``` 1 2 3 4 5 6 7 8 9 10 ``` Если вы хотите указать конкретное количество строк, которые нужно вывести с начала, используйте **флаг `-n`** и укажите нужное число: ``` head -n 5 numbers.txt ``` Результат: ``` 1 2 3 4 5 ``` **Дополнение:** Команда `head` особенно полезна при работе с большими логами, CSV-файлами и другими длинными текстовыми данными — можно быстро глянуть, с чего начинается файл, не открывая его полностью. ### **`tail`** Команда `tail` по умолчанию **отображает последние 10 строк файла**. Можно также использовать дополнительные аргументы, чтобы вывести нужное количество строк **с конца файла**. Пример использования: ``` tail numbers.txt ``` Результат: ``` 91 92 93 94 95 96 97 98 99 100 ``` Если вы хотите указать точное количество строк с конца, используйте **флаг `-n`**: ``` tail -n 5 numbers.txt ``` Результат: ``` 96 97 98 99 100 ``` В этом примере команда `tail` с флагом `-n` выводит **последние 5 строк файла**. **Дополнение** Команда `tail` часто используется для **отслеживания логов в реальном времени**. Например, команда `tail -f filename.log` будет "следить" за обновлением файла в режиме реального времени. ### **`more`** Команда `more` используется для **постраничного просмотра содержимого файла** (или вывода команды), особенно если файл слишком большой (например, лог-файлы). Если содержимое не помещается на одном экране, `more` показывает только часть текста и **ожидает действий пользователя** для продолжения просмотра. При запуске: ``` more numbers.txt ``` Вы увидите, как файл отображается **постранично**. В левом нижнем углу появится строка `--More--`, как на скриншоте, указывающая, что файл ещё не закончился (в примере — просмотрено 20%). Навигация: * **Enter** — пролистывает на одну строку вниз * **Пробел (Space)** — пролистывает на один экран вперёд * Иногда можно использовать `b` для возвращения назад на экран (ограниченная навигация) **Дополнение** `more` удобен, когда вы читаете длинный файл и не хотите, чтобы содержимое "промелькнуло" всё сразу, как это происходит при использовании `cat`. Для ещё более гибкого просмотра лучше использовать `less` — о нём поговорим дальше. ### **`less`** Команда `less` — это **улучшенная версия `more`**. Она также отображает содержимое файла (или вывод команды) **постранично**, но предоставляет **больше возможностей для навигации**. В отличие от `more`, команда `less` позволяет **перемещаться как вперёд, так и назад** по содержимому, а также выполнять **поиск по тексту**. Навигация в `less`: * **Стрелки вверх/вниз** — перемещение по одной строке * **Пробел (Space)** — пролистать вперёд на один экран * **Клавиша `b`** — пролистать назад на один экран * **`g`** — перейти в начало файла * **`G`** — перейти в конец файла * **`/текст`** — поиск по файлу (вперёд) * **`?текст`** — поиск назад Последние два `/текст` и `?текст` следует разобрать подробнее: Представим, что в файле `notes.txt` записано: ``` Today is a sunny day. We are learning Linux commands. The cat command is very simple. Linux is a powerful operating system. You can search inside files using less. Linux is used everywhere. ``` Теперь: 1. Открываем файл командой: ``` less notes.txt ``` 1. Хотим найти слово **Linux**: * Нажимаем `/` (слэш) * Пишем: ``` /Linux ``` * Нажимаем **Enter**. Что происходит: Терминал подсветит первое вхождение слова **Linux**, начиная **от текущей позиции и дальше вниз по тексту**. 1. Теперь хотим искать **назад**: * Нажимаем `?` (вопросительный знак) * Пишем: ``` ?Linux ``` * Нажимаем **Enter**. Что происходит: Теперь поиск будет в обратную сторону — **ищет выше по тексту**. ### Итог: * `/Linux` — ищет **вперёд по файлу** * `?Linux` — ищет **назад по файлу** * `n` — перейти к следующему совпадению * `N` — перейти к предыдущему совпадению **Дополнение** `less` — это наиболее удобная и безопасная команда для просмотра больших файлов (например, логов), потому что она: * не загружает весь файл в память, * не "сбрасывает" содержимое в терминал сразу, * и даёт гибкий контроль над просмотром. Если не уверен, использовать `cat`, `more` или `less`, — **используй `less`**. ## **Команда `echo` в Linux** Команда `echo` — одна из самых простых команд, используемых в оболочке. Она **аналогична команде `print` в других языках программирования**. Команда `echo` просто **выводит переданную ей строку на экран**. **Пример:** ``` echo "hello world" ``` Результат: ``` hello world ``` **Дополнение** Команда `echo` полезна: * для вывода сообщений в скриптах * для проверки значений переменных * для формирования строк в файлы (в связке с `>` или `>>`) Пример с переменной: ``` name="Alice" echo "Hello, $name!" ``` Результат: ``` Hello, Alice! ``` ## **Команды для обработки текста** В предыдущем разделе мы научились просматривать содержимое файлов. Однако во многих случаях нам нужно выполнять и другие действия, например: * Выводить только строки, содержащие определённое слово(а) * Заменять одно слово на другое в файле * Сортировать строки в определённом порядке Для этого в Linux часто используются три основные команды: * `grep` * `sed` * `sort` Сейчас мы разберём, что делает каждая из этих команд и как с ними работать. Рекомендуется попробовать примеры в онлайн-интерпретаторе Bash. Для демонстрации мы **создадим файл `numbers.txt`** и **запишем в него числа от 1 до 10**, по одному числу на строку. ``` seq 1 10 > numbers.txt ``` После выполнения команды `seq 1 10 > numbers.txt`, вы можете убедиться в наличии файла: ### **`grep`** Команда `grep` в своей базовой форме используется для **поиска определённых слов или фрагментов текста в файле**. Она **выводит все строки**, в которых найдено соответствие с введённым шаблоном. Слово или строка для поиска передаётся в `grep` как аргумент. Общий синтаксис: ``` grep <что_искать> <имя_файла> ``` Пример: Здесь `grep` нашёл и вывел все строки, содержащие символ `1`. Это: * строка с числом `1` * строка с числом `10` (так как она тоже содержит `1`) **Дополнение** `grep` чувствителен к регистру, но это можно отключить флагом `-i`. Чтобы искать точное совпадение, можно использовать регулярные выражения или ограничители (`^`, `$`, `\b` и др.). ### **`sed`** Команда `sed` в своей простой форме может использоваться для **замены текста в файле**. Общий синтаксис команды замены: ``` sed 's/<что_заменить>/<на_что_заменить>/' <имя_файла> ``` В данном примере мы пробуем заменить каждое вхождение **"1" на "3"** в файле с помощью команды: ``` sed 's/1/3/' numbers.txt ``` Результат: `1` → `3` `10` → `30` Обратите внимание: **содержимое файла при этом не изменяется**. `sed` просто выводит результат в терминал. Чтобы **сделать изменения в самом файле**, нужно использовать флаг `-i`: ``` sed -i 's/1/3/' numbers.txt ``` **Дополнение** * Без `i` → работает как просмотр * С `i` → вносит изменения в файл напрямую * Добавьте `g` (глобально), чтобы заменить **все вхождения в строке**: ``` sed -i 's/1/3/g' numbers.txt ``` Подробнее об этом на примерах: Что делает `sed 's/старое/новое/'` По умолчанию `sed` **заменяет только первое вхождение** шаблона **в каждой строке**. **Пример:** Допустим, в строке есть: ``` 1 1 1 ``` Команда: ``` sed 's/1/3/' file.txt ``` даст результат: ``` 3 1 1 ``` Только **первое** `1` заменилось на `3`. Почему не изменились остальные? Потому что `sed` ищет **первое** вхождение В СТРОКЕ. Она работает **построчно**. Она **ищет первое вхождение `"1"` в каждой строке** и заменяет только его. Что делает `g` в `sed 's/старое/новое/g'` (с добавление `g`) Флаг **`g` (global)** означает: **заменить все вхождения** в каждой строке, а не только первое. Пример: ``` sed 's/1/3/g' file.txt ``` Результат: ``` 3 3 3 ``` Теперь **все** `1` в строке стали `3`. Визуально: | Команда | Строка до | Строка после | | ------- | --------- | ------------ | | `sed 's/1/3/'` | `1 1 1` | `3 1 1` | | `sed 's/1/3/g'` | `1 1 1` | `3 3 3` | ### **`sort`** Команда `sort` используется для **сортировки входных данных**, переданных ей в качестве аргумента. **По умолчанию** сортировка происходит **в порядке возрастания** (по алфавиту или числово, в зависимости от содержимого). Прежде чем сортировать файл, давайте посмотрим его содержимое: ``` cat numbers.txt ``` Результат (как видно на скриншоте): ``` 3 2 3 4 5 6 7 8 9 30 ``` Теперь мы попробуем отсортировать файл с помощью команды `sort`. Команда `sort` сортирует содержимое **в лексикографическом (алфавитном) порядке**. В приведённом выше примере **содержимое файла не изменяется** — `sort` просто выводит отсортированный результат в терминал. ``` sort numbers.txt ``` Результат: ``` 2 3 3 30 4 5 6 7 8 9 ``` Почему `30` идёт **после `3`**, но **перед `4`**? Потому что **лексикографическая сортировка** работает так же, как сортировка строк: `"30"` сравнивается посимвольно с `"4"` — и `"3"` идёт раньше `"4"`. **Важно:** Если вы хотите, чтобы `30` воспринималось **как число**, а не как строка, используйте **числовую сортировку**: ``` sort -n numbers.txt ``` Результат: ``` 2 3 3 4 5 6 7 8 9 30 ``` **Дополнительно:** Вот полезные примеры с флагами команды `sort`, которые помогут управлять порядком и дубликатами: **Сортировка в обратном порядке:** ``` sort -r numbers.txt ``` * Флаг `r` означает **reverse** * Вывод будет отсортирован **в убывающем порядке** (по убыванию строк, не чисел) **Числовая сортировка:** ``` sort -n numbers.txt ``` * Флаг `n` означает **numeric** * Строки будут интерпретироваться как числа (а не как строки) * `30` будет идти **после `9`**, как и ожидается **Числовая сортировка в обратном порядке:** ``` sort -nr numbers.txt ``` Сначала **числовая**, потом **обратная** Результат будет: ``` 30 9 8 7 ... 2 ``` **Удаление дубликатов:** ``` sort -u numbers.txt ``` * `u` = **unique** * Удаляет **дублирующиеся строки (удаляет только в выводе, а не из файла)** Если в файле было несколько `3`, то после `sort -u` останется только одна. **Комбинирование флагов:** Можно совмещать: ``` sort -nru numbers.txt ``` * Числовая * Обратный порядок * Без повторов ## **Перенаправление ввода/вывода (I/O Redirection)** Каждому открытому файлу в системе присваивается **дескриптор файла** — это уникальный идентификатор для обращения к нему. В Linux всегда открыты три стандартных дескриптора: * `stdin` — стандартный ввод (обычно клавиатура) * `stdout` — стандартный вывод (экран) * `stderr` — вывод ошибок (тоже экран) 🔧 Все эти потоки можно **перенаправлять**. 💡 В Linux всё является файлом — от текстов до устройств. Подробнее: [https://unix.stackexchange.com/questions/225537/everything-is-a-file](https://unix.stackexchange.com/questions/225537/everything-is-a-file) До этого момента весь вывод команд отображался **на экране** — это **стандартный вывод (stdout)**. Но мы можем использовать **специальные операторы** для **перенаправления вывода** в файлы или на вход другим командам. Это называется **I/O Redirection**, и это очень мощная возможность. Пример со скриншота: ``` ls > output.txt ``` Эта команда: 1. Выполняет `ls` — показывает список файлов 2. Вместо вывода на экран, **перенаправляет результат в файл `output.txt`** Затем: ``` cat output.txt ``` Показывает содержимое файла `output.txt`, в котором теперь лежит результат команды `ls`. **Дополнение** | Оператор | Назначение | | -------- | ---------- | | `>` | Перенаправляет вывод, **перезаписывает** файл | | `>>` | Перенаправляет вывод, **добавляет** в конец файла | | `<` | Перенаправляет **ввод** из файла вместо клавиатуры | | `2>` | Перенаправляет **ошибки (stderr)** | | `&>` | Перенаправляет **stdout и stderr** вместе | В приведённом ниже примере мы **перенаправили вывод команды `echo` в файл**. Мы также можем **перенаправить вывод одной команды как ввод для другой команды**. Это возможно с помощью **конвейеров (pipe)** — символ `|`. Пример со скриншота: ``` cat numbers.txt | grep "3" ``` Здесь: 1. `cat numbers.txt` выводит содержимое файла 2. Этот вывод **перенаправляется в команду `grep "3"`** 3. `grep` фильтрует строки, содержащие `"3"` Результат: ``` 3 3 30 ``` `grep` вывел только те строки, где встречается символ `3`. **Дополнение** * `|` (pipe) позволяет **связывать команды**, передавая вывод одной как ввод другой * Это мощный инструмент для построения цепочек команд Примеры цепочек: ``` ps aux | grep nginx | sort -k3 -nr ``` ``` cat file.txt | grep "error" | wc -l ``` В примере ниже мы **передали вывод команды `sort` как ввод в команду `uniq`**, используя **оператор пайпа (`|`)**. Команда `uniq` выводит только **уникальные строки** из входных данных — т.е. **удаляет дубликаты**, если они идут **подряд**. ``` sort numbers.txt | uniq ``` Здесь: * `sort numbers.txt` сортирует файл (в том числе, чтобы дубликаты оказались рядом) * `uniq` удаляет **повторяющиеся подряд строки** * В результате на экране — только уникальные значения Важно `uniq` **работает только с подряд идущими дубликатами**, поэтому **сортировка перед `uniq` — обязательна**, если дубликаты разбросаны по файлу. Альтернатива: То же самое можно сделать одной командой с флагом `-u`: ``` sort -u numbers.txt ``` Результат будет такой же — **уникальные строки**, отсортированные по умолчанию. I/O redirection - [https://tldp.org/LDP/abs/html/io-redirection.html](https://tldp.org/LDP/abs/html/io-redirection.html) [Задания (Основы командной строки)](https://www.notion.so/1e31736e9acf80ad9c8bf19dc0f06856?pvs=21)