再現できません:
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
Anyway, I believe that this test case is not appropriate.
You need a co-process when you need a two-way pipe (i.e. you
need to chat with the co-process). You can use a single database
connection (the database connections are resource expensive)
and go back and forth with your queries and shell code.
Edit (see comments below).
The issues related to the stdin buffering could be worked around
with some non standard tools (in this case stdbuf is used (part of recent versions of the GNU coreutils, I believe):
~/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]}
Output:
~/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
I realize this approach has many drawbacks ...