change to behavior of '&' in pattern substitution replacement string; fix for blank lines in multiline commands saved in command history

This commit is contained in:
Chet Ramey
2022-01-18 10:59:53 -05:00
parent 5e6f45d9b1
commit 2a1c81bf63
31 changed files with 1596 additions and 1312 deletions
+28
View File
@@ -2914,3 +2914,31 @@ examples/loadables/accept.c
----
configure.ac
- bumped version to 5.2-alpha.
1/16
----
tests/{unicode1,glob2,intl2}.sub, tests/run-intl
- minor changes to add warnings for missing locales that cause test
failures
1/17
----
parse.y
- history_delimiting_chars: if we have a blank line by the time we
hit the end of the tests, return a semicolon for the first blank
line to avoid running lines of a multi-line command together.
Fixes bug reported by Joakim Lindblad <joakim@cb.uu.se>
subst.c
- expand_string_for_patsub: expand the replacement string for pattern
substitution assuming that it will eventually be passed to
strcreplace to replace `&' with the matched portion of the string.
This calls expand_string_for_pat(), which leaves the string quoted
and does not perform word splitting, then calls
quote_string_for_repl to post-process the expanded string.
- quote_string_for_repl: perform quote removal on passed string while
replacing CTLESC escaping a `&' or a backslash with a backslash. The
result must be passed to strcreplace
- parameter_brace_patsub: call expand_string_for_patsub if
patsub_replacement is set to quote
+6 -3
View File
@@ -148,10 +148,11 @@ redir.h f
bashtypes.h f
mailcheck.h f
xmalloc.h f
y.tab.c f
y.tab.h f
parser-built f
pathnames.h.in f
# order is important here
y.tab.c F
y.tab.h F
parser-built F
builtins/Makefile.in f
builtins/alias.def f
builtins/bind.def f
@@ -955,6 +956,7 @@ tests/assoc14.sub f
tests/assoc15.sub f
tests/assoc16.sub f
tests/assoc17.sub f
tests/assoc18.sub f
tests/attr.tests f
tests/attr.right f
tests/attr1.sub f
@@ -1098,6 +1100,7 @@ tests/exp9.sub f
tests/exp10.sub f
tests/exp11.sub f
tests/exp12.sub f
tests/exp13.sub f
tests/exportfunc.tests f
tests/exportfunc.right f
tests/exportfunc1.sub f
+1 -1
View File
@@ -588,7 +588,7 @@ LOADABLES_DIR = ${top_builddir}/examples/loadables
.made: $(Program) bashbug $(SDIR)/man2html$(EXEEXT)
@echo "$(Program) last made for a $(Machine) running $(OS)" >.made
$(Program): .build $(OBJECTS) $(BUILTINS_DEP) $(LIBDEP)
$(Program): $(OBJECTS) $(BUILTINS_DEP) $(LIBDEP) .build
$(RM) $@
$(PURIFY) $(CC) $(BUILTINS_LDFLAGS) $(LIBRARY_LDFLAGS) $(LDFLAGS) -o $(Program) $(OBJECTS) $(LIBS)
ls -l $(Program)
+30 -20
View File
@@ -9,7 +9,7 @@ SSYYNNOOPPSSIISS
bbaasshh [options] [command_string | file]
CCOOPPYYRRIIGGHHTT
Bash is Copyright (C) 1989-2021 by the Free Software Foundation, Inc.
Bash is Copyright (C) 1989-2022 by the Free Software Foundation, Inc.
DDEESSCCRRIIPPTTIIOONN
BBaasshh is an sshh-compatible command language interpreter that executes
@@ -1849,24 +1849,34 @@ EEXXPPAANNSSIIOONN
end of the expanded value of _p_a_r_a_m_e_t_e_r. If the expansion of
_s_t_r_i_n_g is null, matches of _p_a_t_t_e_r_n are deleted. If _s_t_r_i_n_g is
null, matches of _p_a_t_t_e_r_n are deleted and the // following _p_a_t_t_e_r_n
may be omitted. If the ppaattssuubb__rreeppllaacceemmeenntt shell option is en-
abled using sshhoopptt, any unquoted instances of && in _s_t_r_i_n_g are re-
placed with the matching portion of _p_a_t_t_e_r_n. Backslash is used
to quote && in _s_t_r_i_n_g; the backslash is removed in order to per-
mit a literal && in the replacement string. Users should take
care if _s_t_r_i_n_g is double-quoted to avoid unwanted interactions
between the backslash and double-quoting. Pattern substitution
performs the check for && after expanding _s_t_r_i_n_g; shell program-
mers should quote backslashes intended to escape the && and in-
hibit replacement so they survive any quote removal performed by
the expansion of _s_t_r_i_n_g. If the nnooccaasseemmaattcchh shell option is en-
abled, the match is performed without regard to the case of al-
phabetic characters. If _p_a_r_a_m_e_t_e_r is @@ or **, the substitution
operation is applied to each positional parameter in turn, and
the expansion is the resultant list. If _p_a_r_a_m_e_t_e_r is an array
variable subscripted with @@ or **, the substitution operation is
applied to each member of the array in turn, and the expansion
is the resultant list.
may be omitted.
If the ppaattssuubb__rreeppllaacceemmeenntt shell option is enabled using sshhoopptt,
any unquoted instances of && in _s_t_r_i_n_g are replaced with the
matching portion of _p_a_t_t_e_r_n.
Quoting any part of _s_t_r_i_n_g inhibits replacement in the expansion
of the quoted portion, including replacement strings stored in
shell variables. Backslash will escape && in _s_t_r_i_n_g; the back-
slash is removed in order to permit a literal && in the replace-
ment string. Backslash can also be used to escape a backslash;
\\\\ results in a literal backslash in the replacement. Users
should take care if _s_t_r_i_n_g is double-quoted to avoid unwanted
interactions between the backslash and double-quoting, since
backslash has special meaning within double quotes. Pattern
substitution performs the check for unquoted && after expanding
_s_t_r_i_n_g; shell programmers should quote any occurrences of && they
want to be taken literally in the replacement and ensure any in-
stances of && they want to be replaced are unquoted.
If the nnooccaasseemmaattcchh shell option is enabled, the match is per-
formed without regard to the case of alphabetic characters. If
_p_a_r_a_m_e_t_e_r is @@ or **, the substitution operation is applied to
each positional parameter in turn, and the expansion is the re-
sultant list. If _p_a_r_a_m_e_t_e_r is an array variable subscripted
with @@ or **, the substitution operation is applied to each mem-
ber of the array in turn, and the expansion is the resultant
list.
${_p_a_r_a_m_e_t_e_r^^_p_a_t_t_e_r_n}
${_p_a_r_a_m_e_t_e_r^^^^_p_a_t_t_e_r_n}
@@ -6597,4 +6607,4 @@ BBUUGGSS
GNU Bash 5.2 2021 December 26 BASH(1)
GNU Bash 5.2 2022 January 17 BASH(1)
+21 -12
View File
@@ -5,12 +5,12 @@
.\" Case Western Reserve University
.\" chet.ramey@case.edu
.\"
.\" Last Change: Sun Dec 26 16:02:07 EST 2021
.\" Last Change: Mon Jan 17 17:27:05 EST 2022
.\"
.\" bash_builtins, strip all but Built-Ins section
.if \n(zZ=1 .ig zZ
.if \n(zY=1 .ig zY
.TH BASH 1 "2021 December 26" "GNU Bash 5.2"
.TH BASH 1 "2022 January 17" "GNU Bash 5.2"
.\"
.\" There's some problem with having a `@'
.\" in a tagged paragraph with the BSD man macros.
@@ -50,8 +50,8 @@ bash \- GNU Bourne-Again SHell
[options]
[command_string | file]
.SH COPYRIGHT
.if n Bash is Copyright (C) 1989-2021 by the Free Software Foundation, Inc.
.if t Bash is Copyright \(co 1989-2021 by the Free Software Foundation, Inc.
.if n Bash is Copyright (C) 1989-2022 by the Free Software Foundation, Inc.
.if t Bash is Copyright \(co 1989-2022 by the Free Software Foundation, Inc.
.SH DESCRIPTION
.B Bash
is an \fBsh\fR-compatible command language interpreter that
@@ -3373,18 +3373,27 @@ matches of \fIpattern\fP are deleted.
If \fIstring\fP is null,
matches of \fIpattern\fP are deleted
and the \fB/\fP following \fIpattern\fP may be omitted.
.sp 1
If the \fBpatsub_replacement\fP shell option is enabled using \fBshopt\fP,
any unquoted instances of \fB&\fP in \fIstring\fP are replaced with the
matching portion of \fIpattern\fP.
Backslash is used to quote \fB&\fP in \fIstring\fP; the backslash is removed
.sp 1
Quoting any part of \fIstring\fP inhibits replacement in the
expansion of the quoted portion, including replacement strings stored
in shell variables.
Backslash will escape \fB&\fP in \fIstring\fP; the backslash is removed
in order to permit a literal \fB&\fP in the replacement string.
Users should take care
if \fIstring\fP is double-quoted to avoid unwanted interactions between
the backslash and double-quoting.
Pattern substitution performs the check for \fB&\fP after expanding
\fIstring\fP; shell programmers should quote backslashes intended to escape
the \fB&\fP and inhibit replacement so they survive any quote removal
performed by the expansion of \fIstring\fP.
Backslash can also be used to escape a backslash; \fB\e\e\fP results in
a literal backslash in the replacement.
Users should take care if \fIstring\fP is double-quoted to avoid
unwanted interactions between the backslash and double-quoting, since
backslash has special meaning within double quotes.
Pattern substitution performs the check for unquoted \fB&\fP after
expanding \fIstring\fP;
shell programmers should quote any occurrences of \fB&\fP
they want to be taken literally in the replacement
and ensure any instances of \fB&\fP they want to be replaced are unquoted.
.sp 1
If the
.B nocasematch
shell option is enabled, the match is performed without regard to the case
+178 -158
View File
@@ -2,9 +2,9 @@ This is bashref.info, produced by makeinfo version 6.8 from
bashref.texi.
This text is a brief description of the features that are present in the
Bash shell (version 5.2, 26 December 2021).
Bash shell (version 5.2, 17 January 2022).
This is Edition 5.2, last updated 26 December 2021, of 'The GNU Bash
This is Edition 5.2, last updated 17 January 2022, of 'The GNU Bash
Reference Manual', for 'Bash', Version 5.2.
Copyright (C) 1988-2021 Free Software Foundation, Inc.
@@ -27,10 +27,10 @@ Bash Features
*************
This text is a brief description of the features that are present in the
Bash shell (version 5.2, 26 December 2021). The Bash home page is
Bash shell (version 5.2, 17 January 2022). The Bash home page is
<http://www.gnu.org/software/bash/>.
This is Edition 5.2, last updated 26 December 2021, of 'The GNU Bash
This is Edition 5.2, last updated 17 January 2022, of 'The GNU Bash
Reference Manual', for 'Bash', Version 5.2.
Bash contains features that appear in other popular shells, and some
@@ -2079,38 +2079,58 @@ omitted, the operator tests only for existence.
If the 'patsub_replacement' shell option is enabled using 'shopt',
any unquoted instances of '&' in STRING are replaced with the
matching portion of PATTERN. This is intended to duplicate a
common 'sed' idiom. Backslash is used to quote '&' in STRING; the
backslash is removed in order to permit a literal '&' in the
replacement string. Pattern substitution performs the check for
'&' after expanding STRING, so users should take care to quote
backslashes intended to escape the '&' and inhibit replacement so
they survive any quote removal performed by the expansion of
STRING. For instance,
common 'sed' idiom.
Quoting any part of STRING inhibits replacement in the expansion of
the quoted portion, including replacement strings stored in shell
variables. Backslash will escape '&' in STRING; the backslash is
removed in order to permit a literal '&' in the replacement string.
Users should take care if STRING is double-quoted to avoid unwanted
interactions between the backslash and double-quoting, since
backslash has special meaning within double quotes. Pattern
substitution performs the check for unquoted '&' after expanding
STRING, so users should ensure to properly quote any occurrences of
'&' they want to be taken literally in the replacement and ensure
any instances of '&' they want to be replaced are unquoted.
For instance,
var=abcdef
rep='& '
echo ${var/abc/& }
echo "${var/abc/& }"
echo ${var/abc/"& "}
echo ${var/abc/$rep}
echo "${var/abc/$rep}"
will display three lines of "abc def", while
will display four lines of "abc def", while
var=abcdef
rep='& '
echo ${var/abc/\& }
echo "${var/abc/\& }"
echo ${var/abc/"\& "}
echo ${var/abc/"& "}
echo ${var/abc/"$rep"}
will display two lines of "abc def" and a third line of "& def".
The first two are replaced because the backslash is removed by
quote removal performed during the expansion of STRING (the
expansion is performed in a context that doesn't take any enclosing
double quotes into account, as with other word expansions). In the
third case, the double quotes affect the expansion of '\&', and,
because '&' is not one of the characters for which backslash is
special in double quotes, the backslash survives the expansion,
inhibits the replacement, but is removed because it is treated
specially. One could use '\\&', unquoted, as the replacement
string to achive the same effect. It should rarely be necessary to
enclose only STRING in double quotes.
will display four lines of "& def". Like the pattern removal
operators, double quotes surrounding the replacement string quote
the expanded characters, while double quotes enclosing the entire
parameter substitution do not, since the expansion is performed in
a context that doesn't take any enclosing double quotes into
account.
Since backslash can escape '&', it can also escape a backslash in
the replacement string. This means that '\\' will insert a literal
backslash into the replacement, so these two 'echo' commands
var=abcdef
rep='\\&xyz'
echo ${var/abc/\\&xyz}
echo ${var/abc/$rep}
will both output '\abcxyzdef'.
It should rarely be necessary to enclose only STRING in double
quotes.
If the 'nocasematch' shell option (see the description of 'shopt'
in *note The Shopt Builtin::) is enabled, the match is performed
@@ -12423,138 +12443,138 @@ D.5 Concept Index

Tag Table:
Node: Top897
Node: Introduction2817
Node: What is Bash?3033
Node: What is a shell?4147
Node: Definitions6685
Node: Basic Shell Features9636
Node: Shell Syntax10855
Node: Shell Operation11881
Node: Quoting13174
Node: Escape Character14478
Node: Single Quotes14963
Node: Double Quotes15311
Node: ANSI-C Quoting16589
Node: Locale Translation17899
Node: Creating Internationalized Scripts19210
Node: Comments23327
Node: Shell Commands23945
Node: Reserved Words24883
Node: Simple Commands25639
Node: Pipelines26293
Node: Lists29252
Node: Compound Commands31047
Node: Looping Constructs32059
Node: Conditional Constructs34554
Node: Command Grouping48898
Node: Coprocesses50376
Node: GNU Parallel53039
Node: Shell Functions53956
Node: Shell Parameters61247
Node: Positional Parameters65635
Node: Special Parameters66537
Node: Shell Expansions69751
Node: Brace Expansion71878
Node: Tilde Expansion74612
Node: Shell Parameter Expansion77233
Node: Command Substitution95099
Node: Arithmetic Expansion96454
Node: Process Substitution97422
Node: Word Splitting98542
Node: Filename Expansion100486
Node: Pattern Matching103235
Node: Quote Removal107843
Node: Redirections108138
Node: Executing Commands117798
Node: Simple Command Expansion118468
Node: Command Search and Execution120578
Node: Command Execution Environment122956
Node: Environment125991
Node: Exit Status127654
Node: Signals129438
Node: Shell Scripts132887
Node: Shell Builtin Commands135914
Node: Bourne Shell Builtins137952
Node: Bash Builtins159413
Node: Modifying Shell Behavior190269
Node: The Set Builtin190614
Node: The Shopt Builtin201215
Node: Special Builtins217127
Node: Shell Variables218106
Node: Bourne Shell Variables218543
Node: Bash Variables220647
Node: Bash Features253463
Node: Invoking Bash254476
Node: Bash Startup Files260489
Node: Interactive Shells265592
Node: What is an Interactive Shell?266002
Node: Is this Shell Interactive?266651
Node: Interactive Shell Behavior267466
Node: Bash Conditional Expressions271095
Node: Shell Arithmetic275737
Node: Aliases278681
Node: Arrays281294
Node: The Directory Stack287541
Node: Directory Stack Builtins288325
Node: Controlling the Prompt292585
Node: The Restricted Shell295550
Node: Bash POSIX Mode298160
Node: Shell Compatibility Mode309433
Node: Job Control317462
Node: Job Control Basics317922
Node: Job Control Builtins322924
Node: Job Control Variables328324
Node: Command Line Editing329480
Node: Introduction and Notation331151
Node: Readline Interaction332774
Node: Readline Bare Essentials333965
Node: Readline Movement Commands335748
Node: Readline Killing Commands336708
Node: Readline Arguments338626
Node: Searching339670
Node: Readline Init File341856
Node: Readline Init File Syntax343117
Node: Conditional Init Constructs364605
Node: Sample Init File368801
Node: Bindable Readline Commands371925
Node: Commands For Moving373129
Node: Commands For History375180
Node: Commands For Text380174
Node: Commands For Killing383823
Node: Numeric Arguments386856
Node: Commands For Completion387995
Node: Keyboard Macros392186
Node: Miscellaneous Commands392873
Node: Readline vi Mode398812
Node: Programmable Completion399719
Node: Programmable Completion Builtins407499
Node: A Programmable Completion Example418194
Node: Using History Interactively423441
Node: Bash History Facilities424125
Node: Bash History Builtins427130
Node: History Interaction432138
Node: Event Designators435758
Node: Word Designators437112
Node: Modifiers438872
Node: Installing Bash440683
Node: Basic Installation441820
Node: Compilers and Options445542
Node: Compiling For Multiple Architectures446283
Node: Installation Names447976
Node: Specifying the System Type450085
Node: Sharing Defaults450801
Node: Operation Controls451474
Node: Optional Features452432
Node: Reporting Bugs463650
Node: Major Differences From The Bourne Shell464925
Node: GNU Free Documentation License481775
Node: Indexes506952
Node: Builtin Index507406
Node: Reserved Word Index514233
Node: Variable Index516681
Node: Function Index533173
Node: Concept Index546957
Node: Top895
Node: Introduction2813
Node: What is Bash?3029
Node: What is a shell?4143
Node: Definitions6681
Node: Basic Shell Features9632
Node: Shell Syntax10851
Node: Shell Operation11877
Node: Quoting13170
Node: Escape Character14474
Node: Single Quotes14959
Node: Double Quotes15307
Node: ANSI-C Quoting16585
Node: Locale Translation17895
Node: Creating Internationalized Scripts19206
Node: Comments23323
Node: Shell Commands23941
Node: Reserved Words24879
Node: Simple Commands25635
Node: Pipelines26289
Node: Lists29248
Node: Compound Commands31043
Node: Looping Constructs32055
Node: Conditional Constructs34550
Node: Command Grouping48894
Node: Coprocesses50372
Node: GNU Parallel53035
Node: Shell Functions53952
Node: Shell Parameters61243
Node: Positional Parameters65631
Node: Special Parameters66533
Node: Shell Expansions69747
Node: Brace Expansion71874
Node: Tilde Expansion74608
Node: Shell Parameter Expansion77229
Node: Command Substitution95566
Node: Arithmetic Expansion96921
Node: Process Substitution97889
Node: Word Splitting99009
Node: Filename Expansion100953
Node: Pattern Matching103702
Node: Quote Removal108310
Node: Redirections108605
Node: Executing Commands118265
Node: Simple Command Expansion118935
Node: Command Search and Execution121045
Node: Command Execution Environment123423
Node: Environment126458
Node: Exit Status128121
Node: Signals129905
Node: Shell Scripts133354
Node: Shell Builtin Commands136381
Node: Bourne Shell Builtins138419
Node: Bash Builtins159880
Node: Modifying Shell Behavior190736
Node: The Set Builtin191081
Node: The Shopt Builtin201682
Node: Special Builtins217594
Node: Shell Variables218573
Node: Bourne Shell Variables219010
Node: Bash Variables221114
Node: Bash Features253930
Node: Invoking Bash254943
Node: Bash Startup Files260956
Node: Interactive Shells266059
Node: What is an Interactive Shell?266469
Node: Is this Shell Interactive?267118
Node: Interactive Shell Behavior267933
Node: Bash Conditional Expressions271562
Node: Shell Arithmetic276204
Node: Aliases279148
Node: Arrays281761
Node: The Directory Stack288008
Node: Directory Stack Builtins288792
Node: Controlling the Prompt293052
Node: The Restricted Shell296017
Node: Bash POSIX Mode298627
Node: Shell Compatibility Mode309900
Node: Job Control317929
Node: Job Control Basics318389
Node: Job Control Builtins323391
Node: Job Control Variables328791
Node: Command Line Editing329947
Node: Introduction and Notation331618
Node: Readline Interaction333241
Node: Readline Bare Essentials334432
Node: Readline Movement Commands336215
Node: Readline Killing Commands337175
Node: Readline Arguments339093
Node: Searching340137
Node: Readline Init File342323
Node: Readline Init File Syntax343584
Node: Conditional Init Constructs365072
Node: Sample Init File369268
Node: Bindable Readline Commands372392
Node: Commands For Moving373596
Node: Commands For History375647
Node: Commands For Text380641
Node: Commands For Killing384290
Node: Numeric Arguments387323
Node: Commands For Completion388462
Node: Keyboard Macros392653
Node: Miscellaneous Commands393340
Node: Readline vi Mode399279
Node: Programmable Completion400186
Node: Programmable Completion Builtins407966
Node: A Programmable Completion Example418661
Node: Using History Interactively423908
Node: Bash History Facilities424592
Node: Bash History Builtins427597
Node: History Interaction432605
Node: Event Designators436225
Node: Word Designators437579
Node: Modifiers439339
Node: Installing Bash441150
Node: Basic Installation442287
Node: Compilers and Options446009
Node: Compiling For Multiple Architectures446750
Node: Installation Names448443
Node: Specifying the System Type450552
Node: Sharing Defaults451268
Node: Operation Controls451941
Node: Optional Features452899
Node: Reporting Bugs464117
Node: Major Differences From The Bourne Shell465392
Node: GNU Free Documentation License482242
Node: Indexes507419
Node: Builtin Index507873
Node: Reserved Word Index514700
Node: Variable Index517148
Node: Function Index533640
Node: Concept Index547424

End Tag Table
+43 -22
View File
@@ -2444,46 +2444,67 @@ If the @code{patsub_replacement} shell option is enabled using @code{shopt},
any unquoted instances of @samp{&} in @var{string} are replaced with the
matching portion of @var{pattern}.
This is intended to duplicate a common @code{sed} idiom.
Backslash is used to quote @samp{&} in @var{string}; the backslash is removed
Quoting any part of @var{string} inhibits replacement in the
expansion of the quoted portion, including replacement strings stored
in shell variables.
Backslash will escape @samp{&} in @var{string}; the backslash is removed
in order to permit a literal @samp{&} in the replacement string.
Pattern substitution performs the check for @samp{&} after expanding
@var{string},
so users should take care to quote backslashes intended to escape
the @samp{&} and inhibit replacement so they survive any quote removal
performed by the expansion of @var{string}.
Users should take care if @var{string} is double-quoted to avoid
unwanted interactions between the backslash and double-quoting, since
backslash has special meaning within double quotes.
Pattern substitution performs the check for unquoted @samp{&} after
expanding @var{string},
so users should ensure to properly quote any occurrences of @samp{&}
they want to be taken literally in the replacement
and ensure any instances of @samp{&} they want to be replaced are unquoted.
For instance,
@example
var=abcdef
rep='& '
echo $@{var/abc/& @}
echo "$@{var/abc/& @}"
echo $@{var/abc/"& "@}
echo $@{var/abc/$rep@}
echo "$@{var/abc/$rep@}"
@end example
@noindent
will display three lines of "abc def", while
will display four lines of "abc def", while
@example
var=abcdef
rep='& '
echo $@{var/abc/\& @}
echo "$@{var/abc/\& @}"
echo $@{var/abc/"\& "@}
echo $@{var/abc/"& "@}
echo $@{var/abc/"$rep"@}
@end example
@noindent
will display two lines of "abc def" and a third line of "& def".
The first two are replaced because the backslash is removed by quote
removal performed during the expansion of @var{string}
(the expansion is performed in a
context that doesn't take any enclosing double quotes into account, as
with other word expansions).
In the third case, the double quotes affect the expansion
of @samp{\&}, and, because @samp{&} is not one of the characters for
which backslash is special in double quotes,
the backslash survives the expansion, inhibits the replacement,
but is removed because it is treated specially.
One could use @samp{\\&}, unquoted, as the replacement string to achive
the same effect.
will display four lines of "& def".
Like the pattern removal operators, double quotes surrounding the
replacement string quote the expanded characters, while double quotes
enclosing the entire parameter substitution do not, since
the expansion is performed in a
context that doesn't take any enclosing double quotes into account.
Since backslash can escape @samp{&}, it can also escape a backslash in
the replacement string.
This means that @samp{\\} will insert a literal
backslash into the replacement, so these two @code{echo} commands
@example
var=abcdef
rep='\\&xyz'
echo $@{var/abc/\\&xyz@}
echo $@{var/abc/$rep@}
@end example
@noindent
will both output @samp{\abcxyzdef}.
It should rarely be necessary to enclose only @var{string} in double
quotes.
+4 -4
View File
@@ -1,11 +1,11 @@
@ignore
Copyright (C) 1988-2021 Free Software Foundation, Inc.
Copyright (C) 1988-2022 Free Software Foundation, Inc.
@end ignore
@set LASTCHANGE Sun Dec 26 16:02:48 EST 2021
@set LASTCHANGE Mon Jan 17 17:03:25 EST 2022
@set EDITION 5.2
@set VERSION 5.2
@set UPDATED 26 December 2021
@set UPDATED-MONTH December 2021
@set UPDATED 17 January 2022
@set UPDATED-MONTH January 2022
+4 -1
View File
@@ -5433,8 +5433,11 @@ history_delimiting_chars (line)
return (" ");
}
/* Assume that by this point we are reading lines in a multi-line command.
If we have multiple consecutive blank lines we want to return only one
semicolon. */
if (line_isblank (line))
return ("");
return (current_command_line_count > 1 && last_read_token == '\n' && token_before_that != '\n') ? "; " : "";
return ("; ");
}
BIN
View File
Binary file not shown.
+1026 -1066
View File
File diff suppressed because it is too large Load Diff
+105 -4
View File
@@ -341,6 +341,7 @@ static int shouldexp_replacement PARAMS((char *));
static char *pos_params_pat_subst PARAMS((char *, char *, char *, int));
static char *expand_string_for_patsub PARAMS((char *, int));
static char *parameter_brace_patsub PARAMS((char *, char *, array_eltstate_t *, char *, int, int, int));
static char *pos_params_casemod PARAMS((char *, char *, int, int));
@@ -3603,6 +3604,104 @@ expand_assignment_string_to_string (string, quoted)
return (expand_string_to_string_internal (string, quoted, expand_string_assignment));
}
/* Kind of like a combination of dequote_string and quote_string_for_globbing;
try to remove CTLESC quoting characters and convert CTLESC escaping a `&'
or a backslash into a backslash. The output of this function must eventually
be processed by strcreplace(). */
static char *
quote_string_for_repl (string, flags)
char *string;
int flags;
{
size_t slen;
char *result, *t;
const char *s, *send;
DECLARE_MBSTATE;
slen = strlen (string);
send = string + slen;
result = (char *)xmalloc (slen * 2 + 1);
if (string[0] == CTLESC && string[1] == 0)
{
result[0] = CTLESC;
result[1] = '\0';
return (result);
}
/* This is awkward. We want to translate CTLESC-\ to \\ if we will
eventually send this string through strcreplace(), which we will do
only if shouldexp_replacement() determines that there is something
to replace. We can either make sure to escape backslashes here and
have shouldexp_replacement() signal that we should send the string to
strcreplace() if it sees an escaped backslash, or we can scan the
string before copying it and turn CTLESC-\ into \\ only if we encounter
a CTLESC-& or a &. This does the former and changes shouldexp_replacement().
If we double the backslashes here, we'll get doubled backslashes in any
result that doesn't get passed to strcreplace(). */
for (s = string, t = result; *s; )
{
/* This function's result has to be processed by strcreplace() */
if (*s == CTLESC && (s[1] == '&' || s[1] == '\\'))
{
*t++ = '\\';
s++;
*t++ = *s++;
continue;
}
/* Dequote it */
if (*s == CTLESC)
{
s++;
if (*s == '\0')
break;
}
COPY_CHAR_P (t, s, send);
}
*t = '\0';
return (result);
}
/* This does not perform word splitting on the WORD_LIST it returns and
it treats $* as if it were quoted. It dequotes the WORD_LIST, adds
backslash escapes before CTLESC-quoted backslash and `& if
patsub_replacement is enabled. */
static char *
expand_string_for_patsub (string, quoted)
char *string;
int quoted;
{
WORD_LIST *value;
char *ret, *t;
if (string == 0 || *string == '\0')
return (char *)NULL;
value = expand_string_for_pat (string, quoted, (int *)0, (int *)0);
if (value && value->word)
{
remove_quoted_nulls (value->word->word); /* XXX */
value->word->flags &= ~W_HASQUOTEDNULL;
}
if (value)
{
t = (value->next) ? string_list (value) : value->word->word;
ret = quote_string_for_repl (t, quoted);
if (t != value->word->word)
free (t);
dispose_words (value);
}
else
ret = (char *)NULL;
return (ret);
}
char *
expand_arith_string (string, quoted)
char *string;
@@ -8432,6 +8531,8 @@ shouldexp_replacement (s)
preceding the special character. */
if (s[sindex] == '&')
return 1;
if (s[sindex] == '\\')
return 1;
}
else if (c == '&')
return 1;
@@ -8696,8 +8797,10 @@ parameter_brace_patsub (varname, value, estatep, patsub, quoted, pflags, flags)
the entire expansion is double-quoted because the parser and string
extraction functions treated quotes in the replacement string as
special. THIS IS NOT BACKWARDS COMPATIBLE WITH BASH-4.2. */
if (shell_compatibility_level > 42)
if (shell_compatibility_level > 42 && patsub_replacement == 0)
rep = expand_string_if_necessary (rep, quoted & ~(Q_DOUBLE_QUOTES|Q_HERE_DOCUMENT), expand_string_unsplit);
else if (shell_compatibility_level > 42 && patsub_replacement)
rep = expand_string_for_patsub (rep, quoted & ~(Q_DOUBLE_QUOTES|Q_HERE_DOCUMENT));
/* This is the bash-4.2 code. */
else if ((mflags & MATCH_QUOTED) == 0)
rep = expand_string_if_necessary (rep, quoted, expand_string_unsplit);
@@ -8706,9 +8809,7 @@ parameter_brace_patsub (varname, value, estatep, patsub, quoted, pflags, flags)
/* Check whether or not to replace `&' in the replacement string after
expanding it, since we want to treat backslashes quoting the `&'
consistently. The replacement string already undergoes quote removal
above, so users need to make sure any desired backslash makes it
through that. */
consistently. */
if (patsub_replacement && rep && *rep && shouldexp_replacement (rep))
mflags |= MATCH_EXPREP;
+1
View File
@@ -89,6 +89,7 @@ do
case "$type" in
d) mkdir $newdir/$fname ;;
f) cp -p $SRCDIR/$fname $newdir/$fname ;;
F) cp $SRCDIR/$fname $newdir/$fname ;;
s) ln -s $mode $newdir/$fname ; mode= ;; # symlink
l) ln $mode $newdir/$fname ; mode= ;; # hard link
*) echo "unknown file type $type" 1>&2 ;;
+1 -1
View File
@@ -1,4 +1,4 @@
BUILD_DIR=/usr/local/build/chet/bash/bash-current
BUILD_DIR=/usr/local/build/bash/bash-current
THIS_SH=$BUILD_DIR/bash
PATH=$PATH:$BUILD_DIR
+9 -4
View File
@@ -50,15 +50,20 @@ unset before after
# EPOCHSECONDS
# not exact, but should work
# could also use python -c 'import time; ts = int(time.time()); print(ts)'
now1=$(perl -e 'print time')
# date +%s should be portable enough now
# then try gawk, perl, python in that order
now1=$(date +%s 2>/dev/null) D=date
[ -z "$now1" ] && now1=$(gawk 'BEGIN { print systime(); }' 2>/dev/null) D=gawk
[ -z "$now1" ] && now1=$(perl -e 'print time' 2>/dev/null) D=perl
[ -z "$now1" ] && now1=$(python -c 'import time; ts = int(time.time()); print(ts)' 2>/dev/null) D=python
now2=$EPOCHSECONDS
case $now1 in
$now2) echo EPOCHSECONDS ok ;;
*) echo "current time via perl and EPOCHSECONDS possible mismatch|$now1|$now2" >&2 ;;
'') echo "cannot get current time using date/gawk/perl/python" >&2 ;;
*) echo "current time via $D and EPOCHSECONDS possible mismatch|$now1|$now2" >&2 ;;
esac
unset now1 now2
unset now1 now2 D
LC_ALL=C # force decimal point to `.'
now1=$EPOCHREALTIME
+1 -1
View File
@@ -4,7 +4,7 @@ exportfunc ok 2
./exportfunc.tests: eval: line 44: syntax error: unexpected end of file
./exportfunc.tests: line 43: cve7169-bad2: No such file or directory
./exportfunc1.sub: line 14: maximum here-document count exceeded
./exportfunc.tests: line 64: HELLO_WORLD: No such file or directory
./exportfunc.tests: line 72: HELLO_WORLD: No such file or directory
eval ok
./exportfunc3.sub: line 23: export: foo=bar: cannot export
status: 1
+9 -1
View File
@@ -50,10 +50,18 @@ ${THIS_SH} ./exportfunc1.sub
${THIS_SH} ./exportfunc2.sub
# CVE-2014-6277
A100=AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
A1000=${A100}
for (( i = 0; i < 999; i++ ))
do
A1000+=${A100}
done
env BASH_FUNC_foo%%="() { 000(){>0;}&000(){ 0;}<<0 0" ${THIS_SH} -c foo 2>/dev/null
env BASH_FUNC_foo%%="() { 000(){>0;}&000(){ 0;}<<`perl -e '{print "A"x100000}'` 0" ${THIS_SH} -c foo 2>/dev/null
env BASH_FUNC_foo%%="() { 000(){>0;}&000(){ 0;}<<${A1000} 0" ${THIS_SH} -c foo 2>/dev/null
${THIS_SH} -c "f(){ x(){ _;}; x(){ _;}<<a;}" 2>/dev/null
unset A100 A1000
# CVE-2014-6278
+6
View File
@@ -11,6 +11,12 @@
# You should have received a copy of the GNU General Public License
# along with this program. If not, see <http://www.gnu.org/licenses/>.
#
# since we look at functions below, remove all functions now
funcs=$(compgen -A function)
if [ -n "$funcs" ]; then
unset -f $funcs
fi
a()
{
x=$((x - 1))
+8
View File
@@ -13,6 +13,14 @@
#
. ./test-glue-functions
# this locale causes problems all over the place
if locale -a | grep -i '^zh_HK\.big5hkscs' >/dev/null ; then
:
else
echo "glob2.sub: warning: you do not have the zh_HK.big5hkscs locale installed;" >&2
echo "glob2.sub: warning: that will cause some of these tests to fail." >&2
fi
var='ab\'
case $var in
+2
View File
@@ -11,6 +11,8 @@
# You should have received a copy of the GNU General Public License
# along with this program. If not, see <http://www.gnu.org/licenses/>.
#
[ $UID -eq 0 ] && { echo "glob5.sub: the test suite should not be run as root" >&2 ; }
ORIGD=$PWD
: ${TMPDIR:=/var/tmp}
+1
View File
@@ -12,6 +12,7 @@
# along with this program. If not, see <http://www.gnu.org/licenses/>.
#
# tests of the backslash-in-glob-patterns discussion on the austin-group ML
[ $UID -eq 0 ] && { echo "glob6.sub: the test suite should not be run as root" >&2 ; }
: ${TMPDIR:=/var/tmp}
+6
View File
@@ -11,6 +11,12 @@
# You should have received a copy of the GNU General Public License
# along with this program. If not, see <http://www.gnu.org/licenses/>.
#
# since we look at functions below, remove all functions now
funcs=$(compgen -A function)
if [ -n "$funcs" ]; then
unset -f $funcs
fi
# basics
read x <<<"alpha"
echo "$x"
+21 -1
View File
@@ -1,5 +1,25 @@
# 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/>.
#
# this locale causes problems all over the place
unset LC_ALL LC_NUMERIC
export LANG=de_DE.UTF-8
if locale -a | grep -i '^de_DE\.UTF.*8' >/dev/null ; then
export LANG=de_DE.UTF-8
else
echo "intl2.sub: warning: you do not have the de_DE.UTF-8 locale installed;" >&2
echo "intl2.sub: that will cause some of these tests to fail." >&2
fi
printf '%.4f\n' 1
LANG=C printf '%.4f\n' 1
+2
View File
@@ -34,4 +34,6 @@ wait
# the sleep is intended to give the kill time to execute before the job
# exits
(sleep 1 ; cat ) &
# suppress any message about terminated process
exec 2>/dev/null
kill -1 %% && echo i killed it || echo could not kill it
+2
View File
@@ -3,4 +3,6 @@ set -m
sleep 20 &
echo $(jobs)
echo $(fg %% ; jobs)
# suppress any message about sleep 20 being terminated
exec 2>/dev/null
kill %1
+27 -6
View File
@@ -735,30 +735,51 @@ a
defg
defg
defg
$'&' $'&' $'&' $'&' $'&' $'&' $'&'
$'a' $'b' $'c' $'d' $'e' $'f' $'g'
a b c d e f g
a b c d e f g
a b c d e f g
& & & & & & &
& & & & & & &
& & & & & & &
\& \& \& \& \& \& \&
a a a a a a a
3 3 3 3 3 3 3
abc defg
abc defg
abc defg
abc defg
abc defg
& defg
& defg
& defg
\& defg
\abc defg
abcdefg
abcdefg
&defg
&defg
\abcdefg
\&defg
\&defg
\abcdefg
\\&defg
&defg
&defg
\&defg
\&defg
\\&defg
letx&yee
letx&yee
letxssyee
letxssyee
letx\&yee
letx\&yee
letx&yee
letx&yee
let\&ee
let\\ssee
let\ssee
let\ssee
let\&ee
let\&ee
let&ee
let&ee
argv[1] = </>
argv[1] = </>
+40
View File
@@ -16,6 +16,8 @@ HOME=/homes/chet
string=abcdefg
set -- a b c
shopt -u patsub_replacement
# verify existing behavior
echo ${string/abc/~}
echo "${string/abc/~}"
@@ -29,6 +31,11 @@ echo ${string//?/\$\'&\' }
shopt -s patsub_replacement
echo ${string//?/\$\'&\' }
echo ${string//?/& }
echo "${string//?/& }"
echo ${string//?/\& }
echo "${string//?/\& }"
echo ${string//?/"& "}
@@ -51,7 +58,9 @@ rep='\\&'
echo "${string/abc/&}"
echo ${string/abc/\&}
echo "${string/abc/\\&}"
echo ${string/abc/"\\&"}
echo "${string/abc/"\\&"}"
echo ${string/abc/$rep}
echo ${string/abc/"$rep"}
shopt -u patsub_replacement
@@ -61,3 +70,34 @@ echo ${string/abc/\&}
echo "${string/abc/\\&}"
echo "${string/abc/"\\&"}"
echo ${string/abc/"$rep"}
shopt -s patsub_replacement
repl='x&y'
r2='x\&y'
var='letssee'
pat=ss
echo ${var//$pat/"$repl"}
echo "${var//$pat/"$repl"}"
echo ${var//$pat/$repl}
echo "${var//$pat/$repl}"
echo ${var//$pat/"$r2"}
echo "${var//$pat/"$r2"}"
echo ${var//$pat/$r2}
echo "${var//$pat/$r2}"
r2='\\&'
r3='\&'
echo ${var//$pat/\\\&}
echo ${var//$pat/\\$r2}
echo ${var//$pat/\\&}
echo ${var//$pat/$r2}
echo ${var//$pat/"\&"}
echo ${var//$pat/"$r3"}
echo ${var//$pat/"&"}
echo ${var//$pat/$r3}
+3 -3
View File
@@ -69,11 +69,11 @@ FOO
0
0
1
[?2004h[?2004l
timeout 1: ok
unset or null 1
unset or null 1
timeout 2: ok
unset or null 2
timeout 2: ok
timeout 3: ok
unset or null 3
timeout 4: ok
abcde
+3
View File
@@ -13,6 +13,9 @@
#
# test behavior of native readline timeouts
# turn off bracketed paste to avoid spurious output
bind 'set enable-bracketed-paste off' 2>/dev/null
read -t 0.00001 -e var
estat=$?
if [ $estat -gt 128 ]; then
-3
View File
@@ -1,8 +1,5 @@
# See whether or not we can use `diff -a'
( diff -a ./intl.right ./intl.right >/dev/null 2>&1 ) && AFLAG=-a
echo "warning: some of these tests will fail if you do not have UTF-8" >&2
echo "warning: locales installed on your system." >&2
${THIS_SH} ./intl.tests > ${BASH_TSTOUT}
diff $AFLAG ${BASH_TSTOUT} intl.right && rm -f ${BASH_TSTOUT}
+8 -1
View File
@@ -109,7 +109,14 @@ fr_FR_ISO_8859_1=(
[0x00fb]=$'\373' [0x00fc]=$'\374' [0x00fd]=$'\375' [0x00fe]=$'\376'
)
TestCodePage fr_FR.ISO8859-1 fr_FR_ISO_8859_1
# this locale causes problems all over the place
if locale -a | grep -i '^fr_FR\.ISO8859.*1' >/dev/null ; then
TestCodePage fr_FR.ISO8859-1 fr_FR_ISO_8859_1
else
echo "unicode1.sub: warning: you do not have the fr_FR.ISO8859-1 locale installed;" >&2
echo "unicode1.sub: that will cause some of these tests to fail." >&2
fi
zh_TW_BIG5=(
[0x00f6]=$'\366' [0x00f7]=$'\367' [0x00f8]=$'\370' [0x00f9]=$'\371' [0x00fa]=$'\372'