Встроенная команда bash coproc
позволяет нам запускать команду асинхронно и читать из ее выходных данных (и записывать их входные данные, если мы хотим), но есть некоторые крайние случаи чтения из каналов, которые я не понимаю.
Мы должны быть внимательны к случаю, когда сопроцесс завершается, прежде чем мы проверяем его вывод, поэтому давайте завернем его в подоболочку, которая может подождать, пока мы не прочтем:
child
#!/bin/bash
sleep 5
echo OK
родитель
#!/bin/bash
# use "read" to basically wait forever
coproc ( ./child.sh; read )
while true; do
if read -t .01 -u ${COPROC[0]} VAR; then
echo "VAR=$VAR"
break
else
echo "Waiting..."
sleep 1
fi
done
Все, кажется, хорошо. child запускается и в итоге выдает результат. parent периодически предпринимает попытку чтения с коротким тайм-аутом и ожидает сбоя.В конце концов, чтение завершается успешно, и мы заканчиваем.
За исключением: что произойдет, если read -t .01
закончится в середине чтения?Предполагается, что в man-странице происходит сбой, а все частично прочитанные данные сохраняются в VAR
.(Ради аргумента, допустим, он хранит O
.)
Что произойдет на следующей итерации цикла?
- Будем ли мыв состоянии собрать остальные данные (например,
K\n
)? - Перечитаем ли мы всю строку (
OK\n
)? - Или остальная часть этой строки потеряна??
Пишет в трубу, предположительно, с атомарной скоростью ниже определенного размера.И я думаю, они заблокируют, если будет слишком много данных, ожидающих считывания.Что произойдет, если родитель начнет чтение незадолго до того, как ребенок начнет писать?
Есть ли у нас какие-либо гарантии на то, что будет доступно для родителей
read
?
child parent
situation 1 (obvious):
1. writes
2. reads
situation 2 (obvious):
1. starts read
2. read timeout
3. writes
situation 3:
1. starts writing
2. starts read
3. read timeout?
4. finishes writing
situation 4:
1. starts writing
2. starts read
3. finishes writing
4. read timeout?
situation 5:
1. starts read
2. starts writing
3. read timeout?
4. finishes writing
situation 6:
1. starts read
2. writes
3. read timeout?