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

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