commit bash-20090917 snapshot

This commit is contained in:
Chet Ramey
2011-12-08 20:15:57 -05:00
parent e6dfa71744
commit a8fd3f3e51
67 changed files with 11594 additions and 8731 deletions
+140
View File
@@ -0,0 +1,140 @@
*** ../bash-4.0-patched/lib/glob/glob.c 2009-07-22 23:18:50.000000000 -0400
--- lib/glob/glob.c 2009-09-18 17:53:25.000000000 -0400
***************
*** 247,251 ****
break;
}
! pathname[j] = '\0';
}
--- 247,252 ----
break;
}
! if (pathname)
! pathname[j] = '\0';
}
***************
*** 280,284 ****
break;
}
! wpathname[j] = L'\0';
/* Convert the wide character string into unibyte character set. */
--- 281,286 ----
break;
}
! if (wpathname)
! wpathname[j] = L'\0';
/* Convert the wide character string into unibyte character set. */
***************
*** 308,314 ****
#else /* !HAVE_LSTAT */
# if !defined (AFS)
! # define GLOB_TESTNAME(name) (sh_eaccess (nextname, F_OK))
# else /* AFS */
! # define GLOB_TESTNAME(name) (access (nextname, F_OK))
# endif /* AFS */
#endif /* !HAVE_LSTAT */
--- 310,316 ----
#else /* !HAVE_LSTAT */
# if !defined (AFS)
! # define GLOB_TESTNAME(name) (sh_eaccess (name, F_OK))
# else /* AFS */
! # define GLOB_TESTNAME(name) (access (name, F_OK))
# endif /* AFS */
#endif /* !HAVE_LSTAT */
***************
*** 321,324 ****
--- 323,327 ----
struct stat finfo;
+ /*itrace("glob_testdir: testing %s", dir);*/
if (stat (dir, &finfo) < 0)
return (-1);
***************
*** 427,431 ****
register char *nextname, *npat, *subdir;
unsigned int count;
! int lose, skip, ndirs, isdir, sdlen, add_current;
register char **name_vector;
register unsigned int i;
--- 430,434 ----
register char *nextname, *npat, *subdir;
unsigned int count;
! int lose, skip, ndirs, isdir, sdlen, add_current, patlen;
register char **name_vector;
register unsigned int i;
***************
*** 434,437 ****
--- 437,441 ----
int nalloca;
struct globval *firstmalloc, *tmplink;
+ char *convfn;
lastlink = 0;
***************
*** 467,470 ****
--- 471,476 ----
}
+ patlen = strlen (pat);
+
/* If the filename pattern (PAT) does not contain any globbing characters,
we can dispense with reading the directory, and just see if there is
***************
*** 480,485 ****
dirlen = strlen (dir);
! nextname = (char *)malloc (dirlen + strlen (pat) + 2);
! npat = (char *)malloc (strlen (pat) + 1);
if (nextname == 0 || npat == 0)
lose = 1;
--- 486,491 ----
dirlen = strlen (dir);
! nextname = (char *)malloc (dirlen + patlen + 2);
! npat = (char *)malloc (patlen + 1);
if (nextname == 0 || npat == 0)
lose = 1;
***************
*** 634,639 ****
continue;
}
!
! if (strmatch (pat, dp->d_name, mflags) != FNM_NOMATCH)
{
if (nalloca < ALLOCA_MAX)
--- 640,646 ----
continue;
}
!
! convfn = fnx_fromfs (dp->d_name, D_NAMLEN (dp));
! if (strmatch (pat, convfn, mflags) != FNM_NOMATCH)
{
if (nalloca < ALLOCA_MAX)
***************
*** 920,928 ****
char **temp_results;
/* Scan directory even on a NULL filename. That way, `*h/'
returns only directories ending in `h', instead of all
files ending in `h' with a `/' appended. */
dname = directories[i];
! dflags = flags & ~GX_MARKDIRS;
if ((flags & GX_GLOBSTAR) && filename[0] == '*' && filename[1] == '*' && filename[2] == '\0')
dflags |= GX_ALLDIRS|GX_ADDCURDIR;
--- 927,938 ----
char **temp_results;
+ /* XXX -- we've recursively scanned any directories resulting from
+ a `**', so turn off the flag. We turn it on again below if
+ filename is `**' */
/* Scan directory even on a NULL filename. That way, `*h/'
returns only directories ending in `h', instead of all
files ending in `h' with a `/' appended. */
dname = directories[i];
! dflags = flags & ~(GX_MARKDIRS|GX_ALLDIRS|GX_ADDCURDIR);
if ((flags & GX_GLOBSTAR) && filename[0] == '*' && filename[1] == '*' && filename[2] == '\0')
dflags |= GX_ALLDIRS|GX_ADDCURDIR;
+1
View File
@@ -334,6 +334,7 @@ examples/functions/manpage Tom Tromey
examples/functions/fstty Chet Ramey
examples/functions/jj.bash Chet Ramey
examples/functions/notify.bash Chet Ramey
examples/loadables/getconf.c J.T. Conklin
examples/scripts/shprompt Chet Ramey
examples/scripts/adventure.sh Chet Ramey, Doug Gwyn
examples/scripts/bcsh.sh Chris Robertson, Chet Ramey
+88
View File
@@ -8801,3 +8801,91 @@ make_cmd.[ch],parse.y
- add fourth argument to make_redirection: flags. Sets initial value
of `rflags' member of struct redirect
- changed all callers of make_redirection to add fourth argument of 0
9/15
----
parse.y
- change read_token_word to return REDIR_WORD for tokens of the form
{var} where `var' is a valid shell identifier and the character
following the } is a `<' or `>'
- add REDIR_WORD versions of all input and output file redirections
and here documents
print_cmd.c
- change input and output file redirection direction and here
document cases of print_redirection to print a varname
specification of the form {var} when appropriate. Still need
to fix rest of cases
redir.c
- implement REDIR_VARASSIGN semantics for file input and output
redirections and here documents
9/16
----
parse.y
- added REDIR_WORD versions of remaining redirection constructs except
for err_and_out ones
redir.c
- handle REDIR_VARASSIGN semantics for rest of redirection constructs
- accommodate REDIR_VARASSIGN when translating redirections
- new function, redir_varvalue, does variable lookup for {v} when
redirection needs the value (e.g., r_close_this)
print_cmd.c
- fix rest of cases to print {varname} when REDIR_VARASSIGN is set in
redirect->rflags
doc/{bash.1,bashref.texi}
- document new {varname} REDIR_VARASSIGN form of redirections
tests/vredir.{right,tests},vredir[1-5].sub
- tests for new {varname} REDIR_VARASSIGN form of redirections
9/18
----
subst.c
- new flags argument to split_at_delims: these flags are ORd with
SD_NOJMP and passed to skip_to_delim
- change skip_to_delim to honor new SD_NOQUOTEDELIM flag by not
checking whether or not single and double quotes are delimiters
if it's set in passed flags until after skipping quoted strings.
subst.h
- change extern declaration for split_at_delims
- new define for SD_NOQUOTEDELIM flag
pcomplete.c
- pass SD_NOQUOTEDELIM in flags argument to split_at_delims so single
and double quotes, even though they're in
rl_completer_word_break_characters, don't act as word delimiters
for programmable completion. Fixes bug reported by Freddy
Vulto <fvulto@gmail.com>
lib/glob/glob.c
- in glob_filename, after recursively scanning a directory specified
with `**', turn off GX_ALLDIRS|GX_ADDCURDIR before calling
glob_vector on the rest of the pathname, since it may not apply to
the rest of the pattern. Turned back on if the filename makes it
appropriate. Fixes bug reported by Anders Kaseorg <andersk@mit.edu>
redir.c
- change execute_null_command to fork a child to execute if any of
the commands redirections have the REDIR_VARASSIGN flag set, since
those commands are not supposed to have side effects
test.c
- < and > binary operators will obey the locale by using strcoll if
the TEST_LOCALE flag is passed to binary_test
test.h
- new define for TEST_LOCALE
execute_cmd.c
- execute_cond_node sets TEST_LOCALE so [[ str1 < str2 ]] (and >)
obey the locale. Fixes bug/incompatibility reported by Greg
Wooledge <wooledg@eeg.ccf.org>
doc/{bash.1,bashref.texi}
- documented [[ command new locale-sensitive treatment of < and >
+90
View File
@@ -8796,3 +8796,93 @@ make_cmd.c
make_redirection from int to REDIRECTEE. In general, changes are
using REDIRECTEE sd and assigning old argument to sd.dest, then
passing sd to make_redirection
make_cmd.[ch],parse.y
- add fourth argument to make_redirection: flags. Sets initial value
of `rflags' member of struct redirect
- changed all callers of make_redirection to add fourth argument of 0
9/15
----
parse.y
- change read_token_word to return REDIR_WORD for tokens of the form
{var} where `var' is a valid shell identifier and the character
following the } is a `<' or `>'
- add REDIR_WORD versions of all input and output file redirections
and here documents
print_cmd.c
- change input and output file redirection direction and here
document cases of print_redirection to print a varname
specification of the form {var} when appropriate. Still need
to fix rest of cases
redir.c
- implement REDIR_VARASSIGN semantics for file input and output
redirections and here documents
9/16
----
parse.y
- added REDIR_WORD versions of remaining redirection constructs except
for err_and_out ones
redir.c
- handle REDIR_VARASSIGN semantics for rest of redirection constructs
- accommodate REDIR_VARASSIGN when translating redirections
- new function, redir_varvalue, does variable lookup for {v} when
redirection needs the value (e.g., r_close_this)
print_cmd.c
- fix rest of cases to print {varname} when REDIR_VARASSIGN is set in
redirect->rflags
doc/{bash.1,bashref.texi}
- document new {varname} REDIR_VARASSIGN form of redirections
tests/vredir.{right,tests},vredir[1-5].sub
- tests for new {varname} REDIR_VARASSIGN form of redirections
9/18
----
subst.c
- new flags argument to split_at_delims: these flags are ORd with
SD_NOJMP and passed to skip_to_delim
- change skip_to_delim to honor new SD_NOQUOTEDELIM flag by not
checking whether or not single and double quotes are delimiters
if it's set in passed flags until after skipping quoted strings.
subst.h
- change extern declaration for split_at_delims
- new define for SD_NOQUOTEDELIM flag
pcomplete.c
- pass SD_NOQUOTEDELIM in flags argument to split_at_delims so single
and double quotes, even though they're in
rl_completer_word_break_characters, don't act as word delimiters
for programmable completion. Fixes bug reported by Freddy
Vulto <fvulto@gmail.com>
lib/glob/glob.c
- in glob_filename, after recursively scanning a directory specified
with `**', turn off GX_ALLDIRS|GX_ADDCURDIR before calling
glob_vector on the rest of the pathname, since it may not apply to
the rest of the pattern. Turned back on if the filename makes it
appropriate. Fixes bug reported by Anders Kaseorg <andersk@mit.edu>
redir.c
- change execute_null_command to fork a child to execute if any of
the commands redirections have the REDIR_VARASSIGN flag set, since
those commands are not supposed to have side effects
test.c
- < and > binary operators will obey the locale by using strcoll if
the TEST_LOCALE flag is passed to binary_test
test.h
- new define for TEST_LOCALE
execute_cmd.c
- execute_cond_node sets TEST_LOCALE so [[ str1 < str2 ]] (and >)
obey the locale. Fixes bug/incompatibility reported by Greg
Wooledge <wooledg@eeg.ccf.org>
+9
View File
@@ -858,6 +858,7 @@ tests/glob1.sub f
tests/glob.right f
tests/globstar.tests f
tests/globstar.right f
tests/globstar1.sub f
tests/heredoc.tests f
tests/heredoc.right f
tests/heredoc1.sub f
@@ -1027,6 +1028,7 @@ tests/run-tilde2 f
tests/run-trap f
tests/run-type f
tests/run-varenv f
tests/run-vredir f
tests/set-e.tests f
tests/set-e1.sub f
tests/set-e2.sub f
@@ -1059,6 +1061,13 @@ tests/varenv1.sub f
tests/varenv2.sub f
tests/version f
tests/version.mini f
tests/vredir.tests f
tests/vredir.right f
tests/vredir1.sub f
tests/vredir2.sub f
tests/vredir3.sub f
tests/vredir4.sub f
tests/vredir5.sub f
tests/misc/dev-tcp.tests f
tests/misc/perf-script f
tests/misc/perftest f
+12 -1
View File
@@ -386,6 +386,7 @@ lib/sh/fdprintf.c f
lib/sh/fmtullong.c f
lib/sh/fmtulong.c f
lib/sh/fmtumax.c f
lib/sh/fnxform.c f
lib/sh/fpurge.c f
lib/sh/getcwd.c f
lib/sh/getenv.c f
@@ -526,7 +527,6 @@ CWRU/misc/errlist.c f
CWRU/misc/hpux10-dlfcn.h f
CWRU/PLATFORMS f
CWRU/README f
CWRU/audit-patch f
CWRU/changelog f
CWRU/sh-redir-hack f
CWRU/mh-folder-comp f
@@ -758,6 +758,7 @@ tests/assoc2.sub f
tests/assoc3.sub f
tests/assoc4.sub f
tests/assoc5.sub f
tests/assoc6.sub f
tests/braces.tests f
tests/braces.right f
tests/builtins.tests f
@@ -783,6 +784,7 @@ tests/comsub-eof1.sub f
tests/comsub-eof2.sub f
tests/comsub-eof3.sub f
tests/comsub-eof4.sub f
tests/comsub-eof5.sub f
tests/comsub-eof.right f
tests/comsub-posix.tests f
tests/comsub-posix.right f
@@ -905,6 +907,7 @@ tests/new-exp7.sub f
tests/new-exp.right f
tests/nquote.tests f
tests/nquote.right f
tests/nquote1.sub f
tests/nquote1.tests f
tests/nquote1.right f
tests/nquote2.tests f
@@ -1024,6 +1027,7 @@ tests/run-tilde2 f
tests/run-trap f
tests/run-type f
tests/run-varenv f
tests/run-vredir f
tests/set-e.tests f
tests/set-e1.sub f
tests/set-e2.sub f
@@ -1056,6 +1060,13 @@ tests/varenv1.sub f
tests/varenv2.sub f
tests/version f
tests/version.mini f
tests/vredir.tests f
tests/vredir.right f
tests/vredir1.sub f
tests/vredir2.sub f
tests/vredir3.sub f
tests/vredir4.sub f
tests/vredir5.sub f
tests/misc/dev-tcp.tests f
tests/misc/perf-script f
tests/misc/perftest f
+419 -401
View File
File diff suppressed because it is too large Load Diff
+14 -2
View File
@@ -5,12 +5,12 @@
.\" Case Western Reserve University
.\" chet@po.cwru.edu
.\"
.\" Last Change: Mon Aug 31 08:59:57 EDT 2009
.\" Last Change: Wed Sep 16 21:33:34 EDT 2009
.\"
.\" bash_builtins, strip all but Built-Ins section
.if \n(zZ=1 .ig zZ
.if \n(zY=1 .ig zY
.TH BASH 1 "2009 August 31" "GNU Bash-4.0"
.TH BASH 1 "2009 September 16" "GNU Bash-4.1"
.\"
.\" There's some problem with having a `@'
.\" in a tagged paragraph with the BSD man macros.
@@ -681,6 +681,10 @@ Conditional operators such as \fB\-f\fP must be unquoted to be recognized
as primaries.
.if t .sp 0.5
.if n .sp 1
When used with \fB[[\fP, The \fB<\fP and \fB>\fP operators sort
lexicographically using the current locale.
.if t .sp 0.5
.if n .sp 1
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.
@@ -3186,6 +3190,14 @@ or may follow a
Redirections are processed in the order they appear, from
left to right.
.PP
Each redirection that may be preceded by a file descriptor number
may instead be preceded by a word of the form {\fIvarname\fP}.
In this case, for each redirection operator except
>&- and <&-, the shell will allocate a file descriptor greater
than 10 and assign it to \fIvarname\fP. If >&- or <&- is preceded
by {\fIvarname\fP}, the value of \fIvarname\fP defines the file
descriptor to close.
.PP
In the following descriptions, if the file descriptor number is
omitted, and the first character of the redirection operator is
.BR < ,
+20 -3
View File
@@ -5,12 +5,12 @@
.\" Case Western Reserve University
.\" chet@po.cwru.edu
.\"
.\" Last Change: Sat Aug 22 12:02:47 EDT 2009
.\" Last Change: Wed Sep 16 21:33:34 EDT 2009
.\"
.\" bash_builtins, strip all but Built-Ins section
.if \n(zZ=1 .ig zZ
.if \n(zY=1 .ig zY
.TH BASH 1 "2009 August 22" "GNU Bash-4.0"
.TH BASH 1 "2009 September 16" "GNU Bash-4.1"
.\"
.\" There's some problem with having a `@'
.\" in a tagged paragraph with the BSD man macros.
@@ -681,6 +681,10 @@ Conditional operators such as \fB\-f\fP must be unquoted to be recognized
as primaries.
.if t .sp 0.5
.if n .sp 1
When used with \fB[[\fP, The \fB<\fP and \fB>\fP operators sort
lexicographically using the current locale.
.if t .sp 0.5
.if n .sp 1
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.
@@ -3186,6 +3190,14 @@ or may follow a
Redirections are processed in the order they appear, from
left to right.
.PP
Each redirection that may be preceded by a file descriptor number
may instead be preceded by a word of the form {\fIvarname\fP}.
In this case, for each redirection operator except
>&- and <&-, the shell will allocate a file descriptor greater
than 10 and assign it to \fIvarname\fP. If >&- or <&- is preceded
by {\fIvarname\fP}, the value of \fIvarname\fP defines the file
descriptor to close.
.PP
In the following descriptions, if the file descriptor number is
omitted, and the first character of the redirection operator is
.BR < ,
@@ -4947,6 +4959,11 @@ can be set to either
or
.BR vi .
.TP
.B echo\-control\-characters (On)
When set to \fBOn\fP, on operating systems that indicate they support it,
readline echoes a character corresponding to a signal generated from the
keyboard.
.TP
.B enable\-keypad (Off)
When set to \fBOn\fP, readline will try to enable the application
keypad when it is called. Some systems need this to enable the
@@ -5918,7 +5935,7 @@ completion function would load completions dynamically:
\f(CW_completion_loader()
.br
{
.brb
.br
. "/etc/bash_completion.d/$1.sh" >/dev/null 2>&1 && return 124
.br
}
+27 -3
View File
@@ -3,7 +3,7 @@
</HEAD>
<BODY><TABLE WIDTH=100%>
<TR>
<TH ALIGN=LEFT width=33%>BASH(1)<TH ALIGN=CENTER width=33%>2009 August 17<TH ALIGN=RIGHT width=33%>BASH(1)
<TH ALIGN=LEFT width=33%>BASH(1)<TH ALIGN=CENTER width=33%>2009 September 16<TH ALIGN=RIGHT width=33%>BASH(1)
</TR>
</TABLE>
<BR><A HREF="#index">Index</A>
@@ -4068,6 +4068,15 @@ Redirections are processed in the order they appear, from
left to right.
<P>
Each redirection that may be preceded by a file descriptor number
may instead be preceded by a word of the form {<I>varname</I>}.
In this case, for each redirection operator except
&gt;&amp;- and &lt;&amp;-, the shell will allocate a file descriptor greater
than 10 and assign it to <I>varname</I>. If &gt;&amp;- or &lt;&amp;- is preceded
by {<I>varname</I>}, the value of <I>varname</I> defines the file
descriptor to close.
<P>
In the following descriptions, if the file descriptor number is
omitted, and the first character of the redirection operator is
<B>&lt;</B>,
@@ -6414,6 +6423,12 @@ can be set to either
or
<B>vi</B>.
<DT><B>echo-control-characters (On)</B>
<DD>
When set to <B>On</B>, on operating systems that indicate they support it,
readline echoes a character corresponding to a signal generated from the
keyboard.
<DT><B>enable-keypad (Off)</B>
<DD>
@@ -6541,6 +6556,15 @@ words which have more than one possible completion without any
possible partial completion (the possible completions don't share
a common prefix) cause the matches to be listed immediately instead
of ringing the bell.
<DT><B>skip-completed-text (Off)</B>
<DD>
If set to <B>On</B>, this alters the default completion behavior when
inserting a single match into the line. It's only active when
performing completion in the middle of a word. If enabled, readline
does not insert characters from the completion that match characters
after point in the word being completed, so portions of the word
following the cursor are not duplicated.
<DT><B>visible-stats (Off)</B>
<DD>
@@ -12213,7 +12237,7 @@ There may be only one active coprocess at a time.
<HR>
<TABLE WIDTH=100%>
<TR>
<TH ALIGN=LEFT width=33%>GNU Bash-4.0<TH ALIGN=CENTER width=33%>2009 August 17<TH ALIGN=RIGHT width=33%>BASH(1)
<TH ALIGN=LEFT width=33%>GNU Bash-4.1<TH ALIGN=CENTER width=33%>2009 September 16<TH ALIGN=RIGHT width=33%>BASH(1)
</TR>
</TABLE>
<HR>
@@ -12319,6 +12343,6 @@ There may be only one active coprocess at a time.
</DL>
<HR>
This document was created by man2html from bash.1.<BR>
Time: 17 August 2009 14:46:46 EDT
Time: 16 September 2009 21:35:09 EDT
</BODY>
</HTML>
+1123 -548
View File
File diff suppressed because it is too large Load Diff
BIN
View File
Binary file not shown.
+4332 -4317
View File
File diff suppressed because it is too large Load Diff
+17 -17
View File
@@ -119,13 +119,13 @@
@xrdef{Executing Commands-snt}{Section@tie 3.7}
@xrdef{Simple Command Expansion-title}{Simple Command Expansion}
@xrdef{Simple Command Expansion-snt}{Section@tie 3.7.1}
@xrdef{Command Search and Execution-title}{Command Search and Execution}
@xrdef{Command Search and Execution-snt}{Section@tie 3.7.2}
@xrdef{Executing Commands-pg}{29}
@xrdef{Simple Command Expansion-pg}{29}
@xrdef{Command Search and Execution-pg}{29}
@xrdef{Command Search and Execution-title}{Command Search and Execution}
@xrdef{Command Search and Execution-snt}{Section@tie 3.7.2}
@xrdef{Command Execution Environment-title}{Command Execution Environment}
@xrdef{Command Execution Environment-snt}{Section@tie 3.7.3}
@xrdef{Command Search and Execution-pg}{30}
@xrdef{Command Execution Environment-pg}{30}
@xrdef{Environment-title}{Environment}
@xrdef{Environment-snt}{Section@tie 3.7.4}
@@ -261,46 +261,46 @@
@xrdef{Readline Init File Syntax-pg}{94}
@xrdef{Conditional Init Constructs-title}{Conditional Init Constructs}
@xrdef{Conditional Init Constructs-snt}{Section@tie 8.3.2}
@xrdef{Conditional Init Constructs-pg}{100}
@xrdef{Sample Init File-title}{Sample Init File}
@xrdef{Sample Init File-snt}{Section@tie 8.3.3}
@xrdef{Conditional Init Constructs-pg}{100}
@xrdef{Sample Init File-pg}{100}
@xrdef{Sample Init File-pg}{101}
@xrdef{Bindable Readline Commands-title}{Bindable Readline Commands}
@xrdef{Bindable Readline Commands-snt}{Section@tie 8.4}
@xrdef{Commands For Moving-title}{Commands For Moving}
@xrdef{Commands For Moving-snt}{Section@tie 8.4.1}
@xrdef{Commands For History-title}{Commands For Manipulating The History}
@xrdef{Commands For History-snt}{Section@tie 8.4.2}
@xrdef{Bindable Readline Commands-pg}{103}
@xrdef{Commands For Moving-pg}{103}
@xrdef{Commands For History-pg}{104}
@xrdef{Bindable Readline Commands-pg}{104}
@xrdef{Commands For Moving-pg}{104}
@xrdef{Commands For History-pg}{105}
@xrdef{Commands For Text-title}{Commands For Changing Text}
@xrdef{Commands For Text-snt}{Section@tie 8.4.3}
@xrdef{Commands For Text-pg}{105}
@xrdef{Commands For Text-pg}{106}
@xrdef{Commands For Killing-title}{Killing And Yanking}
@xrdef{Commands For Killing-snt}{Section@tie 8.4.4}
@xrdef{Commands For Killing-pg}{106}
@xrdef{Commands For Killing-pg}{107}
@xrdef{Numeric Arguments-title}{Specifying Numeric Arguments}
@xrdef{Numeric Arguments-snt}{Section@tie 8.4.5}
@xrdef{Commands For Completion-title}{Letting Readline Type For You}
@xrdef{Commands For Completion-snt}{Section@tie 8.4.6}
@xrdef{Numeric Arguments-pg}{107}
@xrdef{Commands For Completion-pg}{107}
@xrdef{Numeric Arguments-pg}{108}
@xrdef{Commands For Completion-pg}{108}
@xrdef{Keyboard Macros-title}{Keyboard Macros}
@xrdef{Keyboard Macros-snt}{Section@tie 8.4.7}
@xrdef{Miscellaneous Commands-title}{Some Miscellaneous Commands}
@xrdef{Miscellaneous Commands-snt}{Section@tie 8.4.8}
@xrdef{Keyboard Macros-pg}{109}
@xrdef{Miscellaneous Commands-pg}{109}
@xrdef{Keyboard Macros-pg}{110}
@xrdef{Miscellaneous Commands-pg}{110}
@xrdef{Readline vi Mode-title}{Readline vi Mode}
@xrdef{Readline vi Mode-snt}{Section@tie 8.5}
@xrdef{Readline vi Mode-pg}{111}
@xrdef{Readline vi Mode-pg}{112}
@xrdef{Programmable Completion-title}{Programmable Completion}
@xrdef{Programmable Completion-snt}{Section@tie 8.6}
@xrdef{Programmable Completion-pg}{112}
@xrdef{Programmable Completion-pg}{113}
@xrdef{Programmable Completion Builtins-title}{Programmable Completion Builtins}
@xrdef{Programmable Completion Builtins-snt}{Section@tie 8.7}
@xrdef{Programmable Completion Builtins-pg}{114}
@xrdef{Programmable Completion Builtins-pg}{115}
@xrdef{Using History Interactively-title}{Using History Interactively}
@xrdef{Using History Interactively-snt}{Chapter@tie 9}
@xrdef{Bash History Facilities-title}{Bash History Facilities}
+3 -3
View File
@@ -52,8 +52,8 @@
\entry{wait}{89}{\code {wait}}
\entry{disown}{89}{\code {disown}}
\entry{suspend}{89}{\code {suspend}}
\entry{compgen}{114}{\code {compgen}}
\entry{complete}{114}{\code {complete}}
\entry{compopt}{117}{\code {compopt}}
\entry{compgen}{115}{\code {compgen}}
\entry{complete}{115}{\code {complete}}
\entry{compopt}{118}{\code {compopt}}
\entry{fc}{119}{\code {fc}}
\entry{history}{120}{\code {history}}
+3 -3
View File
@@ -15,9 +15,9 @@
\entry {\code {caller}}{43}
\entry {\code {cd}}{36}
\entry {\code {command}}{43}
\entry {\code {compgen}}{114}
\entry {\code {complete}}{114}
\entry {\code {compopt}}{117}
\entry {\code {compgen}}{115}
\entry {\code {complete}}{115}
\entry {\code {compopt}}{118}
\entry {\code {continue}}{36}
\initial {D}
\entry {\code {declare}}{43}
+5 -5
View File
@@ -64,8 +64,8 @@
\entry{matching, pattern}{24}{matching, pattern}
\entry{redirection}{26}{redirection}
\entry{command expansion}{29}{command expansion}
\entry{command execution}{29}{command execution}
\entry{command search}{29}{command search}
\entry{command execution}{30}{command execution}
\entry{command search}{30}{command search}
\entry{execution environment}{30}{execution environment}
\entry{environment}{31}{environment}
\entry{exit status}{32}{exit status}
@@ -103,9 +103,9 @@
\entry{kill ring}{93}{kill ring}
\entry{initialization file, readline}{94}{initialization file, readline}
\entry{variables, readline}{95}{variables, readline}
\entry{programmable completion}{112}{programmable completion}
\entry{completion builtins}{114}{completion builtins}
\entry{History, how to use}{117}{History, how to use}
\entry{programmable completion}{113}{programmable completion}
\entry{completion builtins}{115}{completion builtins}
\entry{History, how to use}{118}{History, how to use}
\entry{command history}{119}{command history}
\entry{history list}{119}{history list}
\entry{history builtins}{119}{history builtins}
+5 -5
View File
@@ -13,10 +13,10 @@
\entry {builtin}{3}
\initial {C}
\entry {command editing}{92}
\entry {command execution}{29}
\entry {command execution}{30}
\entry {command expansion}{29}
\entry {command history}{119}
\entry {command search}{29}
\entry {command search}{30}
\entry {command substitution}{22}
\entry {command timing}{8}
\entry {commands, compound}{9}
@@ -28,7 +28,7 @@
\entry {commands, shell}{7}
\entry {commands, simple}{8}
\entry {comments, shell}{7}
\entry {completion builtins}{114}
\entry {completion builtins}{115}
\entry {configuration}{125}
\entry {control operator}{3}
\entry {coprocess}{13}
@@ -61,7 +61,7 @@
\entry {history events}{121}
\entry {history expansion}{121}
\entry {history list}{119}
\entry {History, how to use}{117}
\entry {History, how to use}{118}
\initial {I}
\entry {identifier}{3}
\entry {initialization file, readline}{94}
@@ -100,7 +100,7 @@
\entry {process group}{3}
\entry {process group ID}{3}
\entry {process substitution}{23}
\entry {programmable completion}{112}
\entry {programmable completion}{113}
\entry {prompting}{82}
\initial {Q}
\entry {quoting}{6}
BIN
View File
Binary file not shown.
+103 -103
View File
@@ -1,103 +1,103 @@
\entry{beginning-of-line (C-a)}{103}{\code {beginning-of-line (C-a)}}
\entry{end-of-line (C-e)}{103}{\code {end-of-line (C-e)}}
\entry{forward-char (C-f)}{103}{\code {forward-char (C-f)}}
\entry{backward-char (C-b)}{103}{\code {backward-char (C-b)}}
\entry{forward-word (M-f)}{103}{\code {forward-word (M-f)}}
\entry{backward-word (M-b)}{103}{\code {backward-word (M-b)}}
\entry{shell-forward-word ()}{103}{\code {shell-forward-word ()}}
\entry{shell-backward-word ()}{103}{\code {shell-backward-word ()}}
\entry{clear-screen (C-l)}{103}{\code {clear-screen (C-l)}}
\entry{redraw-current-line ()}{103}{\code {redraw-current-line ()}}
\entry{accept-line (Newline or Return)}{104}{\code {accept-line (Newline or Return)}}
\entry{previous-history (C-p)}{104}{\code {previous-history (C-p)}}
\entry{next-history (C-n)}{104}{\code {next-history (C-n)}}
\entry{beginning-of-history (M-<)}{104}{\code {beginning-of-history (M-<)}}
\entry{end-of-history (M->)}{104}{\code {end-of-history (M->)}}
\entry{reverse-search-history (C-r)}{104}{\code {reverse-search-history (C-r)}}
\entry{forward-search-history (C-s)}{104}{\code {forward-search-history (C-s)}}
\entry{non-incremental-reverse-search-history (M-p)}{104}{\code {non-incremental-reverse-search-history (M-p)}}
\entry{non-incremental-forward-search-history (M-n)}{104}{\code {non-incremental-forward-search-history (M-n)}}
\entry{history-search-forward ()}{104}{\code {history-search-forward ()}}
\entry{history-search-backward ()}{104}{\code {history-search-backward ()}}
\entry{yank-nth-arg (M-C-y)}{104}{\code {yank-nth-arg (M-C-y)}}
\entry{yank-last-arg (M-. or M-_)}{105}{\code {yank-last-arg (M-. or M-_)}}
\entry{delete-char (C-d)}{105}{\code {delete-char (C-d)}}
\entry{backward-delete-char (Rubout)}{105}{\code {backward-delete-char (Rubout)}}
\entry{forward-backward-delete-char ()}{105}{\code {forward-backward-delete-char ()}}
\entry{quoted-insert (C-q or C-v)}{105}{\code {quoted-insert (C-q or C-v)}}
\entry{self-insert (a, b, A, 1, !, ...{})}{105}{\code {self-insert (a, b, A, 1, !, \dots {})}}
\entry{transpose-chars (C-t)}{105}{\code {transpose-chars (C-t)}}
\entry{transpose-words (M-t)}{105}{\code {transpose-words (M-t)}}
\entry{upcase-word (M-u)}{105}{\code {upcase-word (M-u)}}
\entry{downcase-word (M-l)}{105}{\code {downcase-word (M-l)}}
\entry{capitalize-word (M-c)}{106}{\code {capitalize-word (M-c)}}
\entry{overwrite-mode ()}{106}{\code {overwrite-mode ()}}
\entry{kill-line (C-k)}{106}{\code {kill-line (C-k)}}
\entry{backward-kill-line (C-x Rubout)}{106}{\code {backward-kill-line (C-x Rubout)}}
\entry{unix-line-discard (C-u)}{106}{\code {unix-line-discard (C-u)}}
\entry{kill-whole-line ()}{106}{\code {kill-whole-line ()}}
\entry{kill-word (M-d)}{106}{\code {kill-word (M-d)}}
\entry{backward-kill-word (M-DEL)}{106}{\code {backward-kill-word (M-\key {DEL})}}
\entry{shell-kill-word ()}{106}{\code {shell-kill-word ()}}
\entry{backward-kill-word ()}{106}{\code {backward-kill-word ()}}
\entry{unix-word-rubout (C-w)}{106}{\code {unix-word-rubout (C-w)}}
\entry{unix-filename-rubout ()}{106}{\code {unix-filename-rubout ()}}
\entry{delete-horizontal-space ()}{106}{\code {delete-horizontal-space ()}}
\entry{kill-region ()}{107}{\code {kill-region ()}}
\entry{copy-region-as-kill ()}{107}{\code {copy-region-as-kill ()}}
\entry{copy-backward-word ()}{107}{\code {copy-backward-word ()}}
\entry{copy-forward-word ()}{107}{\code {copy-forward-word ()}}
\entry{yank (C-y)}{107}{\code {yank (C-y)}}
\entry{yank-pop (M-y)}{107}{\code {yank-pop (M-y)}}
\entry{digit-argument (M-0, M-1, ...{} M--)}{107}{\code {digit-argument (\kbd {M-0}, \kbd {M-1}, \dots {} \kbd {M--})}}
\entry{universal-argument ()}{107}{\code {universal-argument ()}}
\entry{complete (TAB)}{107}{\code {complete (\key {TAB})}}
\entry{possible-completions (M-?)}{107}{\code {possible-completions (M-?)}}
\entry{insert-completions (M-*)}{108}{\code {insert-completions (M-*)}}
\entry{menu-complete ()}{108}{\code {menu-complete ()}}
\entry{menu-complete-backward ()}{108}{\code {menu-complete-backward ()}}
\entry{delete-char-or-list ()}{108}{\code {delete-char-or-list ()}}
\entry{complete-filename (M-/)}{108}{\code {complete-filename (M-/)}}
\entry{possible-filename-completions (C-x /)}{108}{\code {possible-filename-completions (C-x /)}}
\entry{complete-username (M-~)}{108}{\code {complete-username (M-~)}}
\entry{possible-username-completions (C-x ~)}{108}{\code {possible-username-completions (C-x ~)}}
\entry{complete-variable (M-$)}{108}{\code {complete-variable (M-$)}}
\entry{possible-variable-completions (C-x $)}{108}{\code {possible-variable-completions (C-x $)}}
\entry{complete-hostname (M-@)}{108}{\code {complete-hostname (M-@)}}
\entry{possible-hostname-completions (C-x @)}{108}{\code {possible-hostname-completions (C-x @)}}
\entry{complete-command (M-!)}{108}{\code {complete-command (M-!)}}
\entry{possible-command-completions (C-x !)}{109}{\code {possible-command-completions (C-x !)}}
\entry{dynamic-complete-history (M-TAB)}{109}{\code {dynamic-complete-history (M-\key {TAB})}}
\entry{dabbrev-expand ()}{109}{\code {dabbrev-expand ()}}
\entry{complete-into-braces (M-{\tt \char 123})}{109}{\code {complete-into-braces (M-{\tt \char 123})}}
\entry{start-kbd-macro (C-x ()}{109}{\code {start-kbd-macro (C-x ()}}
\entry{end-kbd-macro (C-x ))}{109}{\code {end-kbd-macro (C-x ))}}
\entry{call-last-kbd-macro (C-x e)}{109}{\code {call-last-kbd-macro (C-x e)}}
\entry{re-read-init-file (C-x C-r)}{109}{\code {re-read-init-file (C-x C-r)}}
\entry{abort (C-g)}{109}{\code {abort (C-g)}}
\entry{do-uppercase-version (M-a, M-b, M-x, ...{})}{109}{\code {do-uppercase-version (M-a, M-b, M-\var {x}, \dots {})}}
\entry{prefix-meta (ESC)}{109}{\code {prefix-meta (\key {ESC})}}
\entry{undo (C-_ or C-x C-u)}{109}{\code {undo (C-_ or C-x C-u)}}
\entry{revert-line (M-r)}{109}{\code {revert-line (M-r)}}
\entry{tilde-expand (M-&)}{110}{\code {tilde-expand (M-&)}}
\entry{set-mark (C-@)}{110}{\code {set-mark (C-@)}}
\entry{exchange-point-and-mark (C-x C-x)}{110}{\code {exchange-point-and-mark (C-x C-x)}}
\entry{character-search (C-])}{110}{\code {character-search (C-])}}
\entry{character-search-backward (M-C-])}{110}{\code {character-search-backward (M-C-])}}
\entry{skip-csi-sequence ()}{110}{\code {skip-csi-sequence ()}}
\entry{insert-comment (M-#)}{110}{\code {insert-comment (M-#)}}
\entry{dump-functions ()}{110}{\code {dump-functions ()}}
\entry{dump-variables ()}{110}{\code {dump-variables ()}}
\entry{dump-macros ()}{110}{\code {dump-macros ()}}
\entry{glob-complete-word (M-g)}{111}{\code {glob-complete-word (M-g)}}
\entry{glob-expand-word (C-x *)}{111}{\code {glob-expand-word (C-x *)}}
\entry{glob-list-expansions (C-x g)}{111}{\code {glob-list-expansions (C-x g)}}
\entry{display-shell-version (C-x C-v)}{111}{\code {display-shell-version (C-x C-v)}}
\entry{shell-expand-line (M-C-e)}{111}{\code {shell-expand-line (M-C-e)}}
\entry{history-expand-line (M-^)}{111}{\code {history-expand-line (M-^)}}
\entry{magic-space ()}{111}{\code {magic-space ()}}
\entry{alias-expand-line ()}{111}{\code {alias-expand-line ()}}
\entry{history-and-alias-expand-line ()}{111}{\code {history-and-alias-expand-line ()}}
\entry{insert-last-argument (M-. or M-_)}{111}{\code {insert-last-argument (M-. or M-_)}}
\entry{operate-and-get-next (C-o)}{111}{\code {operate-and-get-next (C-o)}}
\entry{edit-and-execute-command (C-xC-e)}{111}{\code {edit-and-execute-command (C-xC-e)}}
\entry{beginning-of-line (C-a)}{104}{\code {beginning-of-line (C-a)}}
\entry{end-of-line (C-e)}{104}{\code {end-of-line (C-e)}}
\entry{forward-char (C-f)}{104}{\code {forward-char (C-f)}}
\entry{backward-char (C-b)}{104}{\code {backward-char (C-b)}}
\entry{forward-word (M-f)}{104}{\code {forward-word (M-f)}}
\entry{backward-word (M-b)}{104}{\code {backward-word (M-b)}}
\entry{shell-forward-word ()}{104}{\code {shell-forward-word ()}}
\entry{shell-backward-word ()}{104}{\code {shell-backward-word ()}}
\entry{clear-screen (C-l)}{104}{\code {clear-screen (C-l)}}
\entry{redraw-current-line ()}{104}{\code {redraw-current-line ()}}
\entry{accept-line (Newline or Return)}{105}{\code {accept-line (Newline or Return)}}
\entry{previous-history (C-p)}{105}{\code {previous-history (C-p)}}
\entry{next-history (C-n)}{105}{\code {next-history (C-n)}}
\entry{beginning-of-history (M-<)}{105}{\code {beginning-of-history (M-<)}}
\entry{end-of-history (M->)}{105}{\code {end-of-history (M->)}}
\entry{reverse-search-history (C-r)}{105}{\code {reverse-search-history (C-r)}}
\entry{forward-search-history (C-s)}{105}{\code {forward-search-history (C-s)}}
\entry{non-incremental-reverse-search-history (M-p)}{105}{\code {non-incremental-reverse-search-history (M-p)}}
\entry{non-incremental-forward-search-history (M-n)}{105}{\code {non-incremental-forward-search-history (M-n)}}
\entry{history-search-forward ()}{105}{\code {history-search-forward ()}}
\entry{history-search-backward ()}{105}{\code {history-search-backward ()}}
\entry{yank-nth-arg (M-C-y)}{105}{\code {yank-nth-arg (M-C-y)}}
\entry{yank-last-arg (M-. or M-_)}{106}{\code {yank-last-arg (M-. or M-_)}}
\entry{delete-char (C-d)}{106}{\code {delete-char (C-d)}}
\entry{backward-delete-char (Rubout)}{106}{\code {backward-delete-char (Rubout)}}
\entry{forward-backward-delete-char ()}{106}{\code {forward-backward-delete-char ()}}
\entry{quoted-insert (C-q or C-v)}{106}{\code {quoted-insert (C-q or C-v)}}
\entry{self-insert (a, b, A, 1, !, ...{})}{106}{\code {self-insert (a, b, A, 1, !, \dots {})}}
\entry{transpose-chars (C-t)}{106}{\code {transpose-chars (C-t)}}
\entry{transpose-words (M-t)}{106}{\code {transpose-words (M-t)}}
\entry{upcase-word (M-u)}{106}{\code {upcase-word (M-u)}}
\entry{downcase-word (M-l)}{106}{\code {downcase-word (M-l)}}
\entry{capitalize-word (M-c)}{107}{\code {capitalize-word (M-c)}}
\entry{overwrite-mode ()}{107}{\code {overwrite-mode ()}}
\entry{kill-line (C-k)}{107}{\code {kill-line (C-k)}}
\entry{backward-kill-line (C-x Rubout)}{107}{\code {backward-kill-line (C-x Rubout)}}
\entry{unix-line-discard (C-u)}{107}{\code {unix-line-discard (C-u)}}
\entry{kill-whole-line ()}{107}{\code {kill-whole-line ()}}
\entry{kill-word (M-d)}{107}{\code {kill-word (M-d)}}
\entry{backward-kill-word (M-DEL)}{107}{\code {backward-kill-word (M-\key {DEL})}}
\entry{shell-kill-word ()}{107}{\code {shell-kill-word ()}}
\entry{backward-kill-word ()}{107}{\code {backward-kill-word ()}}
\entry{unix-word-rubout (C-w)}{107}{\code {unix-word-rubout (C-w)}}
\entry{unix-filename-rubout ()}{107}{\code {unix-filename-rubout ()}}
\entry{delete-horizontal-space ()}{107}{\code {delete-horizontal-space ()}}
\entry{kill-region ()}{108}{\code {kill-region ()}}
\entry{copy-region-as-kill ()}{108}{\code {copy-region-as-kill ()}}
\entry{copy-backward-word ()}{108}{\code {copy-backward-word ()}}
\entry{copy-forward-word ()}{108}{\code {copy-forward-word ()}}
\entry{yank (C-y)}{108}{\code {yank (C-y)}}
\entry{yank-pop (M-y)}{108}{\code {yank-pop (M-y)}}
\entry{digit-argument (M-0, M-1, ...{} M--)}{108}{\code {digit-argument (\kbd {M-0}, \kbd {M-1}, \dots {} \kbd {M--})}}
\entry{universal-argument ()}{108}{\code {universal-argument ()}}
\entry{complete (TAB)}{108}{\code {complete (\key {TAB})}}
\entry{possible-completions (M-?)}{108}{\code {possible-completions (M-?)}}
\entry{insert-completions (M-*)}{109}{\code {insert-completions (M-*)}}
\entry{menu-complete ()}{109}{\code {menu-complete ()}}
\entry{menu-complete-backward ()}{109}{\code {menu-complete-backward ()}}
\entry{delete-char-or-list ()}{109}{\code {delete-char-or-list ()}}
\entry{complete-filename (M-/)}{109}{\code {complete-filename (M-/)}}
\entry{possible-filename-completions (C-x /)}{109}{\code {possible-filename-completions (C-x /)}}
\entry{complete-username (M-~)}{109}{\code {complete-username (M-~)}}
\entry{possible-username-completions (C-x ~)}{109}{\code {possible-username-completions (C-x ~)}}
\entry{complete-variable (M-$)}{109}{\code {complete-variable (M-$)}}
\entry{possible-variable-completions (C-x $)}{109}{\code {possible-variable-completions (C-x $)}}
\entry{complete-hostname (M-@)}{109}{\code {complete-hostname (M-@)}}
\entry{possible-hostname-completions (C-x @)}{109}{\code {possible-hostname-completions (C-x @)}}
\entry{complete-command (M-!)}{109}{\code {complete-command (M-!)}}
\entry{possible-command-completions (C-x !)}{110}{\code {possible-command-completions (C-x !)}}
\entry{dynamic-complete-history (M-TAB)}{110}{\code {dynamic-complete-history (M-\key {TAB})}}
\entry{dabbrev-expand ()}{110}{\code {dabbrev-expand ()}}
\entry{complete-into-braces (M-{\tt \char 123})}{110}{\code {complete-into-braces (M-{\tt \char 123})}}
\entry{start-kbd-macro (C-x ()}{110}{\code {start-kbd-macro (C-x ()}}
\entry{end-kbd-macro (C-x ))}{110}{\code {end-kbd-macro (C-x ))}}
\entry{call-last-kbd-macro (C-x e)}{110}{\code {call-last-kbd-macro (C-x e)}}
\entry{re-read-init-file (C-x C-r)}{110}{\code {re-read-init-file (C-x C-r)}}
\entry{abort (C-g)}{110}{\code {abort (C-g)}}
\entry{do-uppercase-version (M-a, M-b, M-x, ...{})}{110}{\code {do-uppercase-version (M-a, M-b, M-\var {x}, \dots {})}}
\entry{prefix-meta (ESC)}{110}{\code {prefix-meta (\key {ESC})}}
\entry{undo (C-_ or C-x C-u)}{110}{\code {undo (C-_ or C-x C-u)}}
\entry{revert-line (M-r)}{110}{\code {revert-line (M-r)}}
\entry{tilde-expand (M-&)}{111}{\code {tilde-expand (M-&)}}
\entry{set-mark (C-@)}{111}{\code {set-mark (C-@)}}
\entry{exchange-point-and-mark (C-x C-x)}{111}{\code {exchange-point-and-mark (C-x C-x)}}
\entry{character-search (C-])}{111}{\code {character-search (C-])}}
\entry{character-search-backward (M-C-])}{111}{\code {character-search-backward (M-C-])}}
\entry{skip-csi-sequence ()}{111}{\code {skip-csi-sequence ()}}
\entry{insert-comment (M-#)}{111}{\code {insert-comment (M-#)}}
\entry{dump-functions ()}{111}{\code {dump-functions ()}}
\entry{dump-variables ()}{111}{\code {dump-variables ()}}
\entry{dump-macros ()}{111}{\code {dump-macros ()}}
\entry{glob-complete-word (M-g)}{112}{\code {glob-complete-word (M-g)}}
\entry{glob-expand-word (C-x *)}{112}{\code {glob-expand-word (C-x *)}}
\entry{glob-list-expansions (C-x g)}{112}{\code {glob-list-expansions (C-x g)}}
\entry{display-shell-version (C-x C-v)}{112}{\code {display-shell-version (C-x C-v)}}
\entry{shell-expand-line (M-C-e)}{112}{\code {shell-expand-line (M-C-e)}}
\entry{history-expand-line (M-^)}{112}{\code {history-expand-line (M-^)}}
\entry{magic-space ()}{112}{\code {magic-space ()}}
\entry{alias-expand-line ()}{112}{\code {alias-expand-line ()}}
\entry{history-and-alias-expand-line ()}{112}{\code {history-and-alias-expand-line ()}}
\entry{insert-last-argument (M-. or M-_)}{112}{\code {insert-last-argument (M-. or M-_)}}
\entry{operate-and-get-next (C-o)}{112}{\code {operate-and-get-next (C-o)}}
\entry{edit-and-execute-command (C-xC-e)}{112}{\code {edit-and-execute-command (C-xC-e)}}
+103 -103
View File
@@ -1,123 +1,123 @@
\initial {A}
\entry {\code {abort (C-g)}}{109}
\entry {\code {accept-line (Newline or Return)}}{104}
\entry {\code {alias-expand-line ()}}{111}
\entry {\code {abort (C-g)}}{110}
\entry {\code {accept-line (Newline or Return)}}{105}
\entry {\code {alias-expand-line ()}}{112}
\initial {B}
\entry {\code {backward-char (C-b)}}{103}
\entry {\code {backward-delete-char (Rubout)}}{105}
\entry {\code {backward-kill-line (C-x Rubout)}}{106}
\entry {\code {backward-kill-word ()}}{106}
\entry {\code {backward-kill-word (M-\key {DEL})}}{106}
\entry {\code {backward-word (M-b)}}{103}
\entry {\code {beginning-of-history (M-<)}}{104}
\entry {\code {beginning-of-line (C-a)}}{103}
\entry {\code {backward-char (C-b)}}{104}
\entry {\code {backward-delete-char (Rubout)}}{106}
\entry {\code {backward-kill-line (C-x Rubout)}}{107}
\entry {\code {backward-kill-word ()}}{107}
\entry {\code {backward-kill-word (M-\key {DEL})}}{107}
\entry {\code {backward-word (M-b)}}{104}
\entry {\code {beginning-of-history (M-<)}}{105}
\entry {\code {beginning-of-line (C-a)}}{104}
\initial {C}
\entry {\code {call-last-kbd-macro (C-x e)}}{109}
\entry {\code {capitalize-word (M-c)}}{106}
\entry {\code {character-search (C-])}}{110}
\entry {\code {character-search-backward (M-C-])}}{110}
\entry {\code {clear-screen (C-l)}}{103}
\entry {\code {complete (\key {TAB})}}{107}
\entry {\code {complete-command (M-!)}}{108}
\entry {\code {complete-filename (M-/)}}{108}
\entry {\code {complete-hostname (M-@)}}{108}
\entry {\code {complete-into-braces (M-{\tt \char 123})}}{109}
\entry {\code {complete-username (M-~)}}{108}
\entry {\code {complete-variable (M-$)}}{108}
\entry {\code {copy-backward-word ()}}{107}
\entry {\code {copy-forward-word ()}}{107}
\entry {\code {copy-region-as-kill ()}}{107}
\entry {\code {call-last-kbd-macro (C-x e)}}{110}
\entry {\code {capitalize-word (M-c)}}{107}
\entry {\code {character-search (C-])}}{111}
\entry {\code {character-search-backward (M-C-])}}{111}
\entry {\code {clear-screen (C-l)}}{104}
\entry {\code {complete (\key {TAB})}}{108}
\entry {\code {complete-command (M-!)}}{109}
\entry {\code {complete-filename (M-/)}}{109}
\entry {\code {complete-hostname (M-@)}}{109}
\entry {\code {complete-into-braces (M-{\tt \char 123})}}{110}
\entry {\code {complete-username (M-~)}}{109}
\entry {\code {complete-variable (M-$)}}{109}
\entry {\code {copy-backward-word ()}}{108}
\entry {\code {copy-forward-word ()}}{108}
\entry {\code {copy-region-as-kill ()}}{108}
\initial {D}
\entry {\code {dabbrev-expand ()}}{109}
\entry {\code {delete-char (C-d)}}{105}
\entry {\code {delete-char-or-list ()}}{108}
\entry {\code {delete-horizontal-space ()}}{106}
\entry {\code {digit-argument (\kbd {M-0}, \kbd {M-1}, \dots {} \kbd {M--})}}{107}
\entry {\code {display-shell-version (C-x C-v)}}{111}
\entry {\code {do-uppercase-version (M-a, M-b, M-\var {x}, \dots {})}}{109}
\entry {\code {downcase-word (M-l)}}{105}
\entry {\code {dump-functions ()}}{110}
\entry {\code {dump-macros ()}}{110}
\entry {\code {dump-variables ()}}{110}
\entry {\code {dynamic-complete-history (M-\key {TAB})}}{109}
\entry {\code {dabbrev-expand ()}}{110}
\entry {\code {delete-char (C-d)}}{106}
\entry {\code {delete-char-or-list ()}}{109}
\entry {\code {delete-horizontal-space ()}}{107}
\entry {\code {digit-argument (\kbd {M-0}, \kbd {M-1}, \dots {} \kbd {M--})}}{108}
\entry {\code {display-shell-version (C-x C-v)}}{112}
\entry {\code {do-uppercase-version (M-a, M-b, M-\var {x}, \dots {})}}{110}
\entry {\code {downcase-word (M-l)}}{106}
\entry {\code {dump-functions ()}}{111}
\entry {\code {dump-macros ()}}{111}
\entry {\code {dump-variables ()}}{111}
\entry {\code {dynamic-complete-history (M-\key {TAB})}}{110}
\initial {E}
\entry {\code {edit-and-execute-command (C-xC-e)}}{111}
\entry {\code {end-kbd-macro (C-x ))}}{109}
\entry {\code {end-of-history (M->)}}{104}
\entry {\code {end-of-line (C-e)}}{103}
\entry {\code {exchange-point-and-mark (C-x C-x)}}{110}
\entry {\code {edit-and-execute-command (C-xC-e)}}{112}
\entry {\code {end-kbd-macro (C-x ))}}{110}
\entry {\code {end-of-history (M->)}}{105}
\entry {\code {end-of-line (C-e)}}{104}
\entry {\code {exchange-point-and-mark (C-x C-x)}}{111}
\initial {F}
\entry {\code {forward-backward-delete-char ()}}{105}
\entry {\code {forward-char (C-f)}}{103}
\entry {\code {forward-search-history (C-s)}}{104}
\entry {\code {forward-word (M-f)}}{103}
\entry {\code {forward-backward-delete-char ()}}{106}
\entry {\code {forward-char (C-f)}}{104}
\entry {\code {forward-search-history (C-s)}}{105}
\entry {\code {forward-word (M-f)}}{104}
\initial {G}
\entry {\code {glob-complete-word (M-g)}}{111}
\entry {\code {glob-expand-word (C-x *)}}{111}
\entry {\code {glob-list-expansions (C-x g)}}{111}
\entry {\code {glob-complete-word (M-g)}}{112}
\entry {\code {glob-expand-word (C-x *)}}{112}
\entry {\code {glob-list-expansions (C-x g)}}{112}
\initial {H}
\entry {\code {history-and-alias-expand-line ()}}{111}
\entry {\code {history-expand-line (M-^)}}{111}
\entry {\code {history-search-backward ()}}{104}
\entry {\code {history-search-forward ()}}{104}
\entry {\code {history-and-alias-expand-line ()}}{112}
\entry {\code {history-expand-line (M-^)}}{112}
\entry {\code {history-search-backward ()}}{105}
\entry {\code {history-search-forward ()}}{105}
\initial {I}
\entry {\code {insert-comment (M-#)}}{110}
\entry {\code {insert-completions (M-*)}}{108}
\entry {\code {insert-last-argument (M-. or M-_)}}{111}
\entry {\code {insert-comment (M-#)}}{111}
\entry {\code {insert-completions (M-*)}}{109}
\entry {\code {insert-last-argument (M-. or M-_)}}{112}
\initial {K}
\entry {\code {kill-line (C-k)}}{106}
\entry {\code {kill-region ()}}{107}
\entry {\code {kill-whole-line ()}}{106}
\entry {\code {kill-word (M-d)}}{106}
\entry {\code {kill-line (C-k)}}{107}
\entry {\code {kill-region ()}}{108}
\entry {\code {kill-whole-line ()}}{107}
\entry {\code {kill-word (M-d)}}{107}
\initial {M}
\entry {\code {magic-space ()}}{111}
\entry {\code {menu-complete ()}}{108}
\entry {\code {menu-complete-backward ()}}{108}
\entry {\code {magic-space ()}}{112}
\entry {\code {menu-complete ()}}{109}
\entry {\code {menu-complete-backward ()}}{109}
\initial {N}
\entry {\code {next-history (C-n)}}{104}
\entry {\code {non-incremental-forward-search-history (M-n)}}{104}
\entry {\code {non-incremental-reverse-search-history (M-p)}}{104}
\entry {\code {next-history (C-n)}}{105}
\entry {\code {non-incremental-forward-search-history (M-n)}}{105}
\entry {\code {non-incremental-reverse-search-history (M-p)}}{105}
\initial {O}
\entry {\code {operate-and-get-next (C-o)}}{111}
\entry {\code {overwrite-mode ()}}{106}
\entry {\code {operate-and-get-next (C-o)}}{112}
\entry {\code {overwrite-mode ()}}{107}
\initial {P}
\entry {\code {possible-command-completions (C-x !)}}{109}
\entry {\code {possible-completions (M-?)}}{107}
\entry {\code {possible-filename-completions (C-x /)}}{108}
\entry {\code {possible-hostname-completions (C-x @)}}{108}
\entry {\code {possible-username-completions (C-x ~)}}{108}
\entry {\code {possible-variable-completions (C-x $)}}{108}
\entry {\code {prefix-meta (\key {ESC})}}{109}
\entry {\code {previous-history (C-p)}}{104}
\entry {\code {possible-command-completions (C-x !)}}{110}
\entry {\code {possible-completions (M-?)}}{108}
\entry {\code {possible-filename-completions (C-x /)}}{109}
\entry {\code {possible-hostname-completions (C-x @)}}{109}
\entry {\code {possible-username-completions (C-x ~)}}{109}
\entry {\code {possible-variable-completions (C-x $)}}{109}
\entry {\code {prefix-meta (\key {ESC})}}{110}
\entry {\code {previous-history (C-p)}}{105}
\initial {Q}
\entry {\code {quoted-insert (C-q or C-v)}}{105}
\entry {\code {quoted-insert (C-q or C-v)}}{106}
\initial {R}
\entry {\code {re-read-init-file (C-x C-r)}}{109}
\entry {\code {redraw-current-line ()}}{103}
\entry {\code {reverse-search-history (C-r)}}{104}
\entry {\code {revert-line (M-r)}}{109}
\entry {\code {re-read-init-file (C-x C-r)}}{110}
\entry {\code {redraw-current-line ()}}{104}
\entry {\code {reverse-search-history (C-r)}}{105}
\entry {\code {revert-line (M-r)}}{110}
\initial {S}
\entry {\code {self-insert (a, b, A, 1, !, \dots {})}}{105}
\entry {\code {set-mark (C-@)}}{110}
\entry {\code {shell-backward-word ()}}{103}
\entry {\code {shell-expand-line (M-C-e)}}{111}
\entry {\code {shell-forward-word ()}}{103}
\entry {\code {shell-kill-word ()}}{106}
\entry {\code {skip-csi-sequence ()}}{110}
\entry {\code {start-kbd-macro (C-x ()}}{109}
\entry {\code {self-insert (a, b, A, 1, !, \dots {})}}{106}
\entry {\code {set-mark (C-@)}}{111}
\entry {\code {shell-backward-word ()}}{104}
\entry {\code {shell-expand-line (M-C-e)}}{112}
\entry {\code {shell-forward-word ()}}{104}
\entry {\code {shell-kill-word ()}}{107}
\entry {\code {skip-csi-sequence ()}}{111}
\entry {\code {start-kbd-macro (C-x ()}}{110}
\initial {T}
\entry {\code {tilde-expand (M-&)}}{110}
\entry {\code {transpose-chars (C-t)}}{105}
\entry {\code {transpose-words (M-t)}}{105}
\entry {\code {tilde-expand (M-&)}}{111}
\entry {\code {transpose-chars (C-t)}}{106}
\entry {\code {transpose-words (M-t)}}{106}
\initial {U}
\entry {\code {undo (C-_ or C-x C-u)}}{109}
\entry {\code {universal-argument ()}}{107}
\entry {\code {unix-filename-rubout ()}}{106}
\entry {\code {unix-line-discard (C-u)}}{106}
\entry {\code {unix-word-rubout (C-w)}}{106}
\entry {\code {upcase-word (M-u)}}{105}
\entry {\code {undo (C-_ or C-x C-u)}}{110}
\entry {\code {universal-argument ()}}{108}
\entry {\code {unix-filename-rubout ()}}{107}
\entry {\code {unix-line-discard (C-u)}}{107}
\entry {\code {unix-word-rubout (C-w)}}{107}
\entry {\code {upcase-word (M-u)}}{106}
\initial {Y}
\entry {\code {yank (C-y)}}{107}
\entry {\code {yank-last-arg (M-. or M-_)}}{105}
\entry {\code {yank-nth-arg (M-C-y)}}{104}
\entry {\code {yank-pop (M-y)}}{107}
\entry {\code {yank (C-y)}}{108}
\entry {\code {yank-last-arg (M-. or M-_)}}{106}
\entry {\code {yank-nth-arg (M-C-y)}}{105}
\entry {\code {yank-pop (M-y)}}{108}
+362 -331
View File
File diff suppressed because it is too large Load Diff
+178 -151
View File
@@ -2,10 +2,10 @@ This is bashref.info, produced by makeinfo version 4.13 from
/Users/chet/src/bash/src/doc/bashref.texi.
This text is a brief description of the features that are present in
the Bash shell (version 4.0, 17 August 2009).
the Bash shell (version 4.1, 16 September 2009).
This is Edition 4.0, last updated 17 August 2009, of `The GNU Bash
Reference Manual', for `Bash', Version 4.0.
This is Edition 4.1, last updated 16 September 2009, of `The GNU
Bash Reference Manual', for `Bash', Version 4.1.
Copyright (C) 1988-2009 Free Software Foundation, Inc.
@@ -38,10 +38,10 @@ Bash Features
*************
This text is a brief description of the features that are present in
the Bash shell (version 4.0, 17 August 2009).
the Bash shell (version 4.1, 16 September 2009).
This is Edition 4.0, last updated 17 August 2009, of `The GNU Bash
Reference Manual', for `Bash', Version 4.0.
This is Edition 4.1, last updated 16 September 2009, of `The GNU
Bash Reference Manual', for `Bash', Version 4.1.
Bash contains features that appear in other popular shells, and some
features that only appear in Bash. Some of the shells that Bash has
@@ -1811,6 +1811,13 @@ environment. The following redirection operators may precede or appear
anywhere within a simple command or may follow a command. Redirections
are processed in the order they appear, from left to right.
Each redirection that may be preceded by a file descriptor number
may instead be preceded by a word of the form {VARNAME}. In this case,
for each redirection operator except >&- and <&-, the shell will
allocate a file descriptor greater than 10 and assign it to {VARNAME}.
If >&- or <&- is preceded by {VARNAME}, the value of {VARNAME} defines
the file descriptor to close.
In the following descriptions, if the file descriptor number is
omitted, and the first character of the redirection operator is `<',
the redirection refers to the standard input (file descriptor 0). If
@@ -6465,6 +6472,11 @@ Variable Settings
editing mode, where the keystrokes are most similar to Emacs.
This variable can be set to either `emacs' or `vi'.
`echo-control-characters'
When set to `on', on operating systems that indicate they
support it, readline echoes a character corresponding to a
signal generated from the keyboard. The default is `on'.
`enable-keypad'
When set to `on', Readline will try to enable the application
keypad when it is called. Some systems need this to enable
@@ -6572,6 +6584,19 @@ Variable Settings
be listed immediately instead of ringing the bell. The
default value is `off'.
`skip-completed-text'
If set to `on', this alters the default completion behavior
when inserting a single match into the line. It's only
active when performing completion in the middle of a word.
If enabled, readline does not insert characters from the
completion that match characters after point in the word
being completed, so portions of the word following the cursor
are not duplicated. For instance, if this is enabled,
attempting completion when the cursor is after the `e' in
`Makefile' will result in `Makefile' rather than
`Makefilefile', assuming there is a single possible
completion. The default value is `off'.
`visible-stats'
If set to `on', a character denoting a file's type is
appended to the filename when listing possible completions.
@@ -9786,10 +9811,10 @@ D.3 Parameter and Variable Index
(line 88)
* EMACS: Bash Variables. (line 208)
* enable-keypad: Readline Init File Syntax.
(line 94)
(line 99)
* EUID: Bash Variables. (line 213)
* expand-tilde: Readline Init File Syntax.
(line 99)
(line 104)
* FCEDIT: Bash Variables. (line 217)
* FIGNORE: Bash Variables. (line 221)
* FUNCNAME: Bash Variables. (line 227)
@@ -9802,15 +9827,15 @@ D.3 Parameter and Variable Index
* HISTFILESIZE: Bash Variables. (line 288)
* HISTIGNORE: Bash Variables. (line 296)
* history-preserve-point: Readline Init File Syntax.
(line 103)
(line 108)
* history-size: Readline Init File Syntax.
(line 109)
(line 114)
* HISTSIZE: Bash Variables. (line 315)
* HISTTIMEFORMAT: Bash Variables. (line 319)
* HOME: Bourne Shell Variables.
(line 13)
* horizontal-scroll-mode: Readline Init File Syntax.
(line 114)
(line 119)
* HOSTFILE: Bash Variables. (line 328)
* HOSTNAME: Bash Variables. (line 339)
* HOSTTYPE: Bash Variables. (line 342)
@@ -9818,12 +9843,12 @@ D.3 Parameter and Variable Index
(line 18)
* IGNOREEOF: Bash Variables. (line 345)
* input-meta: Readline Init File Syntax.
(line 121)
(line 126)
* INPUTRC: Bash Variables. (line 355)
* isearch-terminators: Readline Init File Syntax.
(line 128)
(line 133)
* keymap: Readline Init File Syntax.
(line 135)
(line 140)
* LANG: Bash Variables. (line 359)
* LC_ALL: Bash Variables. (line 363)
* LC_COLLATE: Bash Variables. (line 367)
@@ -9840,13 +9865,13 @@ D.3 Parameter and Variable Index
* MAILPATH: Bourne Shell Variables.
(line 27)
* mark-modified-lines: Readline Init File Syntax.
(line 148)
* mark-symlinked-directories: Readline Init File Syntax.
(line 153)
* match-hidden-files: Readline Init File Syntax.
* mark-symlinked-directories: Readline Init File Syntax.
(line 158)
* match-hidden-files: Readline Init File Syntax.
(line 163)
* meta-flag: Readline Init File Syntax.
(line 121)
(line 126)
* OLDPWD: Bash Variables. (line 408)
* OPTARG: Bourne Shell Variables.
(line 34)
@@ -9855,9 +9880,9 @@ D.3 Parameter and Variable Index
(line 38)
* OSTYPE: Bash Variables. (line 415)
* output-meta: Readline Init File Syntax.
(line 165)
* page-completions: Readline Init File Syntax.
(line 170)
* page-completions: Readline Init File Syntax.
(line 175)
* PATH: Bourne Shell Variables.
(line 42)
* PIPESTATUS: Bash Variables. (line 418)
@@ -9875,15 +9900,17 @@ D.3 Parameter and Variable Index
* RANDOM: Bash Variables. (line 460)
* REPLY: Bash Variables. (line 465)
* revert-all-at-newline: Readline Init File Syntax.
(line 180)
(line 185)
* SECONDS: Bash Variables. (line 468)
* SHELL: Bash Variables. (line 474)
* SHELLOPTS: Bash Variables. (line 479)
* SHLVL: Bash Variables. (line 488)
* show-all-if-ambiguous: Readline Init File Syntax.
(line 186)
(line 191)
* show-all-if-unmodified: Readline Init File Syntax.
(line 192)
(line 197)
* skip-completed-text: Readline Init File Syntax.
(line 206)
* TEXTDOMAIN: Locale Translation. (line 11)
* TEXTDOMAINDIR: Locale Translation. (line 11)
* TIMEFORMAT: Bash Variables. (line 493)
@@ -9891,7 +9918,7 @@ D.3 Parameter and Variable Index
* TMPDIR: Bash Variables. (line 543)
* UID: Bash Variables. (line 547)
* visible-stats: Readline Init File Syntax.
(line 201)
(line 219)

File: bashref.info, Node: Function Index, Next: Concept Index, Prev: Variable Index, Up: Indexes
@@ -10160,132 +10187,132 @@ D.5 Concept Index

Tag Table:
Node: Top1342
Node: Introduction3177
Node: What is Bash?3405
Node: What is a shell?4518
Node: Definitions7058
Node: Basic Shell Features9976
Node: Shell Syntax11195
Node: Shell Operation12225
Node: Quoting13519
Node: Escape Character14822
Node: Single Quotes15307
Node: Double Quotes15655
Node: ANSI-C Quoting16780
Node: Locale Translation17736
Node: Comments18632
Node: Shell Commands19250
Node: Simple Commands20074
Node: Pipelines20705
Node: Lists22961
Node: Compound Commands24690
Node: Looping Constructs25494
Node: Conditional Constructs27949
Node: Command Grouping35955
Node: Coprocesses37434
Node: Shell Functions39078
Node: Shell Parameters43632
Node: Positional Parameters46048
Node: Special Parameters46948
Node: Shell Expansions49912
Node: Brace Expansion51837
Node: Tilde Expansion54592
Node: Shell Parameter Expansion56943
Node: Command Substitution65841
Node: Arithmetic Expansion67174
Node: Process Substitution68024
Node: Word Splitting69074
Node: Filename Expansion70697
Node: Pattern Matching72836
Node: Quote Removal76475
Node: Redirections76770
Node: Executing Commands84918
Node: Simple Command Expansion85588
Node: Command Search and Execution87518
Node: Command Execution Environment89855
Node: Environment92841
Node: Exit Status94501
Node: Signals96122
Node: Shell Scripts98090
Node: Shell Builtin Commands100608
Node: Bourne Shell Builtins102636
Node: Bash Builtins120012
Node: Modifying Shell Behavior144311
Node: The Set Builtin144656
Node: The Shopt Builtin154180
Node: Special Builtins165042
Node: Shell Variables166021
Node: Bourne Shell Variables166461
Node: Bash Variables168442
Node: Bash Features191928
Node: Invoking Bash192811
Node: Bash Startup Files198620
Node: Interactive Shells203632
Node: What is an Interactive Shell?204042
Node: Is this Shell Interactive?204691
Node: Interactive Shell Behavior205506
Node: Bash Conditional Expressions208786
Node: Shell Arithmetic212311
Node: Aliases215057
Node: Arrays217629
Node: The Directory Stack221587
Node: Directory Stack Builtins222301
Node: Printing a Prompt225193
Node: The Restricted Shell227945
Node: Bash POSIX Mode229777
Node: Job Control237630
Node: Job Control Basics238090
Node: Job Control Builtins242807
Node: Job Control Variables247171
Node: Command Line Editing248329
Node: Introduction and Notation249896
Node: Readline Interaction251518
Node: Readline Bare Essentials252709
Node: Readline Movement Commands254498
Node: Readline Killing Commands255463
Node: Readline Arguments257383
Node: Searching258427
Node: Readline Init File260613
Node: Readline Init File Syntax261760
Node: Conditional Init Constructs274994
Node: Sample Init File277527
Node: Bindable Readline Commands280644
Node: Commands For Moving281851
Node: Commands For History282995
Node: Commands For Text286150
Node: Commands For Killing288823
Node: Numeric Arguments291274
Node: Commands For Completion292413
Node: Keyboard Macros296373
Node: Miscellaneous Commands296944
Node: Readline vi Mode302750
Node: Programmable Completion303664
Node: Programmable Completion Builtins310870
Node: Using History Interactively320006
Node: Bash History Facilities320690
Node: Bash History Builtins323604
Node: History Interaction327461
Node: Event Designators330166
Node: Word Designators331181
Node: Modifiers332820
Node: Installing Bash334224
Node: Basic Installation335361
Node: Compilers and Options338053
Node: Compiling For Multiple Architectures338794
Node: Installation Names340458
Node: Specifying the System Type341276
Node: Sharing Defaults341992
Node: Operation Controls342665
Node: Optional Features343623
Node: Reporting Bugs353182
Node: Major Differences From The Bourne Shell354383
Node: GNU Free Documentation License371070
Node: Indexes396266
Node: Builtin Index396720
Node: Reserved Word Index403547
Node: Variable Index405995
Node: Function Index417947
Node: Concept Index424956
Node: Top1348
Node: Introduction3189
Node: What is Bash?3417
Node: What is a shell?4530
Node: Definitions7070
Node: Basic Shell Features9988
Node: Shell Syntax11207
Node: Shell Operation12237
Node: Quoting13531
Node: Escape Character14834
Node: Single Quotes15319
Node: Double Quotes15667
Node: ANSI-C Quoting16792
Node: Locale Translation17748
Node: Comments18644
Node: Shell Commands19262
Node: Simple Commands20086
Node: Pipelines20717
Node: Lists22973
Node: Compound Commands24702
Node: Looping Constructs25506
Node: Conditional Constructs27961
Node: Command Grouping35967
Node: Coprocesses37446
Node: Shell Functions39090
Node: Shell Parameters43644
Node: Positional Parameters46060
Node: Special Parameters46960
Node: Shell Expansions49924
Node: Brace Expansion51849
Node: Tilde Expansion54604
Node: Shell Parameter Expansion56955
Node: Command Substitution65853
Node: Arithmetic Expansion67186
Node: Process Substitution68036
Node: Word Splitting69086
Node: Filename Expansion70709
Node: Pattern Matching72848
Node: Quote Removal76487
Node: Redirections76782
Node: Executing Commands85309
Node: Simple Command Expansion85979
Node: Command Search and Execution87909
Node: Command Execution Environment90246
Node: Environment93232
Node: Exit Status94892
Node: Signals96513
Node: Shell Scripts98481
Node: Shell Builtin Commands100999
Node: Bourne Shell Builtins103027
Node: Bash Builtins120403
Node: Modifying Shell Behavior144702
Node: The Set Builtin145047
Node: The Shopt Builtin154571
Node: Special Builtins165433
Node: Shell Variables166412
Node: Bourne Shell Variables166852
Node: Bash Variables168833
Node: Bash Features192319
Node: Invoking Bash193202
Node: Bash Startup Files199011
Node: Interactive Shells204023
Node: What is an Interactive Shell?204433
Node: Is this Shell Interactive?205082
Node: Interactive Shell Behavior205897
Node: Bash Conditional Expressions209177
Node: Shell Arithmetic212702
Node: Aliases215448
Node: Arrays218020
Node: The Directory Stack221978
Node: Directory Stack Builtins222692
Node: Printing a Prompt225584
Node: The Restricted Shell228336
Node: Bash POSIX Mode230168
Node: Job Control238021
Node: Job Control Basics238481
Node: Job Control Builtins243198
Node: Job Control Variables247562
Node: Command Line Editing248720
Node: Introduction and Notation250287
Node: Readline Interaction251909
Node: Readline Bare Essentials253100
Node: Readline Movement Commands254889
Node: Readline Killing Commands255854
Node: Readline Arguments257774
Node: Searching258818
Node: Readline Init File261004
Node: Readline Init File Syntax262151
Node: Conditional Init Constructs276364
Node: Sample Init File278897
Node: Bindable Readline Commands282014
Node: Commands For Moving283221
Node: Commands For History284365
Node: Commands For Text287520
Node: Commands For Killing290193
Node: Numeric Arguments292644
Node: Commands For Completion293783
Node: Keyboard Macros297743
Node: Miscellaneous Commands298314
Node: Readline vi Mode304120
Node: Programmable Completion305034
Node: Programmable Completion Builtins312240
Node: Using History Interactively321376
Node: Bash History Facilities322060
Node: Bash History Builtins324974
Node: History Interaction328831
Node: Event Designators331536
Node: Word Designators332551
Node: Modifiers334190
Node: Installing Bash335594
Node: Basic Installation336731
Node: Compilers and Options339423
Node: Compiling For Multiple Architectures340164
Node: Installation Names341828
Node: Specifying the System Type342646
Node: Sharing Defaults343362
Node: Operation Controls344035
Node: Optional Features344993
Node: Reporting Bugs354552
Node: Major Differences From The Bourne Shell355753
Node: GNU Free Documentation License372440
Node: Indexes397636
Node: Builtin Index398090
Node: Reserved Word Index404917
Node: Variable Index407365
Node: Function Index419458
Node: Concept Index426467

End Tag Table
+22 -23
View File
@@ -1,4 +1,4 @@
This is TeX, Version 3.141592 (Web2C 7.5.4) (format=tex 2008.12.11) 17 AUG 2009 14:46
This is TeX, Version 3.141592 (Web2C 7.5.4) (format=tex 2008.12.11) 16 SEP 2009 21:37
**/Users/chet/src/bash/src/doc/bashref.texi
(/Users/chet/src/bash/src/doc/bashref.texi (./texinfo.tex
Loading texinfo [version 2009-01-18.17]:
@@ -193,7 +193,7 @@ textttsl pat-tern@texttt ][]) @textttsl command-list @texttt ;;][] esac[][]
[10] [11] [12] [13] [14] [15] [16] [17] [18] [19] [20] [21] [22] [23] [24]
[25] [26] [27] [28] [29] [30] [31] [32] Chapter 4 [33] [34] [35] [36] [37]
[38] [39] [40] [41]
Underfull \hbox (badness 5231) in paragraph at lines 3286--3299
Underfull \hbox (badness 5231) in paragraph at lines 3294--3307
@texttt emacs-meta[]@textrm , @texttt emacs-ctlx[]@textrm , @texttt vi[]@textr
m , @texttt vi-move[]@textrm , @texttt vi-command[]@textrm , and
@@ -206,7 +206,7 @@ m , @texttt vi-move[]@textrm , @texttt vi-command[]@textrm , and
.etc.
[42] [43] [44] [45] [46]
Overfull \hbox (102.08961pt too wide) in paragraph at lines 3711--3711
Overfull \hbox (102.08961pt too wide) in paragraph at lines 3719--3719
[]@texttt read [-ers] [-a @textttsl aname@texttt ] [-d @textttsl de-lim@texttt
] [-i @textttsl text@texttt ] [-n @textttsl nchars@texttt ] [-p @textttsl prom
pt@texttt ] [-t @textttsl time-
@@ -220,7 +220,7 @@ pt@texttt ] [-t @textttsl time-
.etc.
[47] [48] [49] [50] [51] [52] [53] [54] [55]
Underfull \hbox (badness 2573) in paragraph at lines 4390--4394
Underfull \hbox (badness 2573) in paragraph at lines 4398--4402
[]@textrm Error trac-ing is en-abled: com-mand sub-sti-tu-tion, shell
@hbox(7.60416+2.12917)x433.62, glue set 2.95305
@@ -237,7 +237,7 @@ Underfull \hbox (badness 2573) in paragraph at lines 4390--4394
[56] [57] [58] Chapter 5 [59] [60] [61] [62] [63] [64] [65] [66] [67] [68]
[69] Chapter 6 [70]
Overfull \hbox (51.96864pt too wide) in paragraph at lines 5258--5258
Overfull \hbox (51.96864pt too wide) in paragraph at lines 5266--5266
[]@texttt bash [long-opt] [-ir] [-abefhkmnptuvxdBCDHP] [-o @textttsl op-tion@t
exttt ] [-O @textttsl shopt_option@texttt ] [@textttsl ar-
@@ -250,7 +250,7 @@ exttt ] [-O @textttsl shopt_option@texttt ] [@textttsl ar-
.etc.
Overfull \hbox (76.23077pt too wide) in paragraph at lines 5259--5259
Overfull \hbox (76.23077pt too wide) in paragraph at lines 5267--5267
[]@texttt bash [long-opt] [-abefhkmnptuvxdBCDHP] [-o @textttsl op-tion@texttt
] [-O @textttsl shopt_option@texttt ] -c @textttsl string @texttt [@textttsl ar
-
@@ -264,7 +264,7 @@ Overfull \hbox (76.23077pt too wide) in paragraph at lines 5259--5259
.etc.
Overfull \hbox (34.72258pt too wide) in paragraph at lines 5260--5260
Overfull \hbox (34.72258pt too wide) in paragraph at lines 5268--5268
[]@texttt bash [long-opt] -s [-abefhkmnptuvxdBCDHP] [-o @textttsl op-tion@text
tt ] [-O @textttsl shopt_option@texttt ] [@textttsl ar-
@@ -277,7 +277,7 @@ tt ] [-O @textttsl shopt_option@texttt ] [@textttsl ar-
.etc.
[71] [72]
Underfull \hbox (badness 2245) in paragraph at lines 5434--5436
Underfull \hbox (badness 2245) in paragraph at lines 5442--5444
[]@textrm When a lo-gin shell ex-its, Bash reads and ex-e-cutes com-mands from
the file
@@ -290,7 +290,7 @@ the file
.etc.
[73] [74] [75] [76] [77] [78] [79] [80] [81] [82] [83] [84] [85]
Underfull \hbox (badness 2521) in paragraph at lines 6573--6576
Underfull \hbox (badness 2521) in paragraph at lines 6581--6584
@textrm `@texttt --enable-strict-posix-default[]@textrm '[] to @texttt configur
e[] @textrm when build-ing (see Sec-tion 10.8
@@ -305,7 +305,7 @@ e[] @textrm when build-ing (see Sec-tion 10.8
Chapter 7 [86] [87] [88] [89]
(/Users/chet/src/bash/src/lib/readline/doc/rluser.texi Chapter 8 [90] [91]
[92] [93] [94] [95] [96]
Underfull \hbox (badness 5231) in paragraph at lines 524--540
Underfull \hbox (badness 5231) in paragraph at lines 529--545
@texttt emacs-meta[]@textrm , @texttt emacs-ctlx[]@textrm , @texttt vi[]@textr
m , @texttt vi-move[]@textrm , @texttt vi-command[]@textrm , and
@@ -317,8 +317,8 @@ m , @texttt vi-move[]@textrm , @texttt vi-command[]@textrm , and
.@texttt c
.etc.
[97] [98] [99] [100]
Overfull \hbox (26.43913pt too wide) in paragraph at lines 846--846
[97] [98] [99] [100] [101]
Overfull \hbox (26.43913pt too wide) in paragraph at lines 865--865
[]@texttt Meta-Control-h: backward-kill-word Text after the function name is i
gnored[]
@@ -330,9 +330,9 @@ gnored[]
.@texttt t
.etc.
[101] [102] [103] [104] [105] [106] [107] [108] [109] [110] [111] [112]
[113]
Overfull \hbox (12.05716pt too wide) in paragraph at lines 1764--1764
[102] [103] [104] [105] [106] [107] [108] [109] [110] [111] [112] [113]
[114]
Overfull \hbox (12.05716pt too wide) in paragraph at lines 1783--1783
[]@texttt complete [-abcdefgjksuv] [-o @textttsl comp-option@texttt ] [-DE] [-
A @textttsl ac-tion@texttt ] [-
@@ -344,8 +344,8 @@ A @textttsl ac-tion@texttt ] [-
.@texttt m
.etc.
[114] [115]
Underfull \hbox (badness 2753) in paragraph at lines 1874--1877
[115] [116]
Underfull \hbox (badness 2753) in paragraph at lines 1893--1896
@texttt hostname[]@textrm Hostnames, as taken from the file spec-i-fied by
@hbox(7.60416+2.12917)x433.62, glue set 3.02202
@@ -356,10 +356,9 @@ Underfull \hbox (badness 2753) in paragraph at lines 1874--1877
.@texttt o
.etc.
[116]) (/Users/chet/src/bash/src/lib/readline/doc/hsuser.texi Chapter 9
[117] [118] [119] [120] [121] [122]) Chapter 10 [123] [124] [125] [126]
[127]
Underfull \hbox (badness 2772) in paragraph at lines 7174--7178
[117]) (/Users/chet/src/bash/src/lib/readline/doc/hsuser.texi Chapter 9
[118] [119] [120] [121] [122]) Chapter 10 [123] [124] [125] [126] [127]
Underfull \hbox (badness 2772) in paragraph at lines 7182--7186
[]@textrm Enable sup-port for large files (@texttt http://www.sas.com/standard
s/large_
@@ -379,10 +378,10 @@ s/large_
Here is how much of TeX's memory you used:
2078 strings out of 97980
28503 string characters out of 1221004
64668 words of memory out of 1500000
65674 words of memory out of 1500000
2894 multiletter control sequences out of 10000+50000
32127 words of font info for 112 fonts, out of 1200000 for 2000
51 hyphenation exceptions out of 8191
16i,6n,14p,315b,699s stack positions out of 5000i,500n,6000p,200000b,5000s
Output written on bashref.dvi (162 pages, 659752 bytes).
Output written on bashref.dvi (162 pages, 661824 bytes).
BIN
View File
Binary file not shown.
+1746 -1702
View File
File diff suppressed because it is too large Load Diff
+11
View File
@@ -976,6 +976,9 @@ 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
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}.
@@ -2088,6 +2091,14 @@ simple command or may follow a command.
Redirections are processed in the order they appear, from
left to right.
Each redirection that may be preceded by a file descriptor number
may instead be preceded by a word of the form @{@var{varname}@}.
In this case, for each redirection operator except
>&- and <&-, the shell will allocate a file descriptor greater
than 10 and assign it to @{@var{varname}@}. If >&- or <&- is preceded
by @{@var{varname}@}, the value of @var{varname} defines the file
descriptor to close.
In the following descriptions, if the file descriptor number is
omitted, and the first character of the redirection operator is
@samp{<}, the redirection refers to the standard input (file
+26
View File
@@ -2088,6 +2088,14 @@ simple command or may follow a command.
Redirections are processed in the order they appear, from
left to right.
Each redirection that may be preceded by a file descriptor number
may instead be preceded by a word of the form @{@var{varname}@}.
In this case, for each redirection operator except
>&- and <&-, the shell will allocate a file descriptor greater
than 10 and assign it to @{@var{varname}@}. If >&- or <&- is preceded
by @{@var{varname}@}, the value of @var{varname} defines the file
descriptor to close.
In the following descriptions, if the file descriptor number is
omitted, and the first character of the redirection operator is
@samp{<}, the redirection refers to the standard input (file
@@ -4772,6 +4780,20 @@ The value of @env{MACHTYPE}.
@item BASH_VERSION
The version number of the current instance of Bash.
@item BASH_XTRACEFD
If set to an integer corresponding to a valid file descriptor, Bash
will write the trace output generated when @samp{set -x}
is enabled to that file descriptor.
This allows tracing output to be separated from diagnostic and error
messages.
The file descriptor is closed when @code{BASH_XTRACEFD} is unset or assigned
a new value.
Unsetting @code{BASH_XTRACEFD} or assigning it the empty string causes the
trace output to be sent to the standard error.
Note that setting @code{BASH_XTRACEFD} to 2 (the standard error file
descriptor) and then unsetting it will result in the standard error
being closed.
@item COLUMNS
Used by the @code{select} builtin command to determine the terminal width
when printing selection lists. Automatically set upon receipt of a
@@ -7252,6 +7274,10 @@ Include support for the @code{((@dots{}))} command
Include support for the extended pattern matching features described
above under @ref{Pattern Matching}.
@item --enable-extended-glob-default
Set the default value of the @var{extglob} shell option described
above under @ref{The Shopt Builtin} to be enabled.
@item --enable-help-builtin
Include the @code{help} builtin, which displays help on shell builtins and
variables (@pxref{Bash Builtins}).
+16 -16
View File
@@ -41,15 +41,15 @@
@numsubsecentry{Redirecting Output}{3.6.2}{}{27}
@numsubsecentry{Appending Redirected Output}{3.6.3}{}{27}
@numsubsecentry{Redirecting Standard Output and Standard Error}{3.6.4}{}{27}
@numsubsecentry{Appending Standard Output and Standard Error}{3.6.5}{}{27}
@numsubsecentry{Appending Standard Output and Standard Error}{3.6.5}{}{28}
@numsubsecentry{Here Documents}{3.6.6}{}{28}
@numsubsecentry{Here Strings}{3.6.7}{}{28}
@numsubsecentry{Duplicating File Descriptors}{3.6.8}{}{28}
@numsubsecentry{Moving File Descriptors}{3.6.9}{}{28}
@numsubsecentry{Moving File Descriptors}{3.6.9}{}{29}
@numsubsecentry{Opening File Descriptors for Reading and Writing}{3.6.10}{}{29}
@numsecentry{Executing Commands}{3.7}{Executing Commands}{29}
@numsubsecentry{Simple Command Expansion}{3.7.1}{Simple Command Expansion}{29}
@numsubsecentry{Command Search and Execution}{3.7.2}{Command Search and Execution}{29}
@numsubsecentry{Command Search and Execution}{3.7.2}{Command Search and Execution}{30}
@numsubsecentry{Command Execution Environment}{3.7.3}{Command Execution Environment}{30}
@numsubsecentry{Environment}{3.7.4}{Environment}{31}
@numsubsecentry{Exit Status}{3.7.5}{Exit Status}{32}
@@ -96,19 +96,19 @@
@numsecentry{Readline Init File}{8.3}{Readline Init File}{94}
@numsubsecentry{Readline Init File Syntax}{8.3.1}{Readline Init File Syntax}{94}
@numsubsecentry{Conditional Init Constructs}{8.3.2}{Conditional Init Constructs}{100}
@numsubsecentry{Sample Init File}{8.3.3}{Sample Init File}{100}
@numsecentry{Bindable Readline Commands}{8.4}{Bindable Readline Commands}{103}
@numsubsecentry{Commands For Moving}{8.4.1}{Commands For Moving}{103}
@numsubsecentry{Commands For Manipulating The History}{8.4.2}{Commands For History}{104}
@numsubsecentry{Commands For Changing Text}{8.4.3}{Commands For Text}{105}
@numsubsecentry{Killing And Yanking}{8.4.4}{Commands For Killing}{106}
@numsubsecentry{Specifying Numeric Arguments}{8.4.5}{Numeric Arguments}{107}
@numsubsecentry{Letting Readline Type For You}{8.4.6}{Commands For Completion}{107}
@numsubsecentry{Keyboard Macros}{8.4.7}{Keyboard Macros}{109}
@numsubsecentry{Some Miscellaneous Commands}{8.4.8}{Miscellaneous Commands}{109}
@numsecentry{Readline vi Mode}{8.5}{Readline vi Mode}{111}
@numsecentry{Programmable Completion}{8.6}{Programmable Completion}{112}
@numsecentry{Programmable Completion Builtins}{8.7}{Programmable Completion Builtins}{114}
@numsubsecentry{Sample Init File}{8.3.3}{Sample Init File}{101}
@numsecentry{Bindable Readline Commands}{8.4}{Bindable Readline Commands}{104}
@numsubsecentry{Commands For Moving}{8.4.1}{Commands For Moving}{104}
@numsubsecentry{Commands For Manipulating The History}{8.4.2}{Commands For History}{105}
@numsubsecentry{Commands For Changing Text}{8.4.3}{Commands For Text}{106}
@numsubsecentry{Killing And Yanking}{8.4.4}{Commands For Killing}{107}
@numsubsecentry{Specifying Numeric Arguments}{8.4.5}{Numeric Arguments}{108}
@numsubsecentry{Letting Readline Type For You}{8.4.6}{Commands For Completion}{108}
@numsubsecentry{Keyboard Macros}{8.4.7}{Keyboard Macros}{110}
@numsubsecentry{Some Miscellaneous Commands}{8.4.8}{Miscellaneous Commands}{110}
@numsecentry{Readline vi Mode}{8.5}{Readline vi Mode}{112}
@numsecentry{Programmable Completion}{8.6}{Programmable Completion}{113}
@numsecentry{Programmable Completion Builtins}{8.7}{Programmable Completion Builtins}{115}
@numchapentry{Using History Interactively}{9}{Using History Interactively}{119}
@numsecentry{Bash History Facilities}{9.1}{Bash History Facilities}{119}
@numsecentry{Bash History Builtins}{9.2}{Bash History Builtins}{119}
+3 -2
View File
@@ -114,14 +114,15 @@
\entry{horizontal-scroll-mode}{96}{\code {horizontal-scroll-mode}}
\entry{input-meta}{96}{\code {input-meta}}
\entry{meta-flag}{96}{\code {meta-flag}}
\entry{isearch-terminators}{96}{\code {isearch-terminators}}
\entry{isearch-terminators}{97}{\code {isearch-terminators}}
\entry{keymap}{97}{\code {keymap}}
\entry{mark-modified-lines}{97}{\code {mark-modified-lines}}
\entry{mark-symlinked-directories}{97}{\code {mark-symlinked-directories}}
\entry{match-hidden-files}{97}{\code {match-hidden-files}}
\entry{output-meta}{97}{\code {output-meta}}
\entry{page-completions}{97}{\code {page-completions}}
\entry{revert-all-at-newline}{97}{\code {revert-all-at-newline}}
\entry{revert-all-at-newline}{98}{\code {revert-all-at-newline}}
\entry{show-all-if-ambiguous}{98}{\code {show-all-if-ambiguous}}
\entry{show-all-if-unmodified}{98}{\code {show-all-if-unmodified}}
\entry{skip-completed-text}{98}{\code {skip-completed-text}}
\entry{visible-stats}{98}{\code {visible-stats}}
+3 -2
View File
@@ -90,7 +90,7 @@
\entry {\code {IGNOREEOF}}{67}
\entry {\code {input-meta}}{96}
\entry {\code {INPUTRC}}{67}
\entry {\code {isearch-terminators}}{96}
\entry {\code {isearch-terminators}}{97}
\initial {K}
\entry {\code {keymap}}{97}
\initial {L}
@@ -134,7 +134,7 @@
\initial {R}
\entry {\code {RANDOM}}{68}
\entry {\code {REPLY}}{68}
\entry {\code {revert-all-at-newline}}{97}
\entry {\code {revert-all-at-newline}}{98}
\initial {S}
\entry {\code {SECONDS}}{69}
\entry {\code {SHELL}}{69}
@@ -142,6 +142,7 @@
\entry {\code {SHLVL}}{69}
\entry {\code {show-all-if-ambiguous}}{98}
\entry {\code {show-all-if-unmodified}}{98}
\entry {\code {skip-completed-text}}{98}
\initial {T}
\entry {\code {TEXTDOMAIN}}{7}
\entry {\code {TEXTDOMAINDIR}}{7}
+1 -1
View File
@@ -1,6 +1,6 @@
%!PS-Adobe-3.0
%%Creator: groff version 1.19.2
%%CreationDate: Mon Aug 17 14:38:17 2009
%%CreationDate: Wed Sep 16 21:35:02 2009
%%DocumentNeededResources: font Times-Roman
%%+ font Times-Bold
%%+ font Times-Italic
+1 -1
View File
@@ -1,6 +1,6 @@
%!PS-Adobe-3.0
%%Creator: groff version 1.19.2
%%CreationDate: Mon Aug 17 14:38:17 2009
%%CreationDate: Wed Sep 16 21:35:02 2009
%%DocumentNeededResources: font Times-Roman
%%+ font Times-Bold
%%DocumentSuppliedResources: procset grops 1.19 2
+5 -5
View File
@@ -2,9 +2,9 @@
Copyright (C) 1988-2009 Free Software Foundation, Inc.
@end ignore
@set LASTCHANGE Mon Aug 17 14:38:05 EDT 2009
@set LASTCHANGE Wed Sep 16 21:33:56 EDT 2009
@set EDITION 4.0
@set VERSION 4.0
@set UPDATED 17 August 2009
@set UPDATED-MONTH August 2009
@set EDITION 4.1
@set VERSION 4.1
@set UPDATED 16 September 2009
@set UPDATED-MONTH September 2009
+7 -2
View File
@@ -3268,7 +3268,7 @@ execute_cond_node (cond)
int oe;
oe = extended_glob;
extended_glob = 1;
result = binary_test (cond->op->word, arg1, arg2, TEST_PATMATCH|TEST_ARITHEXP)
result = binary_test (cond->op->word, arg1, arg2, TEST_PATMATCH|TEST_ARITHEXP|TEST_LOCALE)
? EXECUTION_SUCCESS
: EXECUTION_FAILURE;
extended_glob = oe;
@@ -3359,8 +3359,13 @@ execute_null_command (redirects, pipe_in, pipe_out, async)
int pipe_in, pipe_out, async;
{
int r;
int forcefork;
REDIRECT *rd;
if (pipe_in != NO_PIPE || pipe_out != NO_PIPE || async)
for (forcefork = 0, rd = redirects; rd; rd = rd->next)
forcefork += rd->rflags & REDIR_VARASSIGN;
if (forcefork || pipe_in != NO_PIPE || pipe_out != NO_PIPE || async)
{
/* We have a null command, but we really want a subshell to take
care of it. Just fork, do piping and redirections, and exit. */
+13 -3
View File
@@ -1967,7 +1967,7 @@ execute_coproc (command, pipe_in, pipe_out, fds_to_close)
int pipe_in, pipe_out;
struct fd_bitmap *fds_to_close;
{
int rpipe[2], wpipe[2];
int rpipe[2], wpipe[2], estat;
pid_t coproc_pid;
Coproc *cp;
char *tcmd;
@@ -1996,7 +1996,12 @@ execute_coproc (command, pipe_in, pipe_out, fds_to_close)
close (rpipe[0]);
close (wpipe[1]);
exit (execute_in_subshell (command, 1, wpipe[0], rpipe[1], fds_to_close));
estat = execute_in_subshell (command, 1, wpipe[0], rpipe[1], fds_to_close);
fflush (stdout);
fflush (stderr);
exit (estat);
}
close (rpipe[1]);
@@ -3354,8 +3359,13 @@ execute_null_command (redirects, pipe_in, pipe_out, async)
int pipe_in, pipe_out, async;
{
int r;
int forcefork;
REDIRECT *rd;
if (pipe_in != NO_PIPE || pipe_out != NO_PIPE || async)
for (forcefork = 0, rd = redirects; rd; rd = rd->next)
forcefork += rd->rflags & REDIR_VARASSIGN;
if (forcefork || pipe_in != NO_PIPE || pipe_out != NO_PIPE || async)
{
/* We have a null command, but we really want a subshell to take
care of it. Just fork, do piping and redirections, and exit. */
+7 -3
View File
@@ -309,9 +309,9 @@ dequote_pathname (pathname)
# define GLOB_TESTNAME(name) (lstat (name, &finfo))
#else /* !HAVE_LSTAT */
# if !defined (AFS)
# define GLOB_TESTNAME(name) (sh_eaccess (nextname, F_OK))
# define GLOB_TESTNAME(name) (sh_eaccess (name, F_OK))
# else /* AFS */
# define GLOB_TESTNAME(name) (access (nextname, F_OK))
# define GLOB_TESTNAME(name) (access (name, F_OK))
# endif /* AFS */
#endif /* !HAVE_LSTAT */
@@ -322,6 +322,7 @@ glob_testdir (dir)
{
struct stat finfo;
/*itrace("glob_testdir: testing %s", dir);*/
if (stat (dir, &finfo) < 0)
return (-1);
@@ -925,11 +926,14 @@ glob_filename (pathname, flags)
{
char **temp_results;
/* XXX -- we've recursively scanned any directories resulting from
a `**', so turn off the flag. We turn it on again below if
filename is `**' */
/* Scan directory even on a NULL filename. That way, `*h/'
returns only directories ending in `h', instead of all
files ending in `h' with a `/' appended. */
dname = directories[i];
dflags = flags & ~GX_MARKDIRS;
dflags = flags & ~(GX_MARKDIRS|GX_ALLDIRS|GX_ADDCURDIR);
if ((flags & GX_GLOBSTAR) && filename[0] == '*' && filename[1] == '*' && filename[2] == '\0')
dflags |= GX_ALLDIRS|GX_ADDCURDIR;
if (dname[0] == '\0' && filename[0])
+11 -5
View File
@@ -246,7 +246,8 @@ udequote_pathname (pathname)
if (pathname[i - 1] == 0)
break;
}
pathname[j] = '\0';
if (pathname)
pathname[j] = '\0';
}
#if HANDLE_MULTIBYTE
@@ -279,7 +280,8 @@ wdequote_pathname (pathname)
if (wpathname[i - 1] == L'\0')
break;
}
wpathname[j] = L'\0';
if (wpathname)
wpathname[j] = L'\0';
/* Convert the wide character string into unibyte character set. */
memset (&ps, '\0', sizeof(mbstate_t));
@@ -307,9 +309,9 @@ dequote_pathname (pathname)
# define GLOB_TESTNAME(name) (lstat (name, &finfo))
#else /* !HAVE_LSTAT */
# if !defined (AFS)
# define GLOB_TESTNAME(name) (sh_eaccess (nextname, F_OK))
# define GLOB_TESTNAME(name) (sh_eaccess (name, F_OK))
# else /* AFS */
# define GLOB_TESTNAME(name) (access (nextname, F_OK))
# define GLOB_TESTNAME(name) (access (name, F_OK))
# endif /* AFS */
#endif /* !HAVE_LSTAT */
@@ -320,6 +322,7 @@ glob_testdir (dir)
{
struct stat finfo;
/*itrace("glob_testdir: testing %s", dir);*/
if (stat (dir, &finfo) < 0)
return (-1);
@@ -923,11 +926,14 @@ glob_filename (pathname, flags)
{
char **temp_results;
/* XXX -- we've recursively scanned any directories resulting from
a `**', so turn off the flag. We turn it on below if
necessary. */
/* Scan directory even on a NULL filename. That way, `*h/'
returns only directories ending in `h', instead of all
files ending in `h' with a `/' appended. */
dname = directories[i];
dflags = flags & ~GX_MARKDIRS;
dflags = flags & ~(GX_MARKDIRS|GX_ALLDIRS|GX_ADDCURDIR);
if ((flags & GX_GLOBSTAR) && filename[0] == '*' && filename[1] == '*' && filename[2] == '\0')
dflags |= GX_ALLDIRS|GX_ADDCURDIR;
if (dname[0] == '\0' && filename[0])
+180 -81
View File
@@ -442,6 +442,18 @@ redirection: '>' WORD
redir.filename = $3;
$$ = make_redirection (source, r_input_direction, redir, 0);
}
| REDIR_WORD '>' WORD
{
source.filename = $1;
redir.filename = $3;
$$ = make_redirection (source, r_output_direction, redir, REDIR_VARASSIGN);
}
| REDIR_WORD '<' WORD
{
source.filename = $1;
redir.filename = $3;
$$ = make_redirection (source, r_input_direction, redir, REDIR_VARASSIGN);
}
| GREATER_GREATER WORD
{
source.dest = 1;
@@ -454,6 +466,48 @@ redirection: '>' WORD
redir.filename = $3;
$$ = make_redirection (source, r_appending_to, redir, 0);
}
| REDIR_WORD GREATER_GREATER WORD
{
source.filename = $1;
redir.filename = $3;
$$ = make_redirection (source, r_appending_to, redir, REDIR_VARASSIGN);
}
| GREATER_BAR WORD
{
source.dest = 1;
redir.filename = $2;
$$ = make_redirection (source, r_output_force, redir, 0);
}
| NUMBER GREATER_BAR WORD
{
source.dest = $1;
redir.filename = $3;
$$ = make_redirection (source, r_output_force, redir, 0);
}
| REDIR_WORD GREATER_BAR WORD
{
source.filename = $1;
redir.filename = $3;
$$ = make_redirection (source, r_output_force, redir, REDIR_VARASSIGN);
}
| LESS_GREATER WORD
{
source.dest = 0;
redir.filename = $2;
$$ = make_redirection (source, r_input_output, redir, 0);
}
| NUMBER LESS_GREATER WORD
{
source.dest = $1;
redir.filename = $3;
$$ = make_redirection (source, r_input_output, redir, 0);
}
| REDIR_WORD LESS_GREATER WORD
{
source.filename = $1;
redir.filename = $3;
$$ = make_redirection (source, r_input_output, redir, REDIR_VARASSIGN);
}
| LESS_LESS WORD
{
source.dest = 0;
@@ -468,65 +522,12 @@ redirection: '>' WORD
$$ = make_redirection (source, r_reading_until, redir, 0);
redir_stack[need_here_doc++] = $$;
}
| LESS_LESS_LESS WORD
| REDIR_WORD LESS_LESS WORD
{
source.dest = 0;
redir.filename = $2;
$$ = make_redirection (source, r_reading_string, redir, 0);
}
| NUMBER LESS_LESS_LESS WORD
{
source.dest = $1;
source.filename = $1;
redir.filename = $3;
$$ = make_redirection (source, r_reading_string, redir, 0);
}
| LESS_AND NUMBER
{
source.dest = 0;
redir.dest = $2;
$$ = make_redirection (source, r_duplicating_input, redir, 0);
}
| NUMBER LESS_AND NUMBER
{
source.dest = $1;
redir.dest = $3;
$$ = make_redirection (source, r_duplicating_input, redir, 0);
}
| GREATER_AND NUMBER
{
source.dest = 1;
redir.dest = $2;
$$ = make_redirection (source, r_duplicating_output, redir, 0);
}
| NUMBER GREATER_AND NUMBER
{
source.dest = $1;
redir.dest = $3;
$$ = make_redirection (source, r_duplicating_output, redir, 0);
}
| LESS_AND WORD
{
source.dest = 0;
redir.filename = $2;
$$ = make_redirection (source, r_duplicating_input_word, redir, 0);
}
| NUMBER LESS_AND WORD
{
source.dest = $1;
redir.filename = $3;
$$ = make_redirection (source, r_duplicating_input_word, redir, 0);
}
| GREATER_AND WORD
{
source.dest = 1;
redir.filename = $2;
$$ = make_redirection (source, r_duplicating_output_word, redir, 0);
}
| NUMBER GREATER_AND WORD
{
source.dest = $1;
redir.filename = $3;
$$ = make_redirection (source, r_duplicating_output_word, redir, 0);
$$ = make_redirection (source, r_reading_until, redir, REDIR_VARASSIGN);
redir_stack[need_here_doc++] = $$;
}
| LESS_LESS_MINUS WORD
{
@@ -542,6 +543,103 @@ redirection: '>' WORD
$$ = make_redirection (source, r_deblank_reading_until, redir, 0);
redir_stack[need_here_doc++] = $$;
}
| REDIR_WORD LESS_LESS_MINUS WORD
{
source.filename = $1;
redir.filename = $3;
$$ = make_redirection (source, r_deblank_reading_until, redir, REDIR_VARASSIGN);
redir_stack[need_here_doc++] = $$;
}
| LESS_LESS_LESS WORD
{
source.dest = 0;
redir.filename = $2;
$$ = make_redirection (source, r_reading_string, redir, 0);
}
| NUMBER LESS_LESS_LESS WORD
{
source.dest = $1;
redir.filename = $3;
$$ = make_redirection (source, r_reading_string, redir, 0);
}
| REDIR_WORD LESS_LESS_LESS WORD
{
source.filename = $1;
redir.filename = $3;
$$ = make_redirection (source, r_reading_string, redir, REDIR_VARASSIGN);
}
| LESS_AND NUMBER
{
source.dest = 0;
redir.dest = $2;
$$ = make_redirection (source, r_duplicating_input, redir, 0);
}
| NUMBER LESS_AND NUMBER
{
source.dest = $1;
redir.dest = $3;
$$ = make_redirection (source, r_duplicating_input, redir, 0);
}
| REDIR_WORD LESS_AND NUMBER
{
source.filename = $1;
redir.dest = $3;
$$ = make_redirection (source, r_duplicating_input, redir, REDIR_VARASSIGN);
}
| GREATER_AND NUMBER
{
source.dest = 1;
redir.dest = $2;
$$ = make_redirection (source, r_duplicating_output, redir, 0);
}
| NUMBER GREATER_AND NUMBER
{
source.dest = $1;
redir.dest = $3;
$$ = make_redirection (source, r_duplicating_output, redir, 0);
}
| REDIR_WORD GREATER_AND NUMBER
{
source.filename = $1;
redir.dest = $3;
$$ = make_redirection (source, r_duplicating_output, redir, REDIR_VARASSIGN);
}
| LESS_AND WORD
{
source.dest = 0;
redir.filename = $2;
$$ = make_redirection (source, r_duplicating_input_word, redir, 0);
}
| NUMBER LESS_AND WORD
{
source.dest = $1;
redir.filename = $3;
$$ = make_redirection (source, r_duplicating_input_word, redir, 0);
}
| REDIR_WORD LESS_AND WORD
{
source.filename = $1;
redir.filename = $3;
$$ = make_redirection (source, r_duplicating_input_word, redir, REDIR_VARASSIGN);
}
| GREATER_AND WORD
{
source.dest = 1;
redir.filename = $2;
$$ = make_redirection (source, r_duplicating_output_word, redir, 0);
}
| NUMBER GREATER_AND WORD
{
source.dest = $1;
redir.filename = $3;
$$ = make_redirection (source, r_duplicating_output_word, redir, 0);
}
| REDIR_WORD GREATER_AND WORD
{
source.filename = $1;
redir.filename = $3;
$$ = make_redirection (source, r_duplicating_output_word, redir, REDIR_VARASSIGN);
}
| GREATER_AND '-'
{
source.dest = 1;
@@ -554,6 +652,12 @@ redirection: '>' WORD
redir.dest = 0;
$$ = make_redirection (source, r_close_this, redir, 0);
}
| REDIR_WORD GREATER_AND '-'
{
source.filename = $1;
redir.dest = 0;
$$ = make_redirection (source, r_close_this, redir, REDIR_VARASSIGN);
}
| LESS_AND '-'
{
source.dest = 0;
@@ -566,6 +670,12 @@ redirection: '>' WORD
redir.dest = 0;
$$ = make_redirection (source, r_close_this, redir, 0);
}
| REDIR_WORD LESS_AND '-'
{
source.filename = $1;
redir.dest = 0;
$$ = make_redirection (source, r_close_this, redir, REDIR_VARASSIGN);
}
| AND_GREATER WORD
{
source.dest = 1;
@@ -578,30 +688,6 @@ redirection: '>' WORD
redir.filename = $2;
$$ = make_redirection (source, r_append_err_and_out, redir, 0);
}
| NUMBER LESS_GREATER WORD
{
source.dest = $1;
redir.filename = $3;
$$ = make_redirection (source, r_input_output, redir, 0);
}
| LESS_GREATER WORD
{
source.dest = 0;
redir.filename = $2;
$$ = make_redirection (source, r_input_output, redir, 0);
}
| GREATER_BAR WORD
{
source.dest = 1;
redir.filename = $2;
$$ = make_redirection (source, r_output_force, redir, 0);
}
| NUMBER GREATER_BAR WORD
{
source.dest = $1;
redir.filename = $3;
$$ = make_redirection (source, r_output_force, redir, 0);
}
;
simple_command_element: WORD
@@ -4511,6 +4597,19 @@ got_token:
yylval.word = the_word;
if (token[0] == '{' && token[token_index-1] == '}' &&
(character == '<' || character == '>'))
{
/* can use token; already copied to the_word */
token[token_index-1] = '\0';
if (legal_identifier (token+1))
{
strcpy (the_word->word, token+1);
/*itrace("read_token_word: returning REDIR_WORD for %s", the_word->word);*/
return (REDIR_WORD);
}
}
result = ((the_word->flags & (W_ASSIGNMENT|W_NOSPLIT)) == (W_ASSIGNMENT|W_NOSPLIT))
? ASSIGNMENT_WORD : WORD;
+2 -2
View File
@@ -834,7 +834,7 @@ gen_wordlist_matches (cs, text)
do -- there's no way to split a simple list into individual words
that way, since the shell semantics say that word splitting is done
only on the results of expansion. */
l = split_at_delims (cs->words, strlen (cs->words), (char *)NULL, -1, (int *)NULL, (int *)NULL);
l = split_at_delims (cs->words, strlen (cs->words), (char *)NULL, -1, 0, (int *)NULL, (int *)NULL);
if (l == 0)
return ((STRINGLIST *)NULL);
/* This will jump back to the top level if the expansion fails... */
@@ -1199,7 +1199,7 @@ command_line_to_word_list (line, llen, sentinel, nwp, cwp)
#else
delims = rl_completer_word_break_characters;
#endif
ret = split_at_delims (line, llen, delims, sentinel, nwp, cwp);
ret = split_at_delims (line, llen, delims, sentinel, SD_NOQUOTEDELIM, nwp, cwp);
return (ret);
}
+120 -37
View File
@@ -66,6 +66,8 @@
#include <readline/readline.h>
#include <readline/history.h>
#define PCOMP_RETRYFAIL 256
#ifdef STRDUP
# undef STRDUP
#endif
@@ -118,10 +120,15 @@ static STRINGLIST *gen_globpat_matches __P((COMPSPEC *, const char *));
static STRINGLIST *gen_wordlist_matches __P((COMPSPEC *, const char *));
static STRINGLIST *gen_shell_function_matches __P((COMPSPEC *, const char *,
char *, int, WORD_LIST *,
int, int));
int, int, int *));
static STRINGLIST *gen_command_matches __P((COMPSPEC *, const char *, char *,
int, WORD_LIST *, int, int));
static STRINGLIST *gen_progcomp_completions __P((const char *, const char *,
const char *,
int, int, int *, int *,
COMPSPEC **));
static char *pcomp_filename_completion_function __P((const char *, int));
#if defined (ARRAY_VARS)
@@ -653,7 +660,7 @@ gen_matches_from_itemlist (itp, text)
if ((itp->flags & (LIST_DIRTY|LIST_DYNAMIC)) ||
(itp->flags & LIST_INITIALIZED) == 0)
{
if (itp->flags & (LIST_DIRTY | LIST_DYNAMIC))
if (itp->flags & (LIST_DIRTY|LIST_DYNAMIC))
clean_itemlist (itp);
if ((itp->flags & LIST_INITIALIZED) == 0)
initialize_itemlist (itp);
@@ -827,7 +834,7 @@ gen_wordlist_matches (cs, text)
do -- there's no way to split a simple list into individual words
that way, since the shell semantics say that word splitting is done
only on the results of expansion. */
l = split_at_delims (cs->words, strlen (cs->words), (char *)NULL, -1, (int *)NULL, (int *)NULL);
l = split_at_delims (cs->words, strlen (cs->words), (char *)NULL, -1, 0, (int *)NULL, (int *)NULL);
if (l == 0)
return ((STRINGLIST *)NULL);
/* This will jump back to the top level if the expansion fails... */
@@ -992,25 +999,30 @@ build_arg_list (cmd, text, lwords, ind)
variable, this does nothing if arrays are not compiled into the shell. */
static STRINGLIST *
gen_shell_function_matches (cs, text, line, ind, lwords, nw, cw)
gen_shell_function_matches (cs, text, line, ind, lwords, nw, cw, foundp)
COMPSPEC *cs;
const char *text;
char *line;
int ind;
WORD_LIST *lwords;
int nw, cw;
int *foundp;
{
char *funcname;
STRINGLIST *sl;
SHELL_VAR *f, *v;
WORD_LIST *cmdlist;
int fval;
int fval, found;
sh_parser_state_t ps;
sh_parser_state_t * restrict pps;
#if defined (ARRAY_VARS)
ARRAY *a;
#endif
found = 0;
if (foundp)
*foundp = found;
funcname = cs->funcname;
f = find_function (funcname);
if (f == 0)
@@ -1043,6 +1055,12 @@ gen_shell_function_matches (cs, text, line, ind, lwords, nw, cw)
discard_unwind_frame ("gen-shell-function-matches");
restore_parser_state (pps);
found = fval != EX_NOTFOUND;
if (fval == EX_RETRYFAIL)
found |= PCOMP_RETRYFAIL;
if (foundp)
*foundp = found;
/* Now clean up and destroy everything. */
dispose_words (cmdlist);
unbind_compfunc_variables (0);
@@ -1057,7 +1075,7 @@ gen_shell_function_matches (cs, text, line, ind, lwords, nw, cw)
VUNSETATTR (v, att_invisible);
a = array_cell (v);
if (a == 0 || array_empty (a))
if (found == 0 || (found & PCOMP_RETRYFAIL) || a == 0 || array_empty (a))
sl = (STRINGLIST *)NULL;
else
{
@@ -1181,25 +1199,28 @@ command_line_to_word_list (line, llen, sentinel, nwp, cwp)
#else
delims = rl_completer_word_break_characters;
#endif
ret = split_at_delims (line, llen, delims, sentinel, nwp, cwp);
ret = split_at_delims (line, llen, delims, sentinel, SD_NOQUOTEDELIMS, nwp, cwp);
return (ret);
}
/* Evaluate COMPSPEC *cs and return all matches for WORD. */
STRINGLIST *
gen_compspec_completions (cs, cmd, word, start, end)
gen_compspec_completions (cs, cmd, word, start, end, foundp)
COMPSPEC *cs;
const char *cmd;
const char *word;
int start, end;
int *foundp;
{
STRINGLIST *ret, *tmatches;
char *line;
int llen, nw, cw;
int llen, nw, cw, found, foundf;
WORD_LIST *lwords;
COMPSPEC *tcs;
found = 1;
#ifdef DEBUG
debug_printf ("gen_compspec_completions (%s, %s, %d, %d)", cmd, word, start, end);
debug_printf ("gen_compspec_completions: %s -> %p", cmd, cs);
@@ -1284,7 +1305,10 @@ gen_compspec_completions (cs, cmd, word, start, end)
if (cs->funcname)
{
tmatches = gen_shell_function_matches (cs, word, line, rl_point - start, lwords, nw, cw);
foundf = 0;
tmatches = gen_shell_function_matches (cs, word, line, rl_point - start, lwords, nw, cw, &foundf);
if (foundf != 0)
found = foundf;
if (tmatches)
{
#ifdef DEBUG
@@ -1325,6 +1349,15 @@ gen_compspec_completions (cs, cmd, word, start, end)
FREE (line);
}
if (foundp)
*foundp = found;
if (found == 0 || (found & PCOMP_RETRYFAIL))
{
strlist_dispose (ret);
return NULL;
}
if (cs->filterpat)
{
tmatches = filter_stringlist (ret, cs->filterpat, word);
@@ -1399,35 +1432,28 @@ pcomp_set_compspec_options (cs, flags, set_or_unset)
cs->options &= ~flags;
}
/* The driver function for the programmable completion code. Returns a list
of matches for WORD, which is an argument to command CMD. START and END
bound the command currently being completed in rl_line_buffer. */
char **
programmable_completions (cmd, word, start, end, foundp)
static STRINGLIST *
gen_progcomp_completions (ocmd, cmd, word, start, end, foundp, retryp, lastcs)
const char *ocmd;
const char *cmd;
const char *word;
int start, end, *foundp;
int start, end;
int *foundp, *retryp;
COMPSPEC **lastcs;
{
COMPSPEC *cs, *oldcs;
STRINGLIST *ret;
char **rmatches, *t;
const char *oldcmd;
STRINGLIST *ret;
/* We look at the basename of CMD if the full command does not have
an associated COMPSPEC. */
cs = progcomp_search (cmd);
if (cs == 0)
{
t = strrchr (cmd, '/');
if (t)
cs = progcomp_search (++t);
}
if (cs == 0)
{
if (foundp)
*foundp = 0;
return ((char **)NULL);
}
cs = progcomp_search (ocmd);
if (cs == 0 || cs == *lastcs)
return (NULL);
if (*lastcs)
compspec_dispose (*lastcs);
cs->refcount++; /* XXX */
*lastcs = cs;
cs = compspec_copy (cs);
@@ -1437,17 +1463,68 @@ programmable_completions (cmd, word, start, end, foundp)
pcomp_curcs = cs;
pcomp_curcmd = cmd;
ret = gen_compspec_completions (cs, cmd, word, start, end);
ret = gen_compspec_completions (cs, cmd, word, start, end, foundp);
pcomp_curcs = oldcs;
pcomp_curcmd = oldcmd;
/* Signal the caller that we found a COMPSPEC for this command, and pass
back any meta-options associated with the compspec. */
/* We need to conditionally handle setting *retryp here */
if (retryp)
*retryp = foundp && (*foundp & PCOMP_RETRYFAIL);
if (foundp)
*foundp = 1|cs->options;
{
*foundp &= ~PCOMP_RETRYFAIL;
*foundp |= cs->options;
}
compspec_dispose (cs);
return ret;
}
/* The driver function for the programmable completion code. Returns a list
of matches for WORD, which is an argument to command CMD. START and END
bound the command currently being completed in rl_line_buffer. */
char **
programmable_completions (cmd, word, start, end, foundp)
const char *cmd;
const char *word;
int start, end, *foundp;
{
COMPSPEC *cs, *lastcs;
STRINGLIST *ret;
char **rmatches, *t;
int found, retry, count;
lastcs = 0;
found = count = 0;
do
{
retry = 0;
/* We look at the basename of CMD if the full command does not have
an associated COMPSPEC. */
ret = gen_progcomp_completions (cmd, cmd, word, start, end, &found, &retry, &lastcs);
if (found == 0)
{
t = strrchr (cmd, '/');
if (t && *(++t))
ret = gen_progcomp_completions (t, cmd, word, start, end, &found, &retry, &lastcs);
}
if (found == 0)
ret = gen_progcomp_completions (DEFAULTCMD, cmd, word, start, end, &found, &retry, &lastcs);
count++;
if (count > 32)
{
internal_warning ("programmable_completion: %s: possible retry loop", cmd);
break;
}
}
while (retry);
if (ret)
{
@@ -1457,6 +1534,12 @@ programmable_completions (cmd, word, start, end, foundp)
else
rmatches = (char **)NULL;
if (foundp)
*foundp = found;
if (lastcs) /* XXX - should be while? */
compspec_dispose (lastcs);
return (rmatches);
}
+434 -463
View File
File diff suppressed because it is too large Load Diff
+170 -319
View File
File diff suppressed because it is too large Load Diff
+78 -35
View File
@@ -1024,7 +1024,9 @@ print_heredoc_header (redirect)
kill_leading = redirect->instruction == r_deblank_reading_until;
/* Here doc header */
if (redirect->redirector.dest != 0)
if (redirect->rflags & REDIR_VARASSIGN)
cprintf ("{%s}", redirect->redirector.filename->word);
else if (redirect->redirector.dest != 0)
cprintf ("%d", redirect->redirector.dest);
/* If the here document delimiter is quoted, single-quote it. */
@@ -1051,37 +1053,61 @@ print_redirection (redirect)
REDIRECT *redirect;
{
int kill_leading, redirector, redir_fd;
WORD_DESC *redirectee;
WORD_DESC *redirectee, *redir_word;
kill_leading = 0;
redirectee = redirect->redirectee.filename;
redirector = redirect->redirector.dest;
redir_fd = redirect->redirectee.dest;
redir_word = redirect->redirector.filename;
redirector = redirect->redirector.dest;
switch (redirect->instruction)
{
case r_output_direction:
if (redirector != 1)
cprintf ("%d", redirector);
cprintf ("> %s", redirectee->word);
break;
case r_input_direction:
if (redirector != 0)
if (redirect->rflags & REDIR_VARASSIGN)
cprintf ("{%s}", redir_word->word);
else if (redirector != 0)
cprintf ("%d", redirector);
cprintf ("< %s", redirectee->word);
break;
case r_output_direction:
if (redirect->rflags & REDIR_VARASSIGN)
cprintf ("{%s}", redir_word->word);
else if (redirector != 1)
cprintf ("%d", redirector);
cprintf ("> %s", redirectee->word);
break;
case r_inputa_direction: /* Redirection created by the shell. */
cprintf ("&");
break;
case r_output_force:
if (redirect->rflags & REDIR_VARASSIGN)
cprintf ("{%s}", redir_word->word);
else if (redirector != 1)
cprintf ("%d", redirector);
cprintf (">|%s", redirectee->word);
break;
case r_appending_to:
if (redirector != 1)
if (redirect->rflags & REDIR_VARASSIGN)
cprintf ("{%s}", redir_word->word);
else if (redirector != 1)
cprintf ("%d", redirector);
cprintf (">> %s", redirectee->word);
break;
case r_input_output:
if (redirect->rflags & REDIR_VARASSIGN)
cprintf ("{%s}", redir_word->word);
else if (redirector != 1)
cprintf ("%d", redirector);
cprintf ("<> %s", redirectee->word);
break;
case r_deblank_reading_until:
case r_reading_until:
print_heredoc_header (redirect);
@@ -1090,7 +1116,9 @@ print_redirection (redirect)
break;
case r_reading_string:
if (redirector != 0)
if (redirect->rflags & REDIR_VARASSIGN)
cprintf ("{%s}", redir_word->word);
else if (redirector != 0)
cprintf ("%d", redirector);
if (ansic_shouldquote (redirect->redirectee.filename->word))
{
@@ -1104,39 +1132,66 @@ print_redirection (redirect)
break;
case r_duplicating_input:
cprintf ("%d<&%d", redirector, redir_fd);
if (redirect->rflags & REDIR_VARASSIGN)
cprintf ("{%s}<&%d", redir_word->word, redir_fd);
else
cprintf ("%d<&%d", redirector, redir_fd);
break;
case r_duplicating_output:
cprintf ("%d>&%d", redirector, redir_fd);
if (redirect->rflags & REDIR_VARASSIGN)
cprintf ("{%s}>&%d", redir_word->word, redir_fd);
else
cprintf ("%d>&%d", redirector, redir_fd);
break;
case r_duplicating_input_word:
cprintf ("%d<&%s", redirector, redirectee->word);
if (redirect->rflags & REDIR_VARASSIGN)
cprintf ("{%s}<&%s", redir_word->word, redirectee->word);
else
cprintf ("%d<&%s", redirector, redirectee->word);
break;
case r_duplicating_output_word:
cprintf ("%d>&%s", redirector, redirectee->word);
if (redirect->rflags & REDIR_VARASSIGN)
cprintf ("{%s}>&%s", redir_word->word, redirectee->word);
else
cprintf ("%d>&%s", redirector, redirectee->word);
break;
case r_move_input:
cprintf ("%d<&%d-", redirector, redir_fd);
if (redirect->rflags & REDIR_VARASSIGN)
cprintf ("{%s}<&%d-", redir_word->word, redir_fd);
else
cprintf ("%d<&%d-", redirector, redir_fd);
break;
case r_move_output:
cprintf ("%d>&%d-", redirector, redir_fd);
if (redirect->rflags & REDIR_VARASSIGN)
cprintf ("{%s}>&%d-", redir_word->word, redir_fd);
else
cprintf ("%d>&%d-", redirector, redir_fd);
break;
case r_move_input_word:
cprintf ("%d<&%s-", redirector, redirectee->word);
if (redirect->rflags & REDIR_VARASSIGN)
cprintf ("{%s}<&%s-", redir_word->word, redirectee->word);
else
cprintf ("%d<&%s-", redirector, redirectee->word);
break;
case r_move_output_word:
cprintf ("%d>&%s-", redirector, redirectee->word);
if (redirect->rflags & REDIR_VARASSIGN)
cprintf ("{%s}>&%s-", redir_word->word, redirectee->word);
else
cprintf ("%d>&%s-", redirector, redirectee->word);
break;
case r_close_this:
cprintf ("%d>&-", redirector);
if (redirect->rflags & REDIR_VARASSIGN)
cprintf ("{%s}>&-", redir_word->word);
else
cprintf ("%d>&-", redirector);
break;
case r_err_and_out:
@@ -1146,18 +1201,6 @@ print_redirection (redirect)
case r_append_err_and_out:
cprintf ("&>>%s", redirectee->word);
break;
case r_input_output:
if (redirector != 1)
cprintf ("%d", redirector);
cprintf ("<> %s", redirectee->word);
break;
case r_output_force:
if (redirector != 1)
cprintf ("%d", redirector);
cprintf (">|%s", redirectee->word);
break;
}
}
@@ -1339,7 +1382,7 @@ semicolon ()
{
if (command_string_index > 0 &&
(the_printed_command[command_string_index - 1] == '&' ||
the_printed_command[command_string_index - 1] == '\n'))
the_printed_command[command_string_index - 1] == '\n'))
return;
cprintf (";");
}
@@ -1404,7 +1447,7 @@ cprintf (control, va_alist)
argp = intbuf;
}
else
argp = inttostr (digit_arg, intbuf, sizeof (intbuf));
argp = inttostr (digit_arg, intbuf, sizeof (intbuf));
arg_len = strlen (argp);
break;
+114 -12
View File
@@ -82,6 +82,9 @@ static int redir_special_open __P((int, char *, int, int, enum r_instruction));
static int noclobber_open __P((char *, int, int, enum r_instruction));
static int redir_open __P((char *, int, int, enum r_instruction));
static int redir_varassign __P((REDIRECT *, int));
static int redir_varvalue __P((REDIRECT *));
/* Spare redirector used when translating [N]>&WORD[-] or [N]<&WORD[-] to
a new redirection and when creating the redirection undo list. */
static REDIRECTEE rd;
@@ -120,6 +123,18 @@ redirection_error (temp, error)
case r_move_output:
filename = allocname = itos (temp->redirectee.dest);
break;
case r_duplicating_input_word:
if (temp->redirector.dest == 0) /* Guess */
filename = temp->redirectee.filename->word; /* XXX */
else
filename = allocname = itos (temp->redirector.dest);
break;
case r_duplicating_output_word:
if (temp->redirector.dest == 1) /* Guess */
filename = temp->redirectee.filename->word; /* XXX */
else
filename = allocname = itos (temp->redirector.dest);
break;
default:
filename = allocname = itos (temp->redirector.dest);
break;
@@ -128,6 +143,7 @@ redirection_error (temp, error)
#endif
else if (expandable_redirection_filename (temp))
{
expandable_filename:
if (posixly_correct && interactive_shell == 0)
{
oflags = temp->redirectee.filename->flags;
@@ -165,7 +181,7 @@ redirection_error (temp, error)
break;
case BADVAR_REDIRECT:
internal_error (_("cannot assign fd to variable %s"), filename);
internal_error (_("%s: cannot assign fd to variable"), filename);
break;
default:
@@ -667,8 +683,9 @@ do_redirection_internal (redirect, flags)
if (TRANSLATE_REDIRECT (ri))
{
/* We have [N]>&WORD[-] or [N]<&WORD[-]. Expand WORD, then translate
the redirection into a new one and continue. */
/* We have [N]>&WORD[-] or [N]<&WORD[-] (or {V}>&WORD[-] or {V}<&WORD-).
and WORD, then translate the redirection into a new one and
continue. */
redirectee_word = redirection_expand (redirectee);
/* XXX - what to do with [N]<&$w- where w is unset or null? ksh93
@@ -677,13 +694,13 @@ do_redirection_internal (redirect, flags)
return (AMBIGUOUS_REDIRECT);
else if (redirectee_word[0] == '-' && redirectee_word[1] == '\0')
{
sd.dest = redirector;
sd = redirect->redirector;
rd.dest = 0;
new_redirect = make_redirection (sd, r_close_this, rd, 0);
}
else if (all_digits (redirectee_word))
{
sd.dest = redirector;
sd = redirect->redirector;
if (legal_number (redirectee_word, &lfd) && (int)lfd == lfd)
rd.dest = lfd;
else
@@ -704,9 +721,9 @@ do_redirection_internal (redirect, flags)
break;
}
}
else if (ri == r_duplicating_output_word && redirector == 1)
else if (ri == r_duplicating_output_word && (redirect->rflags & REDIR_VARASSIGN) == 0 && redirector == 1)
{
sd.dest = 1;
sd = redirect->redirector;
rd.filename = make_bare_word (redirectee_word);
new_redirect = make_redirection (sd, r_err_and_out, rd, 0);
}
@@ -789,6 +806,9 @@ do_redirection_internal (redirect, flags)
if (flags & RX_ACTIVE)
{
if (redirect->rflags & REDIR_VARASSIGN)
redirector = fcntl (fd, F_DUPFD, SHELL_FD_BASE); /* XXX try this for now */
if (flags & RX_UNDOABLE)
{
/* Only setup to undo it if the thing to undo is active. */
@@ -816,7 +836,16 @@ do_redirection_internal (redirect, flags)
fpurge (stderr);
}
if ((fd != redirector) && (dup2 (fd, redirector) < 0))
if (redirect->rflags & REDIR_VARASSIGN)
{
if ((r = redir_varassign (redirect, redirector)) < 0)
{
close (redirector);
close (fd);
return (r); /* XXX */
}
}
else if ((fd != redirector) && (dup2 (fd, redirector) < 0))
return (errno);
#if defined (BUFFERED_INPUT)
@@ -852,7 +881,7 @@ do_redirection_internal (redirect, flags)
}
/* If we are hacking both stdout and stderr, do the stderr
redirection here. */
redirection here. XXX - handle {var} here? */
if (ri == r_err_and_out || ri == r_append_err_and_out)
{
if (flags & RX_ACTIVE)
@@ -880,6 +909,9 @@ do_redirection_internal (redirect, flags)
return (HEREDOC_REDIRECT);
}
if (redirect->rflags & REDIR_VARASSIGN)
redirector = fcntl (fd, F_DUPFD, SHELL_FD_BASE); /* XXX try this for now */
if (flags & RX_ACTIVE)
{
if (flags & RX_UNDOABLE)
@@ -894,7 +926,16 @@ do_redirection_internal (redirect, flags)
#if defined (BUFFERED_INPUT)
check_bash_input (redirector);
#endif
if (fd != redirector && dup2 (fd, redirector) < 0)
if (redirect->rflags & REDIR_VARASSIGN)
{
if ((r = redir_varassign (redirect, redirector)) < 0)
{
close (redirector);
close (fd);
return (r); /* XXX */
}
}
else if (fd != redirector && dup2 (fd, redirector) < 0)
{
r = errno;
close (fd);
@@ -922,6 +963,9 @@ do_redirection_internal (redirect, flags)
case r_duplicating_output:
case r_move_input:
case r_move_output:
if ((flags & RX_ACTIVE) && (redirect->rflags & REDIR_VARASSIGN))
redirector = fcntl (redir_fd, F_DUPFD, SHELL_FD_BASE); /* XXX try this for now */
if ((flags & RX_ACTIVE) && (redir_fd != redirector))
{
if (flags & RX_UNDOABLE)
@@ -935,8 +979,16 @@ do_redirection_internal (redirect, flags)
#if defined (BUFFERED_INPUT)
check_bash_input (redirector);
#endif
if (redirect->rflags & REDIR_VARASSIGN)
{
if ((r = redir_varassign (redirect, redirector)) < 0)
{
close (redirector);
return (r); /* XXX */
}
}
/* This is correct. 2>&1 means dup2 (1, 2); */
if (dup2 (redir_fd, redirector) < 0)
else if (dup2 (redir_fd, redirector) < 0)
return (errno);
#if defined (BUFFERED_INPUT)
@@ -987,6 +1039,13 @@ do_redirection_internal (redirect, flags)
case r_close_this:
if (flags & RX_ACTIVE)
{
if (redirect->rflags & REDIR_VARASSIGN)
{
redirector = redir_varvalue (redirect);
if (redirector < 0)
return AMBIGUOUS_REDIRECT;
}
if ((flags & RX_UNDOABLE) && (fcntl (redirector, F_GETFD, 0) != -1))
add_undo_redirect (redirector, ri, -1);
@@ -1170,6 +1229,49 @@ stdin_redirects (redirs)
int n;
for (n = 0, rp = redirs; rp; rp = rp->next)
n += stdin_redirection (rp->instruction, rp->redirector.dest);
if ((rp->rflags & REDIR_VARASSIGN) == 0)
n += stdin_redirection (rp->instruction, rp->redirector.dest);
return n;
}
/* These don't yet handle array references */
static int
redir_varassign (redir, fd)
REDIRECT *redir;
int fd;
{
WORD_DESC *w;
SHELL_VAR *v;
w = redir->redirector.filename;
v = bind_var_to_int (w->word, fd);
if (v == 0 || readonly_p (v) || noassign_p (v))
return BADVAR_REDIRECT;
return 0;
}
static int
redir_varvalue (redir)
REDIRECT *redir;
{
SHELL_VAR *v;
char *val;
intmax_t vmax;
int i;
/* XXX - handle set -u here? */
v = find_variable (redir->redirector.filename->word);
if (v == 0 || invisible_p (v))
return -1;
val = get_variable_value (v);
if (val == 0 || *val == 0)
return -1;
if (legal_number (val, &vmax) < 0)
return -1;
i = vmax; /* integer truncation */
return i;
}
+13 -7
View File
@@ -1625,7 +1625,7 @@ skip_to_delim (string, start, delims, flags)
char *delims;
int flags;
{
int i, pass_next, backq, si, c, invert;
int i, pass_next, backq, si, c, invert, skipquote;
size_t slen;
char *temp;
DECLARE_MBSTATE;
@@ -1639,6 +1639,11 @@ skip_to_delim (string, start, delims, flags)
pass_next = backq = 0;
while (c = string[i])
{
/* If this is non-zero, we should not let quote characters be delimiters
and the current character is a single or double quote. We should not
test whether or not it's a delimiter until after we skip single- or
double-quoted strings. */
skipquote = ((flags & SD_NOQUOTEDELIM) && (c == '\'' || c =='"'));
if (pass_next)
{
pass_next = 0;
@@ -1666,7 +1671,7 @@ skip_to_delim (string, start, delims, flags)
i++;
continue;
}
else if (invert == 0 && member (c, delims))
else if (skipquote == 0 && invert == 0 && member (c, delims))
break;
else if (c == '\'' || c == '"')
{
@@ -1690,7 +1695,7 @@ skip_to_delim (string, start, delims, flags)
i++;
continue;
}
else if (invert && (member (c, delims) == 0))
else if ((skipquote || invert) && (member (c, delims) == 0))
break;
else
ADVANCE_CHAR (string, slen, i);
@@ -1808,14 +1813,14 @@ unclosed_pair (string, eindex, openstr)
the index of the word containing SENTINEL. Non-whitespace chars in
DELIMS delimit separate fields. */
WORD_LIST *
split_at_delims (string, slen, delims, sentinel, nwp, cwp)
split_at_delims (string, slen, delims, sentinel, flags, nwp, cwp)
char *string;
int slen;
char *delims;
int sentinel;
int sentinel, flags;
int *nwp, *cwp;
{
int ts, te, i, nw, cw, ifs_split;
int ts, te, i, nw, cw, ifs_split, dflags;
char *token, *d, *d2;
WORD_LIST *ret, *tl;
@@ -1882,9 +1887,10 @@ split_at_delims (string, slen, delims, sentinel, nwp, cwp)
ts = i;
nw = 0;
cw = -1;
dflags = flags|SD_NOJMP;
while (1)
{
te = skip_to_delim (string, ts, d, SD_NOJMP);
te = skip_to_delim (string, ts, d, dflags);
/* If we have a non-whitespace delimiter character, use it to make a
separate field. This is just about what $IFS splitting does and
+9 -8
View File
@@ -1625,7 +1625,7 @@ skip_to_delim (string, start, delims, flags)
char *delims;
int flags;
{
int i, pass_next, backq, si, c, invert;
int i, pass_next, backq, si, c, invert, skipquote;
size_t slen;
char *temp;
DECLARE_MBSTATE;
@@ -1639,6 +1639,7 @@ skip_to_delim (string, start, delims, flags)
pass_next = backq = 0;
while (c = string[i])
{
skipquote = ((flags & SD_NOQUOTEDELIM) && (c == '\'' || c =='"'));
if (pass_next)
{
pass_next = 0;
@@ -1666,7 +1667,7 @@ skip_to_delim (string, start, delims, flags)
i++;
continue;
}
else if (invert == 0 && member (c, delims))
else if (skipquote == 0 && invert == 0 && member (c, delims))
break;
else if (c == '\'' || c == '"')
{
@@ -1690,7 +1691,7 @@ skip_to_delim (string, start, delims, flags)
i++;
continue;
}
else if (invert && (member (c, delims) == 0))
else if ((skipquote || invert) && (member (c, delims) == 0))
break;
else
ADVANCE_CHAR (string, slen, i);
@@ -1808,14 +1809,14 @@ unclosed_pair (string, eindex, openstr)
the index of the word containing SENTINEL. Non-whitespace chars in
DELIMS delimit separate fields. */
WORD_LIST *
split_at_delims (string, slen, delims, sentinel, nwp, cwp)
split_at_delims (string, slen, delims, sentinel, flags, nwp, cwp)
char *string;
int slen;
char *delims;
int sentinel;
int sentinel, flags;
int *nwp, *cwp;
{
int ts, te, i, nw, cw, ifs_split;
int ts, te, i, nw, cw, ifs_split, dflags;
char *token, *d, *d2;
WORD_LIST *ret, *tl;
@@ -1882,9 +1883,10 @@ split_at_delims (string, slen, delims, sentinel, nwp, cwp)
ts = i;
nw = 0;
cw = -1;
dflags = flags|SD_NOJMP;
while (1)
{
te = skip_to_delim (string, ts, d, SD_NOJMP);
te = skip_to_delim (string, ts, d, dflags);
/* If we have a non-whitespace delimiter character, use it to make a
separate field. This is just about what $IFS splitting does and
@@ -2662,7 +2664,6 @@ do_assignment_internal (word, expand)
}
else
#endif
if (expand && temp[0])
value = expand_string_if_necessary (temp, 0, expand_string_assignment);
else
+2 -1
View File
@@ -266,13 +266,14 @@ extern char *cond_expand_word __P((WORD_DESC *, int));
/* Flags for skip_to_delim */
#define SD_NOJMP 0x01 /* don't longjmp on fatal error. */
#define SD_INVERT 0x02 /* look for chars NOT in passed set */
#define SD_NOQUOTEDELIM 0x04 /* don't let single or double quotes act as delimiters */
extern int skip_to_delim __P((char *, int, char *, int));
#if defined (READLINE)
extern int char_is_quoted __P((char *, int));
extern int unclosed_pair __P((char *, int, char *));
extern WORD_LIST *split_at_delims __P((char *, int, char *, int, int *, int *));
extern WORD_LIST *split_at_delims __P((char *, int, char *, int, int, int *, int *));
#endif
/* Variables used to keep track of the characters in IFS. */
+299
View File
@@ -0,0 +1,299 @@
/* subst.h -- Names of externally visible functions in subst.c. */
/* Copyright (C) 1993-2009 Free Software Foundation, Inc.
This file is part of GNU Bash, the Bourne Again SHell.
Bash 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.
Bash 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 Bash. If not, see <http://www.gnu.org/licenses/>.
*/
#if !defined (_SUBST_H_)
#define _SUBST_H_
#include "stdc.h"
/* Constants which specify how to handle backslashes and quoting in
expand_word_internal (). Q_DOUBLE_QUOTES means to use the function
slashify_in_quotes () to decide whether the backslash should be
retained. Q_HERE_DOCUMENT means slashify_in_here_document () to
decide whether to retain the backslash. Q_KEEP_BACKSLASH means
to unconditionally retain the backslash. Q_PATQUOTE means that we're
expanding a pattern ${var%#[#%]pattern} in an expansion surrounded
by double quotes. */
#define Q_DOUBLE_QUOTES 0x01
#define Q_HERE_DOCUMENT 0x02
#define Q_KEEP_BACKSLASH 0x04
#define Q_PATQUOTE 0x08
#define Q_QUOTED 0x10
#define Q_ADDEDQUOTES 0x20
#define Q_QUOTEDNULL 0x40
/* Flag values controlling how assignment statements are treated. */
#define ASS_APPEND 0x01
#define ASS_MKLOCAL 0x02
#define ASS_MKASSOC 0x04
/* Flags for the string extraction functions. */
#define SX_NOALLOC 0x01 /* just skip; don't return substring */
#define SX_VARNAME 0x02 /* variable name; for string_extract () */
#define SX_REQMATCH 0x04 /* closing/matching delimiter required */
#define SX_COMMAND 0x08 /* extracting a shell script/command */
#define SX_NOCTLESC 0x10 /* don't honor CTLESC quoting */
#define SX_NOESCCTLNUL 0x20 /* don't let CTLESC quote CTLNUL */
#define SX_NOLONGJMP 0x40 /* don't longjmp on fatal error */
/* Remove backslashes which are quoting backquotes from STRING. Modifies
STRING, and returns a pointer to it. */
extern char * de_backslash __P((char *));
/* Replace instances of \! in a string with !. */
extern void unquote_bang __P((char *));
/* Extract the $( construct in STRING, and return a new string.
Start extracting at (SINDEX) as if we had just seen "$(".
Make (SINDEX) get the position just after the matching ")".
XFLAGS is additional flags to pass to other extraction functions, */
extern char *extract_command_subst __P((char *, int *, int));
/* Extract the $[ construct in STRING, and return a new string.
Start extracting at (SINDEX) as if we had just seen "$[".
Make (SINDEX) get the position just after the matching "]". */
extern char *extract_arithmetic_subst __P((char *, int *));
#if defined (PROCESS_SUBSTITUTION)
/* Extract the <( or >( construct in STRING, and return a new string.
Start extracting at (SINDEX) as if we had just seen "<(".
Make (SINDEX) get the position just after the matching ")". */
extern char *extract_process_subst __P((char *, char *, int *));
#endif /* PROCESS_SUBSTITUTION */
/* Extract the name of the variable to bind to from the assignment string. */
extern char *assignment_name __P((char *));
/* Return a single string of all the words present in LIST, separating
each word with SEP. */
extern char *string_list_internal __P((WORD_LIST *, char *));
/* Return a single string of all the words present in LIST, separating
each word with a space. */
extern char *string_list __P((WORD_LIST *));
/* Turn $* into a single string, obeying POSIX rules. */
extern char *string_list_dollar_star __P((WORD_LIST *));
/* Expand $@ into a single string, obeying POSIX rules. */
extern char *string_list_dollar_at __P((WORD_LIST *, int));
/* Turn the positional paramters into a string, understanding quoting and
the various subtleties of using the first character of $IFS as the
separator. Calls string_list_dollar_at, string_list_dollar_star, and
string_list as appropriate. */
extern char *string_list_pos_params __P((int, WORD_LIST *, int));
/* Perform quoted null character removal on each element of LIST.
This modifies LIST. */
extern void word_list_remove_quoted_nulls __P((WORD_LIST *));
/* This performs word splitting and quoted null character removal on
STRING. */
extern WORD_LIST *list_string __P((char *, char *, int));
extern char *ifs_firstchar __P((int *));
extern char *get_word_from_string __P((char **, char *, char **));
extern char *strip_trailing_ifs_whitespace __P((char *, char *, int));
/* Given STRING, an assignment string, get the value of the right side
of the `=', and bind it to the left side. If EXPAND is true, then
perform tilde expansion, parameter expansion, command substitution,
and arithmetic expansion on the right-hand side. Do not perform word
splitting on the result of expansion. */
extern int do_assignment __P((char *));
extern int do_assignment_no_expand __P((char *));
extern int do_word_assignment __P((WORD_DESC *));
/* Append SOURCE to TARGET at INDEX. SIZE is the current amount
of space allocated to TARGET. SOURCE can be NULL, in which
case nothing happens. Gets rid of SOURCE by free ()ing it.
Returns TARGET in case the location has changed. */
extern char *sub_append_string __P((char *, char *, int *, int *));
/* Append the textual representation of NUMBER to TARGET.
INDEX and SIZE are as in SUB_APPEND_STRING. */
extern char *sub_append_number __P((intmax_t, char *, int *, int *));
/* Return the word list that corresponds to `$*'. */
extern WORD_LIST *list_rest_of_args __P((void));
/* Make a single large string out of the dollar digit variables,
and the rest_of_args. If DOLLAR_STAR is 1, then obey the special
case of "$*" with respect to IFS. */
extern char *string_rest_of_args __P((int));
extern int number_of_args __P((void));
/* Expand STRING by performing parameter expansion, command substitution,
and arithmetic expansion. Dequote the resulting WORD_LIST before
returning it, but do not perform word splitting. The call to
remove_quoted_nulls () is made here because word splitting normally
takes care of quote removal. */
extern WORD_LIST *expand_string_unsplit __P((char *, int));
/* Expand the rhs of an assignment statement. */
extern WORD_LIST *expand_string_assignment __P((char *, int));
/* Expand a prompt string. */
extern WORD_LIST *expand_prompt_string __P((char *, int, int));
/* Expand STRING just as if you were expanding a word. This also returns
a list of words. Note that filename globbing is *NOT* done for word
or string expansion, just when the shell is expanding a command. This
does parameter expansion, command substitution, arithmetic expansion,
and word splitting. Dequote the resultant WORD_LIST before returning. */
extern WORD_LIST *expand_string __P((char *, int));
/* Convenience functions that expand strings to strings, taking care of
converting the WORD_LIST * returned by the expand_string* functions
to a string and deallocating the WORD_LIST *. */
extern char *expand_string_to_string __P((char *, int));
extern char *expand_string_unsplit_to_string __P((char *, int));
extern char *expand_assignment_string_to_string __P((char *, int));
/* Expand an arithmetic expression string */
extern char *expand_arith_string __P((char *, int));
/* De-quote quoted characters in STRING. */
extern char *dequote_string __P((char *));
/* De-quote CTLESC-escaped CTLESC or CTLNUL characters in STRING. */
extern char *dequote_escapes __P((char *));
/* De-quote quoted characters in each word in LIST. */
extern WORD_LIST *dequote_list __P((WORD_LIST *));
/* Expand WORD, performing word splitting on the result. This does
parameter expansion, command substitution, arithmetic expansion,
word splitting, and quote removal. */
extern WORD_LIST *expand_word __P((WORD_DESC *, int));
/* Expand WORD, but do not perform word splitting on the result. This
does parameter expansion, command substitution, arithmetic expansion,
and quote removal. */
extern WORD_LIST *expand_word_unsplit __P((WORD_DESC *, int));
extern WORD_LIST *expand_word_leave_quoted __P((WORD_DESC *, int));
/* Return the value of a positional parameter. This handles values > 10. */
extern char *get_dollar_var_value __P((intmax_t));
/* Quote a string to protect it from word splitting. */
extern char *quote_string __P((char *));
/* Quote escape characters (characters special to interals of expansion)
in a string. */
extern char *quote_escapes __P((char *));
/* And remove such quoted special characters. */
extern char *remove_quoted_escapes __P((char *));
/* Remove CTLNUL characters from STRING unless they are quoted with CTLESC. */
extern char *remove_quoted_nulls __P((char *));
/* Perform quote removal on STRING. If QUOTED > 0, assume we are obeying the
backslash quoting rules for within double quotes. */
extern char *string_quote_removal __P((char *, int));
/* Perform quote removal on word WORD. This allocates and returns a new
WORD_DESC *. */
extern WORD_DESC *word_quote_removal __P((WORD_DESC *, int));
/* Perform quote removal on all words in LIST. If QUOTED is non-zero,
the members of the list are treated as if they are surrounded by
double quotes. Return a new list, or NULL if LIST is NULL. */
extern WORD_LIST *word_list_quote_removal __P((WORD_LIST *, int));
/* Called when IFS is changed to maintain some private variables. */
extern void setifs __P((SHELL_VAR *));
/* Return the value of $IFS, or " \t\n" if IFS is unset. */
extern char *getifs __P((void));
/* This splits a single word into a WORD LIST on $IFS, but only if the word
is not quoted. list_string () performs quote removal for us, even if we
don't do any splitting. */
extern WORD_LIST *word_split __P((WORD_DESC *, char *));
/* Take the list of words in LIST and do the various substitutions. Return
a new list of words which is the expanded list, and without things like
variable assignments. */
extern WORD_LIST *expand_words __P((WORD_LIST *));
/* Same as expand_words (), but doesn't hack variable or environment
variables. */
extern WORD_LIST *expand_words_no_vars __P((WORD_LIST *));
/* Perform the `normal shell expansions' on a WORD_LIST. These are
brace expansion, tilde expansion, parameter and variable substitution,
command substitution, arithmetic expansion, and word splitting. */
extern WORD_LIST *expand_words_shellexp __P((WORD_LIST *));
extern WORD_DESC *command_substitute __P((char *, int));
extern char *pat_subst __P((char *, char *, char *, int));
extern int fifos_pending __P((void));
extern void unlink_fifo_list __P((void));
extern WORD_LIST *list_string_with_quotes __P((char *));
#if defined (ARRAY_VARS)
extern char *extract_array_assignment_list __P((char *, int *));
#endif
#if defined (COND_COMMAND)
extern char *remove_backslashes __P((char *));
extern char *cond_expand_word __P((WORD_DESC *, int));
#endif
/* Flags for skip_to_delim */
#define SD_NOJMP 0x01 /* don't longjmp on fatal error. */
#define SD_INVERT 0x02 /* look for chars NOT in passed set */
extern int skip_to_delim __P((char *, int, char *, int));
#if defined (READLINE)
extern int char_is_quoted __P((char *, int));
extern int unclosed_pair __P((char *, int, char *));
extern WORD_LIST *split_at_delims __P((char *, int, char *, int, int, int *, int *));
#endif
/* Variables used to keep track of the characters in IFS. */
extern SHELL_VAR *ifs_var;
extern char *ifs_value;
extern unsigned char ifs_cmap[];
#if defined (HANDLE_MULTIBYTE)
extern unsigned char ifs_firstc[];
extern size_t ifs_firstc_len;
#else
extern unsigned char ifs_firstc;
#endif
/* Evaluates to 1 if C is a character in $IFS. */
#define isifs(c) (ifs_cmap[(unsigned char)(c)] != 0)
/* How to determine the quoted state of the character C. */
#define QUOTED_CHAR(c) ((c) == CTLESC)
/* Is the first character of STRING a quoted NULL character? */
#define QUOTED_NULL(string) ((string)[0] == CTLNUL && (string)[1] == '\0')
#endif /* !_SUBST_H_ */
+9 -4
View File
@@ -65,8 +65,9 @@ extern int errno;
#endif
#if !defined (STREQ)
# define STREQ(a, b) ((a)[0] == (b)[0] && strcmp (a, b) == 0)
# define STREQ(a, b) ((a)[0] == (b)[0] && strcmp ((a), (b)) == 0)
#endif /* !STREQ */
#define STRCOLLEQ(a, b) ((a)[0] == (b)[0] && strcoll ((a), (b)) == 0)
#if !defined (R_OK)
#define R_OK 4
@@ -375,12 +376,16 @@ binary_test (op, arg1, arg2, flags)
if (op[0] == '=' && (op[1] == '\0' || (op[1] == '=' && op[2] == '\0')))
return (patmatch ? patcomp (arg1, arg2, EQ) : STREQ (arg1, arg2));
else if ((op[0] == '>' || op[0] == '<') && op[1] == '\0')
return ((op[0] == '>') ? (strcmp (arg1, arg2) > 0) : (strcmp (arg1, arg2) < 0));
{
if (flags & TEST_LOCALE)
return ((op[0] == '>') ? (strcoll (arg1, arg2) > 0) : (strcoll (arg1, arg2) < 0));
else
return ((op[0] == '>') ? (strcmp (arg1, arg2) > 0) : (strcmp (arg1, arg2) < 0));
}
else if (op[0] == '!' && op[1] == '=' && op[2] == '\0')
return (patmatch ? patcomp (arg1, arg2, NE) : (STREQ (arg1, arg2) == 0));
else if (op[2] == 't')
{
+825
View File
@@ -0,0 +1,825 @@
/* test.c - GNU test program (ksb and mjb) */
/* Modified to run with the GNU shell Apr 25, 1988 by bfox. */
/* Copyright (C) 1987-2009 Free Software Foundation, Inc.
This file is part of GNU Bash, the Bourne Again SHell.
Bash 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.
Bash 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 Bash. If not, see <http://www.gnu.org/licenses/>.
*/
/* Define PATTERN_MATCHING to get the csh-like =~ and !~ pattern-matching
binary operators. */
/* #define PATTERN_MATCHING */
#if defined (HAVE_CONFIG_H)
# include <config.h>
#endif
#include <stdio.h>
#include "bashtypes.h"
#if !defined (HAVE_LIMITS_H)
# include <sys/param.h>
#endif
#if defined (HAVE_UNISTD_H)
# include <unistd.h>
#endif
#include <errno.h>
#if !defined (errno)
extern int errno;
#endif /* !errno */
#if !defined (_POSIX_VERSION) && defined (HAVE_SYS_FILE_H)
# include <sys/file.h>
#endif /* !_POSIX_VERSION */
#include "posixstat.h"
#include "filecntl.h"
#include "bashintl.h"
#include "shell.h"
#include "pathexp.h"
#include "test.h"
#include "builtins/common.h"
#include <glob/strmatch.h>
#if !defined (STRLEN)
# define STRLEN(s) ((s)[0] ? ((s)[1] ? ((s)[2] ? strlen(s) : 2) : 1) : 0)
#endif
#if !defined (STREQ)
# define STREQ(a, b) ((a)[0] == (b)[0] && strcmp (a, b) == 0)
#endif /* !STREQ */
#if !defined (R_OK)
#define R_OK 4
#define W_OK 2
#define X_OK 1
#define F_OK 0
#endif /* R_OK */
#define EQ 0
#define NE 1
#define LT 2
#define GT 3
#define LE 4
#define GE 5
#define NT 0
#define OT 1
#define EF 2
/* The following few defines control the truth and false output of each stage.
TRUE and FALSE are what we use to compute the final output value.
SHELL_BOOLEAN is the form which returns truth or falseness in shell terms.
Default is TRUE = 1, FALSE = 0, SHELL_BOOLEAN = (!value). */
#define TRUE 1
#define FALSE 0
#define SHELL_BOOLEAN(value) (!(value))
#define TEST_ERREXIT_STATUS 2
static procenv_t test_exit_buf;
static int test_error_return;
#define test_exit(val) \
do { test_error_return = val; longjmp (test_exit_buf, 1); } while (0)
extern int sh_stat __P((const char *, struct stat *));
static int pos; /* The offset of the current argument in ARGV. */
static int argc; /* The number of arguments present in ARGV. */
static char **argv; /* The argument list. */
static int noeval;
static void test_syntax_error __P((char *, char *)) __attribute__((__noreturn__));
static void beyond __P((void)) __attribute__((__noreturn__));
static void integer_expected_error __P((char *)) __attribute__((__noreturn__));
static int unary_operator __P((void));
static int binary_operator __P((void));
static int two_arguments __P((void));
static int three_arguments __P((void));
static int posixtest __P((void));
static int expr __P((void));
static int term __P((void));
static int and __P((void));
static int or __P((void));
static int filecomp __P((char *, char *, int));
static int arithcomp __P((char *, char *, int, int));
static int patcomp __P((char *, char *, int));
static void
test_syntax_error (format, arg)
char *format, *arg;
{
builtin_error (format, arg);
test_exit (TEST_ERREXIT_STATUS);
}
/*
* beyond - call when we're beyond the end of the argument list (an
* error condition)
*/
static void
beyond ()
{
test_syntax_error (_("argument expected"), (char *)NULL);
}
/* Syntax error for when an integer argument was expected, but
something else was found. */
static void
integer_expected_error (pch)
char *pch;
{
test_syntax_error (_("%s: integer expression expected"), pch);
}
/* Increment our position in the argument list. Check that we're not
past the end of the argument list. This check is supressed if the
argument is FALSE. Made a macro for efficiency. */
#define advance(f) do { ++pos; if (f && pos >= argc) beyond (); } while (0)
#define unary_advance() do { advance (1); ++pos; } while (0)
/*
* expr:
* or
*/
static int
expr ()
{
if (pos >= argc)
beyond ();
return (FALSE ^ or ()); /* Same with this. */
}
/*
* or:
* and
* and '-o' or
*/
static int
or ()
{
int value, v2;
value = and ();
if (pos < argc && argv[pos][0] == '-' && argv[pos][1] == 'o' && !argv[pos][2])
{
advance (0);
v2 = or ();
return (value || v2);
}
return (value);
}
/*
* and:
* term
* term '-a' and
*/
static int
and ()
{
int value, v2;
value = term ();
if (pos < argc && argv[pos][0] == '-' && argv[pos][1] == 'a' && !argv[pos][2])
{
advance (0);
v2 = and ();
return (value && v2);
}
return (value);
}
/*
* term - parse a term and return 1 or 0 depending on whether the term
* evaluates to true or false, respectively.
*
* term ::=
* '-'('a'|'b'|'c'|'d'|'e'|'f'|'g'|'h'|'k'|'p'|'r'|'s'|'u'|'w'|'x') filename
* '-'('G'|'L'|'O'|'S'|'N') filename
* '-t' [int]
* '-'('z'|'n') string
* '-o' option
* string
* string ('!='|'='|'==') string
* <int> '-'(eq|ne|le|lt|ge|gt) <int>
* file '-'(nt|ot|ef) file
* '(' <expr> ')'
* int ::=
* positive and negative integers
*/
static int
term ()
{
int value;
if (pos >= argc)
beyond ();
/* Deal with leading `not's. */
if (argv[pos][0] == '!' && argv[pos][1] == '\0')
{
value = 0;
while (pos < argc && argv[pos][0] == '!' && argv[pos][1] == '\0')
{
advance (1);
value = 1 - value;
}
return (value ? !term() : term());
}
/* A paren-bracketed argument. */
if (argv[pos][0] == '(' && argv[pos][1] == '\0') /* ) */
{
advance (1);
value = expr ();
if (argv[pos] == 0) /* ( */
test_syntax_error (_("`)' expected"), (char *)NULL);
else if (argv[pos][0] != ')' || argv[pos][1]) /* ( */
test_syntax_error (_("`)' expected, found %s"), argv[pos]);
advance (0);
return (value);
}
/* are there enough arguments left that this could be dyadic? */
if ((pos + 3 <= argc) && test_binop (argv[pos + 1]))
value = binary_operator ();
/* Might be a switch type argument */
else if (argv[pos][0] == '-' && argv[pos][2] == '\0')
{
if (test_unop (argv[pos]))
value = unary_operator ();
else
test_syntax_error (_("%s: unary operator expected"), argv[pos]);
}
else
{
value = argv[pos][0] != '\0';
advance (0);
}
return (value);
}
static int
filecomp (s, t, op)
char *s, *t;
int op;
{
struct stat st1, st2;
int r1, r2;
if ((r1 = sh_stat (s, &st1)) < 0)
{
if (op == EF)
return (FALSE);
}
if ((r2 = sh_stat (t, &st2)) < 0)
{
if (op == EF)
return (FALSE);
}
switch (op)
{
case OT: return (r1 < r2 || (r2 == 0 && st1.st_mtime < st2.st_mtime));
case NT: return (r1 > r2 || (r1 == 0 && st1.st_mtime > st2.st_mtime));
case EF: return (same_file (s, t, &st1, &st2));
}
return (FALSE);
}
static int
arithcomp (s, t, op, flags)
char *s, *t;
int op, flags;
{
intmax_t l, r;
int expok;
if (flags & TEST_ARITHEXP)
{
l = evalexp (s, &expok);
if (expok == 0)
return (FALSE); /* should probably longjmp here */
r = evalexp (t, &expok);
if (expok == 0)
return (FALSE); /* ditto */
}
else
{
if (legal_number (s, &l) == 0)
integer_expected_error (s);
if (legal_number (t, &r) == 0)
integer_expected_error (t);
}
switch (op)
{
case EQ: return (l == r);
case NE: return (l != r);
case LT: return (l < r);
case GT: return (l > r);
case LE: return (l <= r);
case GE: return (l >= r);
}
return (FALSE);
}
static int
patcomp (string, pat, op)
char *string, *pat;
int op;
{
int m;
m = strmatch (pat, string, FNMATCH_EXTFLAG|FNMATCH_IGNCASE);
return ((op == EQ) ? (m == 0) : (m != 0));
}
int
binary_test (op, arg1, arg2, flags)
char *op, *arg1, *arg2;
int flags;
{
int patmatch;
patmatch = (flags & TEST_PATMATCH);
if (op[0] == '=' && (op[1] == '\0' || (op[1] == '=' && op[2] == '\0')))
return (patmatch ? patcomp (arg1, arg2, EQ) : STREQ (arg1, arg2));
else if ((op[0] == '>' || op[0] == '<') && op[1] == '\0')
return ((op[0] == '>') ? (strcmp (arg1, arg2) > 0) : (strcmp (arg1, arg2) < 0));
else if (op[0] == '!' && op[1] == '=' && op[2] == '\0')
return (patmatch ? patcomp (arg1, arg2, NE) : (STREQ (arg1, arg2) == 0));
else if (op[2] == 't')
{
switch (op[1])
{
case 'n': return (filecomp (arg1, arg2, NT)); /* -nt */
case 'o': return (filecomp (arg1, arg2, OT)); /* -ot */
case 'l': return (arithcomp (arg1, arg2, LT, flags)); /* -lt */
case 'g': return (arithcomp (arg1, arg2, GT, flags)); /* -gt */
}
}
else if (op[1] == 'e')
{
switch (op[2])
{
case 'f': return (filecomp (arg1, arg2, EF)); /* -ef */
case 'q': return (arithcomp (arg1, arg2, EQ, flags)); /* -eq */
}
}
else if (op[2] == 'e')
{
switch (op[1])
{
case 'n': return (arithcomp (arg1, arg2, NE, flags)); /* -ne */
case 'g': return (arithcomp (arg1, arg2, GE, flags)); /* -ge */
case 'l': return (arithcomp (arg1, arg2, LE, flags)); /* -le */
}
}
return (FALSE); /* should never get here */
}
static int
binary_operator ()
{
int value;
char *w;
w = argv[pos + 1];
if ((w[0] == '=' && (w[1] == '\0' || (w[1] == '=' && w[2] == '\0'))) || /* =, == */
((w[0] == '>' || w[0] == '<') && w[1] == '\0') || /* <, > */
(w[0] == '!' && w[1] == '=' && w[2] == '\0')) /* != */
{
value = binary_test (w, argv[pos], argv[pos + 2], 0);
pos += 3;
return (value);
}
#if defined (PATTERN_MATCHING)
if ((w[0] == '=' || w[0] == '!') && w[1] == '~' && w[2] == '\0')
{
value = patcomp (argv[pos], argv[pos + 2], w[0] == '=' ? EQ : NE);
pos += 3;
return (value);
}
#endif
if ((w[0] != '-' || w[3] != '\0') || test_binop (w) == 0)
{
test_syntax_error (_("%s: binary operator expected"), w);
/* NOTREACHED */
return (FALSE);
}
value = binary_test (w, argv[pos], argv[pos + 2], 0);
pos += 3;
return value;
}
static int
unary_operator ()
{
char *op;
intmax_t r;
op = argv[pos];
if (test_unop (op) == 0)
return (FALSE);
/* the only tricky case is `-t', which may or may not take an argument. */
if (op[1] == 't')
{
advance (0);
if (pos < argc)
{
if (legal_number (argv[pos], &r))
{
advance (0);
return (unary_test (op, argv[pos - 1]));
}
else
return (FALSE);
}
else
return (unary_test (op, "1"));
}
/* All of the unary operators take an argument, so we first call
unary_advance (), which checks to make sure that there is an
argument, and then advances pos right past it. This means that
pos - 1 is the location of the argument. */
unary_advance ();
return (unary_test (op, argv[pos - 1]));
}
int
unary_test (op, arg)
char *op, *arg;
{
intmax_t r;
struct stat stat_buf;
switch (op[1])
{
case 'a': /* file exists in the file system? */
case 'e':
return (sh_stat (arg, &stat_buf) == 0);
case 'r': /* file is readable? */
return (sh_eaccess (arg, R_OK) == 0);
case 'w': /* File is writeable? */
return (sh_eaccess (arg, W_OK) == 0);
case 'x': /* File is executable? */
return (sh_eaccess (arg, X_OK) == 0);
case 'O': /* File is owned by you? */
return (sh_stat (arg, &stat_buf) == 0 &&
(uid_t) current_user.euid == (uid_t) stat_buf.st_uid);
case 'G': /* File is owned by your group? */
return (sh_stat (arg, &stat_buf) == 0 &&
(gid_t) current_user.egid == (gid_t) stat_buf.st_gid);
case 'N':
return (sh_stat (arg, &stat_buf) == 0 &&
stat_buf.st_atime <= stat_buf.st_mtime);
case 'f': /* File is a file? */
if (sh_stat (arg, &stat_buf) < 0)
return (FALSE);
/* -f is true if the given file exists and is a regular file. */
#if defined (S_IFMT)
return (S_ISREG (stat_buf.st_mode) || (stat_buf.st_mode & S_IFMT) == 0);
#else
return (S_ISREG (stat_buf.st_mode));
#endif /* !S_IFMT */
case 'd': /* File is a directory? */
return (sh_stat (arg, &stat_buf) == 0 && (S_ISDIR (stat_buf.st_mode)));
case 's': /* File has something in it? */
return (sh_stat (arg, &stat_buf) == 0 && stat_buf.st_size > (off_t) 0);
case 'S': /* File is a socket? */
#if !defined (S_ISSOCK)
return (FALSE);
#else
return (sh_stat (arg, &stat_buf) == 0 && S_ISSOCK (stat_buf.st_mode));
#endif /* S_ISSOCK */
case 'c': /* File is character special? */
return (sh_stat (arg, &stat_buf) == 0 && S_ISCHR (stat_buf.st_mode));
case 'b': /* File is block special? */
return (sh_stat (arg, &stat_buf) == 0 && S_ISBLK (stat_buf.st_mode));
case 'p': /* File is a named pipe? */
#ifndef S_ISFIFO
return (FALSE);
#else
return (sh_stat (arg, &stat_buf) == 0 && S_ISFIFO (stat_buf.st_mode));
#endif /* S_ISFIFO */
case 'L': /* Same as -h */
case 'h': /* File is a symbolic link? */
#if !defined (S_ISLNK) || !defined (HAVE_LSTAT)
return (FALSE);
#else
return ((arg[0] != '\0') &&
(lstat (arg, &stat_buf) == 0) && S_ISLNK (stat_buf.st_mode));
#endif /* S_IFLNK && HAVE_LSTAT */
case 'u': /* File is setuid? */
return (sh_stat (arg, &stat_buf) == 0 && (stat_buf.st_mode & S_ISUID) != 0);
case 'g': /* File is setgid? */
return (sh_stat (arg, &stat_buf) == 0 && (stat_buf.st_mode & S_ISGID) != 0);
case 'k': /* File has sticky bit set? */
#if !defined (S_ISVTX)
/* This is not Posix, and is not defined on some Posix systems. */
return (FALSE);
#else
return (sh_stat (arg, &stat_buf) == 0 && (stat_buf.st_mode & S_ISVTX) != 0);
#endif
case 't': /* File fd is a terminal? */
if (legal_number (arg, &r) == 0)
return (FALSE);
return ((r == (int)r) && isatty ((int)r));
case 'n': /* True if arg has some length. */
return (arg[0] != '\0');
case 'z': /* True if arg has no length. */
return (arg[0] == '\0');
case 'o': /* True if option `arg' is set. */
return (minus_o_option_value (arg) == 1);
}
/* We can't actually get here, but this shuts up gcc. */
return (FALSE);
}
/* Return TRUE if OP is one of the test command's binary operators. */
int
test_binop (op)
char *op;
{
if (op[0] == '=' && op[1] == '\0')
return (1); /* '=' */
else if ((op[0] == '<' || op[0] == '>') && op[1] == '\0') /* string <, > */
return (1);
else if ((op[0] == '=' || op[0] == '!') && op[1] == '=' && op[2] == '\0')
return (1); /* `==' and `!=' */
#if defined (PATTERN_MATCHING)
else if (op[2] == '\0' && op[1] == '~' && (op[0] == '=' || op[0] == '!'))
return (1);
#endif
else if (op[0] != '-' || op[2] == '\0' || op[3] != '\0')
return (0);
else
{
if (op[2] == 't')
switch (op[1])
{
case 'n': /* -nt */
case 'o': /* -ot */
case 'l': /* -lt */
case 'g': /* -gt */
return (1);
default:
return (0);
}
else if (op[1] == 'e')
switch (op[2])
{
case 'q': /* -eq */
case 'f': /* -ef */
return (1);
default:
return (0);
}
else if (op[2] == 'e')
switch (op[1])
{
case 'n': /* -ne */
case 'g': /* -ge */
case 'l': /* -le */
return (1);
default:
return (0);
}
else
return (0);
}
}
/* Return non-zero if OP is one of the test command's unary operators. */
int
test_unop (op)
char *op;
{
if (op[0] != '-' || op[2] != 0)
return (0);
switch (op[1])
{
case 'a': case 'b': case 'c': case 'd': case 'e':
case 'f': case 'g': case 'h': case 'k': case 'n':
case 'o': case 'p': case 'r': case 's': case 't':
case 'u': case 'w': case 'x': case 'z':
case 'G': case 'L': case 'O': case 'S': case 'N':
return (1);
}
return (0);
}
static int
two_arguments ()
{
if (argv[pos][0] == '!' && argv[pos][1] == '\0')
return (argv[pos + 1][0] == '\0');
else if (argv[pos][0] == '-' && argv[pos][2] == '\0')
{
if (test_unop (argv[pos]))
return (unary_operator ());
else
test_syntax_error (_("%s: unary operator expected"), argv[pos]);
}
else
test_syntax_error (_("%s: unary operator expected"), argv[pos]);
return (0);
}
#define ANDOR(s) (s[0] == '-' && !s[2] && (s[1] == 'a' || s[1] == 'o'))
/* This could be augmented to handle `-t' as equivalent to `-t 1', but
POSIX requires that `-t' be given an argument. */
#define ONE_ARG_TEST(s) ((s)[0] != '\0')
static int
three_arguments ()
{
int value;
if (test_binop (argv[pos+1]))
{
value = binary_operator ();
pos = argc;
}
else if (ANDOR (argv[pos+1]))
{
if (argv[pos+1][1] == 'a')
value = ONE_ARG_TEST(argv[pos]) && ONE_ARG_TEST(argv[pos+2]);
else
value = ONE_ARG_TEST(argv[pos]) || ONE_ARG_TEST(argv[pos+2]);
pos = argc;
}
else if (argv[pos][0] == '!' && argv[pos][1] == '\0')
{
advance (1);
value = !two_arguments ();
}
else if (argv[pos][0] == '(' && argv[pos+2][0] == ')')
{
value = ONE_ARG_TEST(argv[pos+1]);
pos = argc;
}
else
test_syntax_error (_("%s: binary operator expected"), argv[pos+1]);
return (value);
}
/* This is an implementation of a Posix.2 proposal by David Korn. */
static int
posixtest ()
{
int value;
switch (argc - 1) /* one extra passed in */
{
case 0:
value = FALSE;
pos = argc;
break;
case 1:
value = ONE_ARG_TEST(argv[1]);
pos = argc;
break;
case 2:
value = two_arguments ();
pos = argc;
break;
case 3:
value = three_arguments ();
break;
case 4:
if (argv[pos][0] == '!' && argv[pos][1] == '\0')
{
advance (1);
value = !three_arguments ();
break;
}
/* FALLTHROUGH */
default:
value = expr ();
}
return (value);
}
/*
* [:
* '[' expr ']'
* test:
* test expr
*/
int
test_command (margc, margv)
int margc;
char **margv;
{
int value;
int code;
USE_VAR(margc);
code = setjmp (test_exit_buf);
if (code)
return (test_error_return);
argv = margv;
if (margv[0] && margv[0][0] == '[' && margv[0][1] == '\0')
{
--margc;
if (margv[margc] && (margv[margc][0] != ']' || margv[margc][1]))
test_syntax_error (_("missing `]'"), (char *)NULL);
if (margc < 2)
test_exit (SHELL_BOOLEAN (FALSE));
}
argc = margc;
pos = 1;
if (pos >= argc)
test_exit (SHELL_BOOLEAN (FALSE));
noeval = 0;
value = posixtest ();
if (pos != argc)
test_syntax_error (_("too many arguments"), (char *)NULL);
test_exit (SHELL_BOOLEAN (value));
}
+1
View File
@@ -26,6 +26,7 @@
/* Values for the flags argument to binary_test */
#define TEST_PATMATCH 0x01
#define TEST_ARITHEXP 0x02
#define TEST_LOCALE 0x04
extern int test_unop __P((char *));
extern int test_binop __P((char *));
+38
View File
@@ -0,0 +1,38 @@
/* test.h -- external interface to the conditional command code. */
/* Copyright (C) 1997-2009 Free Software Foundation, Inc.
This file is part of GNU Bash, the Bourne Again SHell.
Bash 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.
Bash 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 Bash. If not, see <http://www.gnu.org/licenses/>.
*/
#ifndef _TEST_H_
#define _TEST_H_
#include "stdc.h"
/* Values for the flags argument to binary_test */
#define TEST_PATMATCH 0x01
#define TEST_ARITHEXP 0x02
extern int test_unop __P((char *));
extern int test_binop __P((char *));
extern int unary_test __P((char *, char *));
extern int binary_test __P((char *, char *, char *, int));
extern int test_command __P((int, char **));
#endif /* _TEST_H_ */
+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
+3
View File
@@ -150,3 +150,6 @@ getenv.o
input_avail.o
itos.o
alias.o builtins builtins/history.o builtins/jobs.o builtins/kill.o builtins/let.o builtins/mapfile.o lib lib/glob lib/glob/glob.o lib/glob/smatch.o lib/glob/strmatch.o lib/readline lib/readline/bind.o lib/readline/callback.o lib/readline/compat.o lib/readline/complete.o lib/readline/display.o lib/sh lib/sh/casemod.o lib/sh/clktck.o lib/sh/clock.o lib/sh/eaccess.o lib/sh/fdprintf.o lib/sh/fmtullong.o lib/sh/fmtulong.o lib/sh/fmtumax.o lib/sh/fpurge.o lib/sh/getenv.o lib/sh/input_avail.o lib/sh/itos.o pcomplib.o print_cmd.o redir.o shell.o sig.o stringlib.o subst.o syntax.o test.o trap.o unwind_prot.o variables.o version.o xmalloc.o y.tab.o
bar/foo foo
bar/foo/ foo/
bar/foo/e bar/foo/f foo/a foo/b
+2
View File
@@ -37,3 +37,5 @@ echo **
cd $dir
rm -rf $GDIR
${THIS_SH} ./globstar1.sub
+39
View File
@@ -0,0 +1,39 @@
: ${TMPDIR:=/var/tmp}
dir=$PWD
shopt -s globstar
export LANG=C LC_ALL=C LC_COLLATE=C
GDIR=$TMPDIR/globstar-$$
mkdir $GDIR || exit 1
cd $GDIR || exit 1
mkdir lib builtins
mkdir lib/glob lib/readline lib/sh
touch builtins/history.o builtins/jobs.o builtins/kill.o builtins/let.o builtins/mapfile.o
touch lib/glob/glob.o lib/glob/smatch.o lib/glob/strmatch.o
touch lib/readline/bind.o lib/readline/callback.o lib/readline/compat.o lib/readline/complete.o lib/readline/display.o
touch lib/sh/casemod.o lib/sh/clktck.o lib/sh/clock.o lib/sh/eaccess.o
touch lib/sh/fdprintf.o lib/sh/fmtullong.o lib/sh/fmtulong.o lib/sh/fmtumax.o
touch lib/sh/fpurge.o lib/sh/getenv.o lib/sh/input_avail.o lib/sh/itos.o
touch alias.o
touch pcomplib.o print_cmd.o redir.o shell.o sig.o stringlib.o subst.o syntax.o
touch test.o trap.o unwind_prot.o variables.o version.o xmalloc.o y.tab.o
ls lib/**
ls lib/**/*.o
echo **/*.o
ls **
echo **
cd $dir
rm -rf $GDIR
+21
View File
@@ -0,0 +1,21 @@
shopt -s globstar
wdir=$PWD
: ${TMPDIR:=/var/tmp}
DIR=$TMPDIR/globstar-$$
mkdir -p $DIR
cd $DIR || {
echo "$DIR: cannot cd" >&2
exit 1
}
mkdir -p foo/{a,b} bar/{c,d,foo/{e,f}} baz/{g,h}
echo **/foo*
echo **/foo*/
echo **/foo*/*
cd $wdir
rm -rf $DIR
+2
View File
@@ -0,0 +1,2 @@
${THIS_SH} ./vredir.tests > /tmp/xx 2>&1
diff /tmp/xx vredir.right && rm -f /tmp/xx
+88
View File
@@ -0,0 +1,88 @@
10
foo 1
foo 2
foo 3
bar is a function
bar ()
{
exec {v}> $TMPFILE;
echo $v
}
./vredir.tests: line 6: v: readonly variable
./vredir.tests: line 6: v: cannot assign fd to variable
42
./vredir.tests: line 25: $v: Bad file descriptor
./vredir.tests: line 26: $v: Bad file descriptor
./vredir.tests: line 27: $v: Bad file descriptor
bar is a function
bar ()
{
exec {v}> $TMPFILE;
echo $v
}
11
line 1
line 2
line 3
bar is a function
bar ()
{
exec {v}<<EOF
line 1
line 2
line 3
EOF
echo $v
}
11
foo 1
foo 2
foo 3
11
/bin/bash
/bin/csh
/bin/ksh
/bin/sh
/bin/tcsh
/bin/zsh
oclosev is a function
oclosev ()
{
exec {v}>&-
}
iclosev is a function
iclosev ()
{
exec {v}>&-
}
/bin/bash
/bin/csh
/bin/ksh
/bin/sh
/bin/tcsh
/bin/zsh
./vredir3.sub: line 4: v: ambiguous redirect
after
11 12
a
a
swizzle is a function
swizzle ()
{
fd0=0;
fd1=1;
exec {stdin}<&$fd0;
exec {stdout}>&$fd1
}
13 11
a
a
swizzle is a function
swizzle ()
{
exec {fd0}<&0;
exec {fd1}>&1;
exec {stdin}<&$fd0-;
exec {stdout}>&$fd1-
}
+44
View File
@@ -0,0 +1,44 @@
: ${TMPDIR:=/var/tmp}
TMPFILE=$TMPDIR/foo
bar()
{
exec {v}>$TMPFILE
echo $v
}
bar
echo foo 1 >&$v
echo foo 2 >&$v
echo foo 3 >&$v
cat $TMPFILE
rm -f $TMPFILE
type bar
exec {v}>&-
readonly v=42
bar
echo foo 1 >&$v
echo foo 2 >&$v
echo foo 3 >&$v
cat $TMPFILE
rm -f $TMPFILE
type bar
${THIS_SH} ./vredir1.sub
${THIS_SH} ./vredir2.sub
${THIS_SH} ./vredir3.sub
${THIS_SH} ./vredir4.sub
${THIS_SH} ./vredir5.sub
exit 0
+17
View File
@@ -0,0 +1,17 @@
bar()
{
exec {v}<<EOF
line 1
line 2
line 3
EOF
echo $v
}
bar
cat <&$v
type bar
exit 0
+52
View File
@@ -0,0 +1,52 @@
: ${TMPDIR:=/var/tmp}
SHELLSFILE=$TMPDIR/shells-$$
cat > $TMPDIR/shells-$$ <<EOF
/bin/bash
/bin/csh
/bin/ksh
/bin/sh
/bin/tcsh
/bin/zsh
EOF
oclosev()
{
exec {v}>&-
}
iclosev()
{
exec {v}<&-
}
exec {v}>&1
echo $v
echo foo 1 >&$v
echo foo 2 >&$v
echo foo 3 >&$v
oclosev
exec {v}<$SHELLSFILE
echo $v
while read line <&$v
do
echo $line
done
iclosev
type oclosev
type iclosev
while read -r -u ${fd}
do
echo $REPLY
done {fd}<$SHELLSFILE
rm -f $SHELLSFILE
exit 0
+52
View File
@@ -0,0 +1,52 @@
: ${TMPDIR:=/var/tmp}
SHELLSFILE=$TMPDIR/shells-$$
cat > $TMPDIR/shells-$$ <<EOF
/bin/bash
/bin/csh
/bin/ksh
/bin/sh
/bin/tcsh
/bin/zsh
EOF
oclosev()
{
exec {v}>&-
}
iclosev()
{
exec {v}<&-
}
exec {v}>&1
echo $v
echo foo 1 >&$v
echo foo 2 >&$v
echo foo 3 >&$v
oclosev
exec {v}<$SHELLSFILE
echo $v
while read line <&$v
do
echo $line
done
iclosev
type oclosev
type iclosev
while read -r -u ${fd}
do
echo $REPLY
done {fd}<$SHELLSFILE
rm -f $SHELLSFILE
exit 0
+8
View File
@@ -0,0 +1,8 @@
# Right now, the {varname} mechanism does not honor set -u for compatibility
unset v
set -u
exec {v}>&-
echo after
exit 0
+22
View File
@@ -0,0 +1,22 @@
swizzle()
{
fd0=0
fd1=1
exec {stdin}<&$fd0
exec {stdout}>&$fd1
}
swizzle
echo $stdin $stdout
read line <&$stdin <<EOF
a
EOF
echo $line
echo $line >&$stdout
type swizzle
exit 0
+23
View File
@@ -0,0 +1,23 @@
swizzle()
{
exec {fd0}<&0
exec {fd1}>&1
exec {stdin}<&$fd0-
exec {stdout}>&$fd1-
}
swizzle
echo $stdin $stdout
read line <&$stdin <<EOF
a
EOF
echo $line
echo $line >&$stdout
type swizzle
exit 0