автордың кітабын онлайн тегін оқу Bash и кибербезопасность: атака, защита и анализ из командной строки Linux
Научный редактор М. Коробко
Переводчики А. Герасименко, А. Григорьева, О. Сивченко
Технический редактор Н. Гринчик
Литературный редактор Н. Гринчик
Художники Н. Гринчик, В. Мостипан, Г. Синякина (Маклакова)
Корректоры О. Андриевич, Н. Гринчик, Е. Павлович
Верстка Г. Блинов
Пол Тронкон, Карл Олбинг
Bash и кибербезопасность: атака, защита и анализ из командной строки Linux. — СПб.: Питер, 2021.
ISBN 978-5-4461-1514-3
© ООО Издательство "Питер", 2021
Все права защищены. Никакая часть данной книги не может быть воспроизведена в какой бы то ни было форме без письменного разрешения владельцев авторских прав.
Эрин и Киере. Вы приносите радость каждую минуту моей жизни.
Пол
Синтии и нашим сыновьям Грегу, Эрику и Эндрю.
Карл
Введение
В войне самое главное — быстрота: нельзя упускать возможности1.
Сунь-цзы. Искусство войны
В наше время о командной строке часто забывают. Новых специалистов по кибербезопасности манят инструменты с ярким графическим интерфейсом. Более опытные работники или не знают о возможностях командной строки, или недооценивают их. При этом командная строка предоставляет множество функций и должна быть в наборе инструментальных средств каждого специалиста. К примеру, кажущаяся простой команда tail, выводящая последние несколько строк конкретного файла, состоит более чем из 2000 строк кода на С. Похожий инструмент можно создать с использованием Python или другого языка программирования, но зачем, если доступ к этим возможностям можно получить, просто введя одно слово в командной строке?
Вдобавок ко всему, изучив принципы и методы применения командной строки для решения сложных задач, вы сможете лучше понять, как функционирует операционная система. Гуру кибербезопасности понимают не только то, как использовать инструменты, но и как они работают на фундаментальном уровне.
Прочитав эту книгу, вы научитесь грамотно использовать сложные команды Linux и оболочку bash, чтобы улучшить свои навыки, необходимые специалистам по безопасности. С этими навыками вы сможете быстро создавать и моделировать сложные функции с помощью лишь одной строки конвейерных команд.
Хотя изначально оболочка bash и команды, которые мы рассмотрим в книге, были созданы для семейства операционных систем Unix и Linux, теперь они стали универсальными и их можно применять и в Linux, и в Windows, и в macOS.
Для кого эта книга
Книга «Bash и кибербезопасность» предназначена для тех, кто желает научиться работать с командной строкой в контексте компьютерной безопасности. Наша цель — не заменить существующие инструменты скриптами для командной строки, а, скорее, научить вас эффективно использовать командную строку для улучшения существующего функционала.
На протяжении всей книги мы приводим примеры таких методов безопасности, как сбор данных, их анализ и тестирование на проникновение в систему. Цель этих примеров — продемонстрировать возможности командной строки и познакомить вас с некоторыми фундаментальными методами, используемыми в инструментах более высокого уровня.
Мы предполагаем, что вы уже знакомы с интерфейсом командной строки, знаете основы кибербезопасности, программирования и операционных систем Linux и Windows. Предварительное знание bash приветствуется, но не обязательно.
Эта книга не является введением в программирование, хотя в части I и освещены некоторые общие понятия.
Bash или bash
В книге мы придерживаемся такого правила: если предложение не начинается со слова bash и это слово не относится к программе Windows Git Bash, название оболочки bash пишем со строчной буквы b. Тем самым мы опираемся на руководство от Чета Реми (Chet Ramey), который в данный момент поддерживает это программное обеспечение. Чтобы больше узнать о bash, посетите сайт bash (http://bit.ly/2I0ZqzU). Чтобы получить информацию о различных релизах bash, посмотреть справочную документацию и примеры, зайдите на страницу http://bit.ly/2FCjMwi.
Надежность скриптов
Скрипты, приведенные в книге в качестве примеров, написаны с обучающей целью. Они могут быть недостаточно эффективными или надежными для применения на промышленном уровне. Будьте осторожны, если решите использовать их в реальной среде. Убедитесь, что следуете передовым методикам программирования, и перед размещением протестируйте скрипты.
Рабочая среда
Для развития навыков в области безопасности, работы с командной строкой и bash в конце каждой главы вас ждут вопросы и практические задания. Решения для некоторых заданий и дополнительные ресурсы можно найти на сайте https://www.rapidcyberops.com/.
Условные обозначения
В книге применяются следующие типографские обозначения.
Курсив
Обозначает новые термины и слова, на которых сделан акцент.
Рубленый шрифт
Им выделены URL, адреса электронной почты, названия элементов интерфейса.
Моноширинный шрифт
Обозначает программные элементы: названия команд переменных или функций, типы данных, операторы и ключевые слова. Им также выделены имена и расширения файлов, названия папок.
Этот элемент обозначает совет, подсказку или предложение.
Такой элемент обозначает примечание.
Данный элемент обозначает предупреждение.
Использование примеров кода
Эта книга призвана помочь вам в работе. Примеры кода из нее вы можете использовать в своих программах и документации. Если объем кода несущественный, связываться с нами для получения разрешения не нужно. Например, для написания программы, использующей несколько фрагментов кода из этой книги, разрешения не требуется. А вот для продажи или распространения компакт-диска с примерами из книг издательства O’Reilly нужно получить разрешение. Ответы на вопросы с использованием цитат из этой книги и примеров кода разрешения не требуют. Но для включения объемных примеров кода из этой книги в документацию по вашему программному продукту разрешение понадобится.
Мы приветствуем указание ссылки на источник, но не делаем это обязательным требованием. Такая ссылка обычно включает имя автора, название книги, название издательства и ISBN. Например: «Тронкон П., Олбинг К. Bash и кибербезопасность: атака, защита и анализ из командной строки Linux. — СПб.: Питер, 2019. 978-5-4461-1514-3».
Если вам покажется, что использование кода примеров выходит за рамки оговоренных выше условий и разрешений, свяжитесь с нами по адресу permissions@oreilly.com.
Благодарности
Мы хотели бы поблагодарить основных научных редакторов за их знания и помощь в уточнении информации, содержащейся в данной книге. Тони Ли (Tony Lee), главный технический директор Cylance Inc., — энтузиаст в области безопасности. Тони регулярно делится своими знаниями на LinkedIn (http://bit.ly/2HYCIIw) и SecuritySynapse (http://bit.ly/2FEwYka). Чет Реми (Chet Ramey), Senior Technology Architect на факультете информационных технологий Университета Кейс Вестерн Резерв (Case Western Reserve University) (http://bit.ly/2HZHaGW), в данный момент является специалистом по сопровождению ПО в bash.
Мы также благодарим Билла Купера (Bill Cooper), Джосайю Дикстра (Josiah Dykstra), Рика Мессиера (Ric Messier), Кэмерона Ньюхема (Cameron Newham), Сандру Скьяво (Sandra Schiavo) и Дж. П. Воссена (JP Vossen) за советы и критические замечания.
И наконец, мы хотели бы поблагодарить всю команду O’Reily, в частности Нан Барбер (Nan Barber), Джона Девинса (John Devins), Майка Лукидеса (Mike Loukides), Шерон Уилки (Sharon Wilkey), Эллен Траутмэн-Зейг (Ellen Troutman-Zaig), Кристину Эдвардс (Christina Edwards) и Вирджинию Уилсон (Virginia Wilson).
1 Приведенная автором цитата звучит так: What is of the greatest importance in war is extraordinary speed: one cannot afford to neglect opportunity.
В войне самое главное — быстрота: нельзя упускать возможности1.
Приведенная автором цитата звучит так: What is of the greatest importance in war is extraordinary speed: one cannot afford to neglect opportunity.
От издательства
Ваши замечания, предложения, вопросы отправляйте по адресу comp@piter.com (издательство «Питер», компьютерная редакция).
Мы будем рады узнать ваше мнение!
На веб-сайте издательства www.piter.com вы найдете подробную информацию о наших книгах.
Часть I. Основы
Дайте мне шесть часов на то, чтобы срубить дерево, и первые четыре я буду точить топор.
Автор неизвестен
В части I мы начнем с азов работы с командной строкой, оболочкой bash и регулярными выражениями, а также рассмотрим фундаментальные принципы кибербезопасности.
1. Работа с командной строкой
Интерфейс командной строки компьютера предоставляет вам тесную связь с операционной системой (ОС). Командная строка содержит огромное количество функций, отточенных и отшлифованных за десятилетия использования. К сожалению, способность взаимодействовать с ОС с помощью командной строки стремительно утрачивается — все чаще применяют графические пользовательские интерфейсы (graphical user interfaces, GUI), которые за счет скорости и гибкости зачастую облегчают работу, но не дают возможности пользователю задействовать скрытые функции.
Умение эффективно работать с командной строкой — важнейший навык для специалистов по безопасности и администрированию. Он важен для работы со многими инструментами в этой сфере, такими как Metasploit, Nmap и Snort. Во время тестирования на возможность проникновения в систему при взаимодействии с целевой ОС вашим единственным вариантом может оказаться использование интерфейса командной строки, в особенности на ранних стадиях вторжения.
Чтобы создать прочный «фундамент», мы начнем с общей информации о командной строке и ее составляющих, а затем посмотрим, как ею можно воспользоваться для улучшения характеристик кибербезопасности.
Определение командной строки
В этой книге термином «командная строка» мы будем обозначать специальную программу, назначение которой — управление операционной системой с помощью текстовых команд, вводимых в окне приложения (интерфейсе командной строки) без применения графического пользовательского интерфейса (GUI) и встроенных вкладок. Интерфейс командной строки дает возможность написания скриптов (сценариев, script).
Чтобы эффективно использовать командную строку, вам нужно понимать особенности и варианты существующих команд, а также уметь с помощью языка сценариев упорядочить эти команды вместе.
В книге мы познакомим вас более чем с 40 командами, работающими как в ОС Linux, так и в Windows, а также с различными встроенными функциями и ключевыми словами оболочки. Большая часть команд появилась в среде Linux, но, как вы увидите далее, существует множество способов запустить их и на базе Windows.
Почему именно bash
Для создания скриптов мы выбрали оболочку bash и язык команд. Оболочка bash существует уже несколько десятилетий, доступна почти в каждой версии Linux и даже появилась в Windows. Таким образом, оболочка bash стала идеальным инструментом для операций по обеспечению безопасности, поскольку у нее межплатформенные методы и сценарии. Распространенность bash также дает определенное преимущество специалистам, тестирующим на устойчивость к атакам и вторжениям, поскольку во многих случаях им не нужно устанавливать в системе дополнительную инфраструктуру поддержки или интерпретатор.
Примеры использования командной строки
В книге часто приводятся примеры использования командной строки. Примеры однострочных команд будут выглядеть следующим образом:
ls -l
Если в примере с однострочной командой показывается также и результат, он будет выглядеть так:
$ ls –l
-rw-rw-r-- 1 dave dave 15 Jun 29 13:49 hashfilea.txt
-rwxrw-r-- 1 dave dave 627 Jun 29 13:50 hashsearch.sh
Обратите внимание: в примере с результатом присутствует символ $. Символ $, который вы видите в начале команды, не является частью этой команды, а показывает простой фрагмент командной строки оболочки. Это позволит вам различать команду (в том виде, в каком ее надо ввести) и ее результат в терминале. Пустая строка, отделяющая в примерах команду от результата, при реальном запуске команды появляться не будет. Опять-таки она нужна для разделения команды и ее результата.
Примеры команд в Windows, если на это нет особых указаний, запускаются с помощью Git Bash, а не из командной строки Windows.
Запуск Linux и bash в Windows
Оболочка bash и обсуждаемые нами команды практически во всех дистрибутивах Linux установлены по умолчанию, чего нельзя сказать о Windows. Но, к счастью, в Windows существует множество способов запуска Linux-команд и скриптов для bash. Здесь мы опишем четыре варианта: Git Bash, Cygwin, подсистему Windows для Linux (Windows Subsystem for Linux, WSL), командную строку Windows и инструмент написания скриптов.
Git Bash
Многие стандартные команды Linux и оболочку bash можно запустить в Windows, если установить Git, где есть порт bash. Благодаря тому что Git Bash популярен и способен выполнять как стандартные команды Linux и bash, так и многие команды самой Windows, это наиболее предпочтительный способ выполнения приведенных в книге примеров.
Git можно загрузить с сайта https://git-scm.com/. После того как Git будет загружен, для его запуска достаточно щелкнуть правой кнопкой мыши на Рабочем столе и выбрать в появившемся контекстном меню команду Git Bash Here (Установить Git Bash).
Cygwin
Cygwin — это полноценный эмулятор Linux, предоставляющий также возможность установить различные дополнения. Он похож на Git Bash тем, что, помимо стандартных команд Linux, позволяет запускать многие команды самой Windows. Cygwin можно загрузить с сайта https://www.cygwin.com/.
Подсистема Windows для Linux
В Windows 10, если в ней установлена подсистема Windows для Linux (WSL), предумотрен встроенный способ запуска Linux (а следовательно, и bash). Чтобы установить WSL, выполните следующие действия.
1. Щелкните на поисковой строке Windows 10.
2. Введите поисковый запрос Control Panel (Панель управления) и откройте одноименную панель.
3. Щелкните на строке Programs and Features (Программы и компоненты).
4. В левой части открывшегося окна щелкните на строке Turn Windows features on or off (Включение и выключение компонентов Windows).
5. Установите флажок Windows Subsystem for Linux (Подсистема Windows для Linux).
6. Перезагрузите систему.
7. После перезагрузки откройте Windows Store (Хранилище Windows) и введите поисковый запрос Linux. Вы увидите список доступных к установке приложений.
8. Найдите и установите Ubuntu.
9. После установки Ubuntu откройте командную строку Windows, введите ubuntu и нажмите клавишу Enter.
Заметьте, что при подобном использовании дистрибутива WSL Linux вы можете выполнять сценарии bash и подключать файловую систему Windows, но не можете, как в Git Bash и Cygwin, выполнять вызовы системных функций к командам самой Windows.
Установив WSL и зайдя в Windows Store, помимо Ubuntu, вы можете выбрать и другие версии Linux, например Kali.
Командная строка и инструмент создания скриптов Windows
Установив подсистему Windows для Linux, с помощью команды bash-c вы можете выполнять команды Linux и сценарии bash напрямую из командной строки и с использованием инструмента создания скриптов Windows.
Например, можно выполнить Linux-команду pwd из командной строки Windows по отношению к открытому в данный момент каталогу:
C:\Users\Paul\Desktop>bash -c "pwd"
/mnt/c/Users/Paul/Desktop
Если у вас в виде части WSL установлено несколько дистрибутивов Linux, при запуске команды вместо слова bash вы можете использовать название дистрибутива:
C:\Users\Paul\Desktop>ubuntu -c "pwd"
/mnt/c/Users/Paul/Desktop
Этим методом также можно воспользоваться для выполнения пакетов, установленных в вашем дистрибутиве Linux из WSL, если у него есть интерфейс командной строки, например пакета Nmap.
Это дополнение, кажущееся несущественным, предоставляет вам возможность с помощью командной строки Windows и инструментов создания сценариев использовать целый арсенал Linux-команд, пакетов и функций bash.
Основы работы с командной строкой
«Командная строка» — это общий термин, относящийся к средствам, передающим команды в интерактивную систему компьютера. Командная строка появилась с первыми операционными системами, и ею пользовались, пока не был создан GUI. В системах Linux это инструмент ввода в оболочку bash (или другую). Одна из базовых операций bash — исполнение команды, то есть запуск связанной с этой командой программы. Когда вы ввели несколько слов в командную строку, bash предполагает, что первое слово — это название программы, которую нужно запустить, а остальные слова — аргументы команды. Например, чтобы bash запустила команду под названием mkdir и передала ей два аргумента, -p и /tmp/scratch/garble, нужно ввести следующее:
mkdir -p /tmp/scratch/garble
По умолчанию опции программ обычно расположены в начале команды, после названия запускаемого ею приложения, и начинаются с дефиса (-). В нашем примере дефис установлен перед опцией -p (заметьте, между дефисом и буквой пробела быть не должно!). Эта конкретная команда (mkdir) дает указание создать каталог с названием /tmp/scratch/garble, где каталог garble вложен в каталог /scratch, который, в свою очередь, вложен в каталог /tmp. Опция -p обозначает определенное поведение, которое выбирает пользователь: в частности, отсутствие отчетов об ошибках и при необходимости создание (или попытку создания) любых промежуточных каталогов (так как если в команде указан только каталог /tmp, то mkdir сначала создаст каталог /tmp/scratch, а потом попытается создать /tmp/scratch/garble).
Команды, аргументы, встроенные функции и ключевые слова
Команды, которые вы можете запустить, определяют либо файлы, либо встроенные функции, либо ключевые слова.
Файлы — это исполняемые приложения, которые становятся результатом компиляции и теперь состоят из машинных команд. Примером подобного приложения служит программа ls. В большинстве файловых систем Linux этот файл находится в каталоге /bin/ls.
Другой тип файла — это скрипт. Это текстовый файл, который может прочесть человек. Скрипт пишется на одном из языков, поддерживаемых вашей системой, с помощью интерпретатора (программы) для этого языка. Примерами языков для написания скриптов могут служить bash, Python и Perl. В следующих главах мы создадим несколько скриптов (написанных на bash).
Встроенные функции — это часть оболочки. Они выглядят как исполняемые файлы, но в файловой системе нет файла, который загружается для исполнения того, что делают встроенные функции. Вместо этого работа выполняется внутри оболочки. Примером встроенной функции служит команда pwd. Применение таких функций позволит добиться результатов быстрее и с большей продуктивностью. Как пользователь, вы можете определять наиболее часто используемые функции оболочки как встроенные команды.
Существуют и другие слова, которые выглядят как команды, но на самом деле являются частью языка оболочки, например if. Это слово часто используется в качестве первого слова в командной строке, но это не команда. Это ключевое слово. Оно связано с синтаксисом, который может быть сложнее, чем обычный формат командной строки: команда-опцииаргументы. Многие ключевые слова мы рассмотрим в следующей главе.
Вы можете использовать команду type, чтобы определить, чем является конкретное слово — ключевым словом, встроенной функцией, командой или ничем из перечисленного. Если добавить опцию -t, то можно свести результат к одному слову:
$ type -t if
keyword
$ type -t pwd
builtin
$ type -t ls
file
Можно использовать команду compgen, чтобы определить, какие команды, встроенные функции и ключевые слова вам доступны. Чтобы увидеть список команд, добавьте опцию -c, список встроенных функций — -b, перечень ключевых слов — -k:
$ compgen -k
if
then
else
elif
.
.
.
Если поначалу вы будете путаться в этих понятиях, не волнуйтесь. Не всегда нужно понимать разницу, но стоит знать о том, что использование встроенных функций и ключевых слов гораздо эффективнее, чем выполнение команд (исполняемых во внешних файлах), особенно если их зациклить и вызывать много раз подряд.
Стандартные ввод/вывод/ошибка
На жаргоне специалистов по операционным системам запущенная программа называется процессом. Каждый процесс в среде Unix/Linux/POSIX (и, следовательно, в Windows) обладает тремя различными файловыми дескрипторами. Дескрипторам присвоены следующие названия: стандартный ввод (сокращенно stdin), стандартный вывод(stdout) и стандартная ошибка (stderr).
Как можно догадаться по названию, stdin — это ресурс ввода в программу по умолчанию. Обычно это символы, поступающие при вводе с клавиатуры. Когда ваш скрипт читает из stdin, он читает символы, набранные на клавиатуре, или (как вы вскоре увидите) его можно изменить таким образом, что он будет читать из файла. Stdout — это место, куда по умолчанию отправляется результат, выданный программой. По умолчанию результат появляется в окне, в котором запущены ваши оболочка или сценарий оболочки. Стандартная ошибка тоже может быть результатом, отправленным программой. Но в stderr пишутся (или должны писаться) сообщения об ошибках. Программист решает, отправить результат в stdout или stderr. Поэтому стоит писать сценарии аккуратно, чтобы они отправляли отчеты об ошибках в stderr, а не в stdout.
Перенаправление и конвейер
Одной из главнейших инноваций оболочки было то, что она предоставила нам механизм, с помощью которого можно было взять запущенную программу и поменять место ввода и/или вывода, не изменяя саму программу. Если у вас есть программа под названием handywork, читающая ввод из stdin и записывающая результаты в stdout, вы легко можете это изменить:
handywork < data.in > results.out
Так, handywork запустится, но ее ввод будет поступать не с клавиатуры, а из файла под названием data.in (если такой файл существует и в нем есть информация в нужном формате). А результат будет отправляться не на экран, а в файл под названием results.out (если его не существует, он будет создан, а если существует — переписан). Эта техника называется перенаправлением, потому что мы перенаправляем ввод из другого места и вывод не на экран.
А что делать с stderr? Синтаксис в данном случае схож. При перенаправлении данных, выводимых программой, нужно различать stdout и stderr, и мы создаем это различие с помощью номеров файловых дескрипторов. Stdin — это файловый дескриптор 0, stdout — файловый дескриптор 1, а stderr — файловый дескриптор 2. Таким образом, мы можем перенаправить сообщения об ошибках:
handywork 2> err.msgs
Здесь мы перенаправляем только stderr, и любое сообщение об ошибке будет отправлено в файл, который мы назвали err.msgs.
Разумеется, мы можем выполнить все три действия одной строкой кода:
handywork < data.in > results.out 2> err.msgs
Иногда нужно, чтобы сообщения об ошибках были объединены с нормальными результатами (как это происходит по умолчанию, когда и то и другое выводится на экране). Это можно сделать так:
handywork < data.in > results.out 2>&1
Данное действие заставляет отправлять stderr (2) в то же место, что и файловый дескриптор 1 (&1). Отметьте, что, если не будет значка амперсанда (&), сообщения об ошибках будут просто отправляться в файл с названием 1. Такое сочетание stdout и stderr так распространено, что существует удобная сокращенная нотация:
handywork < data.in &> results.out
Если вы хотите отсеять стандартный вывод, можете перенаправить его в специальный файл под названием /dev/null:
handywork < data.in > /dev/null
Чтобы видеть результаты в командной строке и одновременно перенаправлять их в файл, используйте команду tee. Следующий пример выводит результаты выполнения команды handywork на экран и в то же время сохраняет их в файл results.out:
handywork < data.in | tee results.out
Используйте опцию -a команды tee, чтобы добавлять результаты в файл, а не переписывать его заново. Символ | известен как «пайп» (pipe). Указав его, можно использовать результаты одной команды в качестве исходных данных для другой. В данном примере результаты выполнения handywork передаются команде tee для дальнейшей обработки.
При перенаправлении результата с использованием символа > файл будет создан или обрезан (то есть из файла будет удалено содержимое). Если вы хотите заранее сохранить имеющееся содержимое данного файла, вам следует его дополнить, используя символ >>, как показано ниже:
handywork < data.in >> results.out
Таким образом, выполняется handywork, а затем любой результат из stdout добавляется в файл results.out, а не перезаписывается поверх существующего содержимого.
Следующая строка:
handywork < data.in &>> results.out
позволяет выполнить handywork, а затем добавить и stdout, и stderr в файл results.out, не перезаписывая поверх существующего содержимого.
Выполнение команд в фоновом режиме
На протяжении этой книги мы выйдем за рамки однострочных команд и начнем создавать сложные сценарии. Некоторые из них могут выполняться в течение довольно длительного времени, и вы, возможно, не захотите долго ждать. Вместо этого вы можете запустить любую команду или сценарий в фоновом режиме, используя оператор &. Скрипт будет выполняться дальше, но вы сможете продолжать использовать оболочку, давая другие команды и/или выполняя другие сценарии. Например, чтобы запустить ping в фоновом режиме и перенаправить стандартный вывод в файл, используйте эту команду:
ping 192.168.10.56 > ping.log &
Вы можете перенаправить стандартный вывод и/или стандартные ошибки в файл, отправив задание в фоновый режим, иначе задание продолжит выводиться на экран и будет прерывать другие ваши действия:
ping 192.168.10.56 &> ping.log &
Осторожно: не перепутайте символ & (для отправки задания в фоновый режим) и &> (для совместного перенаправления стандартного вывода и стандартных ошибок).
Для получения списка задач, которые сейчас выполняются в фоновом режиме, можно использовать команду jobs:
$ jobs
[1]+ Running ping 192.168.10.56 > ping.log &
Введите команду fg и соответствующий номер задания, чтобы снова вывести задачу в приоритет из фонового режима:
$ fg 1
ping 192.168.10.56 > ping.log
Если ваша задача сейчас выполняется в приоритетном режиме, для приостановки процесса можно нажать сочетание клавиш Ctrl+Z. Для продолжения работы в фоновом режиме введите команду bg. После этого вы можете использовать команды jobs и fg, как описано ранее.
От командной строки до скрипта
Скрипт оболочки — это просто файл, содержащий команды, которые вы можете последовательно ввести в командную строку. Если ввести одну команду или более в файл, получится скрипт оболочки. Если вы, например, назовете этот файл myscript, его можно будет запустить, введя команду bashmyscript. Кроме того, можете наделить его полномочиями на выполнение (например, chmod755myscript), а затем, чтобы управлять сценарием, вызывать его напрямую: ./myscript. Следующая строка, сообщающая операционной системе, какой язык скриптов мы используем, часто становится первой строкой скрипта:
#!/bin/bash -
Конечно, в этой строке предполагается, что bash находится в каталоге /bin. Если вам потребуется сделать скрипт более мобильным, можно воспользоваться следующим подходом:
#!/usr/bin/env bash
Здесь, чтобы найти местонахождение bash, используется команда env. Этот способ считается стандартным методом решения проблемы мобильности. Однако в данном случае предполагается, что команду env можно найти в каталоге /usr/bin.
Выводы
Командная строка — это виртуальный аналог универсального инструмента. Если вам нужно завинтить шуруп в деревянный брусок, лучше всего взять для этого специальный инструмент, например ручную или электрическую отвертку. Но если вы заблудились в лесу и ваши ресурсы ограниченны, нет ничего лучше универсального инструмента. С ним вы можете завинтить шуруп, разрезать веревку и даже открыть бутылку. То же самое можно сказать и о командной строке: она ценна не уровнем выполнения одного конкретного задания, а своей гибкостью и доступностью.
В последние годы оболочка bash и команды Linux стали общедоступными. С помощью Git Bash или Cygwin вы с легкостью можете получить доступ к функционалу из Windows. Для получения большего количества функций можно установить подсистему Windows для Linux, которая даст вам возможность запускать полные версии операционных систем Linux и пользоваться их функциями напрямую из командной строки и с помощью инструмента PowerShell для создания скриптов Windows.
В следующей главе мы обсудим пользу скриптов, проявляющуюся благодаря возможности запускать команды повторно, принимать решения и зацикливать различные исходные данные.
Упражнения
1. Напишите команду, которая выполняет ifconfig и перенаправляет стандартный вывод в файл ipaddress.txt.
2. Напишите команду, которая выполняет ifconfig, перенаправляет стандартный вывод и дополняет им файл ipaddress.txt.
3. Напишите команду, которая копирует все файлы из каталога /etc/a в каталог /etc/b и перенаправляет стандартные ошибки в файл copyerror.log.
4. Напишите команду, которая создает список каталогов (ls), находящихся в корневом каталоге, и направляет вывод в команду more.
5. Напишите команду, которая исполняет mytask.sh и отправляет его в фоновый режим.
6. Основываясь на следующем списке заданий, напишите команду, которая выводит задание по пингу Amazon в приоритет:
[1] Running ping www.google.com > /dev/null &
[2]- Running ping www.amazon.com > /dev/null &
[3]+ Running ping www.oreilly.com > /dev/null &
Чтобы просмотреть дополнительные ресурсы и получить ответы на эти вопросы, зайдите на сайт https://www.rapidcyberops.com/.
2. Основы работы с bash
Bash — это больше чем просто интерфейс командной строки для запуска программ. Это сам по себе язык программирования. По умолчанию он запускает другие программы. Как мы уже говорили ранее, когда несколько слов введены в командную строку, bash предполагает, что первое слово — это имя программы, которую нужно запустить, а остальные слова — аргументы, которые нужно передать этой программе.
Но, как язык программирования bash, также имеет функции для поддержки ввода и вывода и управления структурами: if, while, for, case и др. Его основной тип данных — строки (например, имена файлов и пути), но он поддерживает и целые числа. Поскольку основное внимание уделяется сценариям и запуску программ, а не вычислениям, bash не поддерживает напрямую числа с плавающей точкой. Для этого можно использовать другие команды. Далее мы приводим краткий обзор отдельных функций, которые делают bash мощным языком программирования, особенно при написании сценариев.
Вывод
Как и любой другой язык программирования, bash имеет возможность выводить информацию на экран. Вывод можно успешно выполнить с помощью команды echo:
$ echo "Hello World"
Hello World
Вы также можете использовать встроенную команду printf, которая позволяет добавить дополнительное форматирование:
$ printf "Hello World\n"
Hello World
Вы уже видели в предыдущей главе, как перенаправить этот вывод в файлы, stderr либо другую команду. Больше этих команд и их опций мы рассмотрим далее.
Переменные
Переменные bash начинаются с буквенного символа или символа подчеркивания, за которым следуют алфавитно-цифровые символы. Они являются строковыми, если не указано иное. Чтобы присвоить значение переменной, вы пишете что-то вроде этого:
MYVAR=textforavalue
Чтобы извлечь значение этой переменной (например, вывести на экран с помощью команды echo), вы задаете $ перед именем переменной:
echo $MYVAR
Если вы хотите присвоить переменной последовательность слов, то есть сохранить все пробелы, то заключите значение в кавычки, как показано ниже:
MYVAR='here is a longer set of words'
OTHRV="either double or single quotes will work"
Использование двойных кавычек позволит выполнять другие замены внутри строки. Например:
firstvar=beginning
secondvr="this is just the $firstvar"
echo $secondvr
В результате мы получаем на выходе такое значение переменной firstvar:
this is just the beginning
При извлечении значения переменной вы можете выполнить множество подстановок. Мы покажем эти подстановки так, как они будут использованы в последующих сценариях.
Помните, что при использовании двойных кавычек (") любые замены, начинающиеся с $, все равно выполняются, а если значение находится внутри одинарных кавычек ('), никаких замен не будет.
Вы также можете сохранить вывод, полученный командой оболочки, с помощью символов $(), как показано ниже:
CMDOUT=$(pwd)
Здесь команда pwd выполняется в подоболочке, и вместо того, чтобы печатать результат в stdout, мы сохраняем вывод команды в переменной CMDOUT. Вы также можете передать вместе несколько команд внутри $().
Позиционные параметры. Обычно при использовании инструментов командной строки для передачи данных в команды применяются аргументы или параметры. Каждый параметр отделяется пробелом и доступен внутри bash с помощью специального набора идентификаторов. В скрипте bash доступ к первому параметру, переданному в скрипт, можно получить с помощью $1, ко второму — с $2 и т.д. $0 — это специальный параметр, который содержит имя скрипта, а $# возвращает общее количество параметров. Взгляните на скрипт в примере 2.1.
Пример 2.1. echoparams.sh
#!/bin/bash -
#
# Bash и кибербезопасность
# echoparams.sh
#
# Описание:
# Демонстрация доступа к параметрам в bash
#
# Использование:
# ./echoparms.sh <param 1> <param 2> <param 3>
#
echo $#
echo $0
echo $1
echo $2
echo $3
Этот сценарий сначала выводит на экран количество параметров ($#), затем имя сценария ($0), а потом первые три параметра. Вот вывод:
$ ./echoparams.sh bash is fun
3
./echoparams.sh
bash
is
fun
Ввод
Пользовательский ввод можно получить в bash с помощью команды read. Она извлекает пользовательский ввод из stdin и сохраняет его в указанной переменной. Следующий скрипт читает пользовательский ввод в переменную MYVAR и затем выводит его на экран:
read MYVAR
echo "$MYVAR"
Вы уже видели, как перенаправить этот ввод из файлов. Далее в главе вы найдете гораздо больше информации о read и ее параметрах, а также об этом перенаправлении.
Условия
В bash предусмотрен богатый выбор условных конструкций. Многие условия начинаются с ключевого слова if. Любая команда или программа, вызываемая в bash, может выполнить вывод, но она также всегда возвращает значение, определяющее успешное или неудачное выполнение. В оболочке это значение можно найти в переменной $? сразу после запуска команды. Возвращаемое значение 0 считается success или true; любое ненулевое значение считается error или false. В простейшем виде в выражении if используются именно эти значения.
if cmd
then
some cmds
else
other cmds
fi
Использование 0 для true и ненулевого значения для false кардинально отличает bash от многих языков программирования (C++, Java, Python и др.). Но для bash это имеет смысл, потому что при неудачном выполнении программы нужно вернуть код ошибки (чтобы объяснить, как она вышла из строя), тогда как при успешном завершении кода ошибки не будет, то есть мы получим 0. Это отражает тот факт, что многие вызовы операционной системы возвращают 0, если все прошло успешно, или –1 (или другое ненулевое значение), если случилась ошибка. Но в bash есть исключение из этого правила для значений в двойных скобках (подробнее об этом — позже).
Например, следующий скрипт пытается изменить каталоги в /tmp. Если эта команда выполнена успешно (возвращает 0), тело инструкции if будет выполнено.
if cd /tmp
then
echo "here is what is in /tmp:"
ls -l
fi
Bash таким же образом может обрабатывать конвейер команд:
if ls | grep pdf
then
echo "found one or more pdf files here"
else
echo "no pdf files found"
fi
В случае конвейера при проверке на успех/неудачу именно последняя команда определяет, будет ли выбрана true-ветвь. Вот пример, где этот факт имеет значение:
ls | grep pdf | wc
Эта серия команд будет «истинной», даже если команда grep не найдет строку pdf. Так происходит потому, что команда wc будет успешно выполнена и выведет следующее:
0 0 0
Этот вывод показывает нулевые строки, нулевые слова и нулевые байты (символы), когда от команды grep нет вывода данных. Это успешный (и, следовательно, верный) результат для wc, а не ошибка или сбой. Получено столько строк, сколько было дано, даже если для подсчета было предоставлено ноль строк.
В более типичной форме команды if, используемой для сравнения, применяется составная команда [[, встроенная команда оболочки [ или тест. Укажите их для проверки атрибутов файла или сравнения значений.
Чтобы проверить, существует ли файл в файловой системе, выполните следующую команду:
if [[ -e $FILENAME ]]
then
echo $FILENAME exists
fi
В табл. 2.1 перечислены дополнительные тесты, которые можно выполнить в отношении файлов с помощью if.
Таблица 2.1. Операторы проверки файлов
| Оператор проверки файлов |
Использование |
| -d |
Проверка, существует ли каталог |
| -e |
Проверка, существует ли файл |
| -r |
Проверка, существует ли файл и доступен ли он для чтения |
| -w |
Проверка, существует ли файл и доступен ли он для записи |
