1 ## oils_failures_allowed: 1
2 ## compare_shells: bash dash mksh
3
4 # Test numbers bigger than 255 (2^8 - 1) and bigger than 2^31 - 1
5 # Shells differ in their behavior here. bash silently converts.
6
7 # I think we should implement the "unstrict" but deterministic bash behavior
8 # for compatibility, and then add shopt -s strict_status if we need it.
9
10 #### Truncating 'exit' status
11
12 $SH -c 'exit 255'
13 echo status=$?
14
15 $SH -c 'exit 256'
16 echo status=$?
17
18 $SH -c 'exit 257'
19 echo status=$?
20
21 echo ===
22
23 $SH -c 'exit -1'
24 echo status=$?
25
26 $SH -c 'exit -2'
27 echo status=$?
28
29 ## STDOUT:
30 status=255
31 status=0
32 status=1
33 ===
34 status=255
35 status=254
36 ## END
37 ## OK dash STDOUT:
38 status=255
39 status=0
40 status=1
41 ===
42 status=2
43 status=2
44 ## END
45
46 #### Truncating 'return' status
47 f() { return 255; }; f
48 echo status=$?
49
50 f() { return 256; }; f
51 echo status=$?
52
53 f() { return 257; }; f
54 echo status=$?
55
56 echo ===
57
58 f() { return -1; }; f
59 echo status=$?
60
61 f() { return -2; }; f
62 echo status=$?
63
64 ## STDOUT:
65 status=255
66 status=0
67 status=1
68 ===
69 status=255
70 status=254
71 ## END
72
73 # dash aborts on bad exit code
74 ## OK dash status: 2
75 ## OK dash STDOUT:
76 status=255
77 status=256
78 status=257
79 ===
80 ## END
81
82
83 #### subshell OverflowError https://github.com/oilshell/oil/issues/996
84
85 # We have to capture stderr here
86
87 filter_err() {
88 # check for bash/dash/mksh messages, and unwanted Python OverflowError
89 egrep -o 'Illegal number|bad number|return: can only|expected a small integer|OverflowError'
90 return 0
91 }
92
93 # true; disables subshell optimization!
94
95 # exit status too big, but integer isn't
96 $SH -c 'true; ( return 2147483647; )' 2>err.txt
97 echo status=$?
98 cat err.txt | filter_err
99
100 # now integer is too big
101 $SH -c 'true; ( return 2147483648; )' 2> err.txt
102 echo status=$?
103 cat err.txt | filter_err
104
105 # even bigger
106 $SH -c 'true; ( return 2147483649; )' 2> err.txt
107 echo status=$?
108 cat err.txt | filter_err
109
110 echo
111 echo '--- negative ---'
112
113 # negative vlaues
114 $SH -c 'true; ( return -2147483648; )' 2>err.txt
115 echo status=$?
116 cat err.txt | filter_err
117
118 # negative vlaues
119 $SH -c 'true; ( return -2147483649; )' 2>err.txt
120 echo status=$?
121 cat err.txt | filter_err
122
123 ## STDOUT:
124 ## END
125
126 # osh-cpp checks overflow, but osh-py doesn't
127
128 ## STDOUT:
129 status=255
130 status=1
131 expected a small integer
132 status=1
133 expected a small integer
134
135 --- negative ---
136 status=0
137 status=1
138 expected a small integer
139 ## END
140
141 # mksh behaves similarly, uses '1' as its "bad status" status!
142
143 ## OK mksh STDOUT:
144 status=255
145 status=1
146 bad number
147 status=1
148 bad number
149
150 --- negative ---
151 status=0
152 status=1
153 bad number
154 ## END
155
156 # dash is similar, but seems to reject negative numbers
157
158 ## OK dash STDOUT:
159 status=255
160 status=2
161 Illegal number
162 status=2
163 Illegal number
164
165 --- negative ---
166 status=2
167 Illegal number
168 status=2
169 Illegal number
170 ## END
171
172 # bash disallows return at top level
173 ## OK bash STDOUT:
174 status=2
175 return: can only
176 status=2
177 return: can only
178 status=2
179 return: can only
180
181 --- negative ---
182 status=2
183 return: can only
184 status=2
185 return: can only
186 ## END
187
188
189 #### func subshell OverflowError https://github.com/oilshell/oil/issues/996
190
191 # We have to capture stderr here
192
193 filter_err() {
194 # check for bash/dash/mksh messages, and unwanted Python OverflowError
195 egrep -o 'Illegal number|bad number|return: can only|expected a small integer|OverflowError'
196 return 0
197 }
198
199 # exit status too big, but integer isn't
200 $SH -c 'f() ( return 2147483647; ); f' 2>err.txt
201 echo status=$?
202 cat err.txt | filter_err
203
204 # now integer is too big
205 $SH -c 'f() ( return 2147483648; ); f' 2> err.txt
206 echo status=$?
207 cat err.txt | filter_err
208
209 # even bigger
210 $SH -c 'f() ( return 2147483649; ); f' 2> err.txt
211 echo status=$?
212 cat err.txt | filter_err
213
214 ## STDOUT:
215 status=255
216 status=1
217 expected a small integer
218 status=1
219 expected a small integer
220 ## END
221
222 ## OK dash STDOUT:
223 status=255
224 status=2
225 Illegal number
226 status=2
227 Illegal number
228 ## END
229
230 # bash truncates it to 0 here, I guess it's using 64 bit integers
231 ## OK bash STDOUT:
232 status=255
233 status=0
234 status=1
235 ## END
236
237 ## OK mksh STDOUT:
238 status=255
239 status=1
240 bad number
241 status=1
242 bad number
243 ## END
244
245
246 # Weird case from bash-help mailing list.
247 #
248 # "Evaluations of backticks in if statements". It doesn't relate to if
249 # statements but to $?, since && and || behave the same way.
250
251 # POSIX has a special rule for this. In OSH strict_argv is preferred so it
252 # becomes a moot point. I think this is an artifact of the
253 # "stateful"/imperative nature of $? -- it can be "left over" from a prior
254 # command, and sometimes the prior argv is []. OSH has a more "functional"
255 # implementation so it doesn't have this weirdness.
256
257 #### If empty command
258 if ''; then echo TRUE; else echo FALSE; fi
259 ## stdout: FALSE
260 ## status: 0
261
262 #### If subshell true
263 if `true`; then echo TRUE; else echo FALSE; fi
264 ## stdout: TRUE
265 ## status: 0
266
267 #### If subshell true WITH OUTPUT is different
268 if `sh -c 'echo X; true'`; then echo TRUE; else echo FALSE; fi
269 ## stdout: FALSE
270 ## status: 0
271
272 #### If subshell true WITH ARGUMENT
273 if `true` X; then echo TRUE; else echo FALSE; fi
274 ## stdout: FALSE
275 ## status: 0
276
277 #### If subshell false -- exit code is propagated in a weird way (strict_argv prevents)
278 if `false`; then echo TRUE; else echo FALSE; fi
279 ## stdout: FALSE
280 ## status: 0