new shell option to force globbing never to return .' and ..' as matches

This commit is contained in:
Chet Ramey
2022-01-04 10:11:48 -05:00
parent 701f36c2c3
commit 186129835e
21 changed files with 230 additions and 32 deletions
+26
View File
@@ -2788,4 +2788,30 @@ builtins/common.c
- INTERNAL_DEBUG: use instead of calls to itrace protected by #ifdef
DEBUG
12/26
-----
lib/glob/glob.c
- glob_always_skip_dot_and_dotdot: initialize to 1 (enabled)
builtins/shopt.def
- globskipdots: new shell option, exposes glob_always_skip_dot_and_dotdot
doc/{bash.1,bashref.texi}
- globskipdots: document new shell option
execute_cmd.c
- fix_arrayref_words: call valid_array_reference with 0 for third arg
because the words have not undergone any word expansions yet and
the quotes are still present. This makes things like
A=[\[]=set
unset A[\[]
work
subst.c
- word_list_split: if a word undergoes word splitting but is not
changed, preserve any W_ARRAYREF flag into the new word. This makes
things like
rkey=']'
unset A[$rkey]
work because the unset builtin sees the W_ARRAYREF flag on its
argument
+2
View File
@@ -954,6 +954,7 @@ tests/assoc13.sub f
tests/assoc14.sub f
tests/assoc15.sub f
tests/assoc16.sub f
tests/assoc17.sub f
tests/attr.tests f
tests/attr.right f
tests/attr1.sub f
@@ -1144,6 +1145,7 @@ tests/glob6.sub f
tests/glob7.sub f
tests/glob8.sub f
tests/glob9.sub f
tests/glob10.sub f
tests/glob.right f
tests/globstar.tests f
tests/globstar.right f
+7 -2
View File
@@ -1255,7 +1255,7 @@ tokenize_array_reference (name, flags, subp)
char **subp;
{
char *t;
int r, len, isassoc;
int r, len, isassoc, ssflags;
SHELL_VAR *entry;
t = mbschr (name, '['); /* ] */
@@ -1270,10 +1270,15 @@ tokenize_array_reference (name, flags, subp)
if (r == 0)
return 0;
ssflags = 0;
if (isassoc && ((flags & (VA_NOEXPAND|VA_ONEWORD)) == (VA_NOEXPAND|VA_ONEWORD)))
len = strlen (t) - 1;
else if (isassoc)
len = skipsubscript (t, 0, flags&VA_NOEXPAND); /* VA_NOEXPAND must be 1 */
{
if (flags & VA_NOEXPAND)
ssflags |= 1;
len = skipsubscript (t, 0, ssflags);
}
else
/* Check for a properly-terminated non-null subscript. */
len = skipsubscript (t, 0, 0); /* arithmetic expression */
+2
View File
@@ -89,6 +89,7 @@ extern int check_jobs_at_exit;
extern int autocd;
extern int glob_star;
extern int glob_asciirange;
extern int glob_always_skip_dot_and_dotdot;
extern int lastpipe_opt;
extern int inherit_errexit;
extern int localvar_inherit;
@@ -210,6 +211,7 @@ static struct {
{ "force_fignore", &force_fignore, (shopt_set_func_t *)NULL },
#endif
{ "globasciiranges", &glob_asciirange, (shopt_set_func_t *)NULL },
{ "globskipdots", &glob_always_skip_dot_and_dotdot, (shopt_set_func_t *)NULL },
{ "globstar", &glob_star, (shopt_set_func_t *)NULL },
{ "gnu_errfmt", &gnu_error_format, (shopt_set_func_t *)NULL },
#if defined (HISTORY)
+21 -3
View File
@@ -5,12 +5,12 @@
.\" Case Western Reserve University
.\" chet.ramey@case.edu
.\"
.\" Last Change: Mon Nov 22 09:58:49 EST 2021
.\" Last Change: Sun Dec 26 16:02:07 EST 2021
.\"
.\" bash_builtins, strip all but Built-Ins section
.if \n(zZ=1 .ig zZ
.if \n(zY=1 .ig zY
.TH BASH 1 "2021 November 22" "GNU Bash 5.2"
.TH BASH 1 "2021 December 26" "GNU Bash 5.2"
.\"
.\" There's some problem with having a `@'
.\" in a tagged paragraph with the BSD man macros.
@@ -714,7 +714,7 @@ Expressions are composed of the primaries described below under
.SM
.BR "CONDITIONAL EXPRESSIONS" .
The words between the \fB[[\fP and \fB]]\fP do not undergo word splitting
and filename expansion.
and pathname expansion.
The shell performs tilde expansion, parameter and
variable expansion, arithmetic expansion, command substitution, process
substitution, and quote removal on those words
@@ -3742,6 +3742,14 @@ the pattern must begin with ``.'' (for example, ``.?''),
even if
.B dotglob
is set.
If the
.B globskipdots
shell option is enabled, the filenames
.B ``.''
and
.BR ``..''
are never matched, even if the pattern begins with a
.BR ``.'' .
When not matching pathnames, the
.B ``.''
character is not treated specially.
@@ -3759,6 +3767,7 @@ below under
for a description of the
.BR nocaseglob ,
.BR nullglob ,
.BR globskipdots ,
.BR failglob ,
and
.B dotglob
@@ -10361,6 +10370,15 @@ and
.BR B ,
and upper-case and lower-case ASCII characters will collate together.
.TP 8
.B globskipdots
If set, pathname expansion will never match the filenames
.B ``.''
and
.BR ``..'' ,
even if the pattern begins with a
.BR ``.'' .
This option is enabled by default.
.TP 8
.B globstar
If set, the pattern \fB**\fP used in a pathname expansion context will
match all files and zero or more directories and subdirectories.
+10
View File
@@ -2757,6 +2757,9 @@ must be matched explicitly, unless the shell option @code{dotglob} is set.
In order to match the filenames @samp{.} and @samp{..},
the pattern must begin with @samp{.} (for example, @samp{.?}),
even if @code{dotglob} is set.
If the @code{globskipdots} shell option is enabled, the filenames
@samp{.} and @samp{..} are never matched, even if the pattern begins
with a @samp{.}.
When not matching filenames, the @samp{.} character is not treated specially.
When matching a filename, the slash character must always be
@@ -2766,6 +2769,7 @@ below (@pxref{Pattern Matching}).
See the description of @code{shopt} in @ref{The Shopt Builtin},
for a description of the @code{nocaseglob}, @code{nullglob},
@code{globskipdots},
@code{failglob}, and @code{dotglob} options.
The @env{GLOBIGNORE}
@@ -5692,6 +5696,12 @@ is not taken into account, so
@samp{b} will not collate between @samp{A} and @samp{B},
and upper-case and lower-case ASCII characters will collate together.
@item globskipdots
If set, filename expansion will never match the filenames
@samp{.} and @samp{..},
even if the pattern begins with a @samp{.}.
This option is enabled by default.
@item globstar
If set, the pattern @samp{**} used in a filename expansion context will
match all files and zero or more directories and subdirectories.
+2 -2
View File
@@ -2,10 +2,10 @@
Copyright (C) 1988-2021 Free Software Foundation, Inc.
@end ignore
@set LASTCHANGE Thu Dec 2 15:07:19 EST 2021
@set LASTCHANGE Sun Dec 26 16:02:48 EST 2021
@set EDITION 5.2
@set VERSION 5.2
@set UPDATED 2 December 2021
@set UPDATED 26 December 2021
@set UPDATED-MONTH December 2021
+1 -1
View File
@@ -4268,7 +4268,7 @@ fix_arrayref_words (words)
for (w = wcmd->next; w; w = w->next)
{
if (w->word && w->word->word && valid_array_reference (w->word->word, VA_NOEXPAND))
if (w->word && w->word->word && valid_array_reference (w->word->word, 0))
w->word->flags |= W_ARRAYREF;
}
}
+1 -1
View File
@@ -103,7 +103,7 @@ int glob_ignore_case = 0;
/* Global variable controlling whether globbing ever returns . or ..
regardless of the pattern. If set to 1, no glob pattern will ever
match `.' or `..'. Disabled by default. */
int glob_always_skip_dot_and_dotdot = 0;
int glob_always_skip_dot_and_dotdot = 1;
/* Global variable to return to signify an error in globbing. */
char *glob_error_return;
+7 -1
View File
@@ -1819,7 +1819,7 @@ skip_matched_pair (string, start, open, close, flags)
: skip_double_quoted (ss, slen, ++i, 0);
/* no increment, the skip functions increment past the closing quote. */
}
else if ((flags&1) == 0 && c == '$' && (string[i+1] == LPAREN || string[i+1] == LBRACE))
else if ((flags & 1) == 0 && c == '$' && (string[i+1] == LPAREN || string[i+1] == LBRACE))
{
si = i + 2;
if (string[si] == '\0')
@@ -11608,6 +11608,12 @@ word_list_split (list)
w->word[0] = '\0';
tresult = make_word_list (w, (WORD_LIST *)NULL);
}
#if defined (ARRAY_VARS)
/* pass W_ARRAYREF through for words that are not split and are
identical to the original word. */
if (tresult && tresult->next == 0 && t->next == 0 && (t->word->flags & W_ARRAYREF) && STREQ (t->word->word, tresult->word->word))
tresult->word->flags |= W_ARRAYREF;
#endif
if (result == 0)
result = e = tresult;
else
+16 -6
View File
@@ -253,12 +253,12 @@ declare -A dict=(["?"]="quest" ["*"]="star" ["'"]="squote" ["\$"]="dol" ["\""]="
dict=( "?" "quest" "*" "star" "'" "squote" "\$" "dol" "\"" "dquote" "\\" "bslash" "@" "at" "}" "rbrace" "{" "lbrace" "\`" "bquote" )
declare -A foo=([two]="" [one]="1" )
foo=( two "" one "1" )
rparen dquote rbrace bs
declare -A a=([")"]="rparen" ["\""]="dquote" ["]"]="rbrace" ["\\"]="bs" )
")" "rparen" "\"" "dquote" "]" "rbrace" "\\" "bs"
declare -A a=([")"]="rparen" ["\""]="dquote" ["]"]="rbrace" ["\\"]="bs" )
declare -A a=([")"]="rparen" ["\""]="dquote" ["]"]="rbrace" ["\\"]="bs" )
declare -A a=([")"]="rparen" ["\""]="dquote" ["]"]="rbrace" ["\\"]="bs" )
rparen dquote rbracket bs
declare -A a=([")"]="rparen" ["\""]="dquote" ["]"]="rbracket" ["\\"]="bs" )
")" "rparen" "\"" "dquote" "]" "rbracket" "\\" "bs"
declare -A a=([")"]="rparen" ["\""]="dquote" ["]"]="rbracket" ["\\"]="bs" )
declare -A a=([")"]="rparen" ["\""]="dquote" ["]"]="rbracket" ["\\"]="bs" )
declare -A a=([")"]="rparen" ["\""]="dquote" ["]"]="rbracket" ["\\"]="bs" )
declare -Arx foo=([two]="2" [three]="3" [one]="1" )
./assoc11.sub: line 90: foo: readonly variable
declare -A v1=(["1 2"]="3" )
@@ -383,3 +383,13 @@ set
stderr
42
42
declare -A A=(["]"]="rbracket" ["["]="lbracket" )
declare -A A=()
declare -A A=(["]"]="rbracket" ["["]="lbracket" )
declare -A A=()
declare -A A=(["]"]="rbracket" ["["]="lbracket" )
declare -A A=()
declare -A A=(["]"]="rbracket" ["["]="lbracket" )
declare -A A=()
declare -A A=(["]"]="rbracket" ["["]="lbracket" )
declare -A A=()
+3
View File
@@ -259,3 +259,6 @@ ${THIS_SH} ./assoc15.sub
# tests with subscripts being expanded more than one in ${xxx} word expansions
${THIS_SH} ./assoc16.sub
# tests with `[' and `]' subscripts and `unset'
${THIS_SH} ./assoc17.sub
+1 -1
View File
@@ -69,7 +69,7 @@ foo=(one 1 two)
declare -p foo
echo foo=\( ${foo[@]@K} \)
typeset -A a=( [\\]=bs [\"]=dquote [\)]=rparen [\]]=rbrace )
typeset -A a=( [\\]=bs [\"]=dquote [\)]=rparen [\]]=rbracket )
echo ${a[@]}
declare -p a
+14
View File
@@ -1,3 +1,17 @@
# 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/>.
#
declare -A assoc=(hello world "key with spaces" "value with spaces" one 1 foo bar)
declare -p assoc
+58
View File
@@ -0,0 +1,58 @@
# 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/>.
#
# test behavior with `unset' and `[' and ']' subscripts
declare -A A
rkey=']'
lkey='['
A[$rkey]=rbracket
A[$lkey]=lbracket
declare -p A
unset A[$rkey]
unset A[$lkey]
declare -p A
A["$rkey"]=rbracket
A["$lkey"]=lbracket
declare -p A
unset A["$rkey"]
unset A["$lkey"]
declare -p A
A[\]]=rbracket
A[\[]=lbracket
declare -p A
unset A[\]]
unset A[\[]
declare -p A
A[']']=rbracket
A['[']=lbracket
declare -p A
unset A[']']
unset A['[']
declare -p A
A["]"]=rbracket
A["["]=lbracket
declare -p A
unset A["]"]
unset A["["]
declare -p A
+14 -14
View File
@@ -92,16 +92,16 @@ a ab
a ab
a ab
a
. ..
. .. a.log
*(.)
a.log
*(foo)
*(foo|bar)
a.log
?(foo)
a.log
a.log
. ..
. ..
*(foo).*
*(foo|bar).*
a.log
a.log
.x .y .z
@@ -114,16 +114,16 @@ a b c
.x .y .z a b c
.x .y .z a b c
*
.. .b a
.. .b a
a .. .b
. .. .b
. .. .b
.. .b a
.. .b a
a .. .b
. .. .b
. .. .b
.b a
.b a
a .b
.b
.b
.b a
.b a
a .b
.b
.b
dotglob: .a .foo bar
@(.foo)
.foo
+1
View File
@@ -12,6 +12,7 @@ cd $TESTDIR || {
LC_CTYPE=C LC_COLLATE=C
shopt -s extglob dotglob
shopt -u globskipdots # XXX - backwards compatibility
touch .foo bar .a
echo dotglob: .a .foo bar
+5 -1
View File
@@ -121,6 +121,10 @@ a\*b
a\*b*
é/*
é/*
a aa b bb
.a .aa .b .bb a aa b bb
.a .aa .b .bb
. .. .a .aa .b .bb
argv[1] = <a>
argv[2] = <abc>
argv[3] = <abd>
@@ -135,7 +139,7 @@ argv[2] = <abc>
argv[3] = <abd>
argv[4] = <abe>
tmp/l1 tmp/l2 tmp/*4 tmp/l3
./glob.tests: line 65: no match: tmp/*4
./glob.tests: line 66: no match: tmp/*4
argv[1] = <bdir/>
argv[1] = <*>
argv[1] = <a*>
+1
View File
@@ -30,6 +30,7 @@ ${THIS_SH} ./glob6.sub
${THIS_SH} ./glob7.sub
${THIS_SH} ./glob8.sub
${THIS_SH} ./glob9.sub
${THIS_SH} ./glob10.sub
MYDIR=$PWD # save where we are
+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/>.
#
# test basic behavior of globskipdots
TDIR=/tmp/dotglob-$$
{ mkdir $TDIR && cd $TDIR; } || exit 1
touch a b aa bb .a .b .aa .bb
echo *
shopt -s dotglob
echo *
shopt -s globskipdots
echo .*
shopt -u globskipdots
echo .*
cd $OLDPWD
rm -rf $TDIR
+6
View File
@@ -28,6 +28,7 @@ shopt -s extquote
shopt -u failglob
shopt -s force_fignore
shopt -s globasciiranges
shopt -s globskipdots
shopt -u globstar
shopt -u gnu_errfmt
shopt -u histappend
@@ -69,6 +70,7 @@ shopt -s expand_aliases
shopt -s extquote
shopt -s force_fignore
shopt -s globasciiranges
shopt -s globskipdots
shopt -s hostcomplete
shopt -s interactive_comments
shopt -s patsub_replacement
@@ -302,5 +304,9 @@ xtrace off
--
./shopt.tests: line 106: shopt: xyz1: invalid shell option name
./shopt.tests: line 107: shopt: xyz1: invalid option name
28c28
< globskipdots off
---
> globskipdots on
expand_aliases on
expand_aliases on