Linux объединить вывод двух команд

Урок 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

cp image*.jpg photo/

Только файлы image1.jpg — image15.jpg

Все файлы jpg : image1.jpg — image15.jpg

Абсолютно все файлы в текущем каталоге

Символ “ ? ” указывает на любой одиночный символ. Например, команда cp image?.jpg photo/ скопирует файлы с image1.jpg по image9.jpg , то есть между image и .jpg рассматривается только один знак.

Рассмотрим возможные применения данного символа:

cp image?.jpg photo/

Только с image1.jpg по image9.jpg

cp image1?.jpg photo/

Только с image10.jpg по image15.jpg

В нашем случае выдаст ошибку, так такого файла или каталога не существует

image1.jpg — image9.jpg, image1.txt и image2.txt

Следующий символ групповых операций — это квадратные скобки []. Внутри скобок помещается определенной выражение.

Например, [12] означает, что в условии должен совпасть один из символов, указанных в скобках, то есть либо 1 либо 2. Также можно задать целый диапазон значений — 1, то есть любой символ из указанного диапазона.

Поясним сказанное на примерах:

cp image[12].jpg photo/

Только файлы image1.jpg и image2.jpg

cp image14.jpg photo/

Только файлы image11.jpg — image15.jpg

cp image[12]* photo/

image1.jpg, image2.jpg, image1.txt, image2.txt

cp image?[13].jpg photo/

Только файлы image11.jpg — image13.jpg

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

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

Последовательное безусловное выполнение

Иногда при выполнении задач в Linux может потребоваться выполнить сразу целую последовательность команд.

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

Для этого мы выполним следующее:

cp student*.jpg photo/

Пришлось последовательно вводить команду, затем ждать ее завершения и вводить следующую. Однако данный процесс можно оптимизировать, введя все команды одну за другой, отделив каждую точкой с запятой:

mkdir photo; cp student*.jpg photo/; ls -lh

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

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

Последовательное выполнение при соблюдении условия

Может возникнуть ситуация, когда от успешного выполнения первых команд зависит выполнение последующих команд. То есть, если первая команда завершилась с ошибкой, то вторую команду выполнять не будем.

Например, из каталога photo/ нам нужно скопировать файлы на внешний носитель, а затем удалить их из каталога photo/. В принципе можно воспользоваться указанной ниже последовательностью

Читайте также:  Хороший текстовый редактор для mac os

cp student*.jpg /media/StudentFlash; rm student*.jpg

И все будет работать, однако здесь одно НО. Если мы забудем подключить флэшку и выполним вышеуказанную последовательность, то потеряем все файлы student*.jpg , так как несмотря на ошибку система все равно выполнит вторую команду.

Чтобы избежать подобных ситуаций можно воспользоваться конструкцией:

cp student*.jpg /media/StudentFlash && rm student*.jpg

То есть вместо символа » ; » (точка с запятой) мы используем » && » . Проще говоря, если первая команда завершилась с ошибкой (неважно какая), то система не выполнит вторую команду. Если первая команда завершилась успешно, то будет выполнена вторая команда.

Следующий символ объединения » || « используется, когда из 2-х (или более) команд нужно выполнить либо первую либо вторую команду. То есть, если первая команда завершилась с ошибкой, то ход переходит следующей команде, а если первая команда все же успешно завершилась, то вторая команда выполняться не будет.

Например, перейдем в каталог music/ , если его не существует то создадим его:

cd music/ || mkdir music

В нашем случае каталог music/ не существует и система выдала ошибку, поэтому будет выполнена команда mkdir music .

Передача выхода одной команды на вход другой команды

Иногда при работе с командой ls выводится слишком много информации, которая не помещается на всем экране и приходится прокручивать текст, чтобы увидеть начало

Чтобы постранично просматривать результат выполнения команд можно перенаправить вывод ls на вход команды less . Как мы уже знаем она используется для постраничного просмотра текстовых файлов. Для этого воспользуемся символом » | «:

Теперь попробуем в системе найти файл под названием icon с помощью команды locate (рассмотрим подробнее позже):

Система может выдать сотни и тысячи значений. Здесь тоже можем воспользоваться символом » | «:

locate * icon | less

Разумеется все это частные случаи. В процессе изучения новых команд и работе в Linux тебе придется не раз встречаться с ситуациями, когда будет необходимо воспользоваться символом » | « .

А можно результат работы locate записать в файл и уже потом просмотреть его содержимое с помощью less ?

Конечно можно. Для этого существует другой символ объединения команд » > « :

locate * icon > search_result.txt

В данном случаем символом » > » мы записываем результат выполнения locate в файл search_result.txt .

А файл search_result.txt нужно предварительно создавать?

Нет, если его нет, то система создаст его автоматически. А если он есть, то система перезапишет все его содержимое.

То есть мы можем все потерять по неосторожности?

Совершенно верно, но есть 2 способа избежать этого.

1-й способ. Можно установить специальную опцию noclobber :

set -o noclobber

Теперь, если файл существует, то система выдаст следующее сообщение:

Чтобы отключить эту опцию выполни

set +o noclobber

2-й способ. Вместо символа » > » воспользуйся символом » >> » . Когда указан этот символ система запишет данные в конец файла, тем самым сохранив предыдущие данные.

Подстановка вывода одной команды под аргумент второй команды

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

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

К примеру, у нас имеется текстовый файл links.txt , где хранится следующая запись

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

mkdir $(cat links.txt)

Вывод команды cat был подставлен под аргумент команды mkdir .

Данная последовательность создает каталог по текущей дате.

Источник

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

В командной строке Linux можно объединять сразу несколько команд в одну строку (в один запуск). Например, вам нужно выполнить сначала одну команду, за ней вторую и так далее. Но вы хотите сразу вбить в командной строке одну инструкцию, которая все сделает. Для этого можно воспользоваться служебными символами.

Читайте также:  Windows 10 слетела сеть

Выполнение команд последовательно

Например, мы хотим выполнить сначала одну команду. Затем, когда она отработает (вернет управление в командную строку), нам нужно запустить вторую команду. Для этого служит символ точка с запятой ;. Таким образом, если вы выполните в терминале:

то сначала запустится первая команда mycommand1, а когда управление вернется в терминал, то запустится вторая и так далее.

Для теста попробуйте выполнить (в Ubuntu):

Это называется последовательным выполнением команд. Вне зависимости от того, как выполнилась предыдущая команда, вторая команда должна будет запуститься. Можно выполнять команды в зависимости от того, как отработала предыдущая для этого служат символы && и ||.

Зависимое выполнение команд

Символы && и || означают не что иное, как логическое И и ИЛИ. Поэтому когда мы пишем:

то это означает, что команда mycommand2 будет выполнена только в том случае, если команда mycommand1 была выполнена успешно. Каждая следующая команда выполняется только при успешном выполнении предыдущей.

Если выполнить конструкцию:

то команда mycommand2 будет выполнена только, если mycommand1 вернула ошибку. Каждая следующая команда запускается только если предыдущая вернула ошибку.

Источник

IgorKa — Информационный ресурс

Немного обо всем и все о немногом, или практический опыт системного администратора.

Декабрь 2009
Пн Вт Ср Чт Пт Сб Вс
« Ноя Янв »
1 2 3 4 5 6
7 8 9 10 11 12 13
14 15 16 17 18 19 20
21 22 23 24 25 26 27
28 29 30 31

Лекция №23 — bash. Объединение команд

На этой лекции мы продолжаем изучать bash. Сегодня поговорим об объединении команд в bash, о конструкции case и некоторых других командах. Но сначала о незаслуженно забытой на прошлой лекции конструкции case.

case удобнее использовать для ветвления, когда значение необходимо проверять на точное соответствие и оно может принимать три и более значений. Вместо case можно было бы использовать if, но такие конструкции выглядят громоздко и их не так удобно “читать” в скриптах.

Общий синтаксис команды case следующий:

Для нас case важна еще и потому, что содержится во всех скриптах каталога /etc/init.d/. В качестве шаблона могут указываться буквы, цифры, строки и шаблоны вида [a-z], 7, а также ? — один любой символ и * — любая комбинация. Хотя шаблон в общем синтаксисе указан в круглых скобках, на практике разрешается первую скобку не писать. Давайте рассмотрим практический пример:

В качестве значения здесь использована конструкция $1, которая содержит первый передаваемый скрипту параметр. На прошлой лекции мы говорили, что параметры можно передавать не только функции, но и скрипту. Значение начинает сверятся с шаблонами сверху вниз и как только будет найдено соответствие, будет выполнен блок команд между шаблоном и ;;. Пример работы скрипта:

/ linux$ . / case.sh a
a b c d
igor @ adm-ubuntu:

/ linux$ . / case.sh k
Это буква k
igor @ adm-ubuntu:

/ linux$ . / case.sh qq
Это два любых символа
igor @ adm-ubuntu:

/ linux$ . / case.sh 1
Это цифра 1
igor @ adm-ubuntu:

/ linux$ . / case.sh start
Это слово stop или restart или start

В каталоге /etc/init.d/ расположены скрипты управления службами Linux. С помощью case в них реализован механизм обработки передаваемых скрипту параметров: start, stop, restart, reload и других. Ниже фрагмент скрипта /etc/init.d/reboot:

Подобный case вы найдете в каждом скрипте каталога /etc/init.d/.

Объединение команд

Я уже говорил, что если в одной строке скрипта мы пишем два ключевых слова какой либо конструкции, то их нужно разделять символом ;. Точка с запятой и есть простейший способ объединения команд (ключевые слова тоже воспринимаются bash как команды). Команды записанные таким образом будут выполняться последовательно в независимости от результата выполнения предыдущей команды. Примеры ниже можно набирать как в командной строке так и в скрипте.

/ linux$ a = 127 ; echo $a ; b = 172 ; echo $b ; let c = $a + $b ; echo $c
127
172
299

Как видите из примера на одной строке размещено 6 команд, которые были выполнены последовательно.

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

$ sleep 10 & sleep 10 & echo Hello !
[ 1 ] 8043
[ 2 ] 8044
Hello !

Дальше уже более интересные конструкции. После своего выполнения любая команды возвращает числовой код результата выполнения команды. Если это 0 — значит команда выполнена успешно, если это число отличное от нуля — значит команда завершилась с ошибкой. Можно строить выполнение последовательности команд учитывая этот момент. Для этого существуют следующие элементы: двойной амперсанд — && и двойной “пайп” — ||. Если объединение команд происходит только через &&, то каждая следующая команда будет выполняться, только в случае успешного завершения предыдущей команды. Как только какая либо команда цепочки вернет код возврата отличный от нуля, следующие после нее команды не будут выполнены. Для примера воспользуемся командами true (всегда возвращает 0) и false (всегда возвращает 1).

$ true && echo «1» && false && echo «2»
1

В примере команда true вернула 0 и следующая команда echo “1″ была выполнена и тоже вернула 0, после чего была выполнена команда false, которая вернула 1 и выполнение команд прекратилось (команда echo 2 не выполнилась).

Команда || работает с точностью до наоборот. То есть следующая команда будет выполнена только в том случае, если предыдущая команда вернула код возврата отличный от нуля (правило действует в таком виде если все команды объединены только ||). Если команда вернула 0, то выполнение дальнейшей цепочки команд прерывается. Если в примере выше заменить && на ||, то выполнится только команда true, которая вернет 0 и дальнейшие команды не будут выполнены. Если заменить true на false, то получим такой же результат:

$ false || echo «1» || false || echo «2»
1

Комбинируя && и || можно строить довольно сложные варианты объединения команд. Но в этому случае нужно глубже понимать, как происходит выполнение команд при таком объединении.

Рассмотрим два примера объединения команд и на результат их выполнения:

$ false || echo «1» || false || echo «2»
1
igor @ ubuntu:

$ false || echo «1» || false && echo «2»
1
2

В первом варианте команда false вернет код 1, и будет выполнена следующая команда echo “1″, которая вернет код выполнения 0. И далее цепочка команд прерывается как и описано выше. Во втором случае должна быть, такая же ситуация, но команда echo “2″ выполняется. Все дело в том, что на самом деле происходит проверка всех операторов объединения, которые участвуют в цепочке. Если команда вернула 1, а все дальнейшие операторы объединения && — то поэтому и не будет выполнена ни одна команда. Но если в цепочке встретиться оператор ||, то команда после него будет выполнена и проверка будет идти дальше.

Рассмотрим более подробно эту цепочку:

1) Выполняется команда false и возвращает код выполнения 1
2) Далее стоит оператор ||, а значит следующая команда будет выполняться
3) Выполняется команда echo “1″ и возвращает код 0
4) Далее стоит оператор ||, а значит следующая команда не будет выполнятся
5) Проверяется следующий оператор — это оператор &&, значит следующая команда (echo “2″) будет выполнена.

Посмотрите еще несколько примеров:

$ true || echo «1» && false || echo «2»
2

Источник

Читайте также:  Intel mobile graphics driver windows 10
Оцените статью