mirror of
https://https.git.savannah.gnu.org/git/bash.git
synced 2026-06-23 22:07:58 +02:00
minor documentation changes
This commit is contained in:
@@ -10451,3 +10451,36 @@ parse.y
|
||||
setting it unconditionally. Report and patch from
|
||||
Vincent Menegaux <vincent.menegaux@gmail.com> via
|
||||
https://savannah.gnu.org/patch/?10070
|
||||
|
||||
5/25
|
||||
----
|
||||
doc/{bash.1,bashref.texi}
|
||||
- test: add the ( $2 $3 ) case to the description of the four-argument
|
||||
behavior. Inspired by a discussion with Christoph Anton Mitterer
|
||||
<calestyo@scientia.net>
|
||||
|
||||
5/27
|
||||
----
|
||||
doc/bashref.texi
|
||||
- replace most of the GNU parallel section with a reference to the
|
||||
tutorial on gnu.org
|
||||
|
||||
lib/glob/glob.h
|
||||
- GX_NEGATE: new flag; indicates whether the pattern is being negated
|
||||
as part of an extglob pattern. Not used yet
|
||||
|
||||
lib/glob/glob.c
|
||||
- extglob_skipname,wextglob_skipname: pass GX_NEGATE to the skipname
|
||||
functions if the pattern is being negated. Not checked yet
|
||||
|
||||
5/28
|
||||
----
|
||||
doc/{bash.1,bashref.texi}
|
||||
- dotglob: add text to clarify that `.' and `..' have to be matched by
|
||||
a pattern beginning with `.' or -- and this is the sketchy part --
|
||||
that a pattern beginning with `.' has to be one of the patterns in
|
||||
an extended glob expression
|
||||
|
||||
lib/glob/glob.c
|
||||
- skipname,wskipname: perform the special checks for `.' only if the
|
||||
pattern is not being negated
|
||||
|
||||
+1548
-1512
File diff suppressed because it is too large
Load Diff
+11
-2
@@ -3691,10 +3691,14 @@ The filenames
|
||||
.B ``.''
|
||||
and
|
||||
.B ``..''
|
||||
must always be matched explicitly, even if
|
||||
must always be matched
|
||||
by a pattern beginning with ``.'' (for example, ``.?''),
|
||||
or a pattern beginning with ``.'' must be one of the patterns in an
|
||||
extended pattern matching expression (see below),
|
||||
even if
|
||||
.B dotglob
|
||||
is set.
|
||||
In other cases, the
|
||||
When not matching pathnames, the
|
||||
.B ``.''
|
||||
character is not treated specially.
|
||||
When matching a pathname, the slash character must always be
|
||||
@@ -10491,8 +10495,13 @@ argument.
|
||||
Otherwise, the expression is false.
|
||||
.TP
|
||||
4 arguments
|
||||
The following conditions are applied in the order listed.
|
||||
If the first argument is \fB!\fP, the result is the negation of
|
||||
the three-argument expression composed of the remaining arguments.
|
||||
the two-argument test using the second and third arguments.
|
||||
If the first argument is exactly \fB(\fP and the fourth argument is
|
||||
exactly \fB)\fP, the result is the two-argument test of the second
|
||||
and third arguments.
|
||||
Otherwise, the expression is parsed and evaluated according to
|
||||
precedence using the rules listed above.
|
||||
.TP
|
||||
|
||||
+349
-369
File diff suppressed because it is too large
Load Diff
+19
-114
@@ -1487,117 +1487,9 @@ Parallel provides shorthand references to many of the most common operations
|
||||
the input source, and so on). Parallel can replace @code{xargs} or feed
|
||||
commands from its input sources to several different instances of Bash.
|
||||
|
||||
For a complete description, refer to the GNU Parallel documentation. A few
|
||||
examples should provide a brief introduction to its use.
|
||||
|
||||
For example, it is easy to replace @code{xargs} to gzip all html files in the
|
||||
current directory and its subdirectories:
|
||||
@example
|
||||
find . -type f -name '*.html' -print | parallel gzip
|
||||
@end example
|
||||
@noindent
|
||||
If you need to protect special characters such as newlines in file names,
|
||||
use find's @option{-print0} option and parallel's @option{-0} option.
|
||||
|
||||
You can use Parallel to move files from the current directory when the
|
||||
number of files is too large to process with one @code{mv} invocation:
|
||||
@example
|
||||
printf '%s\n' * | parallel mv @{@} destdir
|
||||
@end example
|
||||
|
||||
As you can see, the @{@} is replaced with each line read from standard input.
|
||||
While using @code{ls} will work in most instances, it is not sufficient to
|
||||
deal with all filenames. @code{printf} is a shell builtin, and therefore is
|
||||
not subject to the kernel's limit on the number of arguments to a program,
|
||||
so you can use @samp{*} (but see below about the @code{dotglob} shell option).
|
||||
If you need to accommodate special characters in filenames, you can use
|
||||
|
||||
@example
|
||||
printf '%s\0' * | parallel -0 mv @{@} destdir
|
||||
@end example
|
||||
|
||||
@noindent
|
||||
as alluded to above.
|
||||
|
||||
This will run as many @code{mv} commands as there are files in the current
|
||||
directory.
|
||||
You can emulate a parallel @code{xargs} by adding the @option{-X} option:
|
||||
@example
|
||||
printf '%s\0' * | parallel -0 -X mv @{@} destdir
|
||||
@end example
|
||||
|
||||
(You may have to modify the pattern if you have the @code{dotglob} option
|
||||
enabled.)
|
||||
|
||||
GNU Parallel can replace certain common idioms that operate on lines read
|
||||
from a file (in this case, filenames listed one per line):
|
||||
@example
|
||||
while IFS= read -r x; do
|
||||
do-something1 "$x" "config-$x"
|
||||
do-something2 < "$x"
|
||||
done < file | process-output
|
||||
@end example
|
||||
|
||||
@noindent
|
||||
with a more compact syntax reminiscent of lambdas:
|
||||
@example
|
||||
cat list | parallel "do-something1 @{@} config-@{@} ; do-something2 < @{@}" |
|
||||
process-output
|
||||
@end example
|
||||
|
||||
Parallel provides a built-in mechanism to remove filename extensions, which
|
||||
lends itself to batch file transformations or renaming:
|
||||
@example
|
||||
ls *.gz | parallel -j+0 "zcat @{@} | bzip2 >@{.@}.bz2 && rm @{@}"
|
||||
@end example
|
||||
@noindent
|
||||
This will recompress all files in the current directory with names ending
|
||||
in .gz using bzip2, running one job per CPU (-j+0) in parallel.
|
||||
(We use @code{ls} for brevity here; using @code{find} as above is more
|
||||
robust in the face of filenames containing unexpected characters.)
|
||||
Parallel can take arguments from the command line; the above can also be
|
||||
written as
|
||||
|
||||
@example
|
||||
parallel "zcat @{@} | bzip2 >@{.@}.bz2 && rm @{@}" ::: *.gz
|
||||
@end example
|
||||
|
||||
If a command generates output, you may want to preserve the input order in
|
||||
the output. For instance, the following command
|
||||
@example
|
||||
@{
|
||||
echo foss.org.my ;
|
||||
echo debian.org ;
|
||||
echo freenetproject.org ;
|
||||
@} | parallel traceroute
|
||||
@end example
|
||||
@noindent
|
||||
will display as output the traceroute invocation that finishes first.
|
||||
Adding the @option{-k} option
|
||||
@example
|
||||
@{
|
||||
echo foss.org.my ;
|
||||
echo debian.org ;
|
||||
echo freenetproject.org ;
|
||||
@} | parallel -k traceroute
|
||||
@end example
|
||||
@noindent
|
||||
will ensure that the output of @code{traceroute foss.org.my} is displayed first.
|
||||
|
||||
Finally, Parallel can be used to run a sequence of shell commands in parallel,
|
||||
similar to @samp{cat file | bash}.
|
||||
It is not uncommon to take a list of filenames, create a series of shell
|
||||
commands to operate on them, and feed that list of commands to a shell.
|
||||
Parallel can speed this up. Assuming that @file{file} contains a list of
|
||||
shell commands, one per line,
|
||||
|
||||
@example
|
||||
parallel -j 10 < file
|
||||
@end example
|
||||
|
||||
@noindent
|
||||
will evaluate the commands using the shell (since no explicit command is
|
||||
supplied as an argument), in blocks of ten shell jobs at a time.
|
||||
For a complete description, refer to the GNU Parallel documentation, which
|
||||
is available at
|
||||
@url{https://www.gnu.org/software/parallel/parallel_tutorial.html}.
|
||||
|
||||
@node Shell Functions
|
||||
@section Shell Functions
|
||||
@@ -2769,9 +2661,12 @@ without regard to the case of alphabetic characters.
|
||||
When a pattern is used for filename expansion, the character @samp{.}
|
||||
at the start of a filename or immediately following a slash
|
||||
must be matched explicitly, unless the shell option @code{dotglob} is set.
|
||||
The filenames @samp{.} and @samp{..} must always be matched explicitly,
|
||||
The filenames @samp{.} and @samp{..} must be matched
|
||||
by a pattern beginning with @samp{.} (for example, @samp{.?}),
|
||||
or a pattern beginning with @samp{.} must be one of the patterns in an
|
||||
extended pattern matching expression (see below),
|
||||
even if @code{dotglob} is set.
|
||||
In other cases, the @samp{.} character is not treated specially.
|
||||
When not matching filenames, the @samp{.} character is not treated specially.
|
||||
|
||||
When matching a filename, the slash character must always be
|
||||
matched explicitly by a slash in the pattern, but in other matching
|
||||
@@ -4096,10 +3991,20 @@ Otherwise, the expression is false.
|
||||
@end enumerate
|
||||
|
||||
@item 4 arguments
|
||||
The following conditions are applied in the order listed.
|
||||
|
||||
@enumerate
|
||||
@item
|
||||
If the first argument is @samp{!}, the result is the negation of
|
||||
the three-argument expression composed of the remaining arguments.
|
||||
@item
|
||||
If the first argument is exactly @samp{(} and the fourth argument is
|
||||
exactly @samp{)}, the result is the two-argument test of the second
|
||||
and third arguments.
|
||||
@item
|
||||
Otherwise, the expression is parsed and evaluated according to
|
||||
precedence using the rules listed above.
|
||||
@end enumerate
|
||||
|
||||
@item 5 or more arguments
|
||||
The expression is parsed and evaluated according to precedence
|
||||
@@ -4601,7 +4506,7 @@ each builtin with an indication of whether or not it is enabled.
|
||||
|
||||
The @option{-f} option means to load the new builtin command @var{name}
|
||||
from shared object @var{filename}, on systems that support dynamic loading.
|
||||
Bash will use the value of the @enable{BASH_LOADABLES_PATH} variable as a
|
||||
Bash will use the value of the @env{BASH_LOADABLES_PATH} variable as a
|
||||
colon-separated list of directories in which to search for @var{filename}.
|
||||
The default is system-dependent.
|
||||
The @option{-d} option will delete a builtin loaded with @option{-f}.
|
||||
|
||||
+57
-15
@@ -201,7 +201,7 @@ extglob_skipname (pat, dname, flags)
|
||||
int flags;
|
||||
{
|
||||
char *pp, *pe, *t, *se;
|
||||
int n, r, negate, wild, nullpat;
|
||||
int n, r, negate, wild, nullpat, xflags;
|
||||
|
||||
negate = *pat == '!';
|
||||
wild = *pat == '*' || *pat == '?';
|
||||
@@ -213,12 +213,17 @@ extglob_skipname (pat, dname, flags)
|
||||
if (pe == 0)
|
||||
return 0;
|
||||
|
||||
xflags = flags | ( negate ? GX_NEGATE : 0);
|
||||
|
||||
/* if pe != se we have more of the pattern at the end of the extglob
|
||||
pattern. Check the easy case first ( */
|
||||
if (pe == se && *pe == 0 && pe[-1] == ')' && (t = strchr (pp, '|')) == 0)
|
||||
{
|
||||
pe[-1] = '\0';
|
||||
r = XSKIPNAME (pp, dname, flags); /*(*/
|
||||
/* This is where we check whether the pattern is being negated and
|
||||
match all files beginning with `.' if the pattern begins with a
|
||||
literal `.'. */
|
||||
r = XSKIPNAME (pp, dname, xflags); /*(*/
|
||||
pe[-1] = ')';
|
||||
return r;
|
||||
}
|
||||
@@ -238,7 +243,7 @@ extglob_skipname (pat, dname, flags)
|
||||
t[-1] = n; /* no-op for now */
|
||||
else
|
||||
t[-1] = '\0';
|
||||
r = XSKIPNAME (pp, dname, flags);
|
||||
r = XSKIPNAME (pp, dname, xflags);
|
||||
t[-1] = n;
|
||||
if (r == 0) /* if any pattern says not skip, we don't skip */
|
||||
return r;
|
||||
@@ -284,15 +289,26 @@ skipname (pat, dname, flags)
|
||||
DOT_OR_DOTDOT (dname))
|
||||
return 1;
|
||||
|
||||
#if 0
|
||||
/* This is where we check whether the pattern is being negated and
|
||||
match all files beginning with `.' if the pattern begins with a
|
||||
literal `.'. This is the negation of the next clause. */
|
||||
else if ((flags & GX_NEGATE) && noglob_dot_filenames == 0 &&
|
||||
dname[0] == '.' &&
|
||||
(pat[0] == '.' || (pat[0] == '\\' && pat[1] == '.')))
|
||||
return 0;
|
||||
#endif
|
||||
|
||||
/* If a dot must be explicitly matched, check to see if they do. */
|
||||
else if (noglob_dot_filenames && dname[0] == '.' && pat[0] != '.' &&
|
||||
(pat[0] != '\\' || pat[1] != '.'))
|
||||
else if (noglob_dot_filenames && dname[0] == '.' &&
|
||||
pat[0] != '.' && (pat[0] != '\\' || pat[1] != '.'))
|
||||
return 1;
|
||||
|
||||
/* Special checks for `.'. The only things that can match `.' are ".",
|
||||
"\.", ".*", and "\.*". We don't try to match everything here, just
|
||||
make sure that we don't let something obviously disqualifying by. */
|
||||
else if (dname[0] == '.' && dname[1] == '\0')
|
||||
make sure that we don't let something obviously disqualifying by.
|
||||
We only do this if we're not negating the pattern. */
|
||||
else if ((flags & GX_NEGATE) == 0 && dname[0] == '.' && dname[1] == '\0')
|
||||
{
|
||||
if (pat[0] != '.' && (pat[0] != '\\' || pat[1] != '.'))
|
||||
return 1;
|
||||
@@ -301,7 +317,21 @@ skipname (pat, dname, flags)
|
||||
return 1;
|
||||
}
|
||||
|
||||
/* We don't currently have any additional special checks for `..' */
|
||||
#if 0
|
||||
/* These are additional special checks for `..'. We let through "..",
|
||||
"\..", ".\.", "\.\.", ".*", ".?", "\.*", and "\.?".
|
||||
Disabled because it doesn't deal with things like `@(.).' at all. */
|
||||
else if (dname[0] == '.' && dname[1] == '.' && dname[2] == '\0')
|
||||
{
|
||||
if (pat[0] != '.' && (pat[0] != '\\' || pat[1] != '.')) /* [\]. */
|
||||
return 1;
|
||||
i = (pat[0] == '.') ? 1 : 2;
|
||||
if (pat[i] && (pat[i] == '*' || pat[i] == '?') && pat[i+1] == '\0')
|
||||
return 0; /* [\].[*?] */
|
||||
if (pat[i] != '.' && (pat[i] != '\\' || pat[i+1] != '.')) /* [\].[\]. */
|
||||
return 1;
|
||||
}
|
||||
#endif
|
||||
|
||||
return 0;
|
||||
}
|
||||
@@ -325,17 +355,27 @@ wskipname (pat, dname, flags)
|
||||
WDOT_OR_DOTDOT (dname))
|
||||
return 1;
|
||||
|
||||
#if 0
|
||||
/* This is where we check whether the pattern is being negated and
|
||||
match all files beginning with `.' if the pattern begins with a
|
||||
literal `.'. This is the negation of the next clause. */
|
||||
else if ((flags & GX_NEGATE) && noglob_dot_filenames == 0 &&
|
||||
dname[0] == L'.' &&
|
||||
(pat[0] == L'.' || (pat[0] == L'\\' && pat[1] == L'.')))
|
||||
return 0;
|
||||
#endif
|
||||
|
||||
/* If a leading dot must be explicitly matched, check to see if the
|
||||
pattern and dirname both have one. */
|
||||
else if (noglob_dot_filenames && dname[0] == L'.' &&
|
||||
pat[0] != L'.' &&
|
||||
(pat[0] != L'\\' || pat[1] != L'.'))
|
||||
pat[0] != L'.' && (pat[0] != L'\\' || pat[1] != L'.'))
|
||||
return 1;
|
||||
|
||||
/* Special checks for `.'. The only things that can match `.' are ".",
|
||||
"\.", ".*", and "\.*". We don't try to match everything here, just
|
||||
make sure that we don't let something obviously disqualifying by. */
|
||||
else if (dname[0] == L'.' && dname[1] == L'\0')
|
||||
make sure that we don't let something obviously disqualifying by.
|
||||
We only do this if we're not negating the pattern. */
|
||||
else if ((flags & GX_NEGATE) == 0 && dname[0] == L'.' && dname[1] == L'\0')
|
||||
{
|
||||
if (pat[0] != L'.' && (pat[0] != L'\\' || pat[1] != L'.'))
|
||||
return 1;
|
||||
@@ -354,7 +394,7 @@ wextglob_skipname (pat, dname, flags)
|
||||
{
|
||||
#if EXTENDED_GLOB
|
||||
wchar_t *pp, *pe, *t, *se, n;
|
||||
int r, negate, wild, nullpat;
|
||||
int r, negate, wild, nullpat, xflags;
|
||||
|
||||
negate = *pat == L'!';
|
||||
wild = *pat == L'*' || *pat == L'?';
|
||||
@@ -366,12 +406,14 @@ wextglob_skipname (pat, dname, flags)
|
||||
if (pe == 0)
|
||||
return 0;
|
||||
|
||||
xflags = flags | ( negate ? GX_NEGATE : 0);
|
||||
|
||||
/* if pe != se we have more of the pattern at the end of the extglob
|
||||
pattern. Check the easy case first ( */
|
||||
if (pe == se && *pe == L'\0' && pe[-1] == L')' && (t = wcschr (pp, L'|')) == 0)
|
||||
{
|
||||
pe[-1] = L'\0';
|
||||
r = wskipname (pp, dname, flags); /*(*/
|
||||
r = wskipname (pp, dname, xflags); /*(*/
|
||||
pe[-1] = L')';
|
||||
return r;
|
||||
}
|
||||
@@ -389,7 +431,7 @@ wextglob_skipname (pat, dname, flags)
|
||||
t[-1] = n; /* no-op for now */
|
||||
else
|
||||
t[-1] = L'\0';
|
||||
r = wskipname (pp, dname, flags);
|
||||
r = wskipname (pp, dname, xflags);
|
||||
t[-1] = n;
|
||||
if (r == 0)
|
||||
return 0;
|
||||
|
||||
@@ -32,6 +32,7 @@
|
||||
#define GX_GLOBSTAR 0x400 /* turn on special handling of ** */
|
||||
#define GX_RECURSE 0x800 /* internal -- glob_filename called recursively */
|
||||
#define GX_SYMLINK 0x1000 /* internal -- symlink to a directory */
|
||||
#define GX_NEGATE 0x2000 /* internal -- extglob pattern being negated */
|
||||
|
||||
extern int glob_pattern_p PARAMS((const char *));
|
||||
extern char **glob_vector PARAMS((char *, char *, int));
|
||||
|
||||
Reference in New Issue
Block a user