1 #!/usr/bin/env bash
2
3 #### implicit for loop
4 # This is like "for i in $@".
5 func() {
6 for i; do
7 echo $i
8 done
9 }
10 func 1 2 3
11 ## stdout-json: "1\n2\n3\n"
12
13 #### empty for loop (has "in")
14 set -- 1 2 3
15 for i in ; do
16 echo $i
17 done
18 ## stdout-json: ""
19
20 #### for loop with invalid identifier
21 # should be compile time error, but runtime error is OK too
22 for - in a b c; do
23 echo hi
24 done
25 ## stdout-json: ""
26 ## status: 2
27 ## OK bash/mksh status: 1
28 ## BUG zsh stdout: hi
29 ## BUG zsh status: 1
30
31 #### Tilde expansion within for loop
32 HOME=/home/bob
33 for name in ~/src ~/git; do
34 echo $name
35 done
36 ## stdout-json: "/home/bob/src\n/home/bob/git\n"
37
38 #### Brace Expansion within Array
39 for i in -{a,b} {c,d}-; do
40 echo $i
41 done
42 ## stdout-json: "-a\n-b\nc-\nd-\n"
43 ## N-I dash stdout-json: "-{a,b}\n{c,d}-\n"
44
45 #### using loop var outside loop
46 func() {
47 for i in a b c; do
48 echo $i
49 done
50 echo $i
51 }
52 func
53 ## status: 0
54 ## stdout-json: "a\nb\nc\nc\n"
55
56 #### continue
57 for i in a b c; do
58 echo $i
59 if test $i = b; then
60 continue
61 fi
62 echo $i
63 done
64 ## status: 0
65 ## stdout-json: "a\na\nb\nc\nc\n"
66
67 #### break
68 for i in a b c; do
69 echo $i
70 if test $i = b; then
71 break
72 fi
73 done
74 ## status: 0
75 ## stdout-json: "a\nb\n"
76
77 #### dynamic control flow (KNOWN INCOMPATIBILITY)
78 # hm would it be saner to make FATAL builtins called break/continue/etc.?
79 # On the other hand, this spits out errors loudly.
80 b=break
81 for i in 1 2 3; do
82 echo $i
83 $b
84 done
85 ## STDOUT:
86 1
87 ## END
88 ## OK osh STDOUT:
89 1
90 2
91 3
92 ## END
93 ## OK osh status: 127
94
95 #### while in while condition
96 # This is a consequence of the grammar
97 while while true; do echo cond; break; done
98 do
99 echo body
100 break
101 done
102 ## stdout-json: "cond\nbody\n"
103
104 #### while in pipe
105 x=$(find spec/ | wc -l)
106 y=$(find spec/ | while read path; do
107 echo $path
108 done | wc -l
109 )
110 test $x -eq $y
111 echo status=$?
112 ## stdout: status=0
113
114 #### while in pipe with subshell
115 i=0
116 find . -maxdepth 1 -name INSTALL.txt -o -name LICENSE.txt | ( while read path; do
117 i=$((i+1))
118 #echo $i
119 done
120 echo $i )
121 ## stdout: 2
122
123 #### until loop
124 # This is just the opposite of while? while ! cond?
125 until false; do
126 echo hi
127 break
128 done
129 ## stdout: hi
130
131 #### continue at top level
132 # zsh behaves with strict-control-flow!
133 if true; then
134 echo one
135 continue
136 echo two
137 fi
138 ## status: 0
139 ## STDOUT:
140 one
141 two
142 ## END
143 ## OK zsh status: 1
144 ## OK zsh STDOUT:
145 one
146 ## END
147
148 #### continue in subshell
149 for i in $(seq 3); do
150 echo "> $i"
151 ( if true; then continue; fi; echo "Should not print" )
152 echo ". $i"
153 done
154 ## STDOUT:
155 > 1
156 . 1
157 > 2
158 . 2
159 > 3
160 . 3
161 ## END
162 ## BUG mksh STDOUT:
163 > 1
164 Should not print
165 . 1
166 > 2
167 Should not print
168 . 2
169 > 3
170 Should not print
171 . 3
172 ## END
173
174 #### bad arg to break
175 x=oops
176 while true; do
177 echo hi
178 break $x
179 sleep 0.1
180 done
181 ## stdout: hi
182 ## status: 1
183 ## OK dash status: 2
184 ## OK bash status: 128
185
186 #### too many args to continue
187 # OSH treats this as a parse error
188 for x in a b c; do
189 echo $x
190 # bash breaks rather than continue or fatal error!!!
191 continue 1 2 3
192 done
193 echo --
194 ## stdout-json: ""
195 ## status: 2
196 ## BUG bash STDOUT:
197 a
198 --
199 ## END
200 ## OK bash status: 0
201 ## BUG dash/mksh/zsh STDOUT:
202 a
203 b
204 c
205 --
206 ## END
207 ## BUG dash/mksh/zsh status: 0