Давай повелосипедим и напишем таймер на со-процессах, без использования каких-то внешних команд типа sleep и т.п.
#!/bin/bash
coproc read
read -t 0.10 -u "${COPROC[0]}"
echo 'new velosiped'
read -t 11 -u "${COPROC[0]}"
exit
- Создаем фоновый со-процесс read
- Спим 0.10 секунды
- Выводим на экран new velosiped
- Опять спим, но уже 11 секунд
- Выходим
За указания задержки, как раз отвечает параметр -t. А параметр -u говорит что чтение данных нужно осуществлять с файлового дескриптора запущенного в фоне со-процесса. Белиберда? Еще какая!
В sleep, кстати тоже можно указывать миллисекунды: sleep 0.10
Со-процессинг это одновременное выполнение двух процедур, одна из которых считывает вывод другой.
Чтобы запустить со-процесс, используется зарезервированное слово coproc. Доступ к этому со-процессу осуществляется посредством массива COPROC.
${COPROC[0]} - для чтения ${COPROC[1]} - для записи
В реализации такого таймера есть и подводные камни. Таймер может отставать как механические часы, это зависит от загруженности самой системы.
Если запустить одну команду coproc read, на экран выведется PID запущенного в фоне процесса [1] 126594. Чтобы посмотреть список запущенных в фоне команд, выполняем jobs и видим список:
[1] Running coproc COPROC read &
[2] Running coproc COPROC read &
[3] Running coproc COPROC read &
То есть получается ты запускаешь в фоне какую-то программу, а в другой программе, подключаешься через массив COPROC записываешь либо считываешь нужные тебе данные.
Еще пример:
coproc awk '{print $2;fflush();}'
echo bom bim bom >&${COPROC[1]}
read -ru ${COPROC[0]} var
echo $var
По итогу получаем вывод на экран, слово: bim
Давай попробуем попроще:
coproc (echo $(whoami))
read -r user <&"${COPROC[0]}"
echo $user
- Создаем со-процесс, который в фоне выполнит whoami
- Прочитаем в переменную user, то что вывел со-процесс
- Выводим на экран, у меня отобразилось root
Фуф, тут вроде более понятно получилось объяснить. Ну а если не понял, значит оно нахер тебе и не нужно.
Короче без бутылки тут не разобраться, это из оперы «высший пилотаж» и брейнфак.
Ну и на закуску, совсем уж упороться:
Несколько команд, которые помогут понять, как вся эта шляпа реализована.
coproc read
echo "${COPROC[@]}"
ls -l /proc/$$/fd | grep 'pipe'
ls -l /proc/$COPROC_PID/fd | grep 'pipe'
- Создаем со-процесс
- Выводим содержимое массива COPROC
- Выводим каналы текущей оболочки.
- Выводим каналы со-процесса.
Смотрим на имена, биты разрешений (r/w) ссылок и на что они указывают.
Как сказал один западный эксперт:
Вот такие пироги, изучай.








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