1
2 #### echo keyword
3 echo done
4 ## stdout: done
5
6 #### if/else
7 if false; then
8 echo THEN
9 else
10 echo ELSE
11 fi
12 ## stdout: ELSE
13
14 #### Turn an array into an integer.
15 a=(1 2 3)
16 (( a = 42 ))
17 echo $a
18 ## stdout: 42
19 ## N-I dash/ash stdout-json: ""
20 ## N-I dash/ash status: 2
21
22
23 #### assign readonly -- one line
24 readonly x=1; x=2; echo hi
25 ## status: 1
26 ## OK dash/mksh/ash status: 2
27 ## STDOUT:
28 ## END
29
30 #### assign readonly -- multiple lines
31 readonly x=1
32 x=2
33 echo hi
34 ## status: 1
35 ## OK dash/mksh/ash status: 2
36 ## STDOUT:
37 ## END
38 ## BUG bash status: 0
39 ## BUG bash STDOUT:
40 hi
41 ## END
42
43 #### assign readonly -- multiple lines -- set -o posix
44 set -o posix
45 readonly x=1
46 x=2
47 echo hi
48 ## status: 1
49 ## OK dash/mksh/ash status: 2
50 ## STDOUT:
51 ## END
52
53 #### unset readonly -- one line
54 readonly x=1; unset x; echo hi
55 ## STDOUT:
56 hi
57 ## END
58 ## OK dash/ash status: 2
59 ## OK zsh status: 1
60 ## OK dash/ash stdout-json: ""
61 ## OK zsh stdout-json: ""
62
63 #### unset readonly -- multiple lines
64 readonly x=1
65 unset x
66 echo hi
67 ## OK dash/ash status: 2
68 ## OK zsh status: 1
69 ## OK dash/ash stdout-json: ""
70 ## OK zsh stdout-json: ""
71
72 #### First word like foo$x() and foo$[1+2] (regression)
73
74 # Problem: $x() func call broke this error message
75 foo$identity('z')
76
77 foo$[1+2]
78
79 echo DONE
80
81 ## status: 2
82 ## OK mksh/zsh status: 1
83 ## STDOUT:
84 ## END
85 ## OK osh status: 0
86 ## OK osh STDOUT:
87 DONE
88 ## END
89
90 #### Function names
91 foo$x() {
92 echo hi
93 }
94
95 foo $x() {
96 echo hi
97 }
98
99 ## status: 2
100 ## OK mksh/zsh/osh status: 1
101 ## BUG zsh status: 0
102 ## STDOUT:
103 ## END
104
105
106 #### file with NUL byte
107 echo -e 'echo one \0 echo two' > tmp.sh
108 $SH tmp.sh
109 ## STDOUT:
110 one echo two
111 ## END
112 ## OK osh STDOUT:
113 one
114 ## END
115 ## N-I dash stdout-json: ""
116 ## N-I dash status: 127
117 ## OK bash stdout-json: ""
118 ## OK bash status: 126
119 ## OK zsh stdout-json: "one \u0000echo two\n"
120
121 #### fastlex: PS1 format string that's incomplete / with NUL byte
122 case $SH in bash) exit ;; esac
123
124 x=$'\\D{%H:%M' # leave off trailing }
125 echo x=${x@P}
126
127 ## STDOUT:
128 x=\D{%H:%M
129 ## END
130
131 # bash just ignores the missing }
132 ## BUG bash stdout-json: ""
133
134 # These shells don't understand @P
135
136 ## N-I dash/ash stdout-json: ""
137 ## N-I dash/ash status: 2
138
139 ## N-I zsh stdout-json: ""
140 ## N-I zsh status: 1
141
142
143 #### 'echo' and printf to disk full
144
145 # Inspired by https://blog.sunfishcode.online/bugs-in-hello-world/
146
147 echo hi > /dev/full
148 echo status=$?
149 printf '%s\n' hi > /dev/full
150 echo status=$?
151
152 ## STDOUT:
153 status=1
154 status=1
155 ## END
156
157 #### subshell while running a script (regression)
158 # Ensures that spawning a subshell doesn't cause a seek on the file input stream
159 # representing the current script (issue #1233).
160 cat >tmp.sh <<'EOF'
161 echo start
162 (:)
163 echo end
164 EOF
165 $SH tmp.sh
166 ## STDOUT:
167 start
168 end
169 ## END
170
171 #### for loop (issue #1446)
172 case $SH in (dash|mksh|ash) exit ;; esac
173
174 for (( n=0; n<(3-(1)); n++ )) ; do echo $n; done
175
176 ## STDOUT:
177 0
178 1
179 ## END
180 ## N-I dash/mksh/ash STDOUT:
181 ## END
182
183
184
185 #### for loop 2 (issue #1446)
186 case $SH in (dash|mksh|ash) exit ;; esac
187
188
189 for (( n=0; n<(3- (1)); n++ )) ; do echo $n; done
190
191 ## STDOUT:
192 0
193 1
194 ## END
195 ## N-I dash/mksh/ash STDOUT:
196 ## END
197
198 #### autoconf word split (#1449)
199
200 mysed() {
201 for line in "$@"; do
202 echo "[$line]"
203 done
204 }
205
206 sedinputs="f1 f2"
207 sedscript='my sed command'
208
209 # Parsed and evaluated correctly: with word_part.EscapedLiteral \"
210
211 x=$(eval "mysed -n \"\$sedscript\" $sedinputs")
212 echo '--- $()'
213 echo "$x"
214
215 # With backticks, the \" gets lost somehow
216
217 x=`eval "mysed -n \"\$sedscript\" $sedinputs"`
218 echo '--- backticks'
219 echo "$x"
220
221
222 # Test it in a case statement
223
224 case `eval "mysed -n \"\$sedscript\" $sedinputs"` in
225 (*'[my sed command]'*)
226 echo 'NOT SPLIT'
227 ;;
228 esac
229
230 ## STDOUT:
231 --- $()
232 [-n]
233 [my sed command]
234 [f1]
235 [f2]
236 --- backticks
237 [-n]
238 [my sed command]
239 [f1]
240 [f2]
241 NOT SPLIT
242 ## END
243
244 #### autoconf arithmetic - relaxed eval_unsafe_arith (#1450)
245
246 as_fn_arith ()
247 {
248 as_val=$(( $* ))
249 }
250 as_fn_arith 1 + 1
251 echo $as_val
252
253 ## STDOUT:
254 2
255 ## END
256
257 #### command execution $(echo 42 | tee PWNED) not allowed
258
259 rm -f PWNED
260
261 x='a[$(echo 42 | tee PWNED)]=1'
262 echo $(( x ))
263
264 if test -f PWNED; then
265 cat PWNED
266 else
267 echo NOPE
268 fi
269
270 ## status: 1
271 ## OK dash/ash status: 2
272 ## stdout-json: ""
273 ## BUG bash/mksh/zsh status: 0
274 ## BUG bash/mksh/zsh STDOUT:
275 1
276 42
277 ## END
278
279 #### process sub <(echo 42 | tee PWNED) not allowed
280
281 rm -f PWNED
282
283 x='a[<(echo 42 | tee PWNED)]=1'
284 echo $(( x ))
285
286 if test -f PWNED; then
287 cat PWNED
288 else
289 echo NOPE
290 fi
291
292 ## status: 1
293 ## stdout-json: ""
294
295 ## OK dash/ash status: 2
296
297 # bash keeps going
298 ## BUG bash status: 0
299 ## BUG bash STDOUT:
300 NOPE
301 ## END
302
303
304 #### unset doesn't allow command execution
305
306 typeset -a a # for mksh
307 a=(42)
308 echo len=${#a[@]}
309
310 unset -v 'a[$(echo 0 | tee PWNED)]'
311 echo len=${#a[@]}
312
313 if test -f PWNED; then
314 echo PWNED
315 cat PWNED
316 else
317 echo NOPE
318 fi
319
320 ## status: 1
321 ## STDOUT:
322 len=1
323 ## END
324
325 ## N-I dash/ash status: 2
326 ## N-I dash/ash stdout-json: ""
327
328 ## BUG bash/mksh status: 0
329 ## BUG bash/mksh STDOUT:
330 len=1
331 len=0
332 PWNED
333 0
334 ## END
335
336 ## BUG zsh status: 0
337 ## BUG zsh STDOUT:
338 len=1
339 len=1
340 PWNED
341 0
342 ## END
343