我無法重現:
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
無論如何,我相信這個測試案例是不恰當的。 當您需要一個雙向管道時(即您需要與協同處理),您需要一個協同過程。您可以使用單個數據庫 連接(數據庫連接是資源昂貴的) 並與您的查詢和shell代碼來回。
編輯(見下面的註釋)。 (與標準輸入緩衝可以圍繞 一些非標準工具先後在這種情況下,問題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
我意識到這種方法有很多缺點......
'$ {COPROC [0]}'仍然評估爲'echo hello'之後的空字符串以外的任何內容嗎? –
@單調,沒有。它是空的。 –
誰投票結束,你能解釋一下對此沒有建設性的意見嗎?如果您反對這個標題(70年代參考),改變它不那麼「幽默」。 –