1 ## oils_failures_allowed: 0
2 ## compare_shells: bash dash mksh zsh
3
4 #
5 # Tests for pipelines.
6 # NOTE: Grammatically, ! is part of the pipeline:
7 #
8 # pipeline : pipe_sequence
9 # | Bang pipe_sequence
10
11 #### Brace group in pipeline
12 { echo one; echo two; } | tac
13 ## STDOUT:
14 two
15 one
16 ## END
17
18 #### For loop starts pipeline
19 for w in one two; do
20 echo $w
21 done | tac
22 ## STDOUT:
23 two
24 one
25 ## END
26
27 #### While Loop ends pipeline
28 seq 3 | while read i
29 do
30 echo ".$i"
31 done
32 ## STDOUT:
33 .1
34 .2
35 .3
36 ## END
37
38 #### Redirect in Pipeline
39 echo hi 1>&2 | wc -l
40 ## stdout: 0
41 ## BUG zsh stdout: 1
42
43 #### Pipeline comments
44 echo abcd | # input
45 # blank line
46 tr a-z A-Z # transform
47 ## stdout: ABCD
48
49 #### Exit code is last status
50 echo a | egrep '[0-9]+'
51 ## status: 1
52
53 #### PIPESTATUS
54 return3() {
55 return 3
56 }
57 { sleep 0.03; exit 1; } | { sleep 0.02; exit 2; } | { sleep 0.01; return3; }
58 echo ${PIPESTATUS[@]}
59 ## stdout: 1 2 3
60 ## N-I dash status: 2
61 ## N-I dash stdout-json: ""
62 ## N-I zsh status: 0
63 ## N-I zsh STDOUT:
64
65 ## END
66
67 #### PIPESTATUS is set on simple commands, but NOT in OSH
68 case $SH in dash|zsh) exit ;; esac
69
70 false
71 echo pipestatus ${PIPESTATUS[@]}
72
73 ## STDOUT:
74 pipestatus 1
75 ## END
76 ## OK osh STDOUT:
77 pipestatus
78 ## END
79 ## N-I dash/zsh STDOUT:
80 ## END
81
82 #### PIPESTATUS with shopt -s lastpipe
83 shopt -s lastpipe
84 return3() {
85 return 3
86 }
87 { sleep 0.03; exit 1; } | { sleep 0.02; exit 2; } | { sleep 0.01; return3; }
88 echo ${PIPESTATUS[@]}
89 ## stdout: 1 2 3
90 ## N-I dash status: 2
91 ## N-I dash stdout-json: ""
92 ## N-I zsh status: 0
93 ## N-I zsh STDOUT:
94
95 ## END
96
97 #### |&
98 stdout_stderr.py |& cat
99 ## STDOUT:
100 STDERR
101 STDOUT
102 ## END
103 ## status: 0
104 ## N-I dash/mksh stdout-json: ""
105 ## N-I dash status: 2
106 ## N-I osh stdout-json: ""
107 ## N-I osh status: 1
108
109 #### ! turns non-zero into zero
110 ! $SH -c 'exit 42'; echo $?
111 ## stdout: 0
112 ## status: 0
113
114 #### ! turns zero into 1
115 ! $SH -c 'exit 0'; echo $?
116 ## stdout: 1
117 ## status: 0
118
119 #### ! in if
120 if ! echo hi; then
121 echo TRUE
122 else
123 echo FALSE
124 fi
125 ## STDOUT:
126 hi
127 FALSE
128 ## END
129 ## status: 0
130
131 #### ! with ||
132 ! echo hi || echo FAILED
133 ## STDOUT:
134 hi
135 FAILED
136 ## END
137 ## status: 0
138
139 #### ! with { }
140 ! { echo 1; echo 2; } || echo FAILED
141 ## STDOUT:
142 1
143 2
144 FAILED
145 ## END
146 ## status: 0
147
148 #### ! with ( )
149 ! ( echo 1; echo 2 ) || echo FAILED
150 ## STDOUT:
151 1
152 2
153 FAILED
154 ## END
155 ## status: 0
156
157 #### ! is not a command
158 v='!'
159 $v echo hi
160 ## status: 127
161
162 #### Evaluation of argv[0] in pipeline occurs in child
163 ${cmd=echo} hi | wc -l
164 echo "cmd=$cmd"
165 ## STDOUT:
166 1
167 cmd=
168 ## END
169 ## BUG zsh STDOUT:
170 1
171 cmd=echo
172 ## END
173
174 #### bash/dash/mksh run the last command is run in its own process
175 echo hi | read line
176 echo "line=$line"
177 ## stdout: line=hi
178 ## OK bash/dash/mksh stdout: line=
179
180 #### shopt -s lastpipe (always on in OSH)
181 shopt -s lastpipe
182 echo hi | read line
183 echo "line=$line"
184 ## stdout: line=hi
185 ## N-I dash/mksh stdout: line=
186
187 #### shopt -s lastpipe (always on in OSH)
188 shopt -s lastpipe
189 i=0
190 seq 3 | while read line; do
191 (( i++ ))
192 done
193 echo i=$i
194 ## stdout: i=3
195 ## N-I dash/mksh stdout: i=0
196
197
198 #### SIGPIPE causes pipeline to die (regression for issue #295)
199 cat /dev/urandom | sleep 0.1
200 echo ${PIPESTATUS[@]}
201
202 # hm bash gives '1 0' which seems wrong
203
204 ## STDOUT:
205 141 0
206 ## END
207 ## BUG bash STDOUT:
208 1 0
209 ## END
210 ## N-I zsh stdout:
211 ## N-I dash status: 2
212 ## N-I dash stdout-json: ""
213
214 #### Nested pipelines
215 { sleep 0.1 | seq 3; } | cat
216 { sleep 0.1 | seq 10; } | { cat | cat; } | wc -l
217 ## STDOUT:
218 1
219 2
220 3
221 10
222 ## END
223
224 #### Pipeline in eval
225 ls /dev/null | eval 'cat | cat' | wc -l
226 ## STDOUT:
227 1
228 ## END
229
230
231 #### shopt -s lastpipe and shopt -s no_last_fork interaction
232
233 case $SH in dash) exit ;; esac
234
235 $SH -c '
236 shopt -s lastpipe
237 set -o errexit
238 set -o pipefail
239
240 ls | false | wc -l'
241 echo status=$?
242
243 # Why does this give status 0? It should fail
244
245 $SH -c '
246 shopt -s lastpipe
247 shopt -s no_fork_last # OSH only
248 set -o errexit
249 set -o pipefail
250
251 ls | false | wc -l'
252 echo status=$?
253
254 ## STDOUT:
255 0
256 status=1
257 0
258 status=1
259 ## END
260
261 ## N-I dash STDOUT:
262 ## END