Linux можно сравнить с самым большим в мире конструктором. Вы открываете коробку и видите необозримую коллекцию деталей - огромное число железных планочек, болтиков, гаечек, шестерёнок, колёсиков, моторчиков и несколько рекомендаций по сборке. Вы начинаете играть. Сначала создаёте один предлагаемый образец, затем другой. Затем вы обнаруживаете, что у вас появились собственные идеи новых конструкций и механизмов.
(C) Уильям Шоттс, "Командная строка Linux".
Правила, по которым из слов (лексем) конструируются фразы и предложения, называются синтаксисом. У оболочки bash он тоже имеется, благодаря чему простые команды можно группировать для выполнения более сложных действий.
Всё, что поступает на вход командной строки после нажатия Enter, разбивается интерпретатором bash на отдельные лексемы, а затем с помощью синтаксического анализа преобразуется в структуру, пригодную для выполнения.
Для взаимопонимания пользователя и системы необходимо придерживаться понятного bash синтаксиса. Синтаксис простой команды: команда -параметры аргументы.
- Пример: ls -lhF /usr/games /usr/local
Лексемы отделены друг от друга хотя бы одним пробелом. Лексема, записаннная первой, является командой. Лексема, перед которой указан дефис, является параметром, все лексемы, записанные далее - аргументы, т.е. данные, с которыми надлежит работать команде.
Для того, чтобы дать понять bash, что ей передаётся сложная команда, существуют специальные лексемы, называемые операторами. Оболочка воспринимает их как определённые команды, аргументами которых могут быть результаты выполнения других команд.
Простейший пример оператора - ;. Отделяя друг от друга точкой с запятой можно в строку записать сразу несколько команд и оболочка их выполнит одну за другой.
-Пример: 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*
Оператором ">" можно изменить направление вывода, например с экрана на файл:
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)
Также в командную строку могут быть подставлены переменные окружения, если запись будет вида $ИМЯ, например echo $GDMSESSION
"|" - конвейер. Передаёт стандартный вывод одной команды на стандартный ввод другой команды.
-Пример: dmesg | sort | uniq | grep usb
Получив такую команду, bash извлекает в поток вывода буфер сообщений ядра, сортирует записи, оставляет из них не повторяющиеся, находит в них относящиеся к usb и выводит результат на экран.
С помощью команды tee можно вставить в конвейер T-разветвитель, который копирует данные со стандартного ввода на стандартный вывод для передачи по конвейеру и отдельно направляет в файл, чтобы можно было сохранить промежуточный результат.
-Пример: apt-cache search python | tee python.txt | grep web
Команда найдёт доступные пакеты python, сохранит их список в файл python.txt и выведет на экран такие из них, в названии которых упоминается web.
Другая полезная команда для работы с конвейером - xargs. Она преобразует данные со стандартного ввода в аргументы для следующей команды и выполняет её необходимое количество раз. Например так можно скопировать один файл в несколько папок:
echo ./dir1/ ./dir2/ ./dir3/ | xargs -n 1 cp -v outputfile.txt
Параметр -n указывает на то, что аргументы в команду cp нужно будет подставлять по одному.
"<" - перенаправление ввода. Этот оператор позволяет менять стандартный ввод записанной перед ним команды на источник, указанный после этого оператора. Так можно заменить ввод с клавиатуры на ввод из файла.
-Пример 1: xargs -n 1 touch < 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. Его изучение хорошо не только тем, что общение с компьютером приобретает более осмысленный характер в виде обмена текстовыми сообщениями. Но ещё это может быть хорошим прологом к освоению программирования, где наклонности к текстовой печати раскрываются ещё полнее.