Урок 8. Объединение команд — последовательное и параллельное выполнение в bash
Символы групповых операций
Мы уже изучили достаточно команд и наверняка возникал вопрос как применить данные команды сразу к группе файлов. Например, за раз скопировать несколько файлов в каталог или наоборот удалить ненужные файлы. Делать одну и ту же операцию один за другим довольно утомительное и ненужное занятие.
Поэтому в Linux имеются специальные символы, которые позволяют проводить данные операции над несколькими файлами.
Символ “ * ” указывает на любой символ в любом количестве. Поясним на примере.
У нас имеются следующие файлы:
Необходимо скопировать файлы image в каталог photo/. Для этого достаточно выполнить:
Символ » * « в данном случае означает любые символы после слова image , то есть image1.jpg , image2.jpg и так далее, включая image1.txt , image2.txt и image.pdf .
Чтобы лучше понять данный принцип рассмотрим возможные применения данного символа в таблице:
Все файлы image1.jpg — image15.jpg, image1.txt, image2.txt image.pdf
Только файлы image1.jpg — image15.jpg
Все файлы jpg : image1.jpg — image15.jpg
Абсолютно все файлы в текущем каталоге
Символ “ ? ” указывает на любой одиночный символ. Например, команда cp image?.jpg photo/ скопирует файлы с image1.jpg по image9.jpg , то есть между image и .jpg рассматривается только один знак.
Рассмотрим возможные применения данного символа:
Только с image1.jpg по image9.jpg
Только с image10.jpg по image15.jpg
В нашем случае выдаст ошибку, так такого файла или каталога не существует
image1.jpg — image9.jpg, image1.txt и image2.txt
Следующий символ групповых операций — это квадратные скобки []. Внутри скобок помещается определенной выражение.
Например, [12] означает, что в условии должен совпасть один из символов, указанных в скобках, то есть либо 1 либо 2. Также можно задать целый диапазон значений — 1, то есть любой символ из указанного диапазона.
Поясним сказанное на примерах:
Только файлы image1.jpg и image2.jpg
Только файлы image11.jpg — image15.jpg
image1.jpg, image2.jpg, image1.txt, image2.txt
Только файлы image11.jpg — image13.jpg
Как видно с помощью данных символов можно гибко управлять файлами. Данные символы можно использовать с любыми командами. В последующих разделам мы будем часто с ними встречаться.
Теперь рассмотрим, как можно объединить между собой сразу несколько команд, заставив их выполнять действие последовательно друг за другом либо параллельно.
Последовательное безусловное выполнение
Иногда при выполнении задач в Linux может потребоваться выполнить сразу целую последовательность команд.
Например, нам нужно создать каталог, скопировать группу файлов student*.jpg в данный каталог и проверить размер данного каталога в килобайтах.
Для этого мы выполним следующее:
Пришлось последовательно вводить команду, затем ждать ее завершения и вводить следующую. Однако данный процесс можно оптимизировать, введя все команды одну за другой, отделив каждую точкой с запятой:
mkdir photo; cp student*.jpg photo/; ls -lh
Результат будет тот же, но в данном случае мы все сделали гораздо быстрее. Это особенно актуально, если приходится использовать команды, на выполнение которых может уходить больше времени.
Следует помнить, что выполнение всегда передается следующей команде даже, если выполнение предыдущей команды завершилось с ошибкой.
Последовательное выполнение при соблюдении условия
Может возникнуть ситуация, когда от успешного выполнения первых команд зависит выполнение последующих команд. То есть, если первая команда завершилась с ошибкой, то вторую команду выполнять не будем.
Например, из каталога photo/ нам нужно скопировать файлы на внешний носитель, а затем удалить их из каталога photo/. В принципе можно воспользоваться указанной ниже последовательностью
cp student*.jpg /media/StudentFlash; rm student*.jpg
И все будет работать, однако здесь одно НО. Если мы забудем подключить флэшку и выполним вышеуказанную последовательность, то потеряем все файлы student*.jpg , так как несмотря на ошибку система все равно выполнит вторую команду.
Чтобы избежать подобных ситуаций можно воспользоваться конструкцией:
cp student*.jpg /media/StudentFlash && rm student*.jpg
То есть вместо символа » ; » (точка с запятой) мы используем » && » . Проще говоря, если первая команда завершилась с ошибкой (неважно какая), то система не выполнит вторую команду. Если первая команда завершилась успешно, то будет выполнена вторая команда.
Следующий символ объединения » || « используется, когда из 2-х (или более) команд нужно выполнить либо первую либо вторую команду. То есть, если первая команда завершилась с ошибкой, то ход переходит следующей команде, а если первая команда все же успешно завершилась, то вторая команда выполняться не будет.
Например, перейдем в каталог music/ , если его не существует то создадим его:
В нашем случае каталог music/ не существует и система выдала ошибку, поэтому будет выполнена команда mkdir music .
Передача выхода одной команды на вход другой команды
Иногда при работе с командой ls выводится слишком много информации, которая не помещается на всем экране и приходится прокручивать текст, чтобы увидеть начало
Чтобы постранично просматривать результат выполнения команд можно перенаправить вывод ls на вход команды less . Как мы уже знаем она используется для постраничного просмотра текстовых файлов. Для этого воспользуемся символом » | «:
Теперь попробуем в системе найти файл под названием icon с помощью команды locate (рассмотрим подробнее позже):
Система может выдать сотни и тысячи значений. Здесь тоже можем воспользоваться символом » | «:
Разумеется все это частные случаи. В процессе изучения новых команд и работе в Linux тебе придется не раз встречаться с ситуациями, когда будет необходимо воспользоваться символом » | « .
А можно результат работы locate записать в файл и уже потом просмотреть его содержимое с помощью less ?
Конечно можно. Для этого существует другой символ объединения команд » > « :
locate * icon > search_result.txt
В данном случаем символом » > » мы записываем результат выполнения locate в файл search_result.txt .
А файл search_result.txt нужно предварительно создавать?
Нет, если его нет, то система создаст его автоматически. А если он есть, то система перезапишет все его содержимое.
То есть мы можем все потерять по неосторожности?
Совершенно верно, но есть 2 способа избежать этого.
1-й способ. Можно установить специальную опцию noclobber :
Теперь, если файл существует, то система выдаст следующее сообщение:
Чтобы отключить эту опцию выполни
2-й способ. Вместо символа » > » воспользуйся символом » >> » . Когда указан этот символ система запишет данные в конец файла, тем самым сохранив предыдущие данные.
Подстановка вывода одной команды под аргумент второй команды
Некоторые команды не могут использоваться самостоятельно без указания аргументов. В качестве аргументов обычно выступают файлы, каталоги либо различные шаблоны и условия (об этом немного позже).
Вместо аргументов в некоторых случаях можно использовать и результаты выполнения некоторых команд.
К примеру, у нас имеется текстовый файл links.txt , где хранится следующая запись
Это простая текстовая строка. Попробуем подставить данную строку, чтобы создать каталоги согласно указанной строке. Для этого можно воспользоваться конструкцией типа $() :
Вывод команды cat был подставлен под аргумент команды mkdir .
Данная последовательность создает каталог по текущей дате.
Источник статьи: http://easy-network.ru/uroki-linux/87-urok-8-combined-commands-execution.html
4 инструмента для одновременного выполнения команд на нескольких Linux-серверах
Статья, перевод которой мы сегодня публикуем, посвящена технологиям одновременного выполнения команд на нескольких Linux-серверах. Речь здесь пойдёт о нескольких широко известных инструментах, реализующих подобный функционал. Этот материал пригодится системным администраторам, которым, например, регулярно приходится проверять состояние множества удалённых систем. Предполагается, что у читателя уже имеется несколько серверов, к которым организован доступ по SSH. Кроме того, при одновременной работе с несколькими машинами весьма полезно настроить SSH-доступ к ним по ключу, без пароля. Такой подход, с одной стороны, повышает безопасность сервера, а с другой — облегчает работу с ним.
1. PSSH — Parallel SSH
PSSH — это опенсорсный набор инструментов командной строки, написанный на Python и предназначенный для параллельного выполнения SSH-команд на множестве Linux-систем. Он быстро работает и лёгок в освоении. PSSH включает в себя такие средства, как parallel-ssh , parallel-scp, parallel-rsync , parallel-slurp и parallel-nuke (подробности об этих средствах можно посмотреть в man).
Перед установкой parallel-ssh в Linux-системе сначала надо установить pip . Вот как это делается в разных дистрибутивах:
Затем parallel-ssh устанавливают с использованием pip :
Далее, нужно внести имена хостов или IP-адреса удалённых Linux-серверов и сведения о портах в файл hosts (на самом деле, назвать его можно как угодно). Тут нам пригодится такая команда:
Вот пример содержимого такого файла:
После того, как в файл будет внесено всё необходимое, пришло время запустить parallel-ssh , передав этой утилите имя файла с использованием опции -h , а также — команды, которые нужно выполнить на всех серверах, адреса которых имеются в файле hosts . Флаг -i утилиты используется для того, чтобы вывести на экран то, что попадёт в стандартные потоки вывода и ошибок после завершения выполнения команд на серверах.
Команда запуска parallel-ssh может выглядеть так:
На следующем рисунке показано использование утилиты при работе с тремя серверами.
Утилита parallel-ssh выполняет команды на нескольких серверах
2. Pdsh — Parallel Remote Shell Utility
Pdsh — это, опять же, опенсорсное решение, представляющее собой оболочку для одновременного выполнения команд на нескольких Linux-серверах.
Вот как установить pdsh в различных дистрибутивах:
Для того чтобы выполнять команды на нескольких серверах, адреса этих серверов, как и при использовании parallel-ssh , надо добавить в файл, который тоже можно назвать hosts . Затем нужно запустить pdsh в следующем виде:
Здесь флаг -w используется для указания файла со списком серверов, флаг -R применяется для указания модуля удалённых команд (среди доступных модулей удалённых команд имеются ssh , rsh , exec ; по умолчанию используется rsh ). Обратите внимание на значок ^ перед именем файла со списком серверов.
Вот как выглядит работа с этой командой.
Выполнение команд на нескольких серверах с использованием pdsh
Если вы, при вызове pdsh , не указали список команд, которые надо выполнить на серверах, эта утилита запустится в интерактивном режиме. Подробности о pdsh можно узнать на соответствующей странице man.
3. ClusterSSH
ClusterSSH — это инструмент командной строки, предназначенный для администрирования кластеров серверов. Он запускает консоль администратора и, для каждого сервера, отдельное окно xterm . После этого на всех этих серверах можно одновременно выполнять одни и те же команды.
Теперь, для подключения к серверам, нужно выполнить команду следующего вида:
Можно воспользоваться и такой конструкцией:
После этого вы увидите нечто, подобное тому, что показано на следующем рисунке.
Работа с несколькими серверами с помощью clusterssh
Команды, введённые в консоли администратора, выполняются на всех серверах. Для выполнения команд на отдельном сервере нужно вводить их в окне, открытом для него.
4. Ansible
Ansible — это популярный опенсорсный инструмент для автоматизации IT-процессов. Он используется для настройки систем и для управления ими, для установки приложений и для решения других задач.
После этого надо добавить адреса серверов в файл /etc/ansible/hosts .
Вот пример фрагмента подобного файла с несколькими системами, объединёнными в группу webservers :
Теперь, для того, чтобы получить сведения команды uptime и узнать, какие пользователи подключены к хостам, входящим в группу webservers , можно воспользоваться следующей конструкцией:
Здесь опция -a используется для указания аргументов, передаваемых модулю, а флаг -u позволяет задать имя пользователя по умолчанию, применяемое для подключения к удалённым серверам по SSH.
Обратите внимание на то, что интерфейс командной строки ansible позволяет выполнять команды лишь по одной.
Взаимодействие с несколькими серверами средствами ansible
Итоги
В этом материале мы рассказали об инструментах, которые предназначены для одновременного выполнения команд на нескольких серверах, работающих под управлением Linux. Если вы подумываете об автоматизации задач по управлению множеством серверов — надеемся, вы найдёте здесь что-нибудь такое, что вам подойдёт.
Уважаемые читатели! Знаете ли вы о каких-нибудь полезных утилитах, упрощающих администрирование большого количества серверов?
Похожие публикации
Kali Linux: виды проверок информационных систем
Пять шагов к спасению Linux-сервера, который рухнул
Простой, надёжный и удобный мониторинг серверов на Linux
Комментарии 29
А как же знаменитый в узких кругах paexec?
Если есть анчибле то почему бы не добавить соль папки и иже с ними.
Ради интереса проверил простенький скрипт
из того, что я вижу, команды выполняются последовательно. Для сравнения ansible
Как бы разница налицо. И это было всего лишь 15 хостов. На 500+ разница будет очень заметной.
Интересно. У меня на долгих операциях разница между -f и без форка весьма заметна. Решил проверить ещё раз.
Итак, эталон с последовательным выполнением:
$ for HOST in `cat hosts.txt`; do ssh $HOST «sleep 5s; date»; done
19 октября 2018 г., 10:51:58 CEST
19 октября 2018 г., 10:52:06 CEST
19 октября 2018 г., 10:52:11 CEST
19 октября 2018 г., 10:52:17 CEST
19 октября 2018 г., 10:52:23 CEST
19 октября 2018 г., 10:52:29 CEST
19 октября 2018 г., 10:52:35 CEST
19 октября 2018 г., 10:52:40 CEST
19 октября 2018 г., 10:52:47 CEST
19 октября 2018 г., 10:52:53 CEST
19 октября 2018 г., 10:52:59 CEST
19 октября 2018 г., 10:53:04 CEST
19 октября 2018 г., 10:53:10 CEST
19 октября 2018 г., 10:53:16 CEST
19 октября 2018 г., 10:53:22 CEST
19 октября 2018 г., 10:53:27 CEST
19 октября 2018 г., 10:53:33 CEST
19 октября 2018 г., 10:53:39 CEST
19 октября 2018 г., 10:53:45 CEST
19 октября 2018 г., 10:53:50 CEST
19 октября 2018 г., 10:53:56 CEST
Теперь с форком:
$ for HOST in `cat hosts.txt`; do ssh -f $HOST «sleep 5s; date»; done
19 октября 2018 г., 10:55:58 CEST
19 октября 2018 г., 10:55:58 CEST
19 октября 2018 г., 10:55:59 CEST
19 октября 2018 г., 10:55:59 CEST
19 октября 2018 г., 10:56:00 CEST
19 октября 2018 г., 10:56:01 CEST
19 октября 2018 г., 10:56:01 CEST
19 октября 2018 г., 10:56:02 CEST
19 октября 2018 г., 10:56:02 CEST
19 октября 2018 г., 10:56:03 CEST
19 октября 2018 г., 10:56:03 CEST
19 октября 2018 г., 10:56:04 CEST
19 октября 2018 г., 10:56:04 CEST
19 октября 2018 г., 10:56:05 CEST
19 октября 2018 г., 10:56:06 CEST
19 октября 2018 г., 10:56:06 CEST
19 октября 2018 г., 10:56:07 CEST
19 октября 2018 г., 10:56:07 CEST
19 октября 2018 г., 10:56:08 CEST
19 октября 2018 г., 10:56:08 CEST
19 октября 2018 г., 10:56:09 CEST
Как видим, есть примерно секундная задержка на запуск нового фонового процесса. На пяти сотнях хостов это, возможно, будет критично. Таки да, согласен. Посыпаю голову пеплом.
Но теперь сделаем финт ушами:
$ for HOST in `cat hosts.txt`; do ssh -f $HOST «sleep 5s; date»& done
19 октября 2018 г., 10:58:43 CEST
19 октября 2018 г., 10:58:43 CEST
19 октября 2018 г., 10:58:43 CEST
19 октября 2018 г., 10:58:43 CEST
19 октября 2018 г., 10:58:43 CEST
19 октября 2018 г., 10:58:43 CEST
19 октября 2018 г., 10:58:43 CEST
19 октября 2018 г., 10:58:43 CEST
19 октября 2018 г., 10:58:43 CEST
19 октября 2018 г., 10:58:43 CEST
19 октября 2018 г., 10:58:43 CEST
19 октября 2018 г., 10:58:43 CEST
19 октября 2018 г., 10:58:43 CEST
19 октября 2018 г., 10:58:43 CEST
19 октября 2018 г., 10:58:43 CEST
19 октября 2018 г., 10:58:43 CEST
19 октября 2018 г., 10:58:43 CEST
19 октября 2018 г., 10:58:43 CEST
19 октября 2018 г., 10:58:43 CEST
19 октября 2018 г., 10:58:43 CEST
19 октября 2018 г., 10:58:43 CEST
Спасибо за наводку. До сих пор мне хватало просто -f, но теперь буду знать как сделать реально ОДНОВРЕМЕННО на всех хостах.
Источник статьи: http://habr.com/ru/company/ruvds/blog/426849/