Pull to refresh
2675.18
RUVDS.com
VDS/VPS-хостинг. Скидка 15% по коду HABR15

Кунг-фу стиля Linux: делаем все и сразу

Reading time5 min
Views16K
Original author: Al Williams
Вы никогда не задумывались о том, что компьютеры чрезвычайно глупы? Даже самый мощный процессор не может много сделать. Однако он может делать то, что делает, очень быстро и повторять это много раз. Компьютеры настолько быстрые, что может казаться, что они делают много вещей одновременно, а современные компьютеры еще и имеют несколько процессоров, чтобы улучшить свои возможности по многозадачности. Мы часто не пишем программы или сценарии, чтобы воспользоваться этим. Однако, как вы сейчас поймёте, для этого нет никаких причин.



Все переводы серии
Кунг-фу стиля Linux: удобная работа с файлами по SSH
Кунг-фу стиля Linux: мониторинг дисковой подсистемы
Кунг-фу стиля Linux: глобальный поиск и замена строк с помощью ripgrep
Кунг-фу стиля Linux: упрощение работы с awk
Кунг-фу стиля Linux: наблюдение за файловой системой
Кунг-фу стиля Linux: наблюдение за файлами
Кунг-фу стиля Linux: удобный доступ к справке при работе с bash
Кунг-фу стиля Linux: великая сила make
Кунг-фу стиля Linux: устранение неполадок в работе incron
Кунг-фу стиля Linux: расшаривание терминала в браузере
Кунг-фу стиля Linux: синхронизация настроек
Кунг-фу стиля Linux: бесплатный VPN по SSH
Кунг-фу стиля Linux: превращение веб-приложений в полноценные программы
Кунг-фу стиля Linux: утилита marker и меню для командной строки
Кунг-фу стиля Linux: sudo и поворот двух ключей
Кунг-фу стиля Linux: программное управление окнами
Кунг-фу стиля Linux: организация работы программ после выхода из системы
Кунг-фу стиля Linux: регулярные выражения
Кунг-фу стиля Linux: запуск команд
Кунг-фу стиля Linux: разбираемся с последовательными портами
Кунг-фу стиля Linux: базы данных — это файловые системы нового уровня
Кунг-фу стиля Linux: о повторении кое-каких событий сетевой истории
Кунг-фу стиля Linux: PDF для пингвинов


Поддержка Bash


На удивление легко запустить несколько процессов под Bash. Прежде всего, процессы на обеих сторонах конвейера работают вместе, и это, вероятно, самый распространённый способ сценариев с использованием мультипрограммирования. Другими словами, подумайте, что произойдёт, если вы напишете ls | more.

В старой системе MSDOS первая программа выполнялась до конца, буферизуя вывод во временный файл. Затем будет запускаться вторая программа, считывающая ввод из того же файла. В Linux и большинстве других современных операционных систем, обе программы будут работать вместе с входом второй программы, соединённым с выходом первой программы.

Это легко, потому что программы синхронизируются по входному и выходному каналу. Однако, так же легко запустить несколько программ независимо друг от друга. Ключ использует "&" для разделения программ или завершения строки сценария.

Достаточно легко преобразовать сценарий вроде:

find /mnt1/usr -name '*.so' >/tmp/libs1
find /mnt2/usr -name '*.so' > /tmp/libs2
 
# to
 
find /mnt1/usr -name '*.so' >/tmp/libs1 &
find /mnt2/usr -name '*.so' > /tmp/libs2 &

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

Проблема


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

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

alw@Enterprise:~$ banner hello & banner goodbye
[1] 173
 
 
# # ###### # # ####
#### #### #### ##### ##### # # ######
# # # # # # #
# # # # # # # # # # # # #
###### ##### # # # #
# # # # # # # ##### # #####
# # # # # # #
# ### # # # # # # # # # #
# # # # # # #
# # # # # # # # # # # #
# # ###### ###### ###### ####
#### #### #### ##### ##### # ######
 
 
[1]+ Done banner hello

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

Control


Есть и другие проблемы. Возможно, вы захотите узнать PID нового процесса. Вы можете использовать bash’s job control. Однако на самом деле вам не нужно заходить так далеко. Команда jobs покажет вам, что вы исполняете в фоновом режиме из текущей оболочки. Если вы добавите -l или -p, вы также можете узнать PID.

Более простой способ узнать PID команды — использовать $!. Конечно, если вы работаете из командной строки оболочки, она также сообщает вам PID последней команды запуска. Например:

ls / & echo PID=$!
[2] 178
PID=178

Ваш номер PID почти наверняка будет другим.

Что дальше?


Вы получили PID, что же дальше с ним делать? Есть две вещи, которые вы найдёте наиболее полезными. Сперва, вы можете использовать wait, чтобы понять, когда процесс (или процессы) завершены.

Ещё вы можете использовать kill для отправки сигналов фоновой программе. Это выходит за рамки этой статьи, но вы можете использовать сигналы для создания сложной связи между программами или для вызова поведения по умолчанию, такого как завершение.

Пример


Рассмотрим случай, когда у вас есть куча файлов jpeg, и вы хотите преобразовать их в файлы png для веб-сайта с помощью ImageMagick. Вы можете попробовать этот простой скрипт:

#!/bin/bash
for I in *.jpg
do
    convert "$I" "png/$(basename "$I" .jpg).png"
done
echo Copying files now...
ls png

Это упростит работу. Предположительно, в последней строке будет следующая команда копирования файла, например sftp, однако список каталогов использовался только для примера.

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

#!/bin/bash
for I in *.jpg
do
    convert "$I" "png/$(basename "$I" .jpg).png" &
done
wait
echo Copying files now...
ls png


Всё ещё есть проблема


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

#!/bin/bash
PIDs=""
for I in *.jpg
do
    convert "$I" "png/$(basename "$I" .jpg).png" &
PIDs+="$! "
done
wait $PIDs
echo Copying files...
ls png

Если вы запустите отсчёт времени с множеством файлов, вы увидите большую разницу. На моём ноутбуке с несколькими картинками прямая версия заняла около 40 секунд. С финальной версией на это ушло чуть больше 10 секунд.

В заключении


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

Все переводы серии
Кунг-фу стиля Linux: удобная работа с файлами по SSH
Кунг-фу стиля Linux: мониторинг дисковой подсистемы
Кунг-фу стиля Linux: глобальный поиск и замена строк с помощью ripgrep
Кунг-фу стиля Linux: упрощение работы с awk
Кунг-фу стиля Linux: наблюдение за файловой системой
Кунг-фу стиля Linux: наблюдение за файлами
Кунг-фу стиля Linux: удобный доступ к справке при работе с bash
Кунг-фу стиля Linux: великая сила make
Кунг-фу стиля Linux: устранение неполадок в работе incron
Кунг-фу стиля Linux: расшаривание терминала в браузере
Кунг-фу стиля Linux: синхронизация настроек
Кунг-фу стиля Linux: бесплатный VPN по SSH
Кунг-фу стиля Linux: превращение веб-приложений в полноценные программы
Кунг-фу стиля Linux: утилита marker и меню для командной строки
Кунг-фу стиля Linux: sudo и поворот двух ключей
Кунг-фу стиля Linux: программное управление окнами
Кунг-фу стиля Linux: организация работы программ после выхода из системы
Кунг-фу стиля Linux: регулярные выражения
Кунг-фу стиля Linux: запуск команд
Кунг-фу стиля Linux: разбираемся с последовательными портами
Кунг-фу стиля Linux: базы данных — это файловые системы нового уровня
Кунг-фу стиля Linux: о повторении кое-каких событий сетевой истории
Кунг-фу стиля Linux: PDF для пингвинов

Tags:
Hubs:
Total votes 23: ↑19 and ↓4+26
Comments4

Articles

Information

Website
ruvds.com
Registered
Founded
Employees
11–30 employees
Location
Россия
Representative
ruvds