1 | #!/usr/bin/env bash
|
2 | #
|
3 | # Demo of coprocesses
|
4 | #
|
5 | # Usage:
|
6 | # ./coproc.sh <function name>
|
7 | #
|
8 | # Reference:
|
9 | # http://unix.stackexchange.com/questions/86270/how-do-you-use-the-command-coproc-in-bash
|
10 | #
|
11 | # Good observations:
|
12 | #
|
13 | # "In short, pipes aren't good for interacting with commands. Co-processes can
|
14 | # only be used to interact with commands that don't buffer their output, or
|
15 | # commands which can be told not to buffer their output; for example, by using
|
16 | # stdbuf with some commands on recent GNU or FreeBSD systems.
|
17 | #
|
18 | # That's why expect or zpty use pseudo-terminals instead. expect is a tool
|
19 | # designed for interacting with commands, and it does it well."
|
20 |
|
21 | set -o nounset
|
22 | set -o pipefail
|
23 | set -o errexit
|
24 |
|
25 | proc-tree() {
|
26 | #sleep 1 &
|
27 | echo
|
28 | pstree --ascii --arguments -p $$
|
29 |
|
30 | # Same result
|
31 | #pstree --ascii --arguments $BASHPID
|
32 | }
|
33 |
|
34 | readonly THIS_DIR=$(dirname $0)
|
35 |
|
36 | read-write() {
|
37 | local read_fd=$1
|
38 | local write_fd=$2
|
39 |
|
40 | for i in $(seq 5); do
|
41 | echo abc $i XYZ >& $write_fd
|
42 | read var <& $read_fd
|
43 | echo $var
|
44 | sleep 0.1
|
45 | done
|
46 | }
|
47 |
|
48 | simple-demo() {
|
49 | # With this syntax, there's only a single coprocess
|
50 | coproc $THIS_DIR/coproc.py
|
51 |
|
52 | proc-tree
|
53 | echo "COPROC PID: $COPROC_PID"
|
54 |
|
55 | # In ksh or zsh, the pipes to and from the co-process are accessed with >&p
|
56 | # and <&p.
|
57 | # But in bash, the file descriptors of the pipe from the co-process and the
|
58 | # other pipe to the co-process are returned in the $COPROC array
|
59 | # (respectively ${COPROC[0]} and ${COPROC[1]}.
|
60 |
|
61 | argv ${COPROC[@]}
|
62 |
|
63 | read-write "${COPROC[@]}"
|
64 | }
|
65 |
|
66 | multi-demo() {
|
67 | proc-tree
|
68 |
|
69 | coproc upper {
|
70 | $THIS_DIR/coproc.py upper
|
71 | }
|
72 | echo "upper PID: $upper_PID"
|
73 |
|
74 | proc-tree
|
75 | read-write "${upper[@]}"
|
76 |
|
77 | # Close the write end to signal we'redone
|
78 | exec {upper[1]}>&-
|
79 |
|
80 | echo '---'
|
81 |
|
82 | proc-tree
|
83 |
|
84 | coproc lower {
|
85 | $THIS_DIR/coproc.py lower
|
86 | }
|
87 | echo "lower PID: $lower_PID"
|
88 |
|
89 | proc-tree
|
90 | read-write "${lower[@]}"
|
91 |
|
92 | exec {lower[1]}>&-
|
93 | }
|
94 |
|
95 | "$@"
|