enough to a non-interactive shell, since we can be interactive with
-i while running a shell script). Fixes oddity reported by
Techlive Zheng <techlivezheng@gmail.com>
+
+ 8/20
+ ----
+arrayfunc.c
+ - quote_array_assignment_chars: don't bother quoting if the word has
+ not been marked as an assignment (W_ASSIGNMENT)
+ - quote_array_assignment_chars: turn on W_NOGLOB in the word flags
+ so assignment statements don't undergo globbing. Partial fix for
+ problems reported by Dan Douglas <ormaaj@gmail.com>
+
+ 8/21
+ ----
+command.h
+ - W_NOBRACE: new word flag that means to inhibit brace expansion
+
+subst.c
+ - brace_expand_word_list: suppress brace expansion for words with
+ W_NOBRACE flag
+
+ 8/22
+ ----
+builtins/read.def
+ - read_builtin: don't call dequote_string on what we've read, even if
+ we saw an escape character, unless (input_string && *input_string).
+ We may have escaped an IFS whitespace character. Fixes seg fault
+ reported by <armandsl@gmail.com>
+
+execute_cmd.c
+ - execute_command_internal: set the_printed_command_except trap when
+ about to execute a ( ... ) user subshell. For now, set it only if
+ ERR is trapped; can relax that later. Fixes bug reported by
+ Mike Frysinger <vapier@gentoo.org>
+
+ 8/23
+ ----
+jobs.c
+ - remove references to first_pid and pid_wrap, since we're not using
+ them for anything anymore
+
+ 8/24
+ ----
+subst.c
+ - changes for W_NOBRACE everywhere appropriate: so it can be displayed
+ for debugging, and passed out of expand_word_internal
+
+doc/{bash.1,bashref.texi}
+ - small changes to make it clearer that the = and == operators are
+ equivalent, and will cause pattern matching when used with [[.
+ From a question from Michal Soltys <soltys@ziu.info>
{
if (l->word == 0 || l->word->word == 0 || l->word->word[0] == '\0')
continue; /* should not happen, but just in case... */
- /* Don't bother if it doesn't look like [ind]=value */
+ /* Don't bother if it hasn't been recognized as an assignment or
+ doesn't look like [ind]=value */
+ if ((l->word->flags & W_ASSIGNMENT) == 0)
+ continue;
if (l->word->word[0] != '[' || mbschr (l->word->word, '=') == 0) /* ] */
continue;
+
nword = quote_assign (l->word->word);
free (l->word->word);
l->word->word = nword;
+ l->word->flags |= W_NOGLOB; /* XXX - W_NOSPLIT also? */
}
}
}
#endif
- if (saw_escape)
+ if (saw_escape && input_string && *input_string)
{
t = dequote_string (input_string);
var = bind_read_variable (list->word->word, t);
#define W_ASSIGNASSOC 0x400000 /* word looks like associative array assignment */
#define W_ARRAYIND 0x800000 /* word is an array index being expanded */
#define W_ASSNGLOBAL 0x1000000 /* word is a global assignment to declare (declare/typeset -g) */
+#define W_NOBRACE 0x2000000 /* Don't perform brace expansion */
/* Possible values for subshell_environment */
#define SUBSHELL_ASYNC 0x01 /* subshell caused by `command &' */
.\" Case Western Reserve University
.\" chet@po.cwru.edu
.\"
-.\" Last Change: Sat Jul 14 14:31:31 EDT 2012
+.\" Last Change: Fri Aug 24 11:50:05 EDT 2012
.\"
.\" bash_builtins, strip all but Built-Ins section
.if \n(zZ=1 .ig zZ
.if \n(zY=1 .ig zY
-.TH BASH 1 "2012 July 14" "GNU Bash 4.2"
+.TH BASH 1 "2012 August 24" "GNU Bash 4.2"
.\"
.\" There's some problem with having a `@'
.\" in a tagged paragraph with the BSD man macros.
When the \fB==\fP and \fB!=\fP operators are used, the string to the
right of the operator is considered a pattern and matched according
to the rules described below under \fBPattern Matching\fP.
+The \fB=\fP operator is equivalent to \fB==\fP.
If the shell option
.B nocasematch
is enabled, the match is performed without regard to the case
.PD
True if the strings are equal. \fB=\fP should be used
with the \fBtest\fP command for POSIX conformance.
+When used with the \fB[[\fP command, this performs pattern matching as
+described above (\fBCompound Commands\fP).
.TP
\fIstring1\fP \fB!=\fP \fIstring2\fP
True if the strings are not equal.
@c %**start of header
@setfilename bashref.info
@settitle Bash Reference Manual
-@c %**end of header
-
-@setchapternewpage odd
@include version.texi
+@c %**end of header
@copying
This text is a brief description of the features that are present in
Copyright @copyright{} 1988--2012 Free Software Foundation, Inc.
-Permission is granted to make and distribute verbatim copies of
-this manual provided the copyright notice and this permission notice
-are preserved on all copies.
-
@quotation
Permission is granted to copy, distribute and/or modify this document
under the terms of the GNU Free Documentation License, Version 1.3 or
Invariant Sections, no Front-Cover Texts, and no Back-Cover Texts.
A copy of the license is included in the section entitled
``GNU Free Documentation License''.
-
@end quotation
@end copying
@vskip 0pt plus 1filll
@insertcopying
-@sp 1
-Published by the Free Software Foundation @*
-59 Temple Place, Suite 330, @*
-Boston, MA 02111-1307 @*
-USA @*
-
@end titlepage
@contents
This text is a brief description of the features that are present in
the Bash shell (version @value{VERSION}, @value{UPDATED}).
+The Bash home page is @url{http://www.gnu.org/software/bash/}.
This is Edition @value{EDITION}, last updated @value{UPDATED},
of @cite{The GNU Bash Reference Manual},
Expressions are composed of the primaries described below in
@ref{Bash Conditional Expressions}.
Word splitting and filename expansion are not performed on the words
-between the @samp{[[} and @samp{]]}; tilde expansion, parameter and
+between the @code{[[} and @code{]]}; tilde expansion, parameter and
variable expansion, arithmetic expansion, command substitution, process
substitution, and quote removal are performed.
Conditional operators such as @samp{-f} must be unquoted to be recognized
as primaries.
-When used with @samp{[[}, the @samp{<} and @samp{>} operators sort
+When used with @code{[[}, the @samp{<} and @samp{>} operators sort
lexicographically using the current locale.
When the @samp{==} and @samp{!=} operators are used, the string to the
right of the operator is considered a pattern and matched according
to the rules described below in @ref{Pattern Matching}.
+The @samp{=} operator is identical to @samp{==}.
If the shell option @code{nocasematch}
(see the description of @code{shopt} in @ref{The Shopt Builtin})
is enabled, the match is performed without regard to the case
The return status is zero unless @var{n} is greater than @code{$#} or
less than zero, non-zero otherwise.
-@item test[B
+@item test
@itemx [
@btindex test
@btindex [
test @var{expr}
@end example
-Evaluate a conditional expression @var{expr} and return a status of 0
+Evaluate a conditional express
+ion @var{expr} and return a status of 0
(true) or 1 (false).
Each operator and operand must be a separate argument.
Expressions are composed of the primaries described below in
changes its behavior to that of version 3.1 with respect to quoted
arguments to the conditional command's @samp{=~} operator
and with respect to locale-specific
-string comparison when using the @samp{[[}
+string comparison when using the @code{[[}
conditional command's @samp{<} and @samp{>} operators.
Bash versions prior to bash-4.1 use ASCII collation and strcmp(3);
bash-4.1 and later use the current locale's collation sequence and strcoll(3).
@item compat32
If set, Bash
changes its behavior to that of version 3.2 with respect to locale-specific
-string comparison when using the @samp{[[}
+string comparison when using the @code{[[}
conditional command's @samp{<} and @samp{>} operators (see previous item).
@item compat40
If set, Bash
changes its behavior to that of version 4.0 with respect to locale-specific
-string comparison when using the @samp{[[}
+string comparison when using the @code{[[}
conditional command's @samp{<} and @samp{>} operators (see description
of @code{compat31})
and the effect of interrupting a command list.
@file{/dev/stdin}, @file{/dev/stdout}, or @file{/dev/stderr}, file
descriptor 0, 1, or 2, respectively, is checked.
-When used with @samp{[[}, the @samp{<} and @samp{>} operators sort
+When used with @code{[[}, the @samp{<} and @samp{>} operators sort
lexicographically using the current locale.
The @code{test} command uses ASCII ordering.
@item @var{string1} == @var{string2}
@itemx @var{string1} = @var{string2}
True if the strings are equal.
+When used with the @code{[[} command, this performs pattern matching as
+described above (@pxref{Conditional Constructs}).
+
@samp{=} should be used with the @code{test} command for @sc{posix} conformance.
@item @var{string1} != @var{string2}
the template it provides for filing a bug report.
Please send all reports concerning this manual to
-@email{chet.ramey@@case.edu}.
+@email{bug-bash@@gnu.org}.
@node Major Differences From The Bourne Shell
@appendix Major Differences From The Bourne Shell
not all words (@pxref{Word Splitting}).
This closes a longstanding shell security hole.
+@item
+The filename expansion bracket expression code uses @samp{!} and @samp{^}
+to negate the set of characters between the brackets.
+The Bourne shell uses only @samp{!}.
+
@item
Bash implements the full set of @sc{posix} filename expansion operators,
including @var{character classes}, @var{equivalence classes}, and
Copyright (C) 1988-2012 Free Software Foundation, Inc.
@end ignore
-@set LASTCHANGE Sat Jul 14 14:31:17 EDT 2012
+@set LASTCHANGE Fri Aug 24 11:49:45 EDT 2012
@set EDITION 4.2
@set VERSION 4.2
-@set UPDATED 14 July 2012
-@set UPDATED-MONTH July 2012
-
+@set UPDATED 24 August 2012
+@set UPDATED-MONTH August 2012
line_number_for_err_trap = line_number;
paren_pid = make_child (savestring (make_command_string (command)),
asynchronous);
+
+ if (user_subshell && signal_is_trapped (ERROR_TRAP) &&
+ signal_in_progress (DEBUG_TRAP) == 0 && running_trap == 0)
+ {
+ FREE (the_printed_command_except_trap);
+ the_printed_command_except_trap = savestring (the_printed_command);
+ }
+
if (paren_pid == 0)
{
/* We want to run the exit trap for forced {} subshells, and we
COMMAND struct. Need to keep in mind that execute_in_subshell
runs the exit trap for () subshells itself. */
s = user_subshell == 0 && command->type == cm_group && pipe_in == NO_PIPE && pipe_out == NO_PIPE && asynchronous;
+
last_command_exit_value = execute_in_subshell (command, asynchronous, pipe_in, pipe_out, fds_to_close);
if (s)
subshell_exit (last_command_exit_value);
static char retcode_name_buffer[64];
-/* flags to detect pid wraparound */
-static pid_t first_pid = NO_PID;
-static int pid_wrap = -1;
-
#if !defined (_POSIX_VERSION)
/* These are definitions to map POSIX 1003.1 functions onto existing BSD
init_job_stats ()
{
js = zerojs;
- first_pid = NO_PID;
- pid_wrap = -1;
}
/* Return the working directory for the current process. Unlike
/* In the parent. Remember the pid of the child just created
as the proper pgrp if this is the first child. */
- if (first_pid == NO_PID)
- first_pid = pid;
- else if (pid_wrap == -1 && pid < first_pid)
- pid_wrap = 0;
- else if (pid_wrap == 0 && pid >= first_pid)
- pid_wrap = 1;
-
if (job_control)
{
if (pipeline_pgrp == 0)
the_word->flags |= W_ASSIGNMENT;
/* Don't perform word splitting on assignment statements. */
if (assignment_acceptable (last_read_token) || (parser_state & PST_COMPASSIGN) != 0)
- the_word->flags |= W_NOSPLIT;
+ {
+ the_word->flags |= W_NOSPLIT;
+ if (parser_state & PST_COMPASSIGN)
+ the_word->flags |= W_NOGLOB; /* XXX - W_NOBRACE? */
+ }
}
if (command_token_position (last_read_token))
f &= ~W_NOSPLIT2;
fprintf (stderr, "W_NOSPLIT2%s", f ? "|" : "");
}
- if (f & W_NOGLOB)
- {
- f &= ~W_NOGLOB;
- fprintf (stderr, "W_NOGLOB%s", f ? "|" : "");
- }
if (f & W_NOSPLIT)
{
f &= ~W_NOSPLIT;
fprintf (stderr, "W_NOSPLIT%s", f ? "|" : "");
}
+ if (f & W_NOBRACE)
+ {
+ f &= ~W_NOBRACE;
+ fprintf (stderr, "W_NOBRACE%s", f ? "|" : "");
+ }
+ if (f & W_NOGLOB)
+ {
+ f &= ~W_NOGLOB;
+ fprintf (stderr, "W_NOGLOB%s", f ? "|" : "");
+ }
if (f & W_GLOBEXP)
{
f &= ~W_GLOBEXP;
tword->flags |= W_COMPASSIGN; /* XXX */
if (word->flags & W_NOGLOB)
tword->flags |= W_NOGLOB; /* XXX */
+ if (word->flags & W_NOBRACE)
+ tword->flags |= W_NOBRACE; /* XXX */
if (word->flags & W_NOEXPAND)
tword->flags |= W_NOEXPAND; /* XXX */
if (quoted & (Q_HERE_DOCUMENT|Q_DOUBLE_QUOTES))
tword->flags |= W_COMPASSIGN;
if (word->flags & W_NOGLOB)
tword->flags |= W_NOGLOB;
+ if (word->flags & W_NOBRACE)
+ tword->flags |= W_NOBRACE;
if (word->flags & W_NOEXPAND)
tword->flags |= W_NOEXPAND;
if (had_quoted_null && QUOTED_NULL (istring))
{
next = tlist->next;
+ if (tlist->word->flags & W_NOBRACE)
+ {
+itrace("brace_expand_word_list: %s: W_NOBRACE", tlist->word->word);
+ PREPEND_LIST (tlist, output_list);
+ continue;
+ }
+
if ((tlist->word->flags & (W_COMPASSIGN|W_ASSIGNARG)) == (W_COMPASSIGN|W_ASSIGNARG))
{
/*itrace("brace_expand_word_list: %s: W_COMPASSIGN|W_ASSIGNARG", tlist->word->word);*/
PREPEND_LIST (tlist, output_list);
continue;
}
-
+
/* Only do brace expansion if the word has a brace character. If
not, just add the word list element to BRACES and continue. In
the common case, at least when running shell scripts, this will
process substitution, word splitting, and pathname expansion, according
to the bits set in EFLAGS. Words with the W_QUOTED or W_NOSPLIT bits
set, or for which no expansion is done, do not undergo word splitting.
- Words with the W_NOGLOB bit set do not undergo pathname expansion. */
+ Words with the W_NOGLOB bit set do not undergo pathname expansion; words
+ with W_NOBRACE set do not undergo brace expansion (see
+ brace_expand_word_list above). */
static WORD_LIST *
expand_word_list_internal (list, eflags)
WORD_LIST *list;