1
2 #### zero args: [ ]
3 [ ] || echo false
4 ## stdout: false
5
6 #### one arg: [ x ] where x is one of '=' '!' '(' ']'
7 [ = ]
8 echo status=$?
9 [ ] ]
10 echo status=$?
11 [ '!' ]
12 echo status=$?
13 [ '(' ]
14 echo status=$?
15 ## STDOUT:
16 status=0
17 status=0
18 status=0
19 status=0
20 ## END
21
22 #### one arg: empty string is false. Equivalent to -n.
23 test 'a' && echo true
24 test '' || echo false
25 ## STDOUT:
26 true
27 false
28 ## END
29
30 #### -a as unary operator (alias of -e)
31 # NOT IMPLEMENTED FOR OSH, but could be later. See comment in core/id_kind.py.
32 [ -a / ]
33 echo status=$?
34 [ -a /nonexistent ]
35 echo status=$?
36 ## STDOUT:
37 status=0
38 status=1
39 ## END
40 ## N-I dash STDOUT:
41 status=2
42 status=2
43 ## END
44
45 #### two args: -z with = ! ( ]
46 [ -z = ]
47 echo status=$?
48 [ -z ] ]
49 echo status=$?
50 [ -z '!' ]
51 echo status=$?
52 [ -z '(' ]
53 echo status=$?
54 ## STDOUT:
55 status=1
56 status=1
57 status=1
58 status=1
59 ## END
60
61 #### three args
62 [ foo = '' ]
63 echo status=$?
64 [ foo -a '' ]
65 echo status=$?
66 [ foo -o '' ]
67 echo status=$?
68 [ ! -z foo ]
69 echo status=$?
70 [ \( foo \) ]
71 echo status=$?
72 ## STDOUT:
73 status=1
74 status=1
75 status=0
76 status=0
77 status=0
78 ## END
79
80 #### four args
81 [ ! foo = foo ]
82 echo status=$?
83 [ \( -z foo \) ]
84 echo status=$?
85 ## STDOUT:
86 status=1
87 status=1
88 ## END
89
90 #### test with extra args is syntax error
91 test -n x ]
92 echo status=$?
93 test -n x y
94 echo status=$?
95 ## STDOUT:
96 status=2
97 status=2
98 ## END
99
100 #### ] syntax errors
101 [
102 echo status=$?
103 test # not a syntax error
104 echo status=$?
105 [ -n x # missing ]
106 echo status=$?
107 [ -n x ] y # extra arg after ]
108 echo status=$?
109 [ -n x y # extra arg
110 echo status=$?
111 ## STDOUT:
112 status=2
113 status=1
114 status=2
115 status=2
116 status=2
117 ## END
118
119 #### -n
120 test -n 'a' && echo true
121 test -n '' || echo false
122 ## STDOUT:
123 true
124 false
125 ## END
126
127 #### ! -a
128 [ -z '' -a ! -z x ]
129 echo status=$?
130 ## stdout: status=0
131
132 #### -o
133 [ -z x -o ! -z x ]
134 echo status=$?
135 ## stdout: status=0
136
137 #### ( )
138 [ -z '' -a '(' ! -z x ')' ]
139 echo status=$?
140 ## stdout: status=0
141
142 #### ( ) ! -a -o with system version of [
143 command [ --version
144 command [ -z '' -a '(' ! -z x ')' ] && echo true
145 ## stdout: true
146
147 #### == is alias for =
148 [ a = a ] && echo true
149 [ a == a ] && echo true
150 ## STDOUT:
151 true
152 true
153 ## END
154 ## BUG dash STDOUT:
155 true
156 ## END
157 ## BUG dash status: 2
158
159 #### == and = does not do glob
160 [ abc = 'a*' ]
161 echo status=$?
162 [ abc == 'a*' ]
163 echo status=$?
164 ## STDOUT:
165 status=1
166 status=1
167 ## END
168 ## N-I dash STDOUT:
169 status=1
170 status=2
171 ## END
172
173 #### [ with op variable
174 # OK -- parsed AFTER evaluation of vars
175 op='='
176 [ a $op a ] && echo true
177 [ a $op b ] || echo false
178 ## status: 0
179 ## STDOUT:
180 true
181 false
182 ## END
183
184 #### [ with unquoted empty var
185 empty=''
186 [ $empty = '' ] && echo true
187 ## status: 2
188
189 #### [ compare with literal -f
190 # Hm this is the same
191 var=-f
192 [ $var = -f ] && echo true
193 [ '-f' = $var ] && echo true
194 ## STDOUT:
195 true
196 true
197 ## END
198
199 #### [ '(' foo ] is runtime syntax error
200 [ '(' foo ]
201 echo status=$?
202 ## stdout: status=2
203
204 #### -z '>' implies two token lookahead
205 [ -z ] && echo true # -z is operand
206 [ -z '>' ] || echo false # -z is operator
207 [ -z '>' -- ] && echo true # -z is operand
208 ## STDOUT:
209 true
210 false
211 true
212 ## END
213
214 #### operator/operand ambiguity with ]
215 # bash parses this as '-z' AND ']', which is true. It's a syntax error in
216 # dash/mksh.
217 [ -z -a ] ]
218 echo status=$?
219 ## stdout: status=0
220 ## OK mksh stdout: status=2
221 ## OK dash stdout: status=2
222
223 #### operator/operand ambiguity with -a
224 # bash parses it as '-z' AND '-a'. It's a syntax error in mksh but somehow a
225 # runtime error in dash.
226 [ -z -a -a ]
227 echo status=$?
228 ## stdout: status=0
229 ## OK mksh stdout: status=2
230 ## OK dash stdout: status=1
231
232 #### -d
233 test -d $TMP
234 echo status=$?
235 test -d $TMP/__nonexistent_Z_Z__
236 echo status=$?
237 ## STDOUT:
238 status=0
239 status=1
240 ## END
241
242 #### -x
243 rm -f $TMP/x
244 echo 'echo hi' > $TMP/x
245 test -x $TMP/x || echo 'no'
246 chmod +x $TMP/x
247 test -x $TMP/x && echo 'yes'
248 test -x $TMP/__nonexistent__ || echo 'bad'
249 ## STDOUT:
250 no
251 yes
252 bad
253 ## END
254
255 #### -r
256 echo '1' > $TMP/testr_yes
257 echo '2' > $TMP/testr_no
258 chmod -r $TMP/testr_no # remove read permission
259 test -r $TMP/testr_yes && echo 'yes'
260 test -r $TMP/testr_no || echo 'no'
261 ## STDOUT:
262 yes
263 no
264 ## END
265
266 #### -w
267 rm -f $TMP/testw_*
268 echo '1' > $TMP/testw_yes
269 echo '2' > $TMP/testw_no
270 chmod -w $TMP/testw_no # remove write permission
271 test -w $TMP/testw_yes && echo 'yes'
272 test -w $TMP/testw_no || echo 'no'
273 ## STDOUT:
274 yes
275 no
276 ## END
277
278 #### -k for sticky bit
279 # not isolated: /tmp usually has sticky bit on
280 # https://en.wikipedia.org/wiki/Sticky_bit
281
282 test -k /tmp
283 echo status=$?
284
285 test -k /bin
286 echo status=$?
287 ## STDOUT:
288 status=0
289 status=1
290 ## END
291
292 #### -h and -L test for symlink
293 tmp=$TMP/builtin-test-1
294 mkdir -p $tmp
295 touch $tmp/zz
296 ln -s -f $tmp/zz $tmp/symlink
297 ln -s -f $tmp/__nonexistent_ZZ__ $tmp/dangling
298 test -L $tmp/zz || echo no
299 test -h $tmp/zz || echo no
300 test -f $tmp/symlink && echo is-file
301 test -L $tmp/symlink && echo symlink
302 test -h $tmp/symlink && echo symlink
303 test -L $tmp/dangling && echo dangling
304 test -h $tmp/dangling && echo dangling
305 test -f $tmp/dangling || echo 'dangling is not file'
306 ## STDOUT:
307 no
308 no
309 is-file
310 symlink
311 symlink
312 dangling
313 dangling
314 dangling is not file
315 ## END
316
317 #### -t 1 for stdout
318 # There is no way to get a terminal in the test environment?
319 [ -t 1 ]
320 echo status=$?
321 ## stdout: status=1
322
323 #### [ -t invalid ]
324 [ -t invalid ]
325 echo status=$?
326 ## stdout: status=2
327 ## BUG bash stdout: status=1
328
329 #### -ot and -nt
330 touch -d 2017/12/31 $TMP/x
331 touch -d 2018/01/01 > $TMP/y
332 test $TMP/x -ot $TMP/y && echo 'older'
333 test $TMP/x -nt $TMP/y || echo 'not newer'
334 test $TMP/x -ot $TMP/x || echo 'not older than itself'
335 test $TMP/x -nt $TMP/x || echo 'not newer than itself'
336 ## STDOUT:
337 older
338 not newer
339 not older than itself
340 not newer than itself
341 ## END
342
343 #### [ a -eq b ]
344 [ a -eq a ]
345 echo status=$?
346 ## STDOUT:
347 status=2
348 ## END
349 ## BUG mksh STDOUT:
350 status=0
351 ## END
352
353 #### test -s
354 test -s __nonexistent
355 echo status=$?
356 touch $TMP/empty
357 test -s $TMP/empty
358 echo status=$?
359 echo nonempty > $TMP/nonempty
360 test -s $TMP/nonempty
361 echo status=$?
362 ## STDOUT:
363 status=1
364 status=1
365 status=0
366 ## END
367
368 #### test -b -c -S (block, character, socket)
369 # NOTE: we do not have the "true" case
370
371 echo -b
372 test -b nonexistent
373 echo status=$?
374 test -b testdata
375 echo status=$?
376
377 echo -c
378 test -c nonexistent
379 echo status=$?
380 test -c testdata
381 echo status=$?
382
383 echo -S
384 test -S nonexistent
385 echo status=$?
386 test -S testdata
387 echo status=$?
388
389 ## STDOUT:
390 -b
391 status=1
392 status=1
393 -c
394 status=1
395 status=1
396 -S
397 status=1
398 status=1
399 ## END
400
401
402 #### test -p named pipe
403 mkfifo $TMP/fifo
404 test -p $TMP/fifo
405 echo status=$?
406
407 test -p testdata
408 echo status=$?
409
410 ## STDOUT:
411 status=0
412 status=1
413 ## END
414
415 #### -G and -O for effective user ID and group ID
416
417 mkdir -p $TMP/bin
418
419 test -O $TMP/bin
420 echo status=$?
421 test -O __nonexistent__
422 echo status=$?
423
424 test -G $TMP/bin
425 echo status=$?
426 test -G __nonexistent__
427 echo status=$?
428
429 ## STDOUT:
430 status=0
431 status=1
432 status=0
433 status=1
434 ## END
435
436 #### -u for setuid, -g too
437
438 touch $TMP/setuid $TMP/setgid
439 chmod u+s $TMP/setuid
440 chmod g+s $TMP/setgid
441
442 test -u $TMP/setuid
443 echo status=$?
444
445 test -u $TMP/setgid
446 echo status=$?
447
448 test -g $TMP/setuid
449 echo status=$?
450
451 test -g $TMP/setgid
452 echo status=$?
453
454
455 ## STDOUT:
456 status=0
457 status=1
458 status=1
459 status=0
460 ## END
461
462 #### -v to test variable
463 test -v nonexistent
464 echo global=$?
465
466 g=1
467 test -v g
468 echo global=$?
469
470 f() {
471 local f_var=0
472 g
473 }
474
475 g() {
476 test -v f_var
477 echo dynamic=$?
478 test -v g
479 echo dynamic=$?
480 test -v nonexistent
481 echo dynamic=$?
482 }
483 f
484
485 ## STDOUT:
486 global=1
487 global=0
488 dynamic=0
489 dynamic=0
490 dynamic=1
491 ## END
492 ## N-I dash/mksh STDOUT:
493 global=2
494 global=2
495 dynamic=2
496 dynamic=2
497 dynamic=2
498 ## END
499
500
501 #### test -o for options
502 # note: it's lame that the 'false' case is confused with the 'typo' case.
503 # but checking for error code 2 is unlikely anyway.
504 test -o nounset
505 echo status=$?
506
507 set -o nounset
508 test -o nounset
509 echo status=$?
510
511 test -o _bad_name_
512 echo status=$?
513 ## STDOUT:
514 status=1
515 status=0
516 status=1
517 ## END
518 ## N-I dash STDOUT:
519 status=2
520 status=2
521 status=2
522 ## END
523
524 #### -nt -ot
525 [ present -nt absent ] || exit 1
526 [ absent -ot present ] || exit 2
527 ## status: 1
528
529 #### -ef
530 left=$TMP/left
531 right=$TMP/right
532 touch $left $right
533
534 ln -f $TMP/left $TMP/hardlink
535
536 test $left -ef $left && echo same
537 test $left -ef $TMP/hardlink && echo same
538 test $left -ef $right || echo different
539
540 test $TMP/__nonexistent -ef $right || echo different
541
542 ## STDOUT:
543 same
544 same
545 different
546 different
547 ## END
548
549 #### Overflow error
550 test -t 12345678910
551 echo status=$?
552 ## STDOUT:
553 status=2
554 ## END
555 ## OK dash/bash STDOUT:
556 status=1
557 ## END
558
559 #### Bug regression
560 test "$ipv6" = "yes" -a "$ipv6lib" != "none"
561 echo status=$?
562 ## STDOUT:
563 status=1
564 ## END