builtin (flags&CMD_COMMAND_BUILTIN), don't bother to print the
command words if set -x is enabled. From a report by Martijn Dekker
<martijn@inlv.org> back in 4/2018
+
+ 6/19
+ ----
+lib/glob/glob.c
+ - glob_filename: if we are not being called recursively, and there is
+ only a directory name, dequote the passed pathname and see if it
+ names an existing directory. If it does, return it; otherwise return
+ failure ((char **)&glob_error_return). This is what makes backslash
+ escaped-characters in pathnames in shell variables work the same as
+ the same value passed directly. From an anonymous comment on
+ https://savannah.gnu.org/support/?109629 and a discussion on the
+ austin-group list.
+
+ 6/20
+ ----
+pathexp.c,lib/glob/glob.c
+ - posix_glob_backslash: variable to control whether or not pathname
+ expansion handles backslashes in the pattern the way Posix says it
+ should. Enabled by default
+
+pathexp.h
+ - posix_glob_backslash: new extern declaration
+
+builtins/shopt.def
+ - posixglob: new option, reflects the value of posix_glob_backslash
+
+general.c
+ - posix_vars: add posix_glob_backslash to the table
+ - posix_initialize: set posix_glob_backslash to 1 when turning on
+ posix mode
general.o: general.h xmalloc.h bashtypes.h variables.h arrayfunc.h conftypes.h array.h hashlib.h
general.o: quit.h ${BASHINCDIR}/maxpath.h unwind_prot.h dispose_cmd.h
general.o: make_cmd.h subst.h sig.h pathnames.h externs.h flags.h parser.h
+general.o: pathexp.h
general.o: ${BASHINCDIR}/maxpath.h ${BASHINCDIR}/posixtime.h
general.o: ${BASHINCDIR}/chartypes.h
hashcmd.o: config.h ${BASHINCDIR}/posixstat.h bashtypes.h bashansi.h ${BASHINCDIR}/ansi_stdlib.h
extern int inherit_errexit;
extern int localvar_inherit;
extern int localvar_unset;
+extern int posix_glob_backslash;
#if defined (EXTENDED_GLOB)
extern int extended_glob;
{ "nocaseglob", &glob_ignore_case, (shopt_set_func_t *)NULL },
{ "nocasematch", &match_ignore_case, (shopt_set_func_t *)NULL },
{ "nullglob", &allow_null_glob_expansion, (shopt_set_func_t *)NULL },
+ { "posixglob", &posix_glob_backslash, (shopt_set_func_t *)NULL },
#if defined (PROGRAMMABLE_COMPLETION)
{ "progcomp", &prog_completion_enabled, (shopt_set_func_t *)NULL },
# if defined (ALIAS)
.\" Case Western Reserve University
.\" chet.ramey@case.edu
.\"
-.\" Last Change: Mon May 20 10:45:39 EDT 2019
+.\" Last Change: Wed Jun 19 11:22:28 EDT 2019
.\"
.\" bash_builtins, strip all but Built-Ins section
.if \n(zZ=1 .ig zZ
.if \n(zY=1 .ig zY
-.TH BASH 1 "2019 May 20" "GNU Bash 5.0"
+.TH BASH 1 "2019 June 19" "GNU Bash 5.0"
.\"
.\" There's some problem with having a `@'
.\" in a tagged paragraph with the BSD man macros.
A shell variable need not have its \fIinteger\fP attribute
turned on to be used in an expression.
.PP
+Integer constants follow the C language definition, without suffixes or
+character constants.
Constants with a leading 0 are interpreted as octal numbers.
A leading 0x or 0X denotes hexadecimal.
Otherwise, numbers take the form [\fIbase#\fP]n, where the optional \fIbase\fP
base, and \fIn\fP is a number in that base.
If \fIbase#\fP is omitted, then base 10 is used.
When specifying \fIn\fP,
+if a non-digit is required,
the digits greater than 9 are represented by the lowercase letters,
the uppercase letters, @, and _, in that order.
If \fIbase\fP is less than or equal to 36, lowercase and uppercase
A shell variable need not have its @var{integer} attribute turned on
to be used in an expression.
+Integer constants follow the C language definition, without suffixes or
+character constants.
Constants with a leading 0 are interpreted as octal numbers.
A leading @samp{0x} or @samp{0X} denotes hexadecimal. Otherwise,
numbers take the form [@var{base}@code{#}]@var{n}, where the optional @var{base}
base, and @var{n} is a number in that base.
If @var{base}@code{#} is omitted, then base 10 is used.
When specifying @var{n},
+if a non-digit is required,
the digits greater than 9 are represented by the lowercase letters,
the uppercase letters, @samp{@@}, and @samp{_}, in that order.
If @var{base} is less than or equal to 36, lowercase and uppercase
Copyright (C) 1988-2019 Free Software Foundation, Inc.
@end ignore
-@set LASTCHANGE Thu Jun 13 15:43:41 EDT 2019
+@set LASTCHANGE Wed Jun 19 11:22:46 EDT 2019
@set EDITION 5.0
@set VERSION 5.0
-@set UPDATED 13 June 2019
+@set UPDATED 19 June 2019
@set UPDATED-MONTH June 2019
/* general.c -- Stuff that is used by all files. */
-/* Copyright (C) 1987-2016 Free Software Foundation, Inc.
+/* Copyright (C) 1987-2019 Free Software Foundation, Inc.
This file is part of GNU Bash, the Bourne Again SHell.
#include "findcmd.h"
#include "test.h"
#include "trap.h"
+#include "pathexp.h"
#include "builtins/common.h"
expand_aliases
inherit_errexit
print_shift_error
+ posixglob
and the following variables which cannot be user-modified:
&source_uses_path,
&expand_aliases,
&inherit_errexit,
+ &posix_glob_backslash,
&print_shift_error,
0
};
inherit_errexit = 1;
source_searches_cwd = 0;
print_shift_error = 1;
-
+ posix_glob_backslash = 1;
}
/* Things that should be turned on when posix mode is disabled. */
/* glob.c -- file-name wildcard pattern matching for Bash.
- Copyright (C) 1985-2017 Free Software Foundation, Inc.
+ Copyright (C) 1985-2019 Free Software Foundation, Inc.
This file is part of GNU Bash, the Bourne-Again SHell.
extern void run_pending_traps __P((void));
extern int extended_glob;
+extern int posix_glob_backslash;
/* Global variable which controls whether or not * matches .*.
Non-zero means don't match .*. */
/* We could check whether or not the dequoted directory_name is a
directory and return it here, returning the original directory_name
- if not, but we don't do that yet. I'm not sure it matters. */
+ if not, but we don't do that. We do return the dequoted directory
+ name if we're not being called recursively and the dequoted name
+ corresponds to an actual directory. For better backwards compatibility,
+ we can return &glob_error_return unconditionally in this case. */
+
+ if (directory_len > 0 && hasglob == 2 && (flags & GX_RECURSE) == 0)
+ {
+#if 1
+ dequote_pathname (directory_name);
+ if (glob_testdir (directory_name, 0) < 0)
+ {
+ if (free_dirname)
+ free (directory_name);
+ return ((char **)&glob_error_return);
+ }
+#else
+ return ((char **)&glob_error_return);
+#endif
+ }
/* Handle GX_MARKDIRS here. */
result[0] = (char *) malloc (directory_len + 1);
-/* Copyright (C) 1991-2017 Free Software Foundation, Inc.
+/* Copyright (C) 1991-2019 Free Software Foundation, Inc.
This file is part of GNU Bash, the Bourne Again SHell.
return 0;
}
- return bsquote ? 2 : 0;
+ return ((bsquote && posix_glob_backslash) ? 2 : 0);
}
#undef INTERNAL_GLOB_PATTERN_P
/* Control enabling special handling of `**' */
int glob_star = 0;
+/* Do we handle backslashes in patterns the way Posix specifies? */
+int posix_glob_backslash = 1;
+
/* Return nonzero if STRING has any unquoted special globbing chars in it. */
int
unquoted_glob_pattern_p (string)
#endif
}
- return (bsquote ? 2 : 0);
+ return ((bsquote && posix_glob_backslash) ? 2 : 0);
}
/* Return 1 if C is a character that is `special' in a POSIX ERE and needs to
#else /* !USE_POSIX_GLOB_LIBRARY */
char *temp, **results;
- int gflags;
+ int gflags, quoted_pattern;
noglob_dot_filenames = glob_dot_filenames == 0;
temp = quote_string_for_globbing (pathname, QGLOB_FILENAME);
+ quoted_pattern = STREQ (pathname, temp) == 0;
gflags = glob_star ? GX_GLOBSTAR : 0;
results = glob_filename (temp, gflags);
free (temp);
extern int extended_glob;
extern int glob_star;
extern int match_ignore_case; /* doesn't really belong here */
+extern int posix_glob_backslash;
extern int unquoted_glob_pattern_p __P((char *));
./errors.tests: line 42: unset: func: cannot unset: readonly function
./errors.tests: line 45: declare: func: readonly function
./errors.tests: line 49: unset: XPATH: cannot unset: readonly variable
-./errors.tests: line 52: unset: `/bin/sh': not a valid identifier
./errors.tests: line 55: unset: cannot simultaneously unset a function and a variable
./errors.tests: line 58: declare: -z: invalid option
declare: usage: declare [-aAfFgilnrtux] [-p] [name[=value] ...]
argv[1] = <./tmp/a/b/c>
argv[1] = <./tmp/a/>
argv[1] = <./tmp/a/b/>
-argv[1] = <./t\mp/a/>
-argv[1] = <./t\mp/a/b/>
+argv[1] = <./tmp/a/>
+argv[1] = <./tmp/a/b/>
argv[1] = <./tmp/a/*>
argv[1] = <./tmp/a/b/c>
argv[1] = <./tmp/a>
argv[1] = <./tmp/a>
argv[1] = <./tmp/a/b*>
argv[1] = <./tmp/>
+argv[1] = <\$foo>
+argv[2] = <\$foo>
+argv[1] = <mixed\$foo/>
argv[1] = <a>
argv[2] = <abc>
argv[3] = <abd>
chmod +r ./tmp/a
rm -rf ./tmp/a
+a='$foo'
+b='$bar'
+a=$(echo "$a" | sed 's/\$/\\$/g')
+
+recho $a "$a"
+recho 'mixed'$a/
+
+unset a b
+
cd $ORIGD
rm -rf $SD
shopt -u nocaseglob
shopt -u nocasematch
shopt -u nullglob
+shopt -s posixglob
shopt -s progcomp
shopt -u progcomp_alias
shopt -s promptvars
shopt -s globasciiranges
shopt -s hostcomplete
shopt -s interactive_comments
+shopt -s posixglob
shopt -s progcomp
shopt -s promptvars
shopt -s sourcepath