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

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