1
2 #### Process sub input
3 f=_tmp/process-sub.txt
4 { echo 1; echo 2; echo 3; } > $f
5 cat <(head -n 2 $f) <(tail -n 2 $f)
6 ## STDOUT:
7 1
8 2
9 2
10 3
11 ## END
12
13 #### Process sub from external process to stdin
14 seq 3 > >(tac)
15 ## STDOUT:
16 3
17 2
18 1
19 ## END
20
21 #### Process sub from shell to stdin
22 { echo 1; echo 2; echo 3; } > >(tac)
23 ## STDOUT:
24 3
25 2
26 1
27 ## END
28
29 #### Non-linear pipeline with >()
30 stdout_stderr() {
31 echo o1
32 echo o2
33
34 sleep 0.1 # Does not change order
35
36 { echo e1;
37 echo warning: e2
38 echo e3;
39 } >& 2
40 }
41 stdout_stderr 2> >(grep warning) | tac >$TMP/out.txt
42 wait $! # this does nothing in bash 4.3, but probably does in bash 4.4.
43 echo OUT
44 cat $TMP/out.txt
45 # PROBLEM -- OUT comes first, and then 'warning: e2', and then 'o2 o1'. It
46 # looks like it's because nobody waits for the proc sub.
47 # http://lists.gnu.org/archive/html/help-bash/2017-06/msg00018.html
48 ## STDOUT:
49 OUT
50 warning: e2
51 o2
52 o1
53 ## END
54
55 #### $(<file) idiom with process sub
56 echo FOO >foo
57
58 # works in bash and zsh
59 echo $(<foo)
60
61 # this works in zsh, but not in bash
62 tr A-Z a-z < <(<foo)
63
64 cat < <(<foo; echo hi)
65
66 ## STDOUT:
67 FOO
68 hi
69 ## END
70 ## OK zsh STDOUT:
71 FOO
72 foo
73 FOO
74 hi
75 ## END
76
77 #### status code is available
78 cat <(seq 2; exit 2) <(seq 3; exit 3)
79 echo status=${_process_sub_status[@]}
80 echo done
81
82 ## STDOUT:
83 1
84 2
85 1
86 2
87 3
88 status=2 3
89 done
90 ## END
91 ## N-I bash/zsh STDOUT:
92 1
93 2
94 1
95 2
96 3
97 status=
98 done
99 ## END
100
101 #### shopt -s process_sub_fail
102
103 cat <(echo a; exit 2) <(echo b; exit 3)
104 echo status=$? ps=${_process_sub_status[@]}
105
106 echo __
107 shopt -s process_sub_fail
108
109 cat <(echo a; exit 2) <(echo b; exit 3)
110 echo status=$? ps=${_process_sub_status[@]}
111
112 # Now exit because of it
113 set -o errexit
114
115 cat <(echo a; exit 2) <(echo b; exit 3)
116 echo status=$? ps=${_process_sub_status[@]}
117
118 ## status: 3
119 ## STDOUT:
120 a
121 b
122 status=0 ps=2 3
123 __
124 a
125 b
126 status=3 ps=2 3
127 a
128 b
129 ## END
130 ## N-I bash/zsh status: 0
131 ## N-I bash/zsh STDOUT:
132 a
133 b
134 status=0 ps=
135 __
136 a
137 b
138 status=0 ps=
139 a
140 b
141 status=0 ps=
142 ## END
143
144 #### process subs and pipelines together
145
146 # zsh is very similar to bash, but don't bother with the assertions
147 case $SH in (zsh) exit ;; esac
148
149
150 f() {
151 cat <(seq 1; exit 1) | {
152 cat <(seq 2; exit 2) <(seq 3; exit 3)
153 (exit 4)
154 }
155 echo status=$?
156 echo process_sub=${_process_sub_status[@]}
157 echo pipeline=${_pipeline_status[@]}
158 echo __
159 }
160
161 f
162
163 ## STDOUT:
164 1
165 2
166 1
167 2
168 3
169 status=4
170 process_sub=2 3
171 pipeline=0 4
172 __
173 ## END
174 ## N-I bash STDOUT:
175 1
176 2
177 1
178 2
179 3
180 status=4
181 process_sub=
182 pipeline=
183 __
184 ## END
185 ## N-I zsh stdout-json: ""
186
187
188 #### process sub in background &
189
190 cat <(seq 3; sleep 0.1) & wait
191
192 echo sync
193
194 # This one escapes, and the shell should still exit
195 cat <(sleep 0.1) &
196
197 echo fork
198
199 ## STDOUT:
200 1
201 2
202 3
203 sync
204 fork
205 ## END