OILS / spec / builtin-set.test.sh View on Github | oils.pub

424 lines, 217 significant
1## compare_shells: bash dash mksh zsh
2## oils_failures_allowed: 0
3
4#### can continue after unknown option
5#
6# TODO: this is the posix special builtin logic?
7# dash and mksh make this a fatal error no matter what.
8
9set -o errexit
10set -o STRICT || true # unknown option
11echo hello
12## stdout: hello
13## status: 0
14## BUG dash/mksh/zsh stdout-json: ""
15## BUG dash status: 2
16## BUG mksh/zsh status: 1
17
18#### set with both options and argv
19set -o errexit a b c
20echo "$@"
21false
22echo done
23## stdout: a b c
24## status: 1
25
26#### nounset with "$@"
27set a b c
28set -u # shouldn't touch argv
29echo "$@"
30## stdout: a b c
31
32#### set -u -- clears argv
33set a b c
34set -u -- # shouldn't touch argv
35echo "$@"
36## stdout:
37
38#### set -u -- x y z
39set a b c
40set -u -- x y z
41echo "$@"
42## stdout: x y z
43
44#### set -u with undefined variable exits the interpreter
45
46# non-interactive
47$SH -c 'set -u; echo before; echo $x; echo after'
48if test $? -ne 0; then
49 echo OK
50fi
51
52# interactive
53$SH -i -c 'set -u; echo before; echo $x; echo after'
54if test $? -ne 0; then
55 echo OK
56fi
57
58## STDOUT:
59before
60OK
61before
62OK
63## END
64
65#### set -u with undefined var in interactive shell does NOT exit the interpreter
66
67# In bash, it aborts the LINE only. The next line is executed!
68
69# non-interactive
70$SH -c 'set -u; echo before; echo $x; echo after
71echo line2
72'
73if test $? -ne 0; then
74 echo OK
75fi
76
77# interactive
78$SH -i -c 'set -u; echo before; echo $x; echo after
79echo line2
80'
81if test $? -ne 0; then
82 echo OK
83fi
84
85## STDOUT:
86before
87OK
88before
89line2
90## END
91
92## BUG dash/mksh/zsh STDOUT:
93before
94OK
95before
96OK
97## END
98
99#### set -u error can break out of nested evals
100$SH -c '
101set -u
102test_function_2() {
103 x=$blarg
104}
105test_function() {
106 eval "test_function_2"
107}
108
109echo before
110eval test_function
111echo after
112'
113# status must be non-zero: bash uses 1, ash/dash exit 2
114if test $? -ne 0; then
115 echo OK
116fi
117
118## STDOUT:
119before
120OK
121## END
122## BUG zsh/mksh STDOUT:
123before
124after
125## END
126
127#### reset option with long flag
128set -o errexit
129set +o errexit
130echo "[$unset]"
131## stdout: []
132## status: 0
133
134#### reset option with short flag
135set -u
136set +u
137echo "[$unset]"
138## stdout: []
139## status: 0
140
141#### set -eu (flag parsing)
142set -eu
143echo "[$unset]"
144echo status=$?
145## stdout-json: ""
146## status: 1
147## OK dash status: 2
148
149#### set -o lists options
150# NOTE: osh doesn't use the same format yet.
151set -o | grep -o noexec
152## STDOUT:
153noexec
154## END
155
156#### 'set' and 'eval' round trip
157
158# NOTE: not testing arrays and associative arrays!
159_space='[ ]'
160_whitespace=$'[\t\r\n]'
161_sq="'single quotes'"
162_backslash_dq="\\ \""
163_unicode=$'[\u03bc]'
164
165# Save the variables
166varfile=$TMP/vars-$(basename $SH).txt
167
168set | grep '^_' > "$varfile"
169
170# Unset variables
171unset _space _whitespace _sq _backslash_dq _unicode
172echo [ $_space $_whitespace $_sq $_backslash_dq $_unicode ]
173
174# Restore them
175
176. $varfile
177echo "Code saved to $varfile" 1>&2 # for debugging
178
179test "$_space" = '[ ]' && echo OK
180test "$_whitespace" = $'[\t\r\n]' && echo OK
181test "$_sq" = "'single quotes'" && echo OK
182test "$_backslash_dq" = "\\ \"" && echo OK
183test "$_unicode" = $'[\u03bc]' && echo OK
184
185## STDOUT:
186[ ]
187OK
188OK
189OK
190OK
191OK
192## END
193
194## BUG zsh status: 1
195## BUG zsh STDOUT:
196[ ]
197## END
198
199#### set - - and so forth
200set a b
201echo "$@"
202
203set - a b
204echo "$@"
205
206set -- a b
207echo "$@"
208
209set - -
210echo "$@"
211
212set -- --
213echo "$@"
214
215# note: zsh is different, and yash is totally different
216## STDOUT:
217a b
218a b
219a b
220-
221--
222## END
223## N-I yash STDOUT:
224a b
225- a b
226a b
227- -
228--
229## END
230## BUG zsh STDOUT:
231a b
232a b
233a b
234
235--
236## END
237
238#### set - leading single dash is ignored, turns off xtrace verbose (#2364)
239
240show_options() {
241 case $- in
242 *v*) echo verbose-on ;;
243 esac
244 case $- in
245 *x*) echo xtrace-on ;;
246 esac
247}
248
249set -x -v
250show_options
251echo
252
253set - a b c
254echo "$@"
255show_options
256echo
257
258# dash that's not leading is not special
259set x - y z
260echo "$@"
261
262## STDOUT:
263verbose-on
264xtrace-on
265
266a b c
267
268x - y z
269## END
270
271## BUG zsh STDOUT:
272verbose-on
273xtrace-on
274
275a b c
276verbose-on
277xtrace-on
278
279x - y z
280## END
281
282#### set - stops option processing like set --
283case $SH in zsh) exit ;; esac
284
285show_options() {
286 case $- in
287 *v*) echo verbose-on ;;
288 esac
289 case $- in
290 *x*) echo xtrace-on ;;
291 esac
292}
293
294set -x - -v
295
296show_options
297echo argv "$@"
298
299## STDOUT:
300argv -v
301## END
302
303## N-I zsh STDOUT:
304## END
305
306#### A single + is an ignored flag; not an argument
307case $SH in zsh) exit ;; esac
308
309show_options() {
310 case $- in
311 *v*) echo verbose-on ;;
312 esac
313 case $- in
314 *x*) echo xtrace-on ;;
315 esac
316}
317
318set +
319echo plus "$@"
320
321set -x + -v x y
322show_options
323echo plus "$@"
324
325## STDOUT:
326plus
327verbose-on
328xtrace-on
329plus x y
330## END
331
332## BUG mksh STDOUT:
333plus
334xtrace-on
335plus -v x y
336## END
337
338## N-I zsh STDOUT:
339## END
340
341#### set - + and + -
342set - +
343echo "$@"
344
345set + -
346echo "$@"
347
348## STDOUT:
349+
350+
351## END
352
353## BUG mksh STDOUT:
354+
355-
356## END
357
358## OK zsh/osh STDOUT:
359+
360
361## END
362
363#### set -a exports variables
364set -a
365FOO=bar
366BAZ=qux
367printenv.py FOO BAZ
368## STDOUT:
369bar
370qux
371## END
372
373#### set +a stops exporting
374set -a
375FOO=exported
376set +a
377BAR=not_exported
378printenv.py FOO BAR
379## STDOUT:
380exported
381None
382## END
383
384#### set -o allexport (long form)
385set -o allexport
386VAR1=value1
387set +o allexport
388VAR2=value2
389printenv.py VAR1 VAR2
390## STDOUT:
391value1
392None
393## END
394
395#### variables set before set -a are not exported
396BEFORE=before_value
397set -a
398AFTER=after_value
399printenv.py BEFORE AFTER
400## STDOUT:
401None
402after_value
403## END
404
405#### set -a exports local variables
406set -a
407f() {
408 local ZZZ=zzz
409 printenv.py ZZZ
410}
411f
412## STDOUT:
413zzz
414## END
415## BUG mksh stdout: None
416
417#### set -a exports declare variables
418set -a
419declare ZZZ=zzz
420printenv.py ZZZ
421## STDOUT:
422zzz
423## END
424## N-I dash/mksh stdout: None