more changes for bracket expressions in patterns

This commit is contained in:
Chet Ramey
2022-12-02 11:41:48 -05:00
parent e8652353ae
commit 198210c58f
20 changed files with 948 additions and 150 deletions
+103
View File
@@ -0,0 +1,103 @@
--- $GLOBIGNORE vs fnmatch(3) ---
#1: pat=ab/cd/efg yes/yes
#2: pat=ab[/]cd/efg no/no
#3: pat=ab[/a]cd/efg no/no
#4: pat=ab[a/]cd/efg no/no
#5: pat=ab[!a]cd/efg no/no
#6: pat=ab[.-0]cd/efg no/no
#7: pat=*/*/efg yes/yes
#8: pat=*[/]*/efg no/no
#9: pat=*[/a]*/efg no/no
#10: pat=*[a/]*/efg no/no
#11: pat=*[!a]*/efg no/no
#12: pat=*[.-0]*/efg no/no
#13: pat=*/*/efg yes/yes
#14: pat=*[b]/*/efg yes/yes
#15: pat=*[ab]/*/efg yes/yes
#16: pat=*[ba]/*/efg yes/yes
#17: pat=*[!a]/*/efg yes/yes
#18: pat=*[a-c]/*/efg yes/yes
#19: pat=ab@(/)cd/efg no/no
#20: pat=*@(/)cd/efg no/no
#21: pat=*/cd/efg yes/yes
---Tests for a slash in bracket expressions---
#22: pat=ab[/]ef str=ab[/]ef yes/yes
#23: pat=ab[/]ef str=ab/ef no/no
#24: pat=ab[c/d]ef str=ab[c/d]ef yes/yes
#25: pat=ab[c/d]ef str=abcef no/no
#26: pat=ab[.-/]ef str=ab[.-/]ef yes/yes
#27: pat=ab[.-/]ef str=ab.ef no/no
#28: pat=ab[[=/=]]ef str=ab[[=/=]]ef yes/yes
#29: pat=ab[[=/=]]ef str=ab/ef no/no
#30: pat=ab[[=c=]/]ef str=ab[=/]ef yes/yes
#31: pat=ab[[=c=]/]ef str=abcef no/no
#32: pat=ab[[:alpha:]/]ef str=ab[:/]ef yes/yes
#33: pat=ab[[:alpha:]/]ef str=abxef no/no
#34: pat=ab[/[abc]]ef str=ab[/c]ef yes/yes
#35: pat=ab[/[abc]]ef str=abc]ef no/no
#36: pat=ab[c[=/=]]ef str=ab[c[=/=]]ef yes/yes
#37: pat=ab[c[=/=]]ef str=abc[=/=]ef no/no
#38: pat=ab[c[=/=]]ef str=abcef no/no
#39: pat=a[b\/c] str=a[b/c] yes/yes
#40: pat=a[b\/c] str=ab no/no
#41: pat=a[b\/c] str=ac no/no
---Tests for incomplete bracket expressions---
#42: pat=ab[c str=ab[c yes/yes
#43: pat=ab[c str=abc no/no
#44: pat=ab[c[=d= str=ab[c[=d= yes/yes
#45: pat=ab[c[=d= str=abc no/no
#46: pat=ab[c[.d str=ab[c[.d yes/yes
#47: pat=ab[c[.d str=abc no/no
#48: pat=ab[c[:alpha: str=ab[c[:alpha: yes/yes
#49: pat=ab[c[:alpha: str=abc no/no
#50: pat=ab[c- str=ab[c- yes/yes
#51: pat=ab[c- str=abc no/no
#52: pat=ab[c\ str=ab[c\ yes/yes
#53: pat=ab[c\ str=abc no/no
#54: pat=ab[[\ str=ab[[\ yes/yes
#55: pat=ab[[\ str=ab[ no/no
--- PATSCAN vs BRACKMATCH ---
#56: pat=@([[.].])A]) str=] yes/yes
#57: pat=@([[.].])A]) str===]A]) no/no
#58: pat=@([[.].])A]) str=AA]) no/no
#59: pat=@([[=]=])A]) str=] no/no
#60: pat=@([[=]=])A]) str===]A]) yes/yes
#61: pat=@([[=]=])A]) str=AA]) no/no
--- BRACKMATCH: after match vs before match ---
#62: pat=[[=]=]ab] str=a no/no
#63: pat=[[.[=.]ab] str=a yes/yes
#64: pat=[[.[==].]ab] str=a yes/yes
#65: pat=[a[=]=]b] str=a no/no
#66: pat=[a[.[=.]b] str=a yes/yes
#67: pat=[a[.[==].]b] str=a yes/yes
#68: pat=[a[=]=]b] str=b no/no
#69: pat=[a[=]=]b] str=a=]b] yes/yes
#70: pat=[a[.[=.]b] str=b yes/yes
#71: pat=[a[.[=.]b] str=ab] no/no
#72: pat=[a[.[==].]b] str=b yes/yes
#73: pat=[a[.[==].]b] str=ab] no/no
--- incomplete POSIX brackets ---
#74: pat=x[a[:y] str=x[ yes/yes
#75: pat=x[a[:y] str=x: yes/yes
#76: pat=x[a[:y] str=xy yes/yes
#77: pat=x[a[:y] str=x[ay no/no
#78: pat=x[a[.y] str=x[ yes/yes
#79: pat=x[a[.y] str=x. yes/yes
#80: pat=x[a[.y] str=xy yes/yes
#81: pat=x[a[.y] str=x[ay no/no
#82: pat=x[a[=y] str=x[ yes/yes
#83: pat=x[a[=y] str=x= yes/yes
#84: pat=x[a[=y] str=xy yes/yes
#85: pat=x[a[=y] str=x[ay no/no
--- MISC tests ---
#86: pat=a\ str=a\ yes/yes
+291
View File
@@ -0,0 +1,291 @@
# 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 various aspects of pathname expansion, mostly dealing with bracket
# expressions
LC_COLLATE=C
ORIG_DIR=$PWD
: ${TMPDIR:=/tmp} ${BUILD_DIR:=$ORIG_DIR}
trap 'rm -rf $TESTDIR $WORK_DIR' EXIT
WORK_DIR=${TMPDIR}/globtest-$$
mkdir $WORK_DIR || {
echo "cannot create directory $WORK_DIR" >&2
exit 1
}
cd $WORK_DIR || {
echo "cannot cd to directory $WORK_DIR" >&2
exit 1
}
gcc -O2 -xc -o ./fnmatch - <<-EOF
#include <fnmatch.h>
#include <stdlib.h>
#include <stdio.h>
int main(int argc, char **argv) {
if (2 >= argc) {
fprintf(stderr, "usage: fnmatch string pattern\n");
exit(2);
}
#ifdef FNM_EXTMATCH
int flags = FNM_PATHNAME | FNM_PERIOD | FNM_EXTMATCH;
#else
int flags = FNM_PATHNAME | FNM_PERIOD;
#endif
if (fnmatch(argv[2], argv[1], flags) == 0)
return 0;
return 1;
}
EOF
eval $(grep -E '^(CC |SHOBJ_).*=' $BUILD_DIR/examples/loadables/Makefile | sed -e 's/[ ]*=[ ]*/="/' -e 's/$/"/' )
if [ "$SHOBJ_STATUS" != "supported" ]; then
echo "glob-bracket: shared objects not supported, cannot continue" >&2
exit 2
fi
cat > ./strmatch.c <<-EOF
#define BUILTIN_ENABLED 0x01
struct word_desc { char* word; int flags; };
struct word_list { struct word_list* next; struct word_desc* word; };
struct builtin {
const char* name;
int (*function)(struct word_list*);
int flags;
const char** long_doc;
const char* short_doc;
char* handle;
};
/*#include <glob/strmatch.h>*/
int strmatch(char *pattern, char *string, int flags);
#define FNM_PATHNAME (1 << 0)
#define FNM_NOESCAPE (1 << 1)
#define FNM_PERIOD (1 << 2)
#define FNM_LEADING_DIR (1 << 3)
#define FNM_CASEFOLD (1 << 4)
#define FNM_EXTMATCH (1 << 5)
#define FNM_FIRSTCHAR (1 << 6)
#define FNM_DOTDOT (1 << 7)
static int strmatch_builtin(struct word_list* list) {
char *str, *pat;
if (!list || !list->word) return 2;
str = list->word->word;
if (!list->next || !list->next->word) return 2;
pat = list->next->word->word;
if (strmatch (pat, str, FNM_PATHNAME | FNM_PERIOD | FNM_EXTMATCH) == 0)
return 0;
return 1;
}
static const char* strmatch_doc[] = { "This is a builtin to test the behavior of strmatch", 0 };
struct builtin strmatch_struct = { "strmatch", strmatch_builtin, BUILTIN_ENABLED, strmatch_doc, "strmatch string pattern", 0, };
EOF
${SHOBJ_CC} ${SHOBJ_CFLAGS} -c -o strmatch.o strmatch.c
rm -f strmatch.c
${SHOBJ_LD} ${SHOBJ_LDFLAGS} ${SHOBJ_XLDFLAGS} -o strmatch.so strmatch.o ${SHOBJ_LIBS}
rm -f strmatch.o
if [ ! -f strmatch.so ] ; then
echo "glob-bracket: cannot create strmatch loadable builtin" >&2
exit 2
fi
enable -f ./strmatch.so strmatch || {
echo "glob-bracket: cannot load strmatch builtin" >&2
exit 2
}
check_count=1
if [ -z "$BASH_TSTOUT" ]; then
yes=$(printf '\033[32myes\033[m') no=$(printf '\033[31mno\033[m')
else
yes=yes no=no
fi
function check {
# bash impl
if strmatch "$2" "$1"; then
local strmatch=$yes
else
local strmatch=$no
fi
# fnmatch
local expect=${3-}
if [[ ! $expect ]]; then
if $WORK_DIR/fnmatch "$2" "$1"; then
expect=$yes
else
expect=$no
fi
fi
printf '#%d: pat=%-20s str=%-16s %s/%s\n' "$((check_count++))" "$1" "$2" "$strmatch" "$expect"
}
function pcheck {
local GLOBIGNORE=$1
# bash impl
local -a f=(*/*/efg*)
if [[ $f == '*/*/efg*' ]]; then
local strmatch=$yes
else
local strmatch=$no
fi
# Linux fnmatch
if $WORK_DIR/fnmatch ab/cd/efg "$1"; then
local fnmatch=$yes
else
local fnmatch=$no
fi
printf '#%d: pat=%-16s %s/%s\n' "$((check_count++))" "$1" "$strmatch" "$fnmatch"
}
TESTDIR=${TMPDIR}/pathtest-$$
TESTPATH=${TESTDIR}/ab/cd/efg
mkdir -p $TESTPATH
if [ -d "$TESTPATH" ] && cd "$TESTDIR"; then
echo '--- $GLOBIGNORE vs fnmatch(3) ---'
pcheck 'ab/cd/efg'
pcheck 'ab[/]cd/efg'
pcheck 'ab[/a]cd/efg'
pcheck 'ab[a/]cd/efg'
pcheck 'ab[!a]cd/efg'
pcheck 'ab[.-0]cd/efg'
pcheck '*/*/efg'
pcheck '*[/]*/efg'
pcheck '*[/a]*/efg'
pcheck '*[a/]*/efg'
pcheck '*[!a]*/efg'
pcheck '*[.-0]*/efg'
pcheck '*/*/efg'
pcheck '*[b]/*/efg'
pcheck '*[ab]/*/efg'
pcheck '*[ba]/*/efg'
pcheck '*[!a]/*/efg'
pcheck '*[a-c]/*/efg'
pcheck 'ab@(/)cd/efg'
pcheck '*@(/)cd/efg'
pcheck '*/cd/efg'
cd "$WORK_DIR"
fi
echo
echo '---Tests for a slash in bracket expressions---'
check 'ab[/]ef' 'ab[/]ef' "$yes"
check 'ab[/]ef' 'ab/ef' "$no"
check 'ab[c/d]ef' 'ab[c/d]ef' "$yes"
check 'ab[c/d]ef' 'abcef' "$no"
check 'ab[.-/]ef' 'ab[.-/]ef' "$yes"
check 'ab[.-/]ef' 'ab.ef' "$no"
check 'ab[[=/=]]ef' 'ab[[=/=]]ef' "$yes"
check 'ab[[=/=]]ef' 'ab/ef' "$no"
check 'ab[[=c=]/]ef' 'ab[=/]ef' "$yes"
check 'ab[[=c=]/]ef' 'abcef' "$no"
check 'ab[[:alpha:]/]ef' 'ab[:/]ef' "$yes"
check 'ab[[:alpha:]/]ef' 'abxef' "$no"
check 'ab[/[abc]]ef' 'ab[/c]ef' "$yes"
check 'ab[/[abc]]ef' 'abc]ef' "$no"
check 'ab[c[=/=]]ef' 'ab[c[=/=]]ef' "$yes"
check 'ab[c[=/=]]ef' 'abc[=/=]ef' "$no"
check 'ab[c[=/=]]ef' 'abcef' "$no"
check 'a[b\/c]' 'a[b/c]' "$yes"
check 'a[b\/c]' 'ab' "$no"
check 'a[b\/c]' 'ac' "$no"
echo
echo '---Tests for incomplete bracket expressions---'
check 'ab[c' 'ab[c' "$yes"
check 'ab[c' 'abc' "$no"
check 'ab[c[=d=' 'ab[c[=d=' "$yes"
check 'ab[c[=d=' 'abc' "$no"
check 'ab[c[.d' 'ab[c[.d' "$yes"
check 'ab[c[.d' 'abc' "$no"
check 'ab[c[:alpha:' 'ab[c[:alpha:' "$yes"
check 'ab[c[:alpha:' 'abc' "$no"
check 'ab[c-' 'ab[c-' "$yes"
check 'ab[c-' 'abc' "$no"
check 'ab[c\' 'ab[c\' "$yes"
check 'ab[c\' 'abc' "$no"
check 'ab[[\' 'ab[[\' "$yes"
check 'ab[[\' 'ab[' "$no"
echo
echo '--- PATSCAN vs BRACKMATCH ---'
check '@([[.].])A])' ']' "$yes"
check '@([[.].])A])' '==]A])' "$no"
check '@([[.].])A])' 'AA])' "$no"
check '@([[=]=])A])' ']' "$no"
check '@([[=]=])A])' '==]A])' "$yes"
check '@([[=]=])A])' 'AA])' "$no"
echo
echo '--- BRACKMATCH: after match vs before match ---'
check '[[=]=]ab]' 'a' "$no"
check '[[.[=.]ab]' 'a' "$yes"
check '[[.[==].]ab]' 'a' "$yes"
echo
check '[a[=]=]b]' 'a' "$no"
check '[a[.[=.]b]' 'a' "$yes"
check '[a[.[==].]b]' 'a' "$yes"
echo
check '[a[=]=]b]' 'b' "$no"
check '[a[=]=]b]' 'a=]b]' "$yes"
check '[a[.[=.]b]' 'b' "$yes"
check '[a[.[=.]b]' 'ab]' "$no"
check '[a[.[==].]b]' 'b' "$yes"
check '[a[.[==].]b]' 'ab]' "$no"
echo
echo '--- incomplete POSIX brackets ---'
check 'x[a[:y]' 'x[' "$yes"
check 'x[a[:y]' 'x:' "$yes"
check 'x[a[:y]' 'xy' "$yes"
check 'x[a[:y]' 'x[ay' "$no"
echo
check 'x[a[.y]' 'x[' "$yes"
check 'x[a[.y]' 'x.' "$yes"
check 'x[a[.y]' 'xy' "$yes"
check 'x[a[.y]' 'x[ay' "$no"
echo
check 'x[a[=y]' 'x[' "$yes"
check 'x[a[=y]' 'x=' "$yes"
check 'x[a[=y]' 'xy' "$yes"
check 'x[a[=y]' 'x[ay' "$no"
echo
echo '--- MISC tests ---'
check 'a\' 'a\' "$yes"
cd $ORIG_DIR
exit 0
+388
View File
@@ -0,0 +1,388 @@
export LC_COLLATE=C
#
# test the shell globbing
#
expect()
{
echo expect "$@"
}
# First, a test that bash-2.01.1 fails
${THIS_SH} ./glob1.sub
MYDIR=$PWD # save where we are
TESTDIR=/tmp/glob-test
mkdir $TESTDIR
builtin cd $TESTDIR || { echo $0: cannot cd to $TESTDIR >&2 ; exit 1; }
rm -rf *
touch a b c d abc abd abe bb bcd ca cb dd de Beware
mkdir bdir
# see if `regular' globbing works right
expect '<a> <abc> <abd> <abe> <X*>'
recho a* X*
expect '<a> <abc> <abd> <abe>'
recho \a*
# see if null glob expansion works
shopt -s nullglob
expect '<a> <abc> <abd> <abe>'
recho a* X*
shopt -u nullglob
# see if the failglob option works
mkdir tmp
touch tmp/l1 tmp/l2 tmp/l3
builtin echo tmp/l[12] tmp/*4 tmp/*3
shopt -s failglob
builtin echo tmp/l[12] tmp/*4 tmp/*3
rm -r tmp
shopt -u failglob
# see if the code that expands directories only works
expect '<bdir/>'
recho b*/
# Test quoted and unquoted globbing characters
expect '<*>'
recho \*
expect '<a*>'
recho 'a*'
expect '<a*>'
recho a\*
expect '<c> <ca> <cb> <a*> <*q*>'
recho c* a\* *q*
expect '<**>'
recho "*"*
expect '<**>'
recho \**
expect '<\.\./*/>'
recho "\.\./*/"
expect '<s/\..*//>'
recho 's/\..*//'
# Pattern from Larry Wall's Configure that caused bash to blow up
expect '</^root:/{s/^[^:]*:[^:]*:\([^:]*\).*$/\1/>'
recho "/^root:/{s/^[^:]*:[^:]*:\([^:]*\).*"'$'"/\1/"
# Make sure character classes work properly
expect '<abc> <abd> <abe> <bb> <cb>'
recho [a-c]b*
expect '<abd> <abe> <bb> <bcd> <bdir> <ca> <cb> <dd> <de>'
recho [a-y]*[^c]
expect '<abd> <abe>'
recho a*[^c]
touch a-b aXb
expect '<a-b> <aXb>'
recho a[X-]b
touch .x .y
expect '<Beware> <d> <dd> <de>'
recho [^a-c]*
# Make sure that filenames with embedded globbing characters are handled
# properly
mkdir a\*b
> a\*b/ooo
expect '<a*b/ooo>'
recho a\*b/*
expect '<a*b/ooo>'
recho a\*?/*
expect '<no match>'
cmd='echo !7'
case "$cmd" in
*\\!*) echo match ;;
*) echo no match ;;
esac
expect '<not there>'
file='r.*'
case $file in
*.\*) echo not there ;;
*) echo there ;;
esac
# examples from the Posix.2 spec (d11.2, p. 243)
expect '<abc>'
recho a[b]c
expect '<abc>'
recho a["b"]c
expect '<abc>'
recho a[\b]c
expect '<abc>'
recho a?c
expect '<match 1>'
case abc in
a"b"c) echo 'match 1' ;;
*) echo 'BAD match 1' ;;
esac
expect '<match 2>'
case abc in
a*c) echo 'match 2' ;;
*) echo 'BAD match 2' ;;
esac
expect '<ok 1>'
case abc in
"a?c") echo 'bad 1' ;;
*) echo 'ok 1' ;;
esac
expect '<ok 2>'
case abc in
a\*c) echo 'bad 2' ;;
*) echo 'ok 2' ;;
esac
expect '<ok 3>'
case abc in
a\[b]c) echo 'bad 3' ;;
*) echo 'ok 3' ;;
esac
expect '<ok 4>'
case "$nosuchvar" in
"") echo 'ok 4' ;;
*) echo 'bad 4' ;;
esac
# This is very odd, but sh and ksh seem to agree
expect '<ok 5>'
case abc in
a["\b"]c) echo 'ok 5' ;;
*) echo 'bad 5' ;;
esac
mkdir man
mkdir man/man1
touch man/man1/bash.1
expect '<man/man1/bash.1>'
recho */man*/bash.*
expect '<man/man1/bash.1>'
recho $(echo */man*/bash.*)
expect '<man/man1/bash.1>'
recho "$(echo */man*/bash.*)"
# tests with multiple `*'s
case abc in
a***c) echo ok 1;;
esac
case abc in
a*****?c) echo ok 2;;
esac
case abc in
?*****??) echo ok 3;;
esac
case abc in
*****??) echo ok 4;;
esac
case abc in
*****??c) echo ok 5;;
esac
case abc in
?*****?c) echo ok 6;;
esac
case abc in
?***?****c) echo ok 7;;
esac
case abc in
?***?****?) echo ok 8;;
esac
case abc in
?***?****) echo ok 9;;
esac
case abc in
*******c) echo ok 10;;
esac
case abc in
*******?) echo ok 11;;
esac
case abcdecdhjk in
a*cd**?**??k) echo ok 20;;
esac
case abcdecdhjk in
a**?**cd**?**??k) echo ok 21;;
esac
case abcdecdhjk in
a**?**cd**?**??k***) echo ok 22;;
esac
case abcdecdhjk in
a**?**cd**?**??***k) echo ok 23;;
esac
case abcdecdhjk in
a**?**cd**?**??***k**) echo ok 24;;
esac
case abcdecdhjk in
a****c**?**??*****) echo ok 25;;
esac
case '-' in
[-abc]) echo ok 26 ;;
esac
case '-' in
[abc-]) echo ok 27 ;;
esac
case '\' in
\\) echo ok 28 ;;
esac
case '\' in
[\\]) echo ok 29 ;;
esac
case '\' in
'\') echo ok 30 ;;
esac
case '[' in
[[]) echo ok 31 ;;
esac
# a `[' without a closing `]' is just another character to match, in the
# bash implementation
case '[' in
[) echo ok 32 ;;
esac
case '[abc' in
[*) echo 'ok 33';;
esac
# a right bracket shall lose its special meaning and represent itself in
# a bracket expression if it occurs first in the list. -- POSIX.2 2.8.3.2
case ']' in
[]]) echo ok 34 ;;
esac
case '-' in
[]-]) echo ok 35 ;;
esac
# a backslash should just escape the next character in this context
case p in
[a-\z]) echo ok 36 ;;
esac
# this was a bug in all versions up to bash-2.04-release
case "/tmp" in
[/\\]*) echo ok 37 ;;
esac
# none of these should output anything
case abc in
??**********?****?) echo bad 1;;
esac
case abc in
??**********?****c) echo bad 2;;
esac
case abc in
?************c****?****) echo bad 3;;
esac
case abc in
*c*?**) echo bad 4;;
esac
case abc in
a*****c*?**) echo bad 5;;
esac
case abc in
a********???*******) echo bad 6;;
esac
case 'a' in
[]) echo bad 7 ;;
esac
case '[' in
[abc) echo bad 8;;
esac
# let's start testing the case-insensitive globbing code
recho b*
shopt -s nocaseglob
recho b*
recho [b]*
shopt -u nocaseglob
# make sure set -f works right
set -f
recho *
set +f
# test out the GLOBIGNORE code
GLOBIGNORE='.*:*c:*e:?'
recho *
GLOBIGNORE='.*:*b:*d:?'
recho *
# see if GLOBIGNORE can substitute for `set -f'
GLOBIGNORE='.*:*'
recho *
unset GLOBIGNORE
expect '<man/man1/bash.1>'
recho */man*/bash.*
# make sure null values for GLOBIGNORE have no effect
GLOBIGNORE=
expect '<man/man1/bash.1>'
recho */man*/bash.*
# this is for the benefit of pure coverage, so it writes the pcv file
# in the right place, and for gprof
builtin cd $MYDIR
rm -rf $TESTDIR
exit 0
+1 -1
View File
@@ -18,7 +18,7 @@
export TMPDIR
# basic /bin/sh syntax
SUFFIX=`${THIS_SH} -c 'echo $(( $RANDOM + $BASHPID ))'`
SUFFIX=$( ${THIS_SH} -c 'echo $(( $RANDOM + $BASHPID ))' )
BASH_TSTOUT=${TMPDIR}/bashtst-$SUFFIX # for now
export BASH_TSTOUT
+5
View File
@@ -0,0 +1,5 @@
PATH=$PATH:`pwd`
export PATH
${THIS_SH} ./glob-bracket.tests > ${BASH_TSTOUT} 2>&1
diff ${BASH_TSTOUT} glob-bracket.right && rm -f ${BASH_TSTOUT}
+1 -1
View File
@@ -22,7 +22,7 @@
export TMPDIR
# basic /bin/sh syntax
SUFFIX=`${THIS_SH} -c 'echo $(( $RANDOM + $BASHPID ))'`
SUFFIX=$( ${THIS_SH} -c 'echo $(( $RANDOM + $BASHPID ))' )
BASH_TSTOUT=${TMPDIR}/bashtst-$SUFFIX # for now
export BASH_TSTOUT
+3
View File
@@ -90,6 +90,9 @@ ${THIS_SH} ./trap4.sub
# Return trap issues
${THIS_SH} ./trap6.sub
# eval and ERR trap
${THIS_SH} ./trap7.sub
#
# show that setting a trap on SIGCHLD is not disastrous.
#
+8
View File
@@ -0,0 +1,8 @@
func()
{
eval "trap 'return 42' ERR; false"
return 0
}
set -o errtrace
func || echo oops: $?