Я не могу воспроизвести:
bash-4.1 $ cat infile
one
two
three
four
five
bash-4.1 $ cat s.sh
coproc cat infile
while read -u ${COPROC[0]} v; do
echo "$v"
done
bash-4.1 $ bash -x s.sh
+ read -u 63 v
+ cat infile
+ echo one
one
+ read -u 63 v
+ echo two
two
+ read -u 63 v
+ echo three
three
+ read -u 63 v
+ echo four
four
+ read -u 63 v
+ echo five
five
+ read -u 63 v
+ echo ''
+ read -u 63 v
Редактировать: Я воспроизвел это так:
bash-4.1 $ cat s.sh
coproc cat infile
sleep 1
while read -u ${COPROC[0]} v; do
echo "$v"
done
bash-4.1 $ bash -x s.sh
+ sleep 1
+ cat infile
+ read -u v
s.sh: line 5: read: v: invalid file descriptor specification
Редактировать: см. Комментарии ниже.
Этокажется, что процесс совместной работы истекает быстро ... Может быть, ваша система работает медленно :)
Нет, команда, выполняемая как процесс совместной обработки, слишком быстрая, если вы замедлите ее, она работает:
bash-4.1 $ cat s.sh
coproc while read -r; do
printf '%s\n' "$REPLY"
sleep 1
done < infile
sleep 1
while read -u ${COPROC[0]} v; do
echo "$v"
done
bash-4.1 $ bash s.sh
one
two
three
four
five
В любом случае, я считаю, что этот контрольный пример не подходит.Вам нужен совместный процесс, когда вам нужен двусторонний канал (т. Е. Вам нужно общаться с совместным процессом).Вы можете использовать одно соединение с базой данных (соединения с базой данных требуют больших ресурсов) и переходить от одного запроса к другому и к шелл-коду.
Редактировать (см. Комментарии ниже).Проблемы, связанные с буферизацией stdin , можно обойти с помощью некоторых нестандартных инструментов (в данном случае используется stdbuf (часть последних версий GNU coreutils )., Я верю):
~/t$ cat s
coproc stdbuf -oL -i0 mysql
printf '%s;\n' 'show databases' >&${COPROC[1]}
printf '\n\nshowing databases, fisrt time ...\n\n\n'
while read -t3 -u${COPROC[0]}; do
printf '%s\n' "$REPLY"
[[ $REPLY == test ]] && {
printf '%s\n' 'test found, dropping it ...'
printf '%s;\n' 'drop database test' >&${COPROC[1]}
}
done
printf '\n\nshowing databases, second time ...\n\n\n'
printf '%s;\n' 'show databases' >&${COPROC[1]}
while read -t3 -u${COPROC[0]}; do
printf '%s\n' "$REPLY"
done
printf '%s\n' quit >&${COPROC[1]}
Вывод:
~/t$ bash s
showing databases, fisrt time ...
Database
information_schema
mysql
sakila
test
test found, dropping it ...
world
showing databases, second time ...
Database
information_schema
mysql
sakila
world
Я понимаю, что этот подход имеет много недостатков ...