# tests for miscellaneous builtins not tested elsewhere set +p set +o posix ulimit -c 0 2>/dev/null # check that break breaks loops for i in a b c; do echo $i; break; echo bad-$i; done echo end-1 for i in a b c; do echo $i; break 1; echo bad-$i; done echo end-2 for i in a b c; do for j in x y z; do echo $i:$j break echo bad-$i done echo end-$i done echo end-3 # check that break breaks nested loops for i in a b c; do for j in x y z; do echo $i:$j break 2 echo bad-$i done echo end-$i done echo end # check that continue continues loops for i in a b c; do echo $i; continue; echo bad-$i ; done echo end-1 for i in a b c; do echo $i; continue 1; echo bad-$i; done echo end-2 for i in a b c; do for j in x y z; do echo $i:$j continue echo bad-$i-$j done echo end-$i done echo end-3 # check that continue breaks out of nested loops for i in a b c; do for j in x y z; do echo $i:$j continue 2 echo bad-$i-$j done echo end-$i done echo end # check that `eval' re-evaluates arguments, but `builtin' and `command' do not AVAR='$BVAR' BVAR=foo echo $AVAR builtin echo $AVAR command echo $AVAR eval echo \$AVAR eval echo $AVAR # test out eval with a temp environment AVAR=bar eval echo \$AVAR BVAR=xxx eval echo $AVAR unset -v AVAR BVAR # test umask mask=$(umask) umask 022 umask umask -S umask -S u=rwx,g=rwx,o=rx >/dev/null # 002 umask umask -S umask 0 umask -S umask ${mask} # restore original mask # builtin/command without arguments should do nothing. maybe someday they will builtin command # test enable enable -ps enable -aps ; enable -nps enable -n test case "$(type -t test)" in builtin) echo oops -- enable -n test failed ;; *) echo enable -n test worked ;; esac enable test case "$(type -t test)" in builtin) echo enable test worked ;; *) echo oops -- enable test failed ;; esac # test options to exec (exec -a specialname ${THIS_SH} -c 'echo $0' ) # test `clean' environment. if /bin/sh is bash, and the script version of # printenv is run, there will be variables in the environment that bash # sets on startup. (export FOO=BAR ; exec -c printenv ) | grep FOO (FOO=BAR exec -c printenv ) | grep FOO (export FOO=BAR ; exec printenv ) | grep FOO (FOO=BAR exec printenv ) | grep FOO # ok, forget everything about hashed commands hash -r hash # check out source/. AVAR=AVAR . ./source.sub1 AVAR=foo . ./source.sub1 . ./source.sub2 echo $? set -- a b c . ./source.sub3 # make sure source with arguments does not change the shell's positional # parameters, but that the sourced file sees the arguments as its # positional parameters echo "$@" . ./source.sub3 x y z echo "$@" # but if the sourced script sets the positional parameters explicitly, they # should be reflected in the calling shell's positional parameters. this # also tests one of the shopt options that controls source using $PATH to # find the script echo "$@" shopt -u sourcepath . source.sub4 echo "$@" # this is complicated when the sourced scripts gets its own positional # parameters from arguments to `.' set -- a b c echo "$@" . source.sub4 x y z echo "$@" # test out cd and $CDPATH ${THIS_SH} ./builtins.sub1 # in posix mode, assignment statements preceding special builtins are # reflected in the shell environment. `.' and `eval' need special-case # code. set -o posix echo $AVAR AVAR=foo . ./source.sub1 echo $AVAR AVAR=AVAR echo $AVAR AVAR=foo eval echo \$AVAR echo $AVAR AVAR=AVAR echo $AVAR AVAR=foo : echo $AVAR # test out kill -l. bash versions prior to 2.01 did `kill -l num' wrong set +o posix sigone=$(kill -l | sed -n 's:^ 1) *\([^ ]*\)[ ].*$:\1:p') case "$(kill -l 1)" in ${sigone/SIG/}) echo ok;; *) echo oops -- kill -l failure;; esac # POSIX.2 says that exit statuses > 128 are mapped to signal names by # subtracting 128 so you can find out what signal killed a process case "$(kill -l $(( 128 + 1)) )" in ${sigone/SIG/}) echo ok;; *) echo oops -- kill -l 129 failure;; esac # out-of-range signal numbers should report the argument in the error # message, not 128 less than the argument kill -l 4096 # kill -l NAME should return the signal number kill -l ${sigone/SIG/}