1 | ## compare_shells: dash bash-4.4 mksh
|
2 |
|
3 |
|
4 | # In this file:
|
5 | #
|
6 | # - strict_control-flow: break/continue at the top level should be fatal!
|
7 | #
|
8 | # Other tests:
|
9 | # - spec/errexit-strict: command subs inherit errexit
|
10 | # - TODO: does bash 4.4. use inherit_errexit?
|
11 | #
|
12 | # - spec/var-op-other tests strict_word-eval (negative indices and invalid
|
13 | # utf-8)
|
14 | # - hm I think these should be the default? compat-word-eval?
|
15 | #
|
16 | # - spec/arith tests strict_arith - invalid strings become 0
|
17 | # - OSH has a warning that can turn into an error. I think the error could
|
18 | # be the default (since this was a side effect of "ShellMathShock")
|
19 |
|
20 | # - strict_array: unimplemented.
|
21 | # - WAS undef[2]=x, but bash-completion relied on the associative array
|
22 | # version of that.
|
23 | # - TODO: It should disable decay_array EVERYWHERE except a specific case like:
|
24 | # - s="${a[*]}" # quoted, the unquoted ones glob in a command context
|
25 | # - spec/dbracket has array comparison relevant to the case below
|
26 | #
|
27 | # Most of those options could be compat-*.
|
28 | #
|
29 | # One that can't: strict_scope disables dynamic scope.
|
30 |
|
31 |
|
32 | #### strict_arith option
|
33 | shopt -s strict_arith
|
34 | ## status: 0
|
35 | ## N-I bash status: 1
|
36 | ## N-I dash/mksh status: 127
|
37 |
|
38 | #### Sourcing a script that returns at the top level
|
39 | echo one
|
40 | . $REPO_ROOT/spec/testdata/return-helper.sh
|
41 | echo $?
|
42 | echo two
|
43 | ## STDOUT:
|
44 | one
|
45 | return-helper.sh
|
46 | 42
|
47 | two
|
48 | ## END
|
49 |
|
50 | #### top level control flow
|
51 | $SH $REPO_ROOT/spec/testdata/top-level-control-flow.sh
|
52 | ## status: 0
|
53 | ## STDOUT:
|
54 | SUBSHELL
|
55 | BREAK
|
56 | CONTINUE
|
57 | RETURN
|
58 | ## OK bash STDOUT:
|
59 | SUBSHELL
|
60 | BREAK
|
61 | CONTINUE
|
62 | RETURN
|
63 | DONE
|
64 | ## END
|
65 |
|
66 | #### errexit and top-level control flow
|
67 | $SH -o errexit $REPO_ROOT/spec/testdata/top-level-control-flow.sh
|
68 | ## status: 2
|
69 | ## OK bash status: 1
|
70 | ## STDOUT:
|
71 | SUBSHELL
|
72 | ## END
|
73 |
|
74 | #### shopt -s strict_control_flow
|
75 | shopt -s strict_control_flow || true
|
76 | echo break
|
77 | break
|
78 | echo hi
|
79 | ## STDOUT:
|
80 | break
|
81 | ## END
|
82 | ## status: 1
|
83 | ## N-I dash/bash/mksh STDOUT:
|
84 | break
|
85 | hi
|
86 | # END
|
87 | ## N-I dash/bash/mksh status: 0
|
88 |
|
89 | #### return at top level is an error
|
90 | return
|
91 | echo "status=$?"
|
92 | ## stdout-json: ""
|
93 | ## OK bash STDOUT:
|
94 | status=1
|
95 | ## END
|
96 |
|
97 | #### continue at top level is NOT an error
|
98 | # NOTE: bash and mksh both print warnings, but don't exit with an error.
|
99 | continue
|
100 | echo status=$?
|
101 | ## stdout: status=0
|
102 |
|
103 | #### break at top level is NOT an error
|
104 | break
|
105 | echo status=$?
|
106 | ## stdout: status=0
|
107 |
|
108 | #### empty argv WITHOUT strict_argv
|
109 | x=''
|
110 | $x
|
111 | echo status=$?
|
112 |
|
113 | if $x; then
|
114 | echo VarSub
|
115 | fi
|
116 |
|
117 | if $(echo foo >/dev/null); then
|
118 | echo CommandSub
|
119 | fi
|
120 |
|
121 | if "$x"; then
|
122 | echo VarSub
|
123 | else
|
124 | echo VarSub FAILED
|
125 | fi
|
126 |
|
127 | if "$(echo foo >/dev/null)"; then
|
128 | echo CommandSub
|
129 | else
|
130 | echo CommandSub FAILED
|
131 | fi
|
132 |
|
133 | ## STDOUT:
|
134 | status=0
|
135 | VarSub
|
136 | CommandSub
|
137 | VarSub FAILED
|
138 | CommandSub FAILED
|
139 | ## END
|
140 |
|
141 | #### empty argv WITH strict_argv
|
142 | shopt -s strict_argv || true
|
143 | echo empty
|
144 | x=''
|
145 | $x
|
146 | echo status=$?
|
147 | ## status: 1
|
148 | ## STDOUT:
|
149 | empty
|
150 | ## END
|
151 | ## N-I dash/bash/mksh status: 0
|
152 | ## N-I dash/bash/mksh STDOUT:
|
153 | empty
|
154 | status=0
|
155 | ## END
|
156 |
|
157 | #### Arrays are incorrectly compared, but strict_array prevents it
|
158 |
|
159 | # NOTE: from spec/dbracket has a test case like this
|
160 | # sane-array should turn this ON.
|
161 | # bash and mksh allow this because of decay
|
162 |
|
163 | a=('a b' 'c d')
|
164 | b=('a' 'b' 'c' 'd')
|
165 | echo ${#a[@]}
|
166 | echo ${#b[@]}
|
167 | [[ "${a[@]}" == "${b[@]}" ]] && echo EQUAL
|
168 |
|
169 | shopt -s strict_array || true
|
170 | [[ "${a[@]}" == "${b[@]}" ]] && echo EQUAL
|
171 |
|
172 | ## status: 1
|
173 | ## STDOUT:
|
174 | 2
|
175 | 4
|
176 | EQUAL
|
177 | ## END
|
178 | ## OK bash/mksh status: 0
|
179 | ## OK bash/mksh STDOUT:
|
180 | 2
|
181 | 4
|
182 | EQUAL
|
183 | EQUAL
|
184 | ## END
|
185 | ## N-I dash status: 2
|
186 | ## N-I dash stdout-json: ""
|
187 |
|
188 | #### automatically creating arrays WITHOUT strict_array
|
189 | undef[2]=x
|
190 | undef[3]=y
|
191 | argv.py "${undef[@]}"
|
192 | ## STDOUT:
|
193 | ['x', 'y']
|
194 | ## END
|
195 | ## N-I dash status: 2
|
196 | ## N-I dash stdout-json: ""
|
197 |
|
198 | #### automatically creating arrays are INDEXED, not associative
|
199 | shopt -u strict_arith || true
|
200 |
|
201 | undef[2]=x
|
202 | undef[3]=y
|
203 | x='bad'
|
204 | # bad gets coerced to zero, but this is part of the RECURSIVE arithmetic
|
205 | # behavior, which we want to disallow. Consider disallowing in OSH.
|
206 |
|
207 | undef[$x]=zzz
|
208 | argv.py "${undef[@]}"
|
209 | ## STDOUT:
|
210 | ['zzz', 'x', 'y']
|
211 | ## END
|
212 | ## N-I dash status: 2
|
213 | ## N-I dash stdout-json: ""
|
214 |
|
215 | #### simple_eval_builtin
|
216 | for i in 1 2; do
|
217 | eval # zero args
|
218 | echo status=$?
|
219 | eval echo one
|
220 | echo status=$?
|
221 | eval 'echo two'
|
222 | echo status=$?
|
223 | shopt -s simple_eval_builtin
|
224 | echo ---
|
225 | done
|
226 | ## STDOUT:
|
227 | status=0
|
228 | one
|
229 | status=0
|
230 | two
|
231 | status=0
|
232 | ---
|
233 | status=2
|
234 | status=2
|
235 | two
|
236 | status=0
|
237 | ---
|
238 | ## END
|
239 | ## N-I dash/bash/mksh STDOUT:
|
240 | status=0
|
241 | one
|
242 | status=0
|
243 | two
|
244 | status=0
|
245 | ---
|
246 | status=0
|
247 | one
|
248 | status=0
|
249 | two
|
250 | status=0
|
251 | ---
|
252 | ## END
|
253 |
|
254 |
|
255 | #### strict_parse_slice means you need explicit length
|
256 | case $SH in bash*|dash|mksh) exit ;; esac
|
257 |
|
258 | $SH -c '
|
259 | a=(1 2 3); echo /${a[@]::}/
|
260 | '
|
261 | echo status=$?
|
262 |
|
263 | $SH -c '
|
264 | shopt --set strict_parse_slice
|
265 |
|
266 | a=(1 2 3); echo /${a[@]::}/
|
267 | '
|
268 | echo status=$?
|
269 |
|
270 | ## STDOUT:
|
271 | //
|
272 | status=0
|
273 | status=2
|
274 | ## END
|
275 |
|
276 | ## N-I bash/dash/mksh STDOUT:
|
277 | ## END
|