Найти тему

Операторы командной строки и сложные команды Linux

Linux можно сравнить с самым большим в мире конструктором. Вы открываете коробку и видите необозримую коллекцию деталей - огромное число железных планочек, болтиков, гаечек, шестерёнок, колёсиков, моторчиков и несколько рекомендаций по сборке. Вы начинаете играть. Сначала создаёте один предлагаемый образец, затем другой. Затем вы обнаруживаете, что у вас появились собственные идеи новых конструкций и механизмов.
(C) Уильям Шоттс, "Командная строка Linux".
С просторов Интернета: иллюстрация на тему любви конструирования
С просторов Интернета: иллюстрация на тему любви конструирования

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

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

Для взаимопонимания пользователя и системы необходимо придерживаться понятного bash синтаксиса. Синтаксис простой команды: команда -параметры аргументы.
-
Пример: ls -lhF /usr/games /usr/local

Выполнение простой команды с несколькими аргументами
Выполнение простой команды с несколькими аргументами

Лексемы отделены друг от друга хотя бы одним пробелом. Лексема, записаннная первой, является командой. Лексема, перед которой указан дефис, является параметром, все лексемы, записанные далее - аргументы, т.е. данные, с которыми надлежит работать команде.

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

Операторы командной строки в представлении ИИ Kandinsky 2.0
Операторы командной строки в представлении ИИ Kandinsky 2.0

Простейший пример оператора - ;. Отделяя друг от друга точкой с запятой можно в строку записать сразу несколько команд и оболочка их выполнит одну за другой.
-
Пример: mkdir testdir; cd testdir; touch testfile.txt; ls -li testfile.txt; cd ..

Выполнение нескольких команд за раз с помощью оператора точка с запятой
Выполнение нескольких команд за раз с помощью оператора точка с запятой

Для удобства, пользователь может дать название команде, составленной таким образом из простых команд, псевдоним. Для этого существует команда alias, имеющая такой сиснтаксис: alias название команды='список команд'.
-Пример: alias testcmd='mkdir testdir; cd testdir; touch testfile.txt; ls -li testfile.txt; cd ..'

Создание и выполнение собственной составной команды
Создание и выполнение собственной составной команды

Рассмотрим другие операторы.

">" - перенаправление вывода. По умолчанию многие команды выводят результаты работы на экран терминала. Такой вывод называется стандартным потоком вывода. Поскольку в Linux действует концепция "всё есть файл", к этому потоку можно обращаться по индексному дескриптору файла с номером 1. Кстати, найти его можно в каталоге /dev, а также вывести на экран другие потоки ввода-вывода командой:
ls -l /dev/std*

Три стандартных потока ввода/вывода: stdin, stdout и stderr (0 - стандартный поток ввода, 1 - вывода, 2 - вывода ошибок).
Три стандартных потока ввода/вывода: stdin, stdout и stderr (0 - стандартный поток ввода, 1 - вывода, 2 - вывода ошибок).

Оператором ">" можно изменить направление вывода, например с экрана на файл:
ls - hF /opt > outputfile.txt
less outputfile.txt

Результат выполнения команды , записанный  в файл
Результат выполнения команды , записанный в файл

Выдача ls будет помещена в файл outputfile.txt, а если такого файла нет, то он будет создан. В случае, когда файл уже существует, его старое содержимое будет заменено новым. Для того чтобы вместо этого новые данные были добавлены в конец файла, есть оператор ">>".
Появление в командной строке символа
& указывает интерпретатору на необходимость объединения потоков, например так можно перенаправить стандратный вывод ошибок в файл вместе со стандартным выводом: ls -hF /bin/opt > outputfile.txt 2>&1

Без перенаправления потока вывода ошибок, они появляются в окне терминала
Без перенаправления потока вывода ошибок, они появляются в окне терминала

В каталоге /dev есть специальный файл-битоприёмник (null), предназначенный для отправления в него потоков с которыми не нужно ничего делать. Его можно использовать, например, чтобы отключить сообщения об ошибках: ls -hF /bin/opt 2> /dev/null

"$" - подстановка. В зависимости от синтаксиса, bash интерпретирует строку с этим оператором по-разному.
Она может воспринимать это как подстановку арифметического выражения, если формат записи будет таким
$((выражение)), например echo $((2*2)).

Результат выполнения арифметического выражения
Результат выполнения арифметического выражения

Если использовать не двойные, а одинарные скобки $(команда), то оболочка воспримет эту конструкцию как подстановку команды.
-
Пример: mkdir $(less outputfile.txt)

Передача в качестве аргумента команде mkdir результата вывода файла командой less
Передача в качестве аргумента команде mkdir результата вывода файла командой less

Также в командную строку могут быть подставлены переменные окружения, если запись будет вида $ИМЯ, например echo $GDMSESSION

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

"|" - конвейер. Передаёт стандартный вывод одной команды на стандартный ввод другой команды.

-Пример: dmesg | sort | uniq | grep usb

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

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

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

-
Пример: apt-cache search python | tee python.txt | grep web

Использование T-разветвителя для сохранения промежуточных результатов конвейера
Использование T-разветвителя для сохранения промежуточных результатов конвейера

Команда найдёт доступные пакеты python, сохранит их список в файл python.txt и выведет на экран такие из них, в названии которых упоминается web.

Другая полезная команда для работы с конвейером - xargs. Она преобразует данные со стандартного ввода в аргументы для следующей команды и выполняет её необходимое количество раз. Например так можно скопировать один файл в несколько папок:
echo ./dir1/ ./dir2/ ./dir3/ | xargs -n 1 cp -v outputfile.txt

Использование команды xargs в конвейере
Использование команды xargs в конвейере

Параметр -n указывает на то, что аргументы в команду cp нужно будет подставлять по одному.

"<" - перенаправление ввода. Этот оператор позволяет менять стандартный ввод записанной перед ним команды на источник, указанный после этого оператора. Так можно заменить ввод с клавиатуры на ввод из файла.
-
Пример 1: xargs -n 1 touch < outputfile.txt

Создание файлов по списку имён из файла outputfile.txt  перенаправлением ввода
Создание файлов по списку имён из файла outputfile.txt перенаправлением ввода

-Пример 2: comm <(ls ./dir1 | sort) <(ls ./dir2 | sort)

Комбинирование операторов конвейера и перенаправления ввода
Комбинирование операторов конвейера и перенаправления ввода

Вывод в три колонки результатов сравнения содержимого каталогов dir1 и dir2: найденные только в dir1, найденные только в dir2, найденные и в dir1 и в dir2.

"&&" и "||" - операторы последовательного выполнения команд.
При использовании "
&&" каждая последующая за ним команда запускается после того, как успешно выполнилась предыдущая.
- Пример: wget ya.ru && cp -v index.html ./dir1/

Последовательное выполнение  команды при условии успешного выполнения предыдущей - оператор &&.
Последовательное выполнение команды при условии успешного выполнения предыдущей - оператор &&.

Получить файл стартовой страницы с сайта ya.ru и когда он полностью загружен, скопировать его в каталог dir1.
Оператор "
||" - наоборот, запускает последующую команду, если запуск предыдущей команды не удался.
- Пример: ls /etc/bin 2>/dev/null || echo 'Нет такого каталога'

Последовательное выполнение команды при условии неудачного выполнения предыдущей
Последовательное выполнение команды при условии неудачного выполнения предыдущей

Попытаться вывести содержимое каталога /etc/bin, вывод ошибок заглушить, если попытка не удалась, вывести на экран сообщение.

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