small changes to some error messages; greatly expanded builtins tests

This commit is contained in:
Chet Ramey
2023-09-28 10:47:17 -04:00
parent b3958b3ab4
commit 00edd0ee50
71 changed files with 1330 additions and 179 deletions
+16
View File
@@ -7677,3 +7677,19 @@ execute_cmd.c
name is a fatal error, just like with `for'. This is compatible with
ksh93 and mksh
9/25
----
subst.c
- parameter_brace_expand_length: rearrange the code slightly to reduce
the number of find_variable calls. This matters if the variable is
dynamic and produces a new value each time (e.g., RANDOM).
9/26
----
builtins/shift.def
- shift_builtin: if get_numeric_arg returns a number out of range and
we're going to print an error message, make sure to skip over an
argument of `--' so we can print the right argument
builtins/break.def
- break_builtin,continue_builtin: ditto with get_numeric_arg and `--'
+6
View File
@@ -1025,6 +1025,7 @@ tests/builtins6.sub f
tests/builtins7.sub f
tests/builtins8.sub f
tests/builtins9.sub f
tests/builtins10.sub f
tests/source1.sub f
tests/source2.sub f
tests/source3.sub f
@@ -1262,6 +1263,7 @@ tests/history4.sub f
tests/history5.sub f
tests/history6.sub f
tests/history7.sub f
tests/history8.sub f
tests/ifs.tests f
tests/ifs.right f
tests/ifs1.sub f
@@ -1278,6 +1280,7 @@ tests/intl4.sub f
tests/intl.right f
tests/invocation.tests f
tests/invocation.right f
tests/invocation1.sub f
tests/iquote.tests f
tests/iquote.right f
tests/iquote1.sub f
@@ -1291,6 +1294,7 @@ tests/jobs4.sub f
tests/jobs5.sub f
tests/jobs6.sub f
tests/jobs7.sub f
tests/jobs8.sub f
tests/jobs.right f
tests/lastpipe.right f
tests/lastpipe.tests f
@@ -1568,12 +1572,14 @@ tests/trap5.sub f
tests/trap6.sub f
tests/trap7.sub f
tests/trap8.sub f
tests/trap9.sub f
tests/type.tests f
tests/type.right f
tests/type1.sub f
tests/type2.sub f
tests/type3.sub f
tests/type4.sub f
tests/type5.sub f
tests/unicode1.sub f
tests/unicode2.sub f
tests/unicode3.sub f
+6
View File
@@ -73,6 +73,9 @@ break_builtin (WORD_LIST *list)
if (newbreak <= 0)
{
/* skip over `--' option to get the right error message */
if (list && list->word && ISOPTION (list->word->word, '-'))
list = list->next;
sh_erange (list->word->word, _("loop count"));
breaking = loop_level;
return (EXECUTION_FAILURE);
@@ -114,6 +117,9 @@ continue_builtin (WORD_LIST *list)
if (newcont <= 0)
{
/* skip over `--' option to get the right error message */
if (list && list->word && ISOPTION (list->word->word, '-'))
list = list->next;
sh_erange (list->word->word, _("loop count"));
breaking = loop_level;
return (EXECUTION_FAILURE);
+10 -1
View File
@@ -68,6 +68,9 @@ shift_builtin (WORD_LIST *list)
return (EXECUTION_SUCCESS);
else if (times < 0)
{
/* skip over `--' option to get the right error message */
if (list && list->word && ISOPTION (list->word->word, '-'))
list = list->next;
sh_erange (list ? list->word->word : NULL, _("shift count"));
return (EXECUTION_FAILURE);
}
@@ -75,7 +78,13 @@ shift_builtin (WORD_LIST *list)
if (times > nargs)
{
if (print_shift_error)
sh_erange (list ? list->word->word : NULL, _("shift count"));
{
/* skip over `--' option to get the right error message */
if (list && list->word && ISOPTION (list->word->word, '-'))
list = list->next;
sh_erange (list ? list->word->word : NULL, _("shift count"));
}
return (EXECUTION_FAILURE);
}
else if (times == nargs)
+17 -18
View File
@@ -8139,6 +8139,7 @@ parameter_brace_expand_length (char *name)
SHELL_VAR *var;
var = (SHELL_VAR *)NULL;
number = 0;
if (name[1] == '\0') /* ${#} */
number = number_of_args ();
@@ -8175,20 +8176,19 @@ parameter_brace_expand_length (char *name)
else if (valid_array_reference (name + 1, 0))
number = array_length_reference (name + 1);
#endif /* ARRAY_VARS */
else if (legal_number (name + 1, &arg_index)) /* ${#1} */
{
t = get_dollar_var_value (arg_index);
if (t == 0 && unbound_vars_is_error)
return INTMAX_MIN;
number = MB_STRLEN (t);
FREE (t);
}
else
{
number = 0;
if (legal_number (name + 1, &arg_index)) /* ${#1} */
{
t = get_dollar_var_value (arg_index);
if (t == 0 && unbound_vars_is_error)
return INTMAX_MIN;
number = MB_STRLEN (t);
FREE (t);
}
var = find_variable (name + 1);
#if defined (ARRAY_VARS)
else if ((var = find_variable (name + 1)) && (invisible_p (var) == 0) && (array_p (var) || assoc_p (var)))
if (var && (invisible_p (var) == 0) && (array_p (var) || assoc_p (var)))
{
if (assoc_p (var))
t = assoc_reference (assoc_cell (var), "0");
@@ -8198,14 +8198,13 @@ parameter_brace_expand_length (char *name)
return INTMAX_MIN;
number = MB_STRLEN (t);
}
else
#endif
/* Fast path for the common case of taking the length of a non-dynamic
scalar variable value. */
else if ((var || (var = find_variable (name + 1))) &&
invisible_p (var) == 0 &&
array_p (var) == 0 && assoc_p (var) == 0 &&
nameref_p (var) == 0 &&
var->dynamic_value == 0)
/* Fast path for the common case of taking the length of a scalar
variable value. */
if (var && invisible_p (var) == 0 &&
array_p (var) == 0 && assoc_p (var) == 0 &&
nameref_p (var) == 0)
number = value_cell (var) ? MB_STRLEN (value_cell (var)) : 0;
else if ((var = find_variable_last_nameref (name + 1, 0)) && nameref_p (var))
{
+1 -1
View File
@@ -10,4 +10,4 @@ export TMPDIR
export BASH_TSTOUT=/tmp/xx
rm -f ${BASH_TSTOUT}
/bin/sh "$@"
${THIS_SH} "$@"
+2
View File
@@ -5,6 +5,8 @@ alias: 0
quux
hi
declare -a m=([0]="x")
./alias.tests: line 66: alias: `\$': invalid alias name
./alias.tests: line 67: `\$': invalid alias name
bar
value
bar
+4
View File
@@ -62,6 +62,10 @@ alias L='m=("x")'
L
declare -p m
# invalid alias names generate errors
alias '\$'=xx
BASH_ALIASES['\$']=xx
${THIS_SH} ./alias1.sub
${THIS_SH} ./alias2.sub
${THIS_SH} ./alias3.sub
+6
View File
@@ -84,3 +84,9 @@ bash: -c: line 1: syntax error: `(( i=0; i < 3; i++; 7 ))'
2
1
0
43210
ok1
./arith-for.tests: line 133: ((: 7++ : arithmetic syntax error: operand expected (error token is "+ ")
./arith-for.tests: line 134: ((: i < 4/0: division by 0 (error token is "0")
./arith-for.tests: line 135: ((: i=2/0: division by 0 (error token is "0")
./arith-for.tests: line 137: ((: 7=4 : attempted assignment to non-variable (error token is "=4 ")
+9
View File
@@ -126,3 +126,12 @@ echo
for (( i = 4; ;i--)) ; do echo $i; if (( $i == 0 )); then break; fi; done
for (( i = 4;;i--)) ; do echo $i; if (( $i == 0 )); then break; fi; done
i=4 ; for (( ;;i--)) ; do echo -n $i; if (( i == 0 )); then break; fi; done; echo
# arithmetic for commands with expression errors
for (( i=1; i < 4; 7++ )); do echo ok$i ; done
for (( i=2; i < 4/0; 7++ )); do echo whoops1 ; done
for (( i=2/0; i < 4; 7++ )); do echo whoops2 ; done
for (( 7=4 ; 7 > 7; )); do echo whoops3; done
+7 -5
View File
@@ -129,7 +129,9 @@ grep [ 123 ] *
6 7 9 5
length = 3
value = new1 new2 new3
./array.tests: line 257: narray: unbound variable
./array.tests: line 256: syntax error near unexpected token `&'
./array.tests: line 256: `badarray=( metacharacters like & need to be quoted in compound assignments)'
./array.tests: line 260: narray: unbound variable
./array1.sub: line 1: syntax error near unexpected token `('
./array1.sub: line 1: `printf "%s\n" -a a=(a 'b c')'
./array2.sub: line 1: declare: `[]=asdf': not a valid identifier
@@ -156,10 +158,10 @@ for case if then else
12 14 16 18 20
4414758999202
aaa bbb
./array.tests: line 307: syntax error near unexpected token `<>'
./array.tests: line 307: `metas=( <> < > ! )'
./array.tests: line 308: syntax error near unexpected token `<>'
./array.tests: line 308: `metas=( [1]=<> [2]=< [3]=> [4]=! )'
./array.tests: line 310: syntax error near unexpected token `<>'
./array.tests: line 310: `metas=( <> < > ! )'
./array.tests: line 311: syntax error near unexpected token `<>'
./array.tests: line 311: `metas=( [1]=<> [2]=< [3]=> [4]=! )'
abc 3
case 4
abc case if then else 5
+3
View File
@@ -252,6 +252,9 @@ barray=(new1 new2 new3)
echo "length = ${#barray[@]}"
echo "value = ${barray[*]}"
# the compound assignment syntax inherited from ksh93 has some quirks
badarray=( metacharacters like & need to be quoted in compound assignments)
# make sure the array code behaves correctly with respect to unset variables
set -u
( echo ${#narray[4]} )
+140 -3
View File
@@ -91,6 +91,7 @@ FOO=BAR
FOO=BAR
hash: hash table empty
0
no-newline
AVAR
foo
in source.sub2, calling return
@@ -145,11 +146,11 @@ AVAR
foo
declare -x foo=""
declare -x FOO="\$\$"
./builtins.tests: line 228: declare: FOO: not found
./builtins.tests: line 239: declare: FOO: not found
declare -x FOO="\$\$"
ok
ok
./builtins.tests: line 260: kill: 4096: invalid signal specification
./builtins.tests: line 271: kill: 4096: invalid signal specification
1
a\n\n\nb
a
@@ -291,6 +292,10 @@ u=rwx,g=rwx,o=rwx
u=rwx,g=rwx,o=rwx
u=rwx,g=rx,o=rx
u=rwx,g=rx,o=rx
u=rwx,g=rx,o=rx
u=rwx,g=rx,o=rx
u=rwx,g=rx,o=rx
u=rwx,g=rx,o=rx
hash: hash table empty
./builtins9.sub: line 19: hash: notthere: not found
1
@@ -308,4 +313,136 @@ builtin hash -p /nosuchdir/nosuchfile cat
0
found
./builtins9.sub: line 52: hash: /: Is a directory
./builtins.tests: line 290: exit: status: numeric argument required
builtin hash -p /nosuchfile cat
./builtins10.sub: line 17: help: -x: invalid option
help: usage: help [-dms] [pattern ...]
These shell commands are defined internally. Type `help' to see this list.
Type `help name' to find out more about the function `name'.
Use `info bash' to find out more about the shell in general.
Use `man -k' or `info' to find out more about commands not in this list.
A star (*) next to a name means that the command is disabled.
! PIPELINE history [-c] [-d offset] [n] or hist>
job_spec [&] if COMMANDS; then COMMANDS; [ elif C>
(( expression )) jobs [-lnprs] [jobspec ...] or jobs >
. filename [arguments] kill [-s sigspec | -n signum | -sigs>
: let arg [arg ...]
[ arg... ] local [option] name[=value] ...
[[ expression ]] logout [n]
alias [-p] [name[=value] ... ] mapfile [-d delim] [-n count] [-O or>
bg [job_spec ...] popd [-n] [+N | -N]
bind [-lpsvPSVX] [-m keymap] [-f file> printf [-v var] format [arguments]
break [n] pushd [-n] [+N | -N | dir]
builtin [shell-builtin [arg ...]] pwd [-LP]
caller [expr] read [-Eers] [-a array] [-d delim] [>
case WORD in [PATTERN [| PATTERN]...)> readarray [-d delim] [-n count] [-O >
cd [-L|[-P [-e]]] [-@] [dir] readonly [-aAf] [name[=value] ...] o>
command [-pVv] command [arg ...] return [n]
compgen [-V varname] [-abcdefgjksuv] > select NAME [in WORDS ... ;] do COMM>
complete [-abcdefgjksuv] [-pr] [-DEI]> set [-abefhkmnptuvxBCEHPT] [-o optio>
compopt [-o|+o option] [-DEI] [name .> shift [n]
continue [n] shopt [-pqsu] [-o] [optname ...]
coproc [NAME] command [redirections] source filename [arguments]
declare [-aAfFgiIlnrtux] [name[=value> suspend [-f]
dirs [-clpv] [+N] [-N] test [expr]
disown [-h] [-ar] [jobspec ... | pid > time [-p] pipeline
echo [-neE] [arg ...] times
enable [-a] [-dnps] [-f filename] [na> trap [-Plp] [[action] signal_spec ..>
eval [arg ...] true
exec [-cl] [-a name] [command [argume> type [-afptP] name [name ...]
exit [n] typeset [-aAfFgiIlnrtux] name[=value>
export [-fn] [name[=value] ...] or ex> ulimit [-SHabcdefiklmnpqrstuvxPRT] [>
false umask [-p] [-S] [mode]
fc [-e ename] [-lnr] [first] [last] o> unalias [-a] name [name ...]
fg [job_spec] unset [-f] [-v] [-n] [name ...]
for NAME [in WORDS ... ] ; do COMMAND> until COMMANDS; do COMMANDS-2; done
for (( exp1; exp2; exp3 )); do COMMAN> variables - Names and meanings of so>
function name { COMMANDS ; } or name > wait [-fn] [-p var] [id ...]
getopts optstring name [arg ...] while COMMANDS; do COMMANDS-2; done
hash [-lr] [-p pathname] [-dt] [name > { COMMANDS ; }
help [-dms] [pattern ...]
help: help [-dms] [pattern ...]
shift - Shift positional parameters.
shift: shift [n]
Shift positional parameters.
Rename the positional parameters $N+1,$N+2 ... to $1,$2 ... If N is
not given, it is assumed to be 1.
Exit Status:
Returns success unless N is negative or greater than $#.
builtin: builtin [shell-builtin [arg ...]]
shift: shift [n]
Shell commands matching keyword `read*'
read: read [-Eers] [-a array] [-d delim] [-i text] [-n nchars] [-N nchars] [-p prompt] [-t timeout] [-u fd] [name ...]
readarray: readarray [-d delim] [-n count] [-O origin] [-s count] [-t] [-u fd] [-C callback] [-c quantum] [array]
readonly: readonly [-aAf] [name[=value] ...] or readonly -p
NAME
: - Null command.
SYNOPSIS
:
DESCRIPTION
Null command.
No effect; the command does nothing.
Exit Status:
Always succeeds.
SEE ALSO
bash(1)
IMPLEMENTATION
Copyright (C) 2022 Free Software Foundation, Inc.
These shell commands are defined internally. Type `help' to see this list.
Type `help name' to find out more about the function `name'.
Use `info bash' to find out more about the shell in general.
Use `man -k' or `info' to find out more about commands not in this list.
A star (*) next to a name means that the command is disabled.
! PIPELINE history [-c] [-d offset] [n] or hist>
job_spec [&] if COMMANDS; then COMMANDS; [ elif C>
(( expression )) jobs [-lnprs] [jobspec ...] or jobs >
. filename [arguments] kill [-s sigspec | -n signum | -sigs>
: let arg [arg ...]
[ arg... ] local [option] name[=value] ...
[[ expression ]] logout [n]
alias [-p] [name[=value] ... ] mapfile [-d delim] [-n count] [-O or>
bg [job_spec ...] popd [-n] [+N | -N]
bind [-lpsvPSVX] [-m keymap] [-f file> printf [-v var] format [arguments]
break [n] pushd [-n] [+N | -N | dir]
builtin [shell-builtin [arg ...]] pwd [-LP]
caller [expr] read [-Eers] [-a array] [-d delim] [>
case WORD in [PATTERN [| PATTERN]...)> readarray [-d delim] [-n count] [-O >
cd [-L|[-P [-e]]] [-@] [dir] readonly [-aAf] [name[=value] ...] o>
command [-pVv] command [arg ...] return [n]
compgen [-V varname] [-abcdefgjksuv] > select NAME [in WORDS ... ;] do COMM>
complete [-abcdefgjksuv] [-pr] [-DEI]> set [-abefhkmnptuvxBCEHPT] [-o optio>
compopt [-o|+o option] [-DEI] [name .> shift [n]
continue [n] shopt [-pqsu] [-o] [optname ...]
coproc [NAME] command [redirections] source filename [arguments]
declare [-aAfFgiIlnrtux] [name[=value> suspend [-f]
dirs [-clpv] [+N] [-N] test [expr]
disown [-h] [-ar] [jobspec ... | pid > time [-p] pipeline
echo [-neE] [arg ...] times
enable [-a] [-dnps] [-f filename] [na> trap [-Plp] [[action] signal_spec ..>
eval [arg ...] true
exec [-cl] [-a name] [command [argume> type [-afptP] name [name ...]
exit [n] typeset [-aAfFgiIlnrtux] name[=value>
export [-fn] [name[=value] ...] or ex> ulimit [-SHabcdefiklmnpqrstuvxPRT] [>
false umask [-p] [-S] [mode]
fc [-e ename] [-lnr] [first] [last] o> unalias [-a] name [name ...]
fg [job_spec] unset [-f] [-v] [-n] [name ...]
for NAME [in WORDS ... ] ; do COMMAND> until COMMANDS; do COMMANDS-2; done
for (( exp1; exp2; exp3 )); do COMMAN> variables - Names and meanings of so>
function name { COMMANDS ; } or name > wait [-fn] [-p var] [id ...]
getopts optstring name [arg ...] while COMMANDS; do COMMANDS-2; done
hash [-lr] [-p pathname] [-dt] [name > { COMMANDS ; }
help [-dms] [pattern ...]
./builtins.tests: line 316: exit: status: numeric argument required
+30 -4
View File
@@ -71,6 +71,10 @@ for i in a b c; do
done
echo end
# check arguments to break and continue that exceed the loop level
for f in 1 2 3; do break -- 5; done
for f in 1 2 3; do continue -- 5; done
# check that `eval' re-evaluates arguments, but `builtin' and `command' do not
AVAR='$BVAR'
BVAR=foo
@@ -145,11 +149,18 @@ command -p hash rm
# check out source/.
# sourcing a zero-length-file had better not be an error
rm -f /tmp/zero-length-file
cp /dev/null /tmp/zero-length-file
. /tmp/zero-length-file
rm -f $TMPDIR/zero-length-file-$$
cp /dev/null $TMPDIR/zero-length-file-$$
. $TMPDIR/zero-length-file-$$
echo $?
rm /tmp/zero-length-file
rm $TMPDIR/zero-length-file-$$
# and sourcing a file that doesn't end in a newline had better work too
SFILE=$TMPDIR/sourced-file-$$
printf 'echo no-newline' > $SFILE
. $SFILE
rm -f $SFILE
unset -v SFILE
AVAR=AVAR
@@ -262,6 +273,13 @@ kill -l 4096
# kill -l NAME should return the signal number
kill -l ${sigone/SIG/}
# kill -l NAME should work with and without the SIG prefix
x=$(kill -l INT)
y=$(kill -l SIGINT)
[[ $x == $y ]] || echo kill -l error with SIG prefix
unset -v x y
# test behavior of shopt xpg_echo
${THIS_SH} ./builtins2.sub
@@ -286,6 +304,14 @@ ${THIS_SH} ./builtins8.sub
# hash tests
${THIS_SH} ./builtins9.sub
# help tests
${THIS_SH} ./builtins10.sub
shift 0 # succeeds silently
options=$(set -o -B 2>&1 | wc -l)
[[ $options -gt 3 ]] || echo 'set: bad -o option name parsing'
# this must be last -- it is a fatal error
exit status
+32
View File
@@ -0,0 +1,32 @@
# This program is free software: you can redistribute it and/or modify
# it under the terms of the GNU General Public License as published by
# the Free Software Foundation, either version 3 of the License, or
# (at your option) any later version.
#
# This program is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
# GNU General Public License for more details.
#
# You should have received a copy of the GNU General Public License
# along with this program. If not, see <http://www.gnu.org/licenses/>.
#
# have to run through sed or grep to filter out version information
# let's exercise print-help
help -x
help -- | sed 1d
command help -s help
builtin help -d shift
shift --help
help -s builtin shift
# this hasn't ever been very useful
help -s 'read*'
help -m : | grep -v version
LC_ALL=en_US.UTF-8
help -- | sed 1d
+16
View File
@@ -63,3 +63,19 @@ umask -S
umask 022
umask a+xr
umask -S
umask 022
umask g+X
umask -S
umask 022
umask o+X
umask -S
umask 022
umask +X
umask -S
umask 022
umask g+x,o+x
umask -S
+7
View File
@@ -50,3 +50,10 @@ echo $?
hash -r
hash -p / root
hash -r
# assignment to BASH_CMDS[x] should be like hash -p
BASH_CMDS[cat]=/nosuchfile
hash -lt cat
hash -d cat
+227
View File
@@ -61,3 +61,230 @@ complete -d rmdir
complete -f more
complete -f -X '!*.+(gz|tgz)' gzcat
./complete.tests: line 123: complete: notthere: no completion specification
!
%
(( ... ))
.
:
[
[[ ... ]]
alias
bg
bind
break
builtin
caller
case
cd
command
compgen
complete
compopt
continue
coproc
declare
dirs
disown
echo
enable
eval
exec
exit
export
false
fc
fg
for
for ((
function
getopts
hash
help
history
if
jobs
kill
let
local
logout
mapfile
popd
printf
pushd
pwd
read
readarray
readonly
return
select
set
shift
shopt
source
suspend
test
time
times
trap
true
type
typeset
ulimit
umask
unalias
unset
until
variables
wait
while
{ ... }
.
:
[
alias
bg
bind
break
builtin
caller
cd
command
compgen
complete
compopt
continue
declare
dirs
disown
echo
enable
eval
exec
exit
export
false
fc
fg
getopts
hash
help
history
jobs
kill
let
local
logout
mapfile
popd
printf
pushd
pwd
read
readarray
readonly
return
set
shift
shopt
source
suspend
test
times
trap
true
type
typeset
ulimit
umask
unalias
unset
wait
.
:
[
alias
bg
bind
break
builtin
caller
cd
command
compgen
complete
compopt
continue
declare
dirs
disown
echo
enable
eval
exec
exit
export
false
fc
fg
getopts
hash
help
history
jobs
kill
let
local
logout
mapfile
popd
printf
pushd
pwd
read
readarray
readonly
return
set
shift
shopt
source
suspend
test
times
trap
true
type
typeset
ulimit
umask
unalias
unset
wait
if
then
else
elif
fi
case
esac
for
select
while
until
do
done
in
function
time
{
}
!
[[
]]
coproc
./complete.tests: line 136: compgen: -r: invalid option
compgen: usage: compgen [-V varname] [-abcdefgjksuv] [-o option] [-A action] [-G globpat] [-W wordlist] [-F function] [-C command] [-X filterpat] [-P prefix] [-S suffix] [word]
./complete.tests: line 137: compgen: noaction: invalid action name
./complete.tests: line 138: compgen: -D: invalid option
compgen: usage: compgen [-V varname] [-abcdefgjksuv] [-o option] [-A action] [-G globpat] [-W wordlist] [-F function] [-C command] [-X filterpat] [-P prefix] [-S suffix] [word]
./complete.tests: line 140: compopt: nooption: invalid option name
+14
View File
@@ -124,3 +124,17 @@ complete -r notthere
complete -r
complete
# some random compgen topics
compgen -A helptopic
command compgen -b
compgen -A enabled
compgen -k
# and some errors
compgen -r
compgen -A noaction
compgen -D
compopt -o nooption
+1
View File
@@ -24,6 +24,7 @@ blank ----
blank ----
blank ----
blank ----
func: v = comsub
#esac
a
ok 1
+9
View File
@@ -91,6 +91,15 @@ read << EOC
Dir: ${BUILDDIR#<(echo a)/}
EOC
# return in a comsub inside a shell function should abort the comsub
func()
{
local v
v=$( echo comsub ; return ; echo after)
echo $FUNCNAME: v = $v
}
func
${THIS_SH} ./comsub1.sub
${THIS_SH} ./comsub2.sub
${THIS_SH} ./comsub3.sub
+8
View File
@@ -5,3 +5,11 @@ SECONDS ok
EPOCHSECONDS ok
EPOCHREALTIME ok
echo $BASH_COMMAND
110
111
112
113
114
./dynvar.tests: line 115: ((: LINENO / 0 : division by 0 (error token is "0 ")
0
0
+25 -1
View File
@@ -47,6 +47,11 @@ after=$SECONDS
if (( $after > $before )); then echo SECONDS ok; fi
unset before after
# do the best we can to test assignment to SECONDS
SECONDS=2
sleep 1
[[ $SECONDS -ge 10 ]] && echo 'SECONDS: bad value assignment'
# EPOCHSECONDS
# not exact, but should work
@@ -99,4 +104,23 @@ ${THIS_SH} -c 'echo $BASH_COMMAND'
# FUNCNAME tested in func.tests
# RANDOM tested in varenv.sh
# LINENO tested in dbg-support
# LINENO tested in dbg-support, misc additional tests here
arith_lineno()
{
echo $LINENO
for f in 1 ; do echo $LINENO; done
for (( f=1 ; f < 2; f++ )); do echo $LINENO; done
echo $(( $LINENO ))
(( 1 == 1 )) && echo $LINENO
(( LINENO / 0 ))
}
arith_lineno
# assignments to noassign variables are ignored
FUNCNAME=42
echo $? $FUNCNAME
GROUPS[0]=-1
echo $?
[[ ${GROUPS[0]} != -1 ]] || echo GROUPS noassign error
+108 -79
View File
@@ -13,110 +13,137 @@ unalias: usage: unalias [-a] name [name ...]
./errors.tests: line 48: `invalid-name': not a valid identifier
./errors.tests: line 50: `1': not a valid identifier
./errors.tests: line 51: `f\1': not a valid identifier
./errors.tests: line 55: `$1': not a valid identifier
declare -fr func
./errors.tests: line 64: func: readonly function
./errors.tests: line 67: unset: -x: invalid option
./errors.tests: line 72: func: readonly function
./errors.tests: line 75: unset: -x: invalid option
unset: usage: unset [-f] [-v] [-n] [name ...]
./errors.tests: line 70: unset: func: cannot unset: readonly function
./errors.tests: line 73: declare: func: readonly function
./errors.tests: line 77: declare: -a: invalid option
./errors.tests: line 78: declare: -i: invalid option
./errors.tests: line 82: unset: XPATH: cannot unset: readonly variable
./errors.tests: line 88: unset: cannot simultaneously unset a function and a variable
./errors.tests: line 91: declare: -z: invalid option
./errors.tests: line 78: unset: func: cannot unset: readonly function
./errors.tests: line 81: declare: func: readonly function
./errors.tests: line 85: declare: -a: invalid option
./errors.tests: line 86: declare: -i: invalid option
./errors.tests: line 90: unset: XPATH: cannot unset: readonly variable
./errors.tests: line 96: unset: cannot simultaneously unset a function and a variable
./errors.tests: line 99: declare: -z: invalid option
declare: usage: declare [-aAfFgiIlnrtux] [name[=value] ...] or declare -p [-aAfFilnrtux] [name ...]
./errors.tests: line 93: declare: `-z': not a valid identifier
./errors.tests: line 94: declare: `/bin/sh': not a valid identifier
./errors.tests: line 98: declare: cannot use `-f' to make functions
./errors.tests: line 101: exec: -i: invalid option
./errors.tests: line 101: declare: `-z': not a valid identifier
./errors.tests: line 102: declare: `/bin/sh': not a valid identifier
./errors.tests: line 106: declare: cannot use `-f' to make functions
./errors.tests: line 109: exec: -i: invalid option
exec: usage: exec [-cl] [-a name] [command [argument ...]] [redirection ...]
./errors.tests: line 105: export: XPATH: not a function
./errors.tests: line 108: break: only meaningful in a `for', `while', or `until' loop
./errors.tests: line 109: continue: only meaningful in a `for', `while', or `until' loop
./errors.tests: line 112: shift: label: numeric argument required
./errors.tests: line 117: shift: too many arguments
./errors.tests: line 123: let: expression expected
./errors.tests: line 126: local: can only be used in a function
./errors.tests: line 129: logout: not login shell: use `exit'
./errors.tests: line 132: hash: notthere: not found
./errors.tests: line 135: hash: -v: invalid option
./errors.tests: line 113: export: XPATH: not a function
./errors.tests: line 116: break: only meaningful in a `for', `while', or `until' loop
./errors.tests: line 117: continue: only meaningful in a `for', `while', or `until' loop
./errors.tests: line 120: shift: label: numeric argument required
./errors.tests: line 125: shift: too many arguments
./errors.tests: line 131: let: expression expected
./errors.tests: line 134: local: can only be used in a function
./errors.tests: line 137: logout: not login shell: use `exit'
./errors.tests: line 140: hash: notthere: not found
./errors.tests: line 143: hash: -v: invalid option
hash: usage: hash [-lr] [-p pathname] [-dt] [name ...]
./errors.tests: line 139: hash: hashing disabled
./errors.tests: line 142: export: `AA[4]': not a valid identifier
./errors.tests: line 143: readonly: `AA[4]': not a valid identifier
./errors.tests: line 146: unset: [-2]: bad array subscript
./errors.tests: line 150: AA: readonly variable
./errors.tests: line 154: AA: readonly variable
./errors.tests: line 162: shift: 5: shift count out of range
./errors.tests: line 163: shift: -2: shift count out of range
./errors.tests: line 166: shopt: no_such_option: invalid shell option name
./errors.tests: line 167: shopt: no_such_option: invalid shell option name
./errors.tests: line 170: umask: 09: octal number out of range
./errors.tests: line 171: umask: `:': invalid symbolic mode character
./errors.tests: line 172: umask: `:': invalid symbolic mode operator
./errors.tests: line 175: umask: -i: invalid option
./errors.tests: line 147: hash: hashing disabled
./errors.tests: line 150: export: `AA[4]': not a valid identifier
./errors.tests: line 151: readonly: `AA[4]': not a valid identifier
./errors.tests: line 152: export: `invalid-var=4': not a valid identifier
./errors.tests: line 153: readonly: `invalid-var=4': not a valid identifier
./errors.tests: line 154: export: `invalid-var': not a valid identifier
./errors.tests: line 155: readonly: `invalid-var': not a valid identifier
./errors.tests: line 158: unset: [-2]: bad array subscript
./errors.tests: line 162: AA: readonly variable
./errors.tests: line 166: AA: readonly variable
./errors.tests: line 174: shift: 5: shift count out of range
./errors.tests: line 175: shift: -2: shift count out of range
./errors.tests: line 178: shopt: no_such_option: invalid shell option name
./errors.tests: line 179: shopt: no_such_option: invalid shell option name
./errors.tests: line 180: shopt: no_such_option: invalid option name
./errors.tests: line 183: umask: 09: octal number out of range
./errors.tests: line 184: umask: `:': invalid symbolic mode character
./errors.tests: line 185: umask: `:': invalid symbolic mode operator
./errors.tests: line 188: umask: -i: invalid option
umask: usage: umask [-p] [-S] [mode]
./errors.tests: line 179: umask: `p': invalid symbolic mode character
./errors.tests: line 188: VAR: readonly variable
./errors.tests: line 191: declare: VAR: readonly variable
./errors.tests: line 192: declare: VAR: readonly variable
./errors.tests: line 194: declare: unset: not found
./errors.tests: line 197: VAR: readonly variable
./errors.tests: line 192: umask: `p': invalid symbolic mode character
./errors.tests: line 201: VAR: readonly variable
./errors.tests: line 204: declare: VAR: readonly variable
./errors.tests: line 205: declare: VAR: readonly variable
./errors.tests: line 207: declare: unset: not found
./errors.tests: line 210: VAR: readonly variable
comsub: -c: line 1: syntax error near unexpected token `)'
comsub: -c: line 1: `: $( for z in 1 2 3; do )'
comsub: -c: line 1: syntax error near unexpected token `done'
comsub: -c: line 1: `: $( for z in 1 2 3; done )'
./errors.tests: line 204: cd: HOME not set
./errors.tests: line 205: cd: /tmp/xyz.bash: No such file or directory
./errors.tests: line 207: cd: OLDPWD not set
./errors.tests: line 208: cd: /bin/sh: Not a directory
./errors.tests: line 210: cd: /tmp/cd-notthere: No such file or directory
./errors.tests: line 213: .: filename argument required
./errors.tests: line 217: cd: HOME not set
./errors.tests: line 218: cd: /tmp/xyz.bash: No such file or directory
./errors.tests: line 220: cd: OLDPWD not set
./errors.tests: line 221: cd: /bin/sh: Not a directory
./errors.tests: line 223: cd: /tmp/cd-notthere: No such file or directory
./errors.tests: line 225: cd: too many arguments
bash: line 1: PWD: readonly variable
1
./errors.tests: line 230: .: filename argument required
.: usage: . filename [arguments]
./errors.tests: line 214: source: filename argument required
./errors.tests: line 231: source: filename argument required
source: usage: source filename [arguments]
./errors.tests: line 217: .: -i: invalid option
./errors.tests: line 234: .: -i: invalid option
.: usage: . filename [arguments]
./errors.tests: line 220: set: -q: invalid option
./errors.tests: line 237: set: -q: invalid option
set: usage: set [-abefhkmnptuvxBCEHPT] [-o option-name] [--] [-] [arg ...]
./errors.tests: line 223: enable: sh: not a shell builtin
./errors.tests: line 223: enable: bash: not a shell builtin
./errors.tests: line 226: shopt: cannot set and unset shell options simultaneously
./errors.tests: line 229: read: var: invalid timeout specification
./errors.tests: line 232: read: `/bin/sh': not a valid identifier
./errors.tests: line 235: VAR: readonly variable
./errors.tests: line 238: readonly: -x: invalid option
./errors.tests: line 240: enable: sh: not a shell builtin
./errors.tests: line 240: enable: bash: not a shell builtin
./errors.tests: line 243: shopt: cannot set and unset shell options simultaneously
./errors.tests: line 246: read: -x: invalid option
read: usage: read [-Eers] [-a array] [-d delim] [-i text] [-n nchars] [-N nchars] [-p prompt] [-t timeout] [-u fd] [name ...]
./errors.tests: line 249: read: var: invalid timeout specification
./errors.tests: line 252: read: `/bin/sh': not a valid identifier
./errors.tests: line 253: read: `/bin/sh': not a valid identifier
./errors.tests: line 256: VAR: readonly variable
./errors.tests: line 259: read: XX: invalid file descriptor specification
./errors.tests: line 260: read: 42: invalid file descriptor: Bad file descriptor
./errors.tests: line 263: mapfile: XX: invalid file descriptor specification
./errors.tests: line 264: mapfile: 42: invalid file descriptor: Bad file descriptor
./errors.tests: line 268: mapfile: empty array variable name
./errors.tests: line 269: mapfile: `invalid-var': not a valid identifier
./errors.tests: line 272: readonly: -x: invalid option
readonly: usage: readonly [-aAf] [name[=value] ...] or readonly -p
./errors.tests: line 241: eval: -i: invalid option
./errors.tests: line 275: eval: -i: invalid option
eval: usage: eval [arg ...]
./errors.tests: line 242: command: -i: invalid option
./errors.tests: line 276: command: -i: invalid option
command: usage: command [-pVv] command [arg ...]
./errors.tests: line 245: /bin/sh + 0: arithmetic syntax error: operand expected (error token is "/bin/sh + 0")
./errors.tests: line 246: /bin/sh + 0: arithmetic syntax error: operand expected (error token is "/bin/sh + 0")
./errors.tests: line 249: trap: NOSIG: invalid signal specification
./errors.tests: line 252: trap: -s: invalid option
./errors.tests: line 279: /bin/sh + 0: arithmetic syntax error: operand expected (error token is "/bin/sh + 0")
./errors.tests: line 280: /bin/sh + 0: arithmetic syntax error: operand expected (error token is "/bin/sh + 0")
./errors.tests: line 283: trap: NOSIG: invalid signal specification
./errors.tests: line 286: trap: -s: invalid option
trap: usage: trap [-Plp] [[action] signal_spec ...]
./errors.tests: line 258: return: can only `return' from a function or sourced script
./errors.tests: line 262: break: 0: loop count out of range
./errors.tests: line 266: continue: 0: loop count out of range
./errors.tests: line 271: builtin: bash: not a shell builtin
./errors.tests: line 275: bg: no job control
./errors.tests: line 276: fg: no job control
./errors.tests: line 279: kill: -s: option requires an argument
./errors.tests: line 281: kill: S: invalid signal specification
./errors.tests: line 283: kill: `': not a pid or valid job spec
./errors.tests: line 292: return: can only `return' from a function or sourced script
./errors.tests: line 296: break: 0: loop count out of range
./errors.tests: line 300: continue: 0: loop count out of range
./errors.tests: line 305: builtin: bash: not a shell builtin
./errors.tests: line 309: bg: no job control
./errors.tests: line 310: fg: no job control
./errors.tests: line 313: kill: -s: option requires an argument
./errors.tests: line 315: kill: S: invalid signal specification
./errors.tests: line 317: kill: `': not a pid or valid job spec
kill: usage: kill [-s sigspec | -n signum | -sigspec] pid | jobspec ... or kill -l [sigspec]
./errors.tests: line 288: set: trackall: invalid option name
./errors.tests: line 289: set: -q: invalid option
./errors.tests: line 321: kill: SIGBAD: invalid signal specification
./errors.tests: line 323: kill: BAD: invalid signal specification
./errors.tests: line 325: kill: @12: arguments must be process or job IDs
./errors.tests: line 328: unset: BASH_LINENO: cannot unset
./errors.tests: line 328: unset: BASH_SOURCE: cannot unset
./errors.tests: line 331: set: trackall: invalid option name
./errors.tests: line 332: set: -q: invalid option
set: usage: set [-abefhkmnptuvxBCEHPT] [-o option-name] [--] [-] [arg ...]
./errors.tests: line 290: set: -i: invalid option
./errors.tests: line 333: set: -i: invalid option
set: usage: set [-abefhkmnptuvxBCEHPT] [-o option-name] [--] [-] [arg ...]
./errors.tests: line 294: xx: readonly variable
./errors.tests: line 337: xx: readonly variable
1
./errors1.sub: line 14: .: -i: invalid option
.: usage: . filename [arguments]
./errors1.sub: line 22: shift: -4: shift count out of range
./errors1.sub: line 23: shift: -4: shift count out of range
./errors1.sub: line 27: break: -1: loop count out of range
./errors1.sub: line 28: continue: -1: loop count out of range
./errors1.sub: line 29: break: -5: loop count out of range
./errors1.sub: line 30: continue: -5: loop count out of range
after f
./errors2.sub: line 3: ${$NO_SUCH_VAR}: bad substitution
1
@@ -200,6 +227,7 @@ after non-special builtin: 0
after special builtin: 0
./errors7.sub: line 27: x: readonly variable
./errors7.sub: line 29: x: readonly variable
./errors7.sub: line 32: v: readonly variable
./errors7.sub: line 21: x: readonly variable
after no such command: 1
./errors7.sub: line 23: x: readonly variable
@@ -207,6 +235,7 @@ after non-special builtin: 1
./errors7.sub: line 25: x: readonly variable
./errors7.sub: line 27: x: readonly variable
./errors7.sub: line 29: x: readonly variable
./errors7.sub: line 32: v: readonly variable
./errors8.sub: eval: line 7: syntax error: unexpected end of file
ok 1
./errors8.sub: line 8: v: readonly variable
@@ -238,4 +267,4 @@ sh: line 1: unset: `a-b': not a valid identifier
sh: line 1: /nosuchfile: No such file or directory
sh: line 1: trap: SIGNOSIG: invalid signal specification
after trap
./errors.tests: line 333: `!!': not a valid identifier
./errors.tests: line 376: `!!': not a valid identifier
+43
View File
@@ -50,6 +50,14 @@ select invalid-name in a b c; do echo $REPLY; done
(set -o posix ; select 1 in a b c; do echo $REPLY; done; echo after posix select)
(set -o posix ; select f\1 in a b c ; do echo $REPLY ; done ; echo after posix select 2)
# even in functions
bad-select()
{
select $1 in a b c ; do echo $REPLY ; done
}
bad-select 'a b'
unset -f bad-select
# try to rebind a read-only function
func()
{
@@ -141,6 +149,10 @@ hash -p ${THIS_SH} ${THIS_SH##*/}
# bad identifiers to declare/readonly/export
export AA[4]
readonly AA[4]
export invalid-var=4
readonly invalid-var=4
export invalid-var
readonly invalid-var
declare -a AA
unset AA[-2]
@@ -165,6 +177,7 @@ shift -2
# bad shell options
shopt -s no_such_option
shopt no_such_option
shopt -s -o no_such_option
# non-octal digits for umask and other errors
umask 09
@@ -208,6 +221,10 @@ cd -
cd /bin/sh # error - not a directory
OLDPWD=/tmp/cd-notthere
cd -
# too many arguments
cd one two three
# cd doesn't like it if PWD is readonly
${THIS_SH} -c 'readonly PWD ; cd / ; echo $?' bash
# various `source/.' errors
.
@@ -225,15 +242,32 @@ enable sh bash
# try to set and unset shell options simultaneously
shopt -s -u checkhash
# error
read -x
# this is an error -- bad timeout spec
read -t var < /dev/null
# try to read into an invalid identifier
read /bin/sh < /dev/null
read A /bin/sh < /dev/null
# try to read into a readonly variable
read VAR < /dev/null
# invalid file descriptor
read -u XX < /dev/null
read -u 42 < /dev/null
# same with mapfile
mapfile -u XX A < /dev/null
mapfile -u 42 A < /dev/null
unset -v A
# invalid identifier arguments to mapfile
mapfile '' </dev/null
mapfile invalid-var < /dev/null
# bad option to readonly/export
readonly -x foo
@@ -283,6 +317,15 @@ kill -S
kill -INT ''
# argument required
kill -INT
# bad signal specification
kill -l SIGBAD
# bad signal specification
kill -l BAD
# bad process specification
kill -HUP @12
# cannot unset non-unsettable variables
unset -v BASH_LINENO BASH_SOURCE
# bad shell option names
set -o trackall # bash is not ksh
+5 -4
View File
@@ -20,13 +20,14 @@ f()
set -- a b c
shift -4
shift -- -4
f
for f in 1 2 3; do
break -1
done
for f in 1 2 3; do break -1; done
for f in 1 2 3; do continue -1; done
for f in 1 2 3; do break -- -5; done
for f in 1 2 3; do continue -- -5; done
f()
{
+3
View File
@@ -28,3 +28,6 @@ echo after special builtin: $? )
echo after assignment error: $? )
( x=8
echo after assignment statement error: $? )
( readonly v; : ${v:=val}
echo variable assignment error )
+11 -7
View File
@@ -15,7 +15,11 @@ after exec1.sub: one two three
126
/: /: Is a directory
126
./execscript: line 47: .: /: is a directory
bash: line 1: exec: .: cannot execute: Is a directory
posix-bash: line 1: exec: .: cannot execute: Is a directory
bash: line 1: exec: .: cannot execute: Is a directory
posix-bash: line 1: exec: .: cannot execute: Is a directory
./execscript: line 55: .: /: is a directory
1
126
0
@@ -31,17 +35,17 @@ trap -- '' SIGTERM
trap -- 'echo USR1' SIGUSR1
USR1
EXIT
./execscript: line 71: notthere: command not found
127
./execscript: line 73: notthere: command not found
127
./execscript: line 75: notthere: command not found
./execscript: line 79: notthere: command not found
127
./execscript: line 81: notthere: command not found
127
./execscript: line 83: notthere: command not found
127
./execscript: line 85: notthere: command not found
./execscript: line 89: notthere: command not found
127
./execscript: line 91: notthere: command not found
127
./execscript: line 93: notthere: command not found
127
this is sh
this is sh
+8
View File
@@ -43,6 +43,14 @@ echo $?
${THIS_SH} /
echo $?
# trying to exec a directory is a fatal error
${THIS_SH} -c 'exec . ; default: after exec directory' bash
POSIXLY_CORRECT=1 ${THIS_SH} -c 'exec . ; posix: after exec directory' posix-bash
# even if preceded by `command'
${THIS_SH} -c 'command exec . ; default: after command exec directory 2' bash
POSIXLY_CORRECT=1 ${THIS_SH} -c 'command exec . ; posix: after command exec directory 2' posix-bash
# try sourcing a directory
. /
echo $?
+2
View File
@@ -88,6 +88,8 @@ argv[1] = <abc>
argv[1] = <abc>
argv[1] = <posix>
argv[1] = <10>
argv[1] = <5>
argv[1] = <5>
argv[1] = <file.o>
argv[1] = <posix>
argv[1] = </src/cmd>
+9
View File
@@ -237,6 +237,15 @@ POSIX=/usr/posix
expect '<10>'
recho ${#POSIX}
# this was a problem through bash-5.2 -- it would skip random numbers because
# of multiple calls to find_variable
RANDOM=42
expect '<5>'
recho ${#RANDOM} # 17772
declare -i RANDOM=42
expect '<5>'
recho ${#RANDOM} # 17772
# remove shortest trailing match
x=file.c
expect '<file.o>'
+2
View File
@@ -166,6 +166,7 @@ after FUNCNEST unset: f = 201
./func4.sub: line 23: foo: maximum function nesting level exceeded (20)
1
after FUNCNEST assign: f = 38
./func5.sub: line 31: `sys$read': not a valid identifier
11111 ()
{
printf "FUNCNAME: %s\n" $FUNCNAME
@@ -189,4 +190,5 @@ break ()
echo FUNCNAME: $FUNCNAME
}
FUNCNAME: break
./func5.sub: line 54: `break': is a special builtin
5
+16
View File
@@ -12,6 +12,8 @@
# along with this program. If not, see <http://www.gnu.org/licenses/>.
#
# these are ok
function a=2
{
printf "FUNCNAME: %s\n" $FUNCNAME
@@ -22,6 +24,12 @@ function 11111
printf "FUNCNAME: %s\n" $FUNCNAME
}
# but this is still not
function sys$read
{
printf "FUNCNAME: %s\n" $FUNCNAME
}
declare -f
set -o posix
declare -f
@@ -36,3 +44,11 @@ break()
type break
\break
unset -f break
# but in posix mode, declaring such a function is an error
set -o posix
break()
{
echo FUNCNAME: $FUNCNAME
}
+2
View File
@@ -66,3 +66,5 @@ OPTARG = x = ?
unset x = ?
declare -r RO="foo"
declare -r RO="foo"
./getopts10.sub: line 33: V: readonly variable
1
+6
View File
@@ -28,3 +28,9 @@ typeset -p RO
getopts x x
typeset -p RO
readonly V
getopts x V
echo $?
+1
View File
@@ -305,4 +305,5 @@ check 'a\' 'a\' "$yes"
cd $ORIG_DIR
enable -d strmatch # just testing
exit 0
+1 -1
View File
@@ -15,7 +15,7 @@
# test basic behavior of globskipdots
TDIR=/tmp/dotglob-$$
{ mkdir $TDIR && cd $TDIR; } || exit 1
{ mkdir $TDIR && cd -L $TDIR; } || exit 1
touch a b aa bb .a .b .aa .bb
+1 -1
View File
@@ -15,7 +15,7 @@
TESTDIR=${TMPDIR}/glob-test-$$
mkdir ${TESTDIR}
cd $TESTDIR || {
cd -L $TESTDIR || {
echo "$TESTDIR: cannot cd" >&2
exit 1
}
+13
View File
@@ -140,6 +140,8 @@ three
one
two
three
(exit 42)
42
5.3
echo ${BASH_VERSION%\.*}
5.3
@@ -341,3 +343,14 @@ $ 1
$ 2
$ exit
0
a
b
c
d
1 echo a
2 echo c
3 echo d
4 history -d 2
5 history
./history8.sub: line 15: history: 72: history position out of range
./history8.sub: line 16: history: -72: history position out of range
+1
View File
@@ -132,3 +132,4 @@ ${THIS_SH} ./history4.sub
${THIS_SH} ./history5.sub
${THIS_SH} ./history6.sub
${THIS_SH} ./history7.sub
${THIS_SH} ./history8.sub
+5
View File
@@ -26,3 +26,8 @@ three
history
fc -s cat
# try re-executing a failed command, check the exit status
(exit 42)
fc -s -1
echo $?
+16
View File
@@ -0,0 +1,16 @@
trap 'rm -f "$OUT"' 0 1 2 3 6 15
HISTFILE=$TMPDIR/fchist-$$ ; OUT=$HISTFILE
unset HISTIGNORE HISTCONTROL
set -o history
echo a
echo b
echo c
echo d
history -d 2
history
history -d 72
history -d -72
+13 -1
View File
@@ -69,8 +69,20 @@ GNU long options:
Shell options:
-ilrsD or -c command or -O shopt_option (invocation only)
-abefhkmnptuvxBCEHPT or -o option
this-bash
this-bash this-bash
$- for -c includes c
bash: line 0: badopt: invalid shell option name
checkwinsize:cmdhist:complete_fullquote:extquote:force_fignore:globasciiranges:globskipdots:hostcomplete:interactive_comments:patsub_replacement:progcomp:promptvars:sourcepath
checkhash:checkwinsize:cmdhist:complete_fullquote:extquote:force_fignore:globasciiranges:globskipdots:hostcomplete:interactive_comments:patsub_replacement:progcomp:promptvars:sourcepath
cmdhist:complete_fullquote:extquote:force_fignore:globasciiranges:globskipdots:hostcomplete:interactive_comments:patsub_replacement:progcomp:promptvars:sourcepath
./invocation1.sub: line 40: BASHOPTS: readonly variable
braceexpand:hashall:interactive-comments
braceexpand:hashall:interactive-comments
hashall:interactive-comments
hashall:interactive-comments
braceexpand:hashall:interactive-comments:noglob
braceexpand:hashall:interactive-comments:noglob
./invocation2.sub: line 50: SHELLOPTS: readonly variable
a
a
bad-interp
+8 -3
View File
@@ -16,8 +16,6 @@
# invocation modes and errors
export BASH_ARGV0=this-bash
${THIS_SH} .
#${THIS_SH} --version -c 'exit 0' bash
@@ -29,10 +27,17 @@ ${THIS_SH} --badopt |& sed 's|^.*/bash|bash|'
${THIS_SH} --initfile |& sed 's|^.*/bash|bash|'
${THIS_SH} -q |& sed 's|^.*/bash|bash|'
${THIS_SH} -c 'echo $0'
export BASH_ARGV0=this-bash
${THIS_SH} -c 'echo $0 $BASH_ARGV0'
unset BASH_ARGV0
{ ${THIS_SH} -c 'echo $-' bash | grep c >/dev/null; } && echo '$- for -c includes c'
# BASHOPTS
${THIS_SH} ./invocation1.sub
# SHELLOPTS
${THIS_SH} ./invocation2.sub
: ${TMPDIR:=/tmp}
TDIR=$TMPDIR/invocation-$$
mkdir $TDIR || exit 1
+40
View File
@@ -0,0 +1,40 @@
# This program is free software: you can redistribute it and/or modify
# it under the terms of the GNU General Public License as published by
# the Free Software Foundation, either version 3 of the License, or
# (at your option) any later version.
#
# This program is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
# GNU General Public License for more details.
#
# You should have received a copy of the GNU General Public License
# along with this program. If not, see <http://www.gnu.org/licenses/>.
#
set +o posix
shopt -u xpg_echo
# check $BASHOPTS inheritance
# the first should be an error
${THIS_SH} -O checkhash -O badopt -c 'echo $BASHOPTS' bash 2>&1 | sed 's|^.*/bash|bash|'
# this should reflect the default set of options
${THIS_SH} -c 'echo $BASHOPTS'
# now let's turn one of them on (checkhash is not enabled by default)
${THIS_SH} -O checkhash -c 'echo $BASHOPTS' bash
# let's turn one of them off
${THIS_SH} +O checkwinsize -c 'echo $BASHOPTS' bash
# turn on a non-default option
shopt -s checkhash
export BASHOPTS
# and make sure the child shell sees it enabled
if ${THIS_SH} -c 'echo $BASHOPTS' | grep checkhash >/dev/null 2>&1; then
:
else
echo 'BASHOPTS: checkhash not inherited correctly'
fi
shopt -u checkhash
export -n BASHOPTS
# but assigning to BASHOPTS is an error
BASHOPTS=$BASHOPTS
+50
View File
@@ -0,0 +1,50 @@
# This program is free software: you can redistribute it and/or modify
# it under the terms of the GNU General Public License as published by
# the Free Software Foundation, either version 3 of the License, or
# (at your option) any later version.
#
# This program is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
# GNU General Public License for more details.
#
# You should have received a copy of the GNU General Public License
# along with this program. If not, see <http://www.gnu.org/licenses/>.
#
set +o posix
shopt -u xpg_echo
echo $SHELLOPTS
set +B # on by default
# shouldn't appear
echo $SHELLOPTS | grep braceexpand
export SHELLOPTS
# but it will appear here because it's enabled by default
${THIS_SH} -c 'echo $SHELLOPTS'
# turn off an option that's on by default
${THIS_SH} +B -c 'echo $SHELLOPTS'
${THIS_SH} +o braceexpand -c 'echo $SHELLOPTS'
# turn on an option that's off by default
if ${THIS_SH} -f -c 'echo $SHELLOPTS' | grep noglob 2>&1; then
:
else
echo 'SHELLOPTS: noglob not inherited correctly'
fi
# in a different way
set -o noglob
if ${THIS_SH} -c 'echo $SHELLOPTS' | grep noglob 2>&1; then
:
else
echo 'SHELLOPTS: noglob not inherited correctly'
fi
# restore default state
set -o braceexpand
set +o noglob
# but assigning to SHELLOPTS is an error; have to use set -o/+o
SHELLOPTS=$SHELLOPTS
+18 -15
View File
@@ -33,17 +33,19 @@ i killed it
2: ok 3
127
./jobs5.sub: line 71: declare: wpid: not found
./jobs5.sub: line 74: wait: `invalid-varname': not a valid identifier
./jobs5.sub: line 76: wait: WV: cannot unset: readonly variable
child1 exit status 0
[1]+ Running sleep 20 &
./jobs7.sub: line 5: fg: no current jobs
[1]+ Running sleep 20 &
0
./jobs.tests: line 40: wait: %1: no such job
./jobs.tests: line 45: fg: no job control
./jobs.tests: line 42: wait: %1: no such job
./jobs.tests: line 47: fg: no job control
wait-for-pid
wait-errors
./jobs.tests: line 58: wait: `1-1': not a pid or valid job spec
./jobs.tests: line 59: wait: `-4': not a pid or valid job spec
./jobs.tests: line 60: wait: `1-1': not a pid or valid job spec
./jobs.tests: line 61: wait: `-4': not a pid or valid job spec
wait-for-background-pids
async list wait-for-background-pids
async list wait for child
@@ -52,7 +54,7 @@ wait-when-no-children
posix jobs output
[1]+ Done sleep 1
wait-for-job
./jobs.tests: line 84: wait: %2: no such job
./jobs.tests: line 86: wait: %2: no such job
127
async list wait-for-job
forked
@@ -65,19 +67,20 @@ sleep 2
fg-bg 4
sleep 2
fg-bg 5
./jobs.tests: line 111: fg: %2: no such job
./jobs.tests: line 112: bg: job 1 already in background
./jobs.tests: line 113: fg: %2: no such job
./jobs.tests: line 114: bg: job 1 already in background
fg-bg 6
./jobs.tests: line 119: fg: -s: invalid option
./jobs.tests: line 121: fg: -s: invalid option
fg: usage: fg [job_spec]
./jobs.tests: line 120: bg: -s: invalid option
./jobs.tests: line 122: bg: -s: invalid option
bg: usage: bg [job_spec ...]
./jobs.tests: line 125: disown: -s: invalid option
./jobs.tests: line 127: disown: -s: invalid option
disown: usage: disown [-h] [-ar] [jobspec ... | pid ...]
./jobs.tests: line 129: disown: %1: no such job
./jobs.tests: line 132: disown: %2: no such job
./jobs.tests: line 131: disown: %1: no such job
./jobs.tests: line 134: disown: %2: no such job
./jobs.tests: line 137: disown: @12: no such job
wait-for-non-child
./jobs.tests: line 135: wait: pid 1 is not a child of this shell
./jobs.tests: line 140: wait: pid 1 is not a child of this shell
127
3 -- 1 2 3 -- 1 - 2 - 3
[1] Running sleep 300 &
@@ -87,8 +90,8 @@ running jobs:
[1] Running sleep 300 &
[2]- Running sleep 350 &
[3]+ Running sleep 400 &
./jobs.tests: line 152: kill: %4: no such job
./jobs.tests: line 154: jobs: %4: no such job
./jobs.tests: line 157: kill: %4: no such job
./jobs.tests: line 159: jobs: %4: no such job
current job:
[3]+ Running sleep 400 &
previous job:
+5
View File
@@ -32,6 +32,8 @@ ${THIS_SH} ./jobs5.sub
${THIS_SH} ./jobs6.sub
${THIS_SH} ./jobs7.sub
# more disown -h tests
${THIS_SH} ./jobs8.sub
jobs
echo $?
@@ -131,6 +133,9 @@ disown %1
# this, however, is an error
disown %2
# this is definitely an error
disown -h @12
echo wait-for-non-child
wait 1
echo $?
+5
View File
@@ -69,3 +69,8 @@ echo $wpid $?
jobs
wait -p wpid
declare -p wpid
# let's check errors like with other builtins that take variable names
wait -p invalid-varname
readonly WV
wait -p WV
+29
View File
@@ -0,0 +1,29 @@
# This program is free software: you can redistribute it and/or modify
# it under the terms of the GNU General Public License as published by
# the Free Software Foundation, either version 3 of the License, or
# (at your option) any later version.
#
# This program is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
# GNU General Public License for more details.
#
# You should have received a copy of the GNU General Public License
# along with this program. If not, see <http://www.gnu.org/licenses/>.
#
# tests of disown -h
set -m
sleep 1&
sleep 1&
sleep 1&
disown -ah
sleep 1&
sleep 1&
sleep 1&
disown -rh
+14 -13
View File
@@ -59,6 +59,7 @@ argv[1] = <4>
argv[1] = <op>
argv[1] = <abcdefghijklmnop>
argv[1] = <abcdefghijklmnop>
./new-exp.tests: line 189: bad-var: invalid variable name
argv[1] = <a>
argv[2] = <b>
argv[3] = <c>
@@ -66,8 +67,8 @@ argv[4] = <d>
argv[1] = <a>
argv[2] = <b c>
argv[3] = <d>
./new-exp.tests: line 197: ABX: unbound variable
./new-exp.tests: line 201: $6: cannot assign in this way
./new-exp.tests: line 202: ABX: unbound variable
./new-exp.tests: line 206: $6: cannot assign in this way
argv[1] = <xxcde>
argv[1] = <axxde>
argv[1] = <abxyz>
@@ -176,7 +177,7 @@ a
./new-exp2.sub: line 62: 1111111111111111111111: command not found
argv[1] = <6>
./new-exp.tests: line 302: ${#:}: bad substitution
./new-exp.tests: line 307: ${#:}: bad substitution
argv[1] = <'>
argv[1] = <">
argv[1] = <"hello">
@@ -411,13 +412,13 @@ argv[6] = <w>
argv[7] = <x>
argv[8] = <y>
argv[9] = <z>
./new-exp.tests: line 520: $9: unbound variable
./new-exp.tests: line 521: 9: unbound variable
./new-exp.tests: line 522: UNSET: unbound variable
./new-exp.tests: line 523: UNSET: unbound variable
./new-exp.tests: line 524: UNSET: unbound variable
./new-exp.tests: line 525: UNSET: unbound variable
./new-exp.tests: line 526: UNSET: unbound variable
./new-exp.tests: line 525: $9: unbound variable
./new-exp.tests: line 526: 9: unbound variable
./new-exp.tests: line 527: UNSET: unbound variable
./new-exp.tests: line 528: UNSET: unbound variable
./new-exp.tests: line 529: UNSET: unbound variable
./new-exp.tests: line 530: UNSET: unbound variable
./new-exp.tests: line 531: UNSET: unbound variable
argv[1] = <5>
argv[1] = <#>
argv[1] = <#>
@@ -464,7 +465,7 @@ Case05---3---A:B:C---
Case06---1---A B C::---
Case07---3---A:B:C---
Case08---3---A:B:C---
./new-exp.tests: line 546: ${$(($#-1))}: bad substitution
./new-exp.tests: line 551: ${$(($#-1))}: bad substitution
argv[1] = <a>
argv[2] = <b>
argv[3] = <c>
@@ -481,8 +482,8 @@ argv[1] = <a>
argv[1] = <a>
argv[2] = <b>
argv[1] = <>
./new-exp.tests: line 565: $(($# - 2)): substring expression < 0
./new-exp.tests: line 567: -2: substring expression < 0
./new-exp.tests: line 570: $(($# - 2)): substring expression < 0
./new-exp.tests: line 572: -2: substring expression < 0
argv[1] = <bin>
argv[2] = <bin>
argv[3] = <ucb>
+5
View File
@@ -184,6 +184,11 @@ recho ${a-$z}
expect nothing
recho ${!1-$z}
expect an error
v=bad-var
echo ${!v}
unset -v v
set -- a 'b c' d
unset foo
foo=@
+21 -12
View File
@@ -13,6 +13,9 @@ unquoted
unquoted quoted
unquoted quoted
this\&that
echo a\\;ls
echo a\'\;ls
echo 'a'\''b'\;ls
1 2 3 4 5
onestring 0 0 0
onestring 0 0 0.00
@@ -30,7 +33,7 @@ A7
--\"abcd\"--
--\'abcd\'--
--a\x--
./printf.tests: line 95: printf: missing hex digit for \x
./printf.tests: line 105: printf: missing hex digit for \x
--\x--
----
----
@@ -91,12 +94,12 @@ A7
26
26
26
./printf.tests: line 219: printf: `%10': missing format character
./printf.tests: line 220: printf: `M': invalid format character
ab./printf.tests: line 223: printf: `y': invalid format character
./printf.tests: line 226: printf: GNU: invalid number
./printf.tests: line 229: printf: `%10': missing format character
./printf.tests: line 230: printf: `M': invalid format character
ab./printf.tests: line 233: printf: `y': invalid format character
./printf.tests: line 236: printf: GNU: invalid number
0
./printf.tests: line 227: printf: GNU: invalid number
./printf.tests: line 237: printf: GNU: invalid number
0
-
(foo )(bar )
@@ -149,6 +152,10 @@ b
xx
xx
< >< >
./printf.tests: line 341: printf: 9223372036854775825: Result too large
9223372036854775807
./printf.tests: line 342: printf: -9223372036854775815: Result too large
-9223372036854775808
one
one\ctwo
4\.2
@@ -161,6 +168,8 @@ unquoted
unquoted quoted
unquoted quoted
this\&that
'no-quotes-needed'
'quotes;needed'
1 2 3 4 5
onestring 0 0 0
onestring 0 0 0.00
@@ -174,7 +183,7 @@ A7
--\"abcd\"--
--\'abcd\'--
--a\x--
./printf1.sub: line 107: printf: missing hex digit for \x
./printf1.sub: line 111: printf: missing hex digit for \x
--\x--
----
----
@@ -235,12 +244,12 @@ A7
26
26
26
./printf1.sub: line 293: printf: `%10': missing format character
./printf1.sub: line 294: printf: `M': invalid format character
./printf1.sub: line 297: printf: `y': invalid format character
./printf1.sub: line 300: printf: GNU: invalid number
./printf1.sub: line 297: printf: `%10': missing format character
./printf1.sub: line 298: printf: `M': invalid format character
./printf1.sub: line 301: printf: `y': invalid format character
./printf1.sub: line 304: printf: GNU: invalid number
0
./printf1.sub: line 302: printf: GNU: invalid number
./printf1.sub: line 306: printf: GNU: invalid number
0
-
(foo )(bar )
+17
View File
@@ -60,6 +60,16 @@ printf "%s%10q\n" unquoted quoted
printf "%q\n" 'this&that'
# %Q is like %q but treats the precision differently
S="a'b"
S1="${S@Q}"
T=';ls'
printf 'echo %.2q%q\n' "$S" "$T"
printf 'echo %.2Q%Q\n' "$S" "$T" # note the difference
# a different way to do it
printf 'echo %.*s%q\n' ${#S1} "$S1" "$T"
# make sure the format string is reused to use up arguments
printf "%d " 1 2 3 4 5; printf "\n"
@@ -324,6 +334,13 @@ printf -v var "%b" @(hugo); echo "x${var}x"
# make sure that missing arguments are always handled like the empty string
printf "<%3s><%3b>\n"
# let's test some out-of-range integer errors for POSIX-specified behavior
TOOBIG=9223372036854775825
TOOSMALL=-9223372036854775815
printf '%d\n' "$TOOBIG"
printf '%d\n' "$TOOSMALL"
# tests variable assignment with -v
${THIS_SH} ./printf1.sub
${THIS_SH} ./printf2.sub
+4
View File
@@ -60,6 +60,10 @@ printf "%s" "$vv"
printf -v vv "%q\n" 'this&that'
printf "%s" "$vv"
# altform with %q will force single-quoting
printf -v vv '%#q\n' no-quotes-needed 'quotes;needed'
printf "%s" "$vv"
# make sure the format string is reused to use up arguments
printf -v vv "%d " 1 2 3 4 5
printf "%s" "$vv"
+2
View File
@@ -9,6 +9,8 @@ a.
-\ a b\-
-\-a b\-
-\ a b\-
argv[1] = <abc>
argv[1] = <abc\>
argv[1] = <^A>
argv[1] = <^A>
argv[1] = <^?>
+4
View File
@@ -26,6 +26,10 @@ echo "\ a b\ " | ( read -r x ; echo -"$x"- )
echo " \ a b\ " | ( read -r x y ; echo -"$x"-"$y"- )
echo " \ a b\ " | ( read -r x ; echo -"$x"- )
# input ending in backslash
printf 'abc\' | { read var ; recho "$var"; }
printf 'abc\' | { read -r var ; recho "$var"; }
# make sure that CTLESC and CTLNUL are passed through correctly
echo $'\001' | ( read var ; recho "$var" )
echo $'\001' | ( read ; recho "$REPLY" )
+2
View File
@@ -118,6 +118,8 @@ c4 is 4
fd 10
fd 8
fd 10
next fd
fd 10
fd 8
1
2
+5
View File
@@ -22,6 +22,11 @@ ${THIS_SH} -c 'exec 8>&1; echo fd 8 >&8' 8>u
cat u
rm -f u
# command preceding exec acts as if `command' isn't there
${THIS_SH} -c 'command exec 10>&1; echo fd 10 >&10; echo next fd' 10>u
cat u
rm -f u
exec 10>u
exec 10>&1; echo 'fd 10' >&10
cat u
+3
View File
@@ -30,6 +30,9 @@
+ foo+=two
+ echo onetwo
onetwo
+ foo=one
+ echo onetwo
onetwo
+ set +x
1
2
+2
View File
@@ -32,6 +32,8 @@ foo=one
foo+=two
echo $foo
foo=one echo $foo
set +x
# test BASH_XTRACEFD
+27 -1
View File
@@ -1,3 +1,5 @@
t
1
t -a noexist
1
t -a run-all
@@ -136,6 +138,8 @@ t 700 -le 1000 -a -n "1" -a "20" = "20"
0
t ! \( 700 -le 1000 -a -n "1" -a "20" = "20" \)
1
t -n xx -a -z "" -a -t 0 -a -t
0
t /tmp/abc -nt /tmp/def
1
t /tmp/abc -ot /tmp/def
@@ -148,6 +152,18 @@ t /tmp/abc -ef /tmp/def
1
t /tmp/abc -ef /tmp/ghi
0
t noexist -ot /tmp/abc
0
t /tmp/abc -ot noexist
1
t noexist -nt /tmp/abc
1
t noexist -ef /tmp/abc
1
t -N noexist
1
t -N /tmp/abc
1
t -r /dev/fd/0
0
t -w /dev/fd/1
@@ -186,6 +202,8 @@ t -v set
0
t -v set
0
t -R UID
1
t xx -a yy
0
t xx -o ""
@@ -216,6 +234,8 @@ t ( -E )
0
t ( "" )
1
t ( -n xx )
0
t ! -z "$z"
0
t ! -n "$z"
@@ -274,7 +294,13 @@ b ( 1 = 2
2
./test.tests: line 26: test: too many arguments
2
./test.tests: line 434: [: missing `]'
./test.tests: line 26: test: syntax error: `-t' unexpected
2
./test.tests: line 26: test: argument expected
2
./test.tests: line 473: [: missing `]'
2
./test.tests: line 475: [: missing `]'
2
./test.tests: line 26: test: (: unary operator expected
2
+41
View File
@@ -27,6 +27,9 @@ t()
echo $?
}
echo 't'
t
echo 't -a noexist'
t -a noexist
echo 't -a run-all'
@@ -244,6 +247,10 @@ t 700 -le 1000 -a -n "1" -a "20" = "20"
echo 't ! \( 700 -le 1000 -a -n "1" -a "20" = "20" \)'
t ! \( 700 -le 1000 -a -n "1" -a "20" = "20" \)
# more traditional parsing algorithm
echo 't -n xx -a -z "" -a -t 0 -a -t'
t -n xx -a -z "" -a -t 0 -a -t
touch /tmp/abc
sleep 2
touch /tmp/def
@@ -265,6 +272,29 @@ t /tmp/abc -ef /tmp/ghi
rm /tmp/abc /tmp/def /tmp/ghi
touch /tmp/abc
echo 't noexist -ot /tmp/abc'
t noexist -ot /tmp/abc
echo 't /tmp/abc -ot noexist'
t /tmp/abc -ot noexist
echo 't noexist -nt /tmp/abc'
t noexist -nt /tmp/abc
echo 't noexist -ef /tmp/abc'
t noexist -ef /tmp/abc
echo 't -N noexist'
t -N noexist
# false; it's been read since modified
echo 't -N /tmp/abc'
t -N /tmp/abc
rm -f /tmp/abc
echo 't -r /dev/fd/0'
t -r /dev/fd/0
echo 't -w /dev/fd/1'
@@ -317,6 +347,9 @@ set=set
echo 't -v set'
t -v set
echo 't -R UID'
t -R UID
echo 't xx -a yy'
t xx -a yy
echo 't xx -o ""'
@@ -349,6 +382,8 @@ echo 't ( -E )'
t \( -E \)
echo 't ( "" )'
t \( "" \)
echo 't ( -n xx )'
t \( -n xx \)
z=42
@@ -430,9 +465,15 @@ t -A v
t 4 -eq 4 -a 2 -ne 5 -a 4 -ne
# too many arguments
t 4 -eq 4 -a 3 4
# syntax error
t -n xx -a -z "" -a -t 0 -t
# argument expected
t -n xx -a -z "" -a -t 0 -a
[
echo $?
[ -n xx
echo $?
t \( \)
+14
View File
@@ -111,10 +111,24 @@ CHLD
CHLD
CHLD
CHLD
BASH_TRAPSIG = USR1
func=7
222
exit=0
exit=0
A
In trap-argument: last command preceding the trap action
In a function call: last command in the trap action
caught a child death
caught a child death
caught a child death
trap -- 'echo caught a child death' SIGCHLD
echo caught a child death
./trap.tests: line 118: trap: cannot specify both -p and -P
./trap.tests: line 119: trap: -P requires at least one signal name
trap: usage: trap [-Plp] [[action] signal_spec ...]
./trap.tests: line 121: trap: -x: invalid option
trap: usage: trap [-Plp] [[action] signal_spec ...]
trap -- 'echo exiting' EXIT
trap -- 'echo aborting' SIGABRT
trap -- 'echo caught a child death' SIGCHLD
+9
View File
@@ -96,6 +96,8 @@ ${THIS_SH} ./trap7.sub
# SIGCHLD traps
${THIS_SH} ./trap8.sub
# return without argument in trap string
${THIS_SH} ./trap9.sub
#
# show that setting a trap on SIGCHLD is not disastrous.
@@ -110,6 +112,13 @@ sleep 7 & sleep 6 & sleep 5 &
wait
trap -p SIGCHLD
trap -P SIGCHLD
# all errors
trap -p -P
trap -P
trap ''
trap -x
# Now reset some of the signals the shell handles specially back to
# their default values (with or without the SIG prefix)
+2
View File
@@ -54,6 +54,8 @@ if [ -x /bin/false ]; then
FALSE=/bin/false
elif [ -x /usr/bin/false ]; then
FALSE=/usr/bin/false
elif [ -x /usr/local/bin/false ]; then
FALSE=/usr/local/bin/false
else
FALSE='command false'
fi
+84
View File
@@ -0,0 +1,84 @@
# This program is free software: you can redistribute it and/or modify
# it under the terms of the GNU General Public License as published by
# the Free Software Foundation, either version 3 of the License, or
# (at your option) any later version.
#
# This program is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
# GNU General Public License for more details.
#
# You should have received a copy of the GNU General Public License
# along with this program. If not, see <http://www.gnu.org/licenses/>.
#
# return with argument in trap string while function is executing
trap 'echo BASH_TRAPSIG = $(kill -l $BASH_TRAPSIG); return 7' USR1
func() { kill -USR1 $$; }
func
echo func=$?
# test where return with no argument in a trap string gets its exit status
# when a function is executing (posix interp 1602)
setexit() { return "$1"; }
# function called in trap string to set $?
# posix interp 1602: the return in the trap string causees the end of
# execution of the trap action
trap 'setexit 222; echo $? ; return' USR1
process() { kill -USR1 $$; }
process
echo exit=$?
unset -f process
# posix interp 1602; the return in the trap string interrupts loop and causes
# the end of execution of the trap action
trap 'setexit 123; return' USR1
loop() { while :; do :; done; }
get_loop_exit() { loop; echo "exit=$?"; }
{ sleep 1; kill -USR1 $$; } &
get_loop_exit
unset -f loop get_loop_exit
# posix interp 1602; the return in `check' does not cause the end of execution
# of the trap action
check() { false; return; }
handle() { check && echo B || echo A; }
trap handle USR1
kill -USR1 $$
unset -f check handle
# posix interp 1602: show where we get the value of $? for trap actions
# return in trap string causes end of execution of trap action
invoke() { kill -USR1 $$; return 222; }
trap 'setexit 111; return' USR1
invoke
case $? in
(0) echo 'In trap-argument: last command preceding the trap action' ;;
(111) echo 'In trap-argument: last command in the trap action' ;;
(222) echo 'In trap-argument: (failed to exit the function)' ;;
(*) echo 'In trap-argument: (unexpected)' ;;
esac
# return in `handler' does not cause the end of execution of the trap action
stat=99
handler() { setexit 111; return; }
trap 'handler; stat=$?; return' USR1
invoke
case $stat in
(0) echo 'In a function call: last command preceding the trap action' ;;
(111) echo 'In a function call: last command in the trap action' ;;
(*) echo 'In a function call: (unexpected)' ;;
esac
unset -f invoke handler
unset -f setexit
# posix interp 1602: return in function does not cause end of trap action
ReturnFalse()
{
false ; return
}
trap 'ReturnFalse && echo "woops"' EXIT
(exit 0) # set exit status
+9 -3
View File
@@ -1,6 +1,7 @@
./type.tests: line 22: type: -r: invalid option
type: usage: type [-afptP] name [name ...]
./type.tests: line 25: type: notthere: not found
./type.tests: line 29: command: notthere: not found
function
keyword
builtin
@@ -24,7 +25,7 @@ func ()
}
while
while is a shell keyword
./type.tests: line 56: type: m: not found
./type.tests: line 59: type: m: not found
alias m='more'
alias m='more'
m is aliased to `more'
@@ -37,8 +38,8 @@ builtin
builtin is a shell builtin
/bin/sh
/bin/sh is /bin/sh
./type.tests: line 78: type: func: not found
./type.tests: line 80: type: m: not found
./type.tests: line 81: type: func: not found
./type.tests: line 83: type: m: not found
/bin/sh
/tmp/bash
bash is hashed (/tmp/bash)
@@ -133,3 +134,8 @@ EOF
);
echo "coprocs created"
}
cat is /bin/cat
cat is aliased to `echo cat'
/bin/cat
break is a shell builtin
break is a special shell builtin
+5 -4
View File
@@ -21,10 +21,13 @@ type
# this should be a usage error
type -r ${THIS_SH}
# these should behave identically
# these should behave identically, but POSIX says command -v is silent if the name is not found
type notthere
command -v notthere
# but this will produce an error message
command -V notthere
alias m=more
unset -f func 2>/dev/null
@@ -102,9 +105,7 @@ f() {
type f | cat -v
${THIS_SH} type1.sub
${THIS_SH} type2.sub
${THIS_SH} type3.sub
${THIS_SH} type4.sub
${THIS_SH} type5.sub
+41
View File
@@ -0,0 +1,41 @@
# This program is free software: you can redistribute it and/or modify
# it under the terms of the GNU General Public License as published by
# the Free Software Foundation, either version 3 of the License, or
# (at your option) any later version.
#
# This program is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
# GNU General Public License for more details.
#
# You should have received a copy of the GNU General Public License
# along with this program. If not, see <http://www.gnu.org/licenses/>.
#
# make sure . is not in $PATH
PATH=/bin:/usr/bin:/usr/local/bin
# test type -P
# executable in current directory
TDIR=$TMPDIR/type-$$
[ -d "$TDIR" ] || mkdir "$TDIR"
cd -P "$TDIR" || exit 1
touch e ; chmod +x e; type -P e; rm -f e
shopt -s expand_aliases
type cat
alias cat='echo cat'
type -f cat
type -P cat
# some random tests
# the difference between posix and default modes
type break
set -o posix; type break; set +o posix
cd "$OLDPWD"
rm -rf "$TDIR"
+2 -2
View File
@@ -17,7 +17,7 @@ foo()
local -r myvar=0
echo "${myvar[@]}"
declare -p myvar
local -p myvar
}
foo2()
@@ -26,7 +26,7 @@ foo2()
local -r myvar=1
echo "${myvar}"
declare -p myvar
local -p myvar
}
declare -a outside=()