Комбинирование команд

Команды bash могут использоваться не только сами по себе, но и объединяться в конструкции с помощью двух приемов — перенаправления ввода/вывода и конвейеров команд. Начнем с первого.

Во всех примерах предыдущего раздела команды получали данные со стандартного устройства ввода (клавиатуры), отправляя результаты своей работы на стандартное устройство вывода (экран монитора). Однако и ввод, и вывод команды могут быть перенаправлены. Например, команда может получать данные из уже существующего файла (перенаправление ввода) и (или) выводить результаты в файл (перенаправление вывода). Наиболее часто используется второй вариант. Простейший пример такого перенаправления:

ls > listing1

При этом список файлов текущего каталога не выводится на экран, а сохраняется в виде нового файла с именем listing. Символ > означает перенаправление вывода. При повторении этой операции новые данные, перенаправленные на вывод, подменят те, что были сохранены ранее. То есть, в приведенном примере, повторение команды

Is > listingl

приведет к перезаписи файла listing. Чтобы избежать этого, вместо простого перенаправления вывода, можно использовать добавление вывода, обозначаемое символом». Если в рассматриваемом примере после первого исполнения

Is > listingl

применить добавление вывода

Is » listingl

то новый листинг каталога не перепишет старый файл, а будет добавлен в его конец.

С помощью перенаправления вывода можно создавать новые файлы произвольного содержания. Так, команд cat, заданная без аргумента, просто воспринимает последовательности символов, вводимые с клавиатуры, и воспроизводит ихна экране. Если же перенаправить ее вывод, то вводимые с клавиатуры данные можно записать в файл. Делается это следующим образом.

Сначала даем команду cat > newdata

и нажимаем Enter. Курсор переходит на новую строку, в результате чего команда готова к приему данныхс клавиатуры. Набираем требуемые символы, как в любом текстовом редакторе, используя Enter для создания новых строк:

Однажды в студеную зимнюю пору

Я из лесу вышел --- был сильный мороз.

и т.д. По завершении набора опять нажимаем Enter (это необходимо для окончания последней строки) и нажимаем комбинацию клавиш Ctrl|+|~Р~|, символизирующую конец файла (аналогично Ctrl|+|~z~|в командном интерпретаторе MS DOS) и возвращающую приглашение командной строки. Теперь с помощью команды

ls newdata

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

cat newdata

(а также less или more ) — проверить его содержимое.

При вводе в команде cat возможно только самое элементарное редактирование, а именно: уничтожение всех символов строки вплоть до требующего изменения, а затем набор ихзаново. С переходом на новую строку предыдущая становится недоступной для изменения. Поэтому таким способом неудобно создавать сколько-нибудь объемные документы, но использование его для создания коротких записей (например, простых сценариев оболочки) вполне целесообразно.

Благодаря перенаправлению вывода раскрывается вся мощь команды cat (а заодно становится понятным ее название). С ее помощью можно добавить данные к существующему файлу с клавиатуры

cat >> olddata

(тем же способом, что и создать новый файл) или из существующего файла

cat newdata >> olddata

Можно также слить вместе произвольное количество файлов:

cat file1 file2 ... file99 > allfiles

Кроме перенаправления вывода, имеется возможность и перенаправления ввода (символ <). Это получение командой данныхне с клавиатуры, а из существующего файла. Так, если команда

cat > salute

с введенным

Hello, world!

Ctrl + D создает файл salute , то обратная ей команда

cat < salute

выведет его содержимое на экран в виде

Hello, world!

Легко видеть, что это эквивалентно просто команде cat с именем соответствующего файла в качества аргумента. И потому само по себе перенаправление ввода используется редко. Однако оно может применяться в более сложныхконструкциях, объединяющихперенаправление как ввода, так и вывода. Так, ранее созданный перенаправлением вывода файл listing1 содержит список файлов, отсортированный командой ls по умолчанию, то есть в порядке возрастания ASCII-кода первого символа (это не совсем то же самое, что в алфавитном порядке). Это положение можно изменить, применив команду sort (предназначенную для сортировки записей) с опцией -r (от reverse, то есть в обратном порядке) и операцию перенаправления ввода:

sort -r < listing1

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

sort -r < listing1 > listing2

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

Второй прием для объединения командныхконструкций — конвейеры команд. Иногда они именуются в литературе каналами, но название «конвейер» лучше отражает существо дела. В этом случае вывод одной программы направляется не в файл, а на стандартный ввод другой программы. Простой пример такой операции — просмотр списка файлов:

ls -l | less

Перенаправление вывода команды ls, то есть списка файлов, который при использовании полного формата записи (опция -l) может занимать многие экраны, позволяет просматривать результат с помощью команды less постранично или построчно в обоихнаправлениях.

Конвейеризация команд может быть сколь угодно длинной. Так, конструкция

ls -lt | sort -r | lpr

обеспечит не только сортировку списка файлов каталога в полном формате, выведенного командой ls по времени изменения (опция -t ), в обратном относительно исходного порядке (опция -r команды sort ), но и выведет его на печатающее устройство командой lpr .

В составе командныхконструкций полезной может оказаться команда tee . Она обеспечивает получение данныхпо конвейеру от предыдущей команды и одновременный вывод ихна экран для просмотра и в файл для записи:

cat file1 ... file99 | tee allfiles

Приведенные примеры использования перенаправления ввода/вывода могут показаться искусственными и не имеющими практического значения. Это не так: в ряде случаев они позволяют простым и эффективным способом решать реальные пользовательские задачи.

Приведем один из наиболее показательныхпримеров. Имеется: серия тек-стовыхфайлов (например, глав и фрагментов настоящего руководства - ch1, ch2 и т.д.), рассеянныхпо различным каталогам ( dir1, dir2 и т.д.) файловой системы. Требуется собрать из нихв определенном порядке (с главы первой по последнюю) единый документ ( book ) — то руководство, которое вы читаете, записать его в новый файл, который должен быть помещен в собственный каталог. Предлагается подсчитать, сколько действий потребуется для решения этой задачи (согласитесь, более чем жизненной) в любом текстовом редакторе или текстовом процессоре. Средствами же оболочки bash это выполняется одной командой:

cat /dir1/ch1 /dir2/ch2 ... /dir10/ch10 > /pathbook/book

Включив командный конвейер, можно одновременно просмотреть на экране результат и распечатать его на принтере:

cat /dir1/ch1 /dir2/ch2 ... /dir10/ch10 | tee /pathbook/book | lpr

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

Еще материалы по теме: