1 #### benchmark.fact5.test
2 fact() {
3 n=$1
4 if [ "$n" -le 0 ]
5 then echo 1
6 else echo $((n * $(fact $(($n-1)) ) ))
7 fi
8 }
9
10 fact 5
11
12 timing=$(times | head -n 1)
13 minutes=$(echo $timing | sed 's/\([0-9]*\)m\([0-9]*\).\([0-9]*\)s.*/\1/')
14 seconds=$(echo $timing | sed 's/\([0-9]*\)m\([0-9]*\).\([0-9]*\)s.*/\2/')
15 fractional=$(echo $timing | sed 's/\([0-9]*\)m\([0-9]*\).\([0-9]*\)s.*/\3/')
16
17 [ "$minutes" -eq 0 ] && [ "$seconds" -eq 0 ] && [ 1"$fractional" -lt 1001000 ]
18
19 ## STDOUT:
20 120
21 ## END
22
23 #### benchmark.while.test
24 x=0
25 while [ $x -lt 500 ]
26 do
27 : $((x+=1))
28 done
29 echo $x
30
31 timing=$(times | head -n 1)
32 minutes=$(echo $timing | sed 's/\([0-9]*\)m\([0-9]*\).\([0-9]*\)s.*/\1/')
33 seconds=$(echo $timing | sed 's/\([0-9]*\)m\([0-9]*\).\([0-9]*\)s.*/\2/')
34 fractional=$(echo $timing | sed 's/\([0-9]*\)m\([0-9]*\).\([0-9]*\)s.*/\3/')
35
36 [ "$minutes" -eq 0 ] && [ "$seconds" -eq 0 ] && [ 1"$fractional" -lt 1001000 ]
37
38
39 ## STDOUT:
40 500
41 ## END
42
43 #### builtin.alias.empty.test
44 set -e
45
46 alias empty=''
47 empty
48
49 ## stdout-json: ""
50
51 #### builtin.break.lexical.test
52 brk() { break 5 2>/dev/null; echo post; }
53 i=0; while [ $i -lt 5 ]; do echo $i; brk; : $((i+=1)); done
54 ## STDOUT:
55 0
56 post
57 1
58 post
59 2
60 post
61 3
62 post
63 4
64 post
65 ## END
66
67 #### builtin.break.nonlexical.test
68 set -o nonlexicalctrl 2>/dev/null
69 brk() { break 5 2>/dev/null; echo post; }
70 i=0; while [ $i -lt 5 ]; do echo $i; brk; : $((i+=1)); done
71 ## STDOUT:
72 0
73 ## END
74
75 #### builtin.cd.pwd.test
76 pwd -P # resolve physical PWD
77 orig=$(pwd)
78 echo $orig $PWD
79 [ "$orig" = "$PWD" ] || exit 1
80 mkdir inner
81 cd inner
82 [ "$orig"/inner = "$PWD" ] || exit 2
83 [ $(pwd) = "$PWD" ] || exit 3
84 cd ..
85 [ "$orig" = "$PWD" ] || exit 4
86 [ $(pwd) = "$PWD" ] || exit 5
87
88
89 #### builtin.command.ec.test
90 false
91 command -V alias >/dev/null
92 ec=$?
93 echo $ec
94 [ $ec -eq 0 ] || exit 1
95 false
96 x=$(command -V alias)
97 ec=$?
98 echo $ec
99 [ $ec -eq 0 ] || exit 2
100 command -V nonesuch >/dev/null && exit 3
101 exit 0
102 ## STDOUT:
103 0
104 0
105 ## END
106
107 #### builtin.command.exec.test
108 echo hi >file
109 command exec 8<file
110 read msg <&8
111 echo $msg
112 ## STDOUT:
113 hi
114 ## END
115
116 #### builtin.command.keyword.test
117 # ADDTOPOSIX
118 set -e
119 command -v !
120 command -v while
121 command -V while >/dev/null 2>&1
122 type do >/dev/null 2>&1
123 ## STDOUT:
124 !
125 while
126 ## END
127
128 #### builtin.command.nospecial.test
129 command readonly x=foo
130 command readonly x=bar
131 echo ?=$?
132
133 ## STDOUT:
134 ?=1
135 ## END
136
137 #### builtin.command.special.assign.test
138 unset x
139 x=whoops command :
140 echo ${x-unset}
141 ## STDOUT:
142 unset
143 ## END
144
145 #### builtin.continue.lexical.test
146 cnt() { continue 5 2>/dev/null; echo post; }
147 i=0; while [ $i -lt 5 ]; do echo $i; : $((i+=1)); cnt; echo after; done
148 ## STDOUT:
149 0
150 post
151 after
152 1
153 post
154 after
155 2
156 post
157 after
158 3
159 post
160 after
161 4
162 post
163 after
164 ## END
165
166 #### builtin.continue.nonlexical.test
167 set -o nonlexicalctrl 2>/dev/null
168 cnt() { continue 2>/dev/null; echo post; }
169 i=0; while [ $i -lt 5 ]; do echo $i; : $((i+=1)); cnt; echo after; done
170 ## STDOUT:
171 0
172 1
173 2
174 3
175 4
176 ## END
177
178 #### builtin.dot.break.test
179 echo break >scr
180 for x in a b c
181 do
182 echo $x
183 . ./scr
184 done
185 ## STDOUT:
186 a
187 b
188 c
189 ## END
190
191 #### builtin.dot.nonexistent.test
192 . ./nonesuch
193
194 ## status: 1
195 ## stdout-json: ""
196
197 #### builtin.dot.path.test
198 set -e
199
200 # manual cleanup to avoid prompt
201 mkdir p1 p2
202 trap 'rm -rf p1 p2' EXIT
203
204 cat >scr1 <<EOF
205 PATH="$(pwd)/p1:$(pwd)/p2:$PATH"
206 . scr2
207 EOF
208
209 echo 'echo nope' >p1/scr2
210 echo 'echo yep' >p2/scr2
211
212 chmod -f 333 p1/scr2
213 chmod -f 444 p2/scr2
214
215 $TEST_SHELL scr1
216
217
218 ## STDOUT:
219 yep
220 ## END
221
222 #### builtin.dot.return.test
223 cat >scr <<EOF
224 echo always
225 (exit 47)
226 return
227 echo never
228 EOF
229 . ./scr
230 [ $? -eq 47 ] || exit 1
231 echo done
232 ## STDOUT:
233 always
234 done
235 ## END
236
237 #### builtin.dot.unreadable.test
238 set -e
239
240 echo echo yes >weird
241 . ./weird
242
243 echo echo no >weird
244 chmod a-r weird
245 ! $TEST_SHELL -c '. ./weird'
246 rm -f weird
247 echo done
248 ## STDOUT:
249 yes
250 done
251 ## END
252
253 #### builtin.eval.break.test
254 for x in a b c; do echo $x; eval break; done
255
256 ## STDOUT:
257 a
258 ## END
259
260 #### builtin.eval.test
261 echo starting
262 eval echo hi
263 echo nice
264 eval "x=bye"
265 echo $x
266
267
268 ## STDOUT:
269 starting
270 hi
271 nice
272 bye
273 ## END
274
275 #### builtin.exec.badredir.test
276 exec 9&<-
277
278 ## status: 1
279 ## stdout-json: ""
280
281 #### builtin.exec.modernish.mkfifo.loop.test
282 [ -e pipe ] && rm pipe
283 mkfifo pipe
284 ( echo hello >&8 ) 8>pipe &
285 command exec 8<pipe
286 read -r line <&8 ; echo $?
287 echo read [${line-UNSET}]
288 ## STDOUT:
289 0
290 read [hello]
291 ## END
292
293 #### builtin.exec.noargs.ec.test
294 false || command exec
295 echo ok
296
297 ## STDOUT:
298 ok
299 ## END
300
301 #### builtin.exec.true.test
302 exec true
303 false
304
305
306 #### builtin.exit0.test
307 exit 0
308
309
310 #### builtin.export.override.test
311 unset x
312 $TEST_UTIL/getenv x
313 x=4
314 $TEST_UTIL/getenv x
315 export x=5
316 $TEST_UTIL/getenv x
317 x=6 $TEST_UTIL/getenv x
318 echo x is ${x-unset}
319
320 ## STDOUT:
321 x is unset
322 x is unset
323 x='5'
324 x='6'
325 x is 5
326 ## END
327
328 #### builtin.export.test
329 cat >scr <<'EOF'
330 echo ${var-unset}
331 EOF
332 $TEST_SHELL scr
333 var=hi
334 $TEST_SHELL scr
335 var=here $TEST_SHELL scr
336 export var=bye
337 $TEST_SHELL scr
338
339 ## STDOUT:
340 unset
341 unset
342 here
343 bye
344 ## END
345
346 #### builtin.export.unset.test
347 set -e
348 unset x
349 export x
350 export -p | grep 'export x'
351 echo ok
352 ## STDOUT:
353 export x
354 ok
355 ## END
356
357 #### builtin.falsetrue.test
358 false || true
359
360
361 #### builtin.jobs.test
362 sleep 10 & pid=$!
363 sleep 1
364 jobs >job_info
365 grep "sleep 10" job_info >/dev/null || exit 1
366 grep "[1]" job_info >/dev/null || exit 2
367 kill $pid
368
369 rm job_info
370 unset j pid
371
372 sleep 10 & pid=$!
373 sleep 1
374 jobs -l >job_info
375 grep "sleep 10" job_info >/dev/null || exit 3
376 grep "[1]" job_info >/dev/null || exit 4
377 grep $pid job_info >/dev/null || exit 5
378 kill $pid
379
380 rm job_info
381 ## stdout-json: ""
382
383 #### builtin.kill0_+5.test
384 ! kill -s 0 $(($$+5))
385
386
387 #### builtin.kill0.test
388 kill -s 0 $$
389
390
391 #### builtin.kill.jobs.test
392 sleep 5 & pid1=$!
393 sleep 6 & pid2=$!
394 start=$(date "+%s")
395 sleep 1
396 kill %1 %2 && exit 3
397 kill $pid1 $pid2
398 wait
399 stop=$(date "+%s")
400 elapsed=$((stop - start))
401 echo $stop - $start = $elapsed
402 [ $((elapsed)) -lt 2 ] || exit 1
403
404 echo setting -m
405 set -m
406 echo sleeping
407 jobs -l
408 sleep 5 & pid1=$!
409 sleep 6 & pid2=$!
410 start=$(date "+%s")
411 sleep 1
412 jobs -l
413 kill %1 %2
414 wait
415 stop=$(date "+%s")
416 elapsed=$((stop - start))
417 echo $stop - $start = $elapsed
418 [ $((elapsed)) -lt 2 ] || exit 2
419
420
421 #### builtin.kill.signame.test
422 rm -f foo
423 set -e
424
425 trap 'touch foo' TERM
426
427 kill $$
428 [ -f foo ] && ! [ -s foo ]
429 rm foo
430 echo plain kill
431
432 kill -TERM $$
433 [ -f foo ] && ! [ -s foo ]
434 rm foo
435 echo named \(-TERM\)
436
437 kill -15 $$
438 [ -f foo ] && ! [ -s foo ]
439 rm foo
440 echo numbered \(-15\)
441
442 ## STDOUT:
443 plain kill
444 named (-TERM)
445 numbered (-15)
446 ## END
447
448 #### builtin.printf.repeat.test
449 printf '%d %d\n' 1 2 3 4 5 6 7 8 9
450 ## STDOUT:
451 1 2
452 3 4
453 5 6
454 7 8
455 9 0
456 ## END
457
458 #### builtin.readonly.assign.noninteractive.test
459 readonly a=b
460 export a=c
461 echo egad
462
463 ## status: 1
464 ## stdout-json: ""
465
466 #### builtin.set.-m.test
467 set -m
468 echo hi
469
470 ## STDOUT:
471 hi
472 ## END
473
474 #### builtin.set.quoted.test
475 myvar='a b c'
476 set | grep myvar >scr
477 . ./scr
478 printf '%s\n' $myvar
479
480 ## STDOUT:
481 a
482 b
483 c
484 ## END
485
486 #### builtin.source.nonexistent.earlyexit.test
487 source not_a_thing
488 echo hi
489 exit 0
490 ## status: 1
491 ## stdout-json: ""
492
493 #### builtin.source.nonexistent.test
494 source nonesuch
495 . nonesuch
496
497 ## status: 1
498 ## stdout-json: ""
499
500 #### builtin.source.setvar.test
501 set -e
502
503 echo 'x=5' >to_source
504 source ./to_source
505 echo ${x?:unset}
506 rm to_source
507 [ "$x" -eq 5 ]
508 ## STDOUT:
509 5
510 ## END
511
512 #### builtin.special.redir.error.test
513 : 2>&9
514 echo oh no
515
516 ## status: 1
517 ## stdout-json: ""
518
519 #### builtin.test.bigint.test
520 ! test -t 12323454234578326584376438
521 echo ok
522 ## STDOUT:
523 ok
524 ## END
525
526 #### builtin.test.nonposix.test
527 touch first
528 [ first -ef first ] || exit 3
529 sleep 1
530 touch second
531 [ second -nt first ] || exit 3
532 [ second -ot first ] && exit 4
533 [ first -ot second ] || exit 5
534 [ first -nt second ] && exit 6
535 mkdir up
536 [ first -ef up/../first ] || exit 7
537 [ first -ef up/../up/../second ] && exit 8
538 exit 0
539
540
541 #### builtin.test.-nt.-ot.absent.test
542 touch present
543 [ present -nt absent ] || exit 1
544 [ absent -ot present ] || exit 2
545
546
547 #### builtin.test.numeric.spaces.nonposix.test
548 test " 5" -eq " 5 "
549
550
551 #### builtin.test.symlink.test
552 echo hi >file
553 mkdir dir
554 ln -s file link_file
555 ln -s dir link_dir
556 [ -e file ] && [ -e link_file ] && \
557 [ -f file ] && [ -f link_file ] && \
558 [ -e dir ] && [ -e link_dir ] && \
559 [ -d dir ] && [ -d link_dir ] && \
560 [ -L link_file ] && [ -L link_dir ]
561
562 #### builtin.times.ioerror.test
563 exec 3>&1
564 (
565 trap "" PIPE
566 sleep 1
567 command times
568 echo ?=$? >&3
569 ) | true
570
571 ## STDOUT:
572 ?=2
573 ## END
574
575 #### builtin.trap.chained.test
576 # https://www.spinics.net/lists/dash/msg01771.html
577 trap exit INT
578 trap 'true; kill -s INT $$' EXIT
579 false
580
581
582 #### builtin.trap.exit3.test
583 # https://www.spinics.net/lists/dash/msg01750.html
584 trap '(exit 3) && echo BUG' INT
585 kill -s INT $$
586
587 ## stdout-json: ""
588
589 #### builtin.trap.exitcode.test
590 # https://www.spinics.net/lists/dash/msg01770.html
591
592 trap 'set -o bad@option' INT
593 kill -s INT $$
594
595
596 #### builtin.trap.exit.subshell.test
597 trap 'echo bye' EXIT
598 (echo hi)
599 echo $(echo hi)
600
601 ## STDOUT:
602 hi
603 hi
604 bye
605 ## END
606
607 #### builtin.trap.false.test
608 # https://www.spinics.net/lists/dash/msg01750.html
609 trap '(false) && echo BUG' INT
610 kill -s INT $$
611
612 ## stdout-json: ""
613
614 #### builtin.trap.kill.undef.test
615 trap 'echo derp' KILL
616 trap 'echo nevah' 9
617
618 ## stdout-json: ""
619
620 #### builtin.trap.nested.test
621 # https://www.spinics.net/lists/dash/msg01762.html
622 trap '(trap "echo exit" EXIT; :)' EXIT
623 ## STDOUT:
624 exit
625 ## END
626
627 #### builtin.trap.noexit.test
628 trap - 55
629 echo hi
630
631 ## STDOUT:
632 hi
633 ## END
634
635 #### builtin.trap.return.test
636 # https://www.spinics.net/lists/dash/msg01792.html
637 trap 'f() { false; return; }; f; echo $?' EXIT
638 ## STDOUT:
639 1
640 ## END
641
642 #### builtin.trap.subshell.false.exit.test
643 trap "(false) && echo BUG" EXIT
644
645 ## status: 1
646 ## stdout-json: ""
647
648 #### builtin.trap.subshell.false.test
649 trap "(false) && echo BUG" INT; kill -s INT $$
650
651 ## stdout-json: ""
652
653 #### builtin.trap.subshell.loud2.test
654 # https://www.spinics.net/lists/dash/msg01766.html
655 trap 'set -o bad@option' INT; kill -s INT $$ && echo HUH
656 trap '(:; exit) && echo WEIRD' EXIT; false
657 ## STDOUT:
658 HUH
659 WEIRD
660 ## END
661
662 #### builtin.trap.subshell.loud.test
663 # https://www.spinics.net/lists/dash/msg01766.html
664 trap '(:; exit) && echo WEIRD' EXIT; false
665 ## STDOUT:
666 WEIRD
667 ## END
668
669 #### builtin.trap.subshell.quiet.test
670 # https://www.spinics.net/lists/dash/msg01755.html
671 (trap '(! :) && echo BUG1' EXIT)
672 (trap '(false) && echo BUG2' EXIT)
673 (trap 'readonly foo=bar; (foo=baz) && echo BUG3' EXIT)
674 (trap '(set -o bad@option) && echo BUG4' EXIT)
675 exit 0
676 ## stdout-json: ""
677
678 #### builtin.trap.subshell.true.ec1.test
679 # https://www.spinics.net/lists/dash/msg01761.html
680 trap '(true) || echo bug' EXIT; false
681
682 ## stdout-json: ""
683
684 #### builtin.trap.subshell.truefalse.test
685 # https://www.spinics.net/lists/dash/msg01750.html
686 trap '(false) && echo BUG' INT; kill -s INT $$
687 trap "(false) && echo BUG" EXIT
688 trap "(false); echo \$?" EXIT
689
690 ## STDOUT:
691 1
692 ## END
693
694 #### builtin.trap.supershell.test
695 trap 'echo bye' EXIT
696 (trap)
697 (trap 'echo so long' EXIT; trap)
698 (trap)
699
700 ## STDOUT:
701 trap -- 'echo bye' EXIT
702 trap -- 'echo so long' EXIT
703 so long
704 trap -- 'echo bye' EXIT
705 bye
706 ## END
707
708 #### builtin.unset.test
709 readonly x=foo
710 y=bar
711 unset y
712 echo ${y-unset}
713 echo ${x-error}
714 unset y
715 echo ${y-unset}
716 unset x
717
718 ## status: 1
719 ## STDOUT:
720 unset
721 foo
722 unset
723 ## END
724
725 #### parse.eval.error.test
726 cat >scr <<EOF
727 eval "if"
728 echo lived
729 EOF
730 $TEST_SHELL scr && exit 1
731 exit 0
732 ## stdout-json: ""
733
734 #### semantics.arith.assign.multi.test
735 : $((x = y = z = 0))
736 echo $x $y $z
737 ## STDOUT:
738 0 0 0
739 ## END
740
741 #### semantics.arithmetic.bool_to_num.test
742 [ $((5>=5)) -eq 1 ]
743
744
745 #### semantics.arithmetic.tilde.test
746 # bug found in POSIX testing (sh_05.ex tp357)
747
748 echo $((~10))
749 ## STDOUT:
750 -11
751 ## END
752
753 #### semantics.arith.modernish.test
754 # from https://github.com/modernish/modernish/blob/e3b66a8b68695265b9aebd43e1de1ab3fef66e57/lib/modernish/aux/fatal.sh
755 i=7
756 j=0
757 case $(( ((j+=6*i)==0x2A)>0 ? 014 : 015 )) in
758 ( 12 | 14 ) echo ok;; # OK or BUG_NOOCTAL
759 ( * ) echo fail; exit 1 ;;
760 esac
761 case $j in
762 ( 42 ) echo ok;; # BUG_NOOCTAL
763 ( * ) echo fail; exit 1;;
764 esac
765
766 ## STDOUT:
767 ok
768 ok
769 ## END
770
771 #### semantics.arith.pos.test
772 a=+47
773 [ $((a)) -eq 47 ]
774 echo $((a))
775 ## STDOUT:
776 47
777 ## END
778
779 #### semantics.arith.var.space.test
780 x=" 8"
781 y=$((x + 1))
782 echo $x $y
783
784 ## STDOUT:
785 8 9
786 ## END
787
788 #### semantics.assign.noglob.test
789 x='*'
790 echo "$x"
791
792 ## STDOUT:
793 *
794 ## END
795
796 #### semantics.assign.visible.test
797 set -e
798 x=5 y=$((x+2))
799 [ "$x" -eq 5 ]
800 # either x is treated as unset (and so y = 2) or not (and so y = 7)
801 [ "$y" -eq 2 ] || [ "$y" -eq 7 ]
802 echo ok
803 ## STDOUT:
804 ok
805 ## END
806
807 #### semantics.background.nojobs.stdin.test
808 cat >scr <<EOF
809 set +m
810 exec <in
811 cat &
812 wait
813 EOF
814
815 echo illegible >in
816 $TEST_SHELL scr
817
818
819 #### semantics.background.pid.test
820 echo 'echo $$ > pid.out' >showpid.sh
821 chmod +x showpid.sh
822 $TEST_SHELL showpid.sh &
823 sleep 1
824 [ "$!" -eq "$(cat pid.out)" ]
825
826 #### semantics.background.pipe.pid.test
827 echo 'echo $$ > pid.out' >showpid.sh
828 chmod +x showpid.sh
829 true | $TEST_SHELL showpid.sh &
830 sleep 1
831 [ "$!" -eq "$(cat pid.out)" ]
832
833 #### semantics.background.test
834 echo hi
835 { sleep 1 ; echo derp ; } &
836 echo bye
837 wait
838 ## STDOUT:
839 hi
840 bye
841 derp
842 ## END
843
844 #### semantics.backtick.fds.test
845 set -e
846 subshfds=$($TEST_UTIL/fds 0 20)
847 $TEST_UTIL/fds 0 20
848 echo $subshfds
849
850 ## STDOUT:
851 0 open
852 1 open
853 2 open
854 3 closed
855 4 closed
856 5 closed
857 6 closed
858 7 closed
859 8 closed
860 9 closed
861 10 closed
862 11 closed
863 12 closed
864 13 closed
865 14 closed
866 15 closed
867 16 closed
868 17 closed
869 18 closed
870 19 closed
871 20 closed
872 0 open 1 open 2 open 3 closed 4 closed 5 closed 6 closed 7 closed 8 closed 9 closed 10 closed 11 closed 12 closed 13 closed 14 closed 15 closed 16 closed 17 closed 18 closed 19 closed 20 closed
873 ## END
874
875 #### semantics.backtick.ppid.test
876 set -e
877
878 pid1=$($TEST_SHELL -c 'echo $PPID')
879 echo $pid1 >pid1
880
881 $TEST_SHELL -c 'echo $PPID' >pid2
882
883 [ $(cat pid1) = $(cat pid2) ] || exit 2
884 echo pid1=pid2
885
886 (echo $PPID) >ppid
887 [ $PPID = $(cat ppid) ] || exit 3
888 echo ppid=subshell
889 ## STDOUT:
890 pid1=pid2
891 ppid=subshell
892 ## END
893
894 #### semantics.case.ec.test
895 # ADDTOPOSIX
896
897 (exit 3)
898 echo $? # make sure we're making good ecs
899 case a in
900 ( b ) (exit 4) ;;
901 ( * ) ;; # don't alter ec
902 esac
903 echo $? # should be 3
904
905 (exit 5)
906 case a$(echo $?>ec) in # observe ec before entering case
907 ( b ) (exit 6) ;;
908 esac
909 echo $?
910 [ $(cat ec) = "5" ] || exit 2 # shouldn't have been altered yet!
911
912 # make sure the ec is actually visible
913 false
914 case a in
915 ( a ) echo visible $? ;;
916 esac
917
918 # but make sure that no match cases set the ec to 0
919 false
920 case a in
921 ( b ) (exit 6) ;;
922 esac
923 echo $?
924
925
926 ## STDOUT:
927 3
928 0
929 0
930 visible 1
931 0
932 ## END
933
934 #### semantics.case.escape.modernish.test
935 # from https://github.com/modernish/modernish/blob/e3b66a8b68695265b9aebd43e1de1ab3fef66e57/lib/modernish/aux/fatal.sh
936 case 'foo\
937 bar' in
938 ( foo\\"
939 "bar ) echo good ;;
940 ( * ) echo bad ;;
941 esac
942
943 ## STDOUT:
944 good
945 ## END
946
947 #### semantics.command.argv0.test
948 set -e
949
950 explicit=$(${TEST_UTIL}/argv)
951 [ "$explicit" = "argv[0] = \"${TEST_UTIL}/argv\";" ]
952
953 PATH="${TEST_UTIL}:$PATH"
954 inpath=$(argv)
955 [ "$inpath" = "argv[0] = \"argv\";" ]
956 argv
957
958
959 ## STDOUT:
960 argv[0] = "argv";
961 ## END
962
963 #### semantics.command-subst.newline.test
964 # https://www.spinics.net/lists/dash/msg01844.html
965 cat <<END
966 1
967 $(echo "")
968 2
969 END
970 ## STDOUT:
971 1
972
973 2
974 ## END
975
976 #### semantics.command-subst.test
977 x=$(false)
978
979 ## status: 1
980
981 #### semantics.-C.test
982 echo >in <<EOF
983 a one
984 a two
985 a one two three
986 four
987 EOF
988
989 touch out
990
991 set -o noclobber
992 cat <in >out
993 [ $? -gt 0 ] || exit 2
994
995 #### semantics.defun.ec.test
996 # ADDTOPOSIX
997 false
998 f() { echo hi ; }
999 echo $?
1000 f
1001
1002 false
1003 f() { echo hello ; }
1004 echo $?
1005 f
1006 ## STDOUT:
1007 0
1008 hi
1009 0
1010 hello
1011 ## END
1012
1013 #### semantics.dot.glob.test
1014 has_dot() {
1015 $TEST_UTIL/readdir | grep -e '^.$' >/dev/null
1016 }
1017
1018 has_dotdot() {
1019 $TEST_UTIL/readdir | grep -e '^..$' >/dev/null
1020 }
1021
1022 mkdir -p bar/inner
1023 touch bar/foo
1024 touch bar/inner/foo
1025 cd bar/inner
1026 echo .*/foo | sort # should be ../foo and ./foo
1027
1028 # some FS may be weird and not give these entries... simulate!
1029 has_dot || echo "./foo"
1030 has_dotdot || echo "../foo"
1031
1032 cd ../../
1033 rm -r bar
1034
1035 # this issue is under active discussion on the POSIX mailing list
1036
1037 # bash, dash, yash all work
1038 # fish, zsh fail
1039 ## STDOUT:
1040 ../foo ./foo
1041 ## END
1042
1043 #### semantics.errexit.trap.test
1044 set -e; trap "false; echo BUG" USR1; kill -s USR1 $$
1045
1046 ## status: 1
1047
1048 #### semantics.error.noninteractive.test
1049 cat <<EOF > script
1050 unset x
1051 y=z
1052 echo ${x?z}
1053 echo blargh
1054 EOF
1055 chmod +x script
1056 $TEST_SHELL script
1057
1058 ## status: 1
1059
1060 #### semantics.escaping.backslash.modernish.test
1061 # from https://github.com/modernish/modernish/blob/e3b66a8b68695265b9aebd43e1de1ab3fef66e57/lib/modernish/aux/fatal.sh
1062 t=' :: \on\e :\tw'\''o \th\'\''re\e :\\'\''fo\u\r: : : '
1063 IFS=': '
1064 set -- ${t}
1065 IFS=''
1066 t=${#},${1-U},${2-U},${3-U},${4-U},${5-U},${6-U},${7-U},${8-U},${9-U},${10-U},${11-U},${12-U}
1067 case ${t} in
1068 ( '8,,,\on\e,\tw'\''o,\th\'\''re\e,\\'\''fo\u\r,,,U,U,U,U' \
1069 | '9,,,\on\e,\tw'\''o,\th\'\''re\e,\\'\''fo\u\r,,,,U,U,U' ) # QRK_IFSFINAL
1070 echo good ;;
1071 '8,,,\on\e,\tw'\''o,\th\'\''re\e,\\'\''fo\u\r,,,U,U,U,U') echo weird;;
1072 ( * ) echo bad ; exit 1 ;;
1073 esac
1074
1075 ## STDOUT:
1076 good
1077 ## END
1078
1079 #### semantics.escaping.backslash.test
1080 printf '%s\t\n' > scr \
1081 'printf %s\\n foobar\|\&\;\<\>\(\)\$\`\\\"\'\''\ \?\*\[\'
1082 $TEST_SHELL scr
1083
1084
1085 ## STDOUT:
1086 foobar|&;<>()$`\"' ?*[
1087 ## END
1088
1089 #### semantics.escaping.heredoc.dollar.test
1090 cat <<EOF
1091 echo \\\$var
1092 EOF
1093 cat <<'EOF'
1094 echo \\\$var
1095 EOF
1096
1097 ## STDOUT:
1098 echo \$var
1099 echo \\\$var
1100 ## END
1101
1102 #### semantics.escaping.newline.test
1103 printf '%s' '\\'n
1104 printf '%s' "\n"
1105 printf "\n"
1106 printf '\n'
1107 printf '\\n'
1108
1109 ## stdout-json: "\\\\n\\n\n\n\\n"
1110
1111 #### semantics.escaping.quote.test
1112 set -e
1113
1114 for c in '"' '#' '%' '&' "'" '(' ')' '*' '+' ',' '-' '.' '/' ':' \
1115 ';' '<' '=' '>' '?' '@' '[' ']' '^' '_' '{' '|' '}' '~' ' '
1116 do
1117 cat >script <<EOF
1118 x=\`printf '%s' \\$c\`; printf '%s\\n' "\$x"
1119 EOF
1120 echo "$c"
1121 $TEST_SHELL script >out
1122 [ $? -eq 0 ] && [ "$c" = "$(cat out)" ]
1123 done
1124 echo done
1125 ## STDOUT:
1126 "
1127 #
1128 %
1129 &
1130 '
1131 (
1132 )
1133 *
1134 +
1135 ,
1136 -
1137 .
1138 /
1139 :
1140 ;
1141 <
1142 =
1143 >
1144 ?
1145 @
1146 [
1147 ]
1148 ^
1149 _
1150 {
1151 |
1152 }
1153 ~
1154
1155 done
1156 ## END
1157
1158 #### semantics.escaping.single.test
1159 # cf tp399
1160 cat <<weirdo
1161 line one
1162 line two
1163 "line".\${PATH}.\'three\'\\x\
1164 line four
1165 weirdo
1166
1167 ## STDOUT:
1168 line one
1169 line two
1170 "line".${PATH}.\'three\'\xline four
1171 ## END
1172
1173 #### semantics.eval.makeadder.test
1174 makeadder() {
1175 eval "adder() { echo \$((\$1 + $1)) ; }"
1176 }
1177
1178 makeadder 5
1179 adder 1
1180 makeadder 10
1181 adder 1
1182
1183 ## STDOUT:
1184 6
1185 11
1186 ## END
1187
1188 #### semantics.evalorder.fun.test
1189 # bash: assign
1190 # yash, dash, smoosh: redir
1191 # ADDTOPOSIX
1192 show() { echo "got ${EFF-unset}"; }
1193 unset x
1194 EFF=${x=assign} show 2>${x=redir}
1195 echo ${EFF-unset after function call}
1196 [ -f assign ] && echo assign exists && rm assign
1197 [ -f redir ] && echo redir exists && rm redir
1198
1199 ## STDOUT:
1200 got redir
1201 unset after function call
1202 redir exists
1203 ## END
1204
1205 #### semantics.expansion.heredoc.backslash.test
1206 cat <<EOF
1207 an escaped \\[bracket]
1208 should \\ work just fine
1209 EOF
1210 cat <<EOF
1211 exit \$?
1212 EOF
1213 ## STDOUT:
1214 an escaped \[bracket]
1215 should \ work just fine
1216 exit $?
1217 ## END
1218
1219 #### semantics.expansion.quotes.adjacent.test
1220 mkdir a
1221 touch a/b
1222 touch a/c
1223 echo a/*
1224 echo "a"/*
1225 echo 'a'/*
1226 mkdir "foo*["
1227 touch "foo*["/weird
1228 touch "foo*["/wild
1229 touch "foo*["/crazy
1230 echo "foo*["/*
1231 echo "foo*["/[wz]*
1232 ## STDOUT:
1233 a/b a/c
1234 a/b a/c
1235 a/b a/c
1236 foo*[/crazy foo*[/weird foo*[/wild
1237 foo*[/weird foo*[/wild
1238 ## END
1239
1240 #### semantics.for.readonly.test
1241 # ADDTOPOSIX
1242 (for x in a b c; do echo $x; readonly x; done) && exit 1
1243 exit 0
1244
1245 ## STDOUT:
1246 a
1247 ## END
1248
1249 #### semantics.fun.error.restore.test
1250 set -u
1251
1252 f() {
1253 echo $1
1254 echo <none
1255 }
1256
1257 set -- a b c
1258 f arg1 arg2
1259 printf '<%s>\n' "$@"
1260
1261 ## STDOUT:
1262 arg1
1263 <a>
1264 <b>
1265 <c>
1266 ## END
1267
1268 #### semantics.ifs.combine.ws.test
1269 unset IFS
1270 echo > spaced
1271 printf "%b" '\tx' >> spaced
1272 echo >> spaced
1273 echo " 5" >> spaced
1274 printf '%b' ' 12\t ' >> spaced
1275 echo `cat spaced`
1276 IFS=$(printf '%b' ' \n\t')
1277 echo `cat spaced`
1278 ## STDOUT:
1279 x 5 12
1280 x 5 12
1281 ## END
1282
1283 #### semantics.kill.traps.test
1284 trap "echo hi" TERM
1285 sleep 10 &
1286 pid=$!
1287 sleep 1
1288 kill $pid
1289 [ "$?" -eq 0 ] || exit 1
1290 sleep 1
1291 wait $pid
1292 [ "$?" -ge 128 ] || exit 2
1293
1294
1295 ## stdout-json: ""
1296
1297 #### semantics.length.test
1298 # https://www.spinics.net/lists/dash/msg01749.html
1299 v=abc; echo ab${#v}cd
1300
1301 ## STDOUT:
1302 ab3cd
1303 ## END
1304
1305 #### semantics.no-command-subst.test
1306 false ; x=hi
1307
1308
1309 #### semantics.noninteractive.expansion.exit.test
1310 unset x
1311 echo ${x?alas, poor yorick}
1312
1313 ## status: 1
1314
1315 #### semantics.pattern.bracket.quoted.test
1316 # from https://github.com/modernish/modernish/blob/e3b66a8b68695265b9aebd43e1de1ab3fef66e57/lib/modernish/aux/fatal.sh
1317 t='ab]cd'
1318 case c in
1319 ( *["${t}"]* )
1320 case e in
1321 ( *[!"${t}"]* ) echo OK;;
1322 ( * ) echo FAILED inner ;;
1323 esac ;;
1324 ( * ) echo FAILED outer ;;
1325 esac
1326
1327 case \" in
1328 ( *["${t}"]* ) echo QUOTED ;;
1329 ( * ) echo UNQUOTED ;;
1330 esac
1331
1332 ## STDOUT:
1333 OK
1334 UNQUOTED
1335 ## END
1336
1337 #### semantics.pattern.hyphen.test
1338 touch file-
1339 touch filea
1340
1341 echo file[-123]
1342 echo file[123-]
1343 echo file[[.-.]]
1344 echo file[[=-=]]
1345 echo file[!-123]
1346 echo file[[:alpha:]]
1347 echo file[a-z]
1348 ## STDOUT:
1349 file-
1350 file-
1351 file-
1352 file-
1353 filea
1354 filea
1355 filea
1356 ## END
1357
1358 #### semantics.pattern.modernish.test
1359 # from https://github.com/modernish/modernish/blob/e3b66a8b68695265b9aebd43e1de1ab3fef66e57/lib/modernish/aux/fatal.sh
1360 t=' :: \on\e :\tw'\''o \th\'\''re\e :\\'\''fo\u\r: : : '
1361 IFS=': '
1362 set -- ${t}
1363 IFS=''
1364 t=${#},${1-U},${2-U},${3-U},${4-U},${5-U},${6-U},${7-U},${8-U},${9-U},${10-U},${11-U},${12-U}
1365 printf "%s\n" "$t"
1366 case ${t} in
1367 ( '8,,,\on\e,\tw'\''o,\th\'\''re\e,\\'\''fo\u\r,,,U,U,U,U' \
1368 | '9,,,\on\e,\tw'\''o,\th\'\''re\e,\\'\''fo\u\r,,,,U,U,U' ) # QRK_IFSFINAL
1369 echo good ;;
1370 '8,,,\on\e,\tw'\''o,\th\'\''re\e,\\'\''fo\u\r,,,U,U,U,U') echo weird;;
1371 ( * ) echo bad ; exit 1 ;;
1372 esac
1373
1374
1375 #### semantics.pattern.rightbracket.test
1376 touch file]
1377 touch filea
1378
1379 echo file[]123]
1380 echo file[[.].]]
1381 echo file[[=]=]]
1382 echo file[!]123]
1383 echo file[[:alpha:]]
1384 echo file[a-z]
1385 ## STDOUT:
1386 file]
1387 file]
1388 file]
1389 filea
1390 filea
1391 filea
1392 ## END
1393
1394 #### semantics.quote.backslash.test
1395 echo []
1396 echo '\[]'
1397 echo "\[]"
1398
1399 ## STDOUT:
1400 []
1401 \[]
1402 \[]
1403 ## END
1404
1405 #### semantics.quote.tilde.test
1406 echo "~"
1407 ## STDOUT:
1408 ~
1409 ## END
1410
1411 #### semantics.redir.close.test
1412 # https://www.spinics.net/lists/dash/msg01775.html
1413 { exec 8</dev/null; } 8<&-; : <&8 && echo "oops, still open"
1414
1415 ## status: 1
1416 ## stdout-json: ""
1417
1418 #### semantics.redir.fds.test
1419 $TEST_UTIL/fds
1420 exec 3>&1
1421 $TEST_UTIL/fds
1422
1423 ## STDOUT:
1424 0 open
1425 1 open
1426 2 open
1427 3 closed
1428 4 closed
1429 5 closed
1430 6 closed
1431 7 closed
1432 8 closed
1433 9 closed
1434 0 open
1435 1 open
1436 2 open
1437 3 open
1438 4 closed
1439 5 closed
1440 6 closed
1441 7 closed
1442 8 closed
1443 9 closed
1444 ## END
1445
1446 #### semantics.redir.from.test
1447 set -e
1448 echo hi >file
1449 [ -s file ]
1450 read x <file
1451 [ "$x" = "hi" ]
1452 rm file
1453
1454 #### semantics.redir.nonregular.test
1455 set -C
1456 : >/dev/null || exit 2
1457 echo ok
1458
1459 ## STDOUT:
1460 ok
1461 ## END
1462
1463 #### semantics.redir.to.test
1464 set -e
1465 echo hi >file
1466 [ -s file ]
1467 [ "$(cat file)" = "hi" ]
1468 rm file
1469
1470 #### semantics.simple.link.test
1471 set -e
1472 echo 'echo hi' >cmd.sh
1473 chmod +x cmd.sh
1474 ln -s cmd.sh link.sh
1475 OLDPATH=$PATH
1476 PATH=.
1477 [ -x cmd.sh ]
1478 [ -L link.sh ]
1479 cmd.sh # command works
1480 link.sh # symlink works
1481 PATH=$OLDPATH
1482 ls
1483 rm cmd.sh link.sh
1484 ## STDOUT:
1485 hi
1486 hi
1487 cmd.sh
1488 link.sh
1489 ## END
1490
1491 #### semantics.special.assign.visible.nonposix.test
1492 x=5 y=$((x+2)) :
1493 echo $x $y
1494
1495 ## STDOUT:
1496 5 7
1497 ## END
1498
1499 #### semantics.splitting.ifs.test
1500 cat << EOF > input
1501 -,1-,-2,-,3,-
1502 EOF
1503
1504 IFS="-,"
1505 echo `cat input`
1506 ## STDOUT:
1507 1 2 3
1508 ## END
1509
1510 #### semantics.subshell.background.traps.test
1511 (trap - INT; echo INT sleeping...; sleep 10; echo INT awake) & pid=$!
1512 sleep 1
1513 kill $pid
1514 wait $pid
1515 ec=$?
1516 [ "$ec" -ge 128 ] || exit 1
1517 (trap - QUIT; echo QUIT sleeping...; sleep 10; echo QUIT awake) & pid=$!
1518 sleep 1
1519 kill -QUIT $pid
1520 wait $pid
1521 ec=$?
1522 [ "$ec" -ge 128 ] || exit 2
1523 ## STDOUT:
1524 INT sleeping...
1525 QUIT sleeping...
1526 ## END
1527
1528 #### semantics.subshell.break.test
1529 # https://www.spinics.net/lists/dash/msg01773.html
1530 for x in a b
1531 do
1532 (
1533 for y in c d
1534 do
1535 break 2
1536 done
1537 echo $x
1538 )
1539 done
1540 ## STDOUT:
1541 a
1542 b
1543 ## END
1544
1545 #### semantics.tilde.colon.test
1546 tilde=~
1547 cat << EOF >test_script
1548 var=:~
1549 [ "\$var" = ":$tilde" ]
1550 EOF
1551 chmod +x test_script
1552 $TEST_SHELL test_script
1553
1554 #### semantics.tilde.quoted.prefix.test
1555 # ADDTOPOSIX
1556
1557 set -e
1558 tilde=$(echo ~)
1559 [ "$tilde" = "$HOME" ] || exit 1
1560
1561 funny='~'\""$LOGNAME"\"
1562 exp=$(eval "echo $funny")
1563 [ "$exp" = "~$LOGNAME" ] || exit 2
1564
1565 [ ~/ = "$HOME"/ ] || exit 3
1566
1567 echo ok
1568 ## STDOUT:
1569 ok
1570 ## END
1571
1572 #### semantics.tilde.quoted.test
1573 HOME="weird times"
1574 printf '%s\n' ~
1575 touch a1 a2 a3
1576 HOME='a*'
1577 printf '%s\n' ~
1578
1579 ## STDOUT:
1580 weird times
1581 a*
1582 ## END
1583
1584 #### semantics.tilde.sep.test
1585 # ADDTOPOSIX
1586 [ ~: = "~:" ] || exit 1
1587
1588 y=~
1589 [ $y = "$HOME" ] || exit 2
1590
1591 y=~/foo
1592 [ $y = "$HOME/foo" ] || exit 3
1593
1594 y=~:foo
1595 [ $y = "$HOME:foo" ] || exit 4
1596
1597 y=foo:~
1598 [ $y = "foo:$HOME" ] || exit 5
1599
1600 y=foo:~:bar
1601 [ $y = "foo:$HOME:bar" ] || exit 6
1602
1603 echo ok
1604 ## STDOUT:
1605 ok
1606 ## END
1607
1608 #### semantics.tilde.test
1609 echo ~ >tilde.out
1610 var=~
1611 echo $var > var.out
1612 [ -f tilde.out ] && [ -f var.out ] && \
1613 [ -s tilde.out ] && [ -s var.out ] && \
1614 [ $(cat tilde.out) = $(cat var.out) ] && \
1615 [ $(cat tilde.out) != "~" ]
1616
1617
1618
1619 #### semantics.traps.async.test
1620 (
1621 kill -s QUIT $($TEST_SHELL -c 'echo $PPID') || exit 1
1622 echo done
1623 ) &
1624 wait $!
1625
1626 ## STDOUT:
1627 done
1628 ## END
1629
1630 #### semantics.traps.inherit.test
1631 (
1632 trap "echo got SIGINT" INT
1633
1634 # default trap will mean we actually get a QUIT, overriding the default on asyncs
1635 trap - QUIT
1636
1637 mypid=$($TEST_SHELL -c 'echo $PPID')
1638
1639 # this can be overridden
1640 kill -s INT "$mypid" || exit 4
1641
1642 # will kill this shell,
1643 echo "sending SIGQUIT"
1644 kill -s QUIT "$mypid" || exit 2
1645 exit 0
1646 ) &
1647 wait $!
1648 echo $?
1649
1650
1651 ## STDOUT:
1652 got SIGINT
1653 sending SIGQUIT
1654 131
1655 ## END
1656
1657 #### semantics.var.alt.nullifs.test
1658 IFS=
1659 printf '<%s>\n' ${x+uhoh} a b
1660
1661 f() { echo $#; printf '<%s>\n' "$@" ; }
1662 f ${x+uhoh} a b
1663
1664 x=hi
1665 f ${x+uhoh} a b
1666
1667
1668 ## STDOUT:
1669 <a>
1670 <b>
1671 2
1672 <a>
1673 <b>
1674 3
1675 <uhoh>
1676 <a>
1677 <b>
1678 ## END
1679
1680 #### semantics.var.alt.null.test
1681 f() { echo $# ; }
1682 unset -v nonesuch
1683 f ${nonesuch+nonempty} a b
1684
1685 x=foo
1686 f ${x+hi} a b
1687
1688 ## STDOUT:
1689 2
1690 3
1691 ## END
1692
1693 #### semantics.varassign.test
1694 # https://git.kernel.org/pub/scm/utils/dash/dash.git/commit/?id=a29e9a1738a4e7040211842f3f3d90e172fa58ce
1695 foo=bar; echo ${foo=BUG}; echo $foo
1696
1697 ## STDOUT:
1698 bar
1699 bar
1700 ## END
1701
1702 #### semantics.var.builtin.nonspecial.test
1703 # successful command
1704 unset x
1705 x=value command alias >/dev/null 2>&1
1706 echo ${x-unset}
1707 test -z "$x" || exit 1
1708
1709 # unsuccessful command
1710 unset x
1711 x=value command alias -: >/dev/null 2>&1
1712 echo ${x-unset}
1713 test -z "$x" || exit 2
1714
1715 ## STDOUT:
1716 unset
1717 unset
1718 ## END
1719
1720 #### semantics.var.dashu.test
1721 unset nonesuch
1722 $TEST_SHELL -u -c 'echo $nonesuch' && exit 1
1723 $TEST_SHELL -u -c 'echo $3' && exit 1
1724 $TEST_SHELL -u -c 'var=val ; echo ${var+$nonesuch}' && exit 1
1725 $TEST_SHELL -u -c 'echo $(($nonesuch + 1))' && exit 1
1726 $TEST_SHELL -u -c 'echo $((nonesuch + 1))' && exit 1
1727 $TEST_SHELL -u -c 'echo ${#nonesuch}' && exit 1
1728 echo passed
1729
1730 ## STDOUT:
1731 passed
1732 ## END
1733
1734 #### semantics.var.format.tilde.test
1735 unset x
1736 tilde=~
1737 : ${x:=~}
1738 ext=~/foo
1739 [ "$x" = "$tilde" ] && \
1740 [ "/foo" = ${ext#~} ] && \
1741 ! $TEST_SHELL -c 'echo ${y?~}'
1742
1743 #### semantics.variable.escape.length.test
1744 x=\n
1745 echo ${#x}
1746 x=\\n
1747 echo ${#x}
1748
1749 ## STDOUT:
1750 1
1751 2
1752 ## END
1753
1754 #### semantics.var.ifs.sep.test
1755 IFS=", "
1756 set 1 2 3
1757 echo "$*"
1758
1759 ## STDOUT:
1760 1,2,3
1761 ## END
1762
1763 #### semantics.var.star.emptyifs.test
1764 IFS=""
1765 bee="b e e"
1766 set a "$bee" c
1767
1768 printf '<%s>\n' $*
1769 printf '<%s>\n' HI$*BYE
1770
1771 ## STDOUT:
1772 <a>
1773 <b e e>
1774 <c>
1775 <HIa>
1776 <b e e>
1777 <cBYE>
1778 ## END
1779
1780 #### semantics.var.star.format.test
1781 sp="s p aces"
1782 tn=$(printf '%b' 'and\ttabs\n and newlines')
1783 set -- a "$sp" b c "$tn"
1784 IFS=": "
1785 printf '<%s>\n' "${var=$*}"
1786 unset var
1787 unset IFS
1788 printf '<%s>\n' "${var=$*}"
1789
1790 ## STDOUT:
1791 <a:s p aces:b:c:and tabs
1792 and newlines>
1793 <a s p aces b c and tabs
1794 and newlines>
1795 ## END
1796
1797 #### semantics.var.unset.nofield.test
1798 count() { echo $#; }
1799 [ $(count a $nonesuch b) -eq 2 ]
1800
1801 #### semantics.wait.alreadydead.test
1802 sleep 10 &
1803 pid=$!
1804 sleep 1
1805 kill $pid
1806 echo kill ec: $?
1807 sleep 1
1808 wait $pid
1809 echo wait ec: $?
1810
1811 ## STDOUT:
1812 kill ec: 0
1813 wait ec: 143
1814 ## END
1815
1816 #### semantics.while.test
1817 i=0
1818 while [ $i -lt 10 ]
1819 do
1820 i=$((i + 1))
1821 echo $i
1822 done
1823 echo $?
1824 i=0
1825 while [ $i -lt 10 ]
1826 do
1827 i=$((i + 1))
1828 echo $i;
1829 false
1830 done
1831 echo $?
1832
1833 ## STDOUT:
1834 1
1835 2
1836 3
1837 4
1838 5
1839 6
1840 7
1841 8
1842 9
1843 10
1844 0
1845 1
1846 2
1847 3
1848 4
1849 5
1850 6
1851 7
1852 8
1853 9
1854 10
1855 1
1856 ## END
1857
1858 #### sh.-c.arg0.test
1859 cat > scr <<EOF
1860 echo "i am \$0, hear me roar"
1861 EOF
1862 $TEST_SHELL -c '. "$0"' ./scr
1863 ## STDOUT:
1864 i am ./scr, hear me roar
1865 ## END
1866
1867 #### sh.env.ppid.test
1868 $TEST_SHELL -c 'echo $PPID' >ppid
1869 inner=$(cat ppid)
1870 rm ppid
1871 [ "$inner" -eq "$$" ]
1872
1873
1874
1875 #### sh.file.weirdness.test
1876 $TEST_SHELL nonesuch
1877 echo 'echo works' >scr
1878 $TEST_SHELL scr
1879 $TEST_SHELL ./scr
1880 echo 'echo nope' >scr
1881 chmod -r scr
1882 $TEST_SHELL ./scr && exit 1
1883 $TEST_SHELL scr && exit 1
1884 rm -f scr
1885
1886
1887 ## STDOUT:
1888 works
1889 works
1890 ## END
1891
1892 #### sh.monitor.bg.test
1893 set -m
1894
1895 start=$(date "+%s")
1896 sleep 3 & pid=$!
1897 kill -TSTP $pid
1898 jobs -l
1899 stop=$(date "+%s")
1900 elapsed=$((stop - start))
1901 echo $stop - $start = $elapsed
1902 [ $((elapsed)) -lt 2 ] || exit 1
1903
1904 jobs -l
1905 bg >output
1906
1907 stop2=$(date "+%s")
1908 elapsed=$((stop2 - start))
1909 echo $stop2 - $start = $elapsed
1910 [ $((elapsed)) -lt 2 ] || exit 2
1911 grep "[1]" output || exit 3
1912 grep "sleep 3" output || exit 4
1913
1914 wait
1915
1916 stop3=$(date "+%s")
1917 elapsed=$((stop3 - start))
1918 echo $stop3 - $start = $elapsed
1919 [ $((elapsed)) -ge 3 ] || exit 5
1920
1921
1922 #### sh.monitor.fg.test
1923 set -m
1924
1925 start=$(date "+%s")
1926 sleep 3 & pid=$!
1927 kill -TSTP $pid
1928 jobs -l
1929 stop=$(date "+%s")
1930 elapsed=$((stop - start))
1931 echo $stop - $start = $elapsed
1932 [ $((elapsed)) -lt 2 ] || exit 1
1933
1934 jobs -l
1935 fg >output
1936
1937 stop2=$(date "+%s")
1938 elapsed=$((stop2 - start))
1939 echo $stop2 - $start = $elapsed
1940 [ $((elapsed)) -ge 3 ] || exit 2
1941 grep "sleep 3" output || exit 3
1942
1943
1944 #### sh.set.ifs.test
1945 cat >show_ifs <<EOF
1946 printf '%s' "$IFS"
1947 EOF
1948 $TEST_SHELL show_ifs || exit 1
1949 export IFS=123
1950 $TEST_SHELL show_ifs || exit 1
1951 IFS=abc $TEST_SHELL show_ifs || exit 1
1952
1953 ## STDOUT:
1954
1955
1956
1957 ## END
1958