- _rl_isearch_dispatch: when adding character to search string, use
cxt->lastc (which we use in the switch statement) instead of c,
since lastc can be modified earlier in the function
+
+ 7/18
+ ----
+lib/readline/rlprivate.h
+ - _rl_search_context: add another member to save previous value of
+ (multibyte) lastc: pmb is to mb as prevc is to lastc
+
+lib/readline/isearch.c:
+ - _rl_isearch_dispatch: if a key sequence indexes into a new keymap,
+ but doesn't find any bound function (k[ind].function == 0) or is
+ bound to self-insert (k[ind].function == rl_insert), back up and
+ insert the previous character (the one that caused the index into a
+ new keymap) and arrange things so the current character is the next
+ one read, so both of them end up in the search string. Fixes bug
+ reported by Clark Wang <dearvoid@gmail.com>
+ - _rl_isearch_dispatch: a couple of efficiency improvements when adding
+ characters to the isearch string
+
+ 7/24
+ ----
+lib/readline/isearch.c
+ - _rl_isearch_dispatch: save and restore cxt->mb and cxt->pmb
+ appropriately when in a multibyte locale
+
+doc/{bash.1,bashref.texi}
+ - correct description of {x}>file (and other redirection operators
+ that allocate a file descriptor) to note the the fd range is
+ greater than or equal to 10. Fixes problem reported by
+ Christian Ullrich
+
+lib/readline/signals.c
+ - rl_signal_handler: don't interrupt immediately if in callback mode
+
+lib/readline/callback.c
+ - rl_callback_read_char: install signal handlers only when readline
+ has control in callback mode, so readline's signal handlers aren't
+ called when the application is active (e.g., between the calls to
+ rl_callback_handler_install and rl_callback_read_char). If the
+ readline signal handlers only set a flag, which the application
+ doesn't know about, the signals will effectively be ignored until
+ the next time the application calls into the readline callback
+ interface. Fixes problem of calling unsafe functions from signal
+ handlers when in callback mode reported by Jan Kratochvil
+ <jan.kratochvil@redhat.com>
+
+execute_cmd.c
+ - fix_assignment_words: when in Posix mode, the `command' builtin
+ doesn't change whether or not the command name it protects is an
+ assignment builtin. One or more instances of `command'
+ preceding `export', for instance, doesn't make `export' treat its
+ assignment statement arguments differently. Posix interpretation
+ #351
+
+doc/{bash.1,bashref.texi}
+ - document new Posix-mode behavior of `command' when preceding builtins
+ that take assignment statements as arguments
+
+builtins/printf.def
+ - printstr: if fieldwidth or precision are < 0 or > INT_MAX when
+ supplied explicitly (since we take care of the `-' separately),
+ clamp at INT_MAX like when using getint(). Fixes issue reported
+ by Ralph Coredroy <ralph@inputplus.co.uk>
+
+ 7/25
+ ----
+lib/readline/chardefs.h
+ - isxdigit: don't define if compiling with c++; declared as a c++
+ template function. Fixes bug reported by Miroslav Lichvar
+ <mlichvar@redhat.com>
+
+builtins/printf.def
+ - getint: if garglist == 0, return whatever getintmax returns (0).
+ Fixes bug reported by Ralph Coredroy <ralph@inputplus.co.uk>
+
+ 7/28
+ ----
+doc/{bash.1,bashref.texi}
+ - minor changes to the descriptions of the cd and pushd builtins
+
+lib/sh/zread.c
+ - zsyncfd: change variable holding return value from lseek to
+ off_t. Bug report and fix from Gregory Margo <gmargo@pacbell.net>
+
+ 8/1
+ ---
+expr.c
+ - don't check for division by 0 when in a context where no evaluation
+ is taking place. Fixes bug reported by dnade.ext@orange-ftgroup.com
and set LINES and COLUMNS after a foreground job exits. From a
suggestion by Leslie Rhorer <lrhorer@satx.rr.com>
+doc/{bash.1,bashref.texi}
+ - checkwinsize: remove language saying that only interactive shells
+ check the window size after each command
+
lib/readline/histfile.c
- history_backupfile: new file, creates a backup history file name
given a filename (appending `-')
lib/readline/signals.c
- rl_signal_handler: if we're in callback mode, don't interrupt
immediately on a SIGWINCH
+
+ 7/3
+ ---
+bashline.c
+ - set_directory_hook: and its siblings are a new set of functions to
+ set, save, and restore the appropriate directory completion hook
+ - change callers to use {set,save,restore}_directory_hook instead of
+ manipulating rl_directory_rewrite_hook directly
+ - dircomplete_expand: new variable, defaults to 0, if non-zero causes
+ directory names to be word-expanded during word and filename
+ completion
+ - change {set,save,restore}_directory_hook to look at dircomplete_expand
+ and change rl_directory_completion_hook or rl_directory_rewrite_hook
+ appropriately
+
+bashline.h
+ - extern declaration for set_directory_hook so shopt code can use it
+
+ 7/6
+ ---
+builtins/shopt.def
+ - globasciiranges: new settable shopt option, makes glob ranges act
+ as if in the C locale (so b no longer comes between A and B).
+ Suggested by Aharon Robbins <arnold@skeeve.com>
+
+ 7/7
+ ---
+doc/{bash.1,bashref.texi}
+ - document new `globasciiranges' shopt option
+
+ 7/8
+ ---
+builtins/shopt.def
+ - direxpand: new settable option, makes filename completion expand
+ variables in directory names like bash-4.1 did.
+ - shopt_set_complete_direxpand: new function, does the work for the
+ above by calling set_directory_hook
+
+doc/{bash.1,bashref.texi}
+ - document new `direxpand' shopt option
+
+ 7/15
+ ----
+lib/readline/isearch.c
+ - _rl_isearch_dispatch: when adding character to search string, use
+ cxt->lastc (which we use in the switch statement) instead of c,
+ since lastc can be modified earlier in the function
+
+ 7/18
+ ----
+lib/readline/rlprivate.h
+ - _rl_search_context: add another member to save previous value of
+ (multibyte) lastc: pmb is to mb as prevc is to lastc
+
+lib/readline/isearch.c:
+ - _rl_isearch_dispatch: if a key sequence indexes into a new keymap,
+ but doesn't find any bound function (k[ind].function == 0) or is
+ bound to self-insert (k[ind].function == rl_insert), back up and
+ insert the previous character (the one that caused the index into a
+ new keymap) and arrange things so the current character is the next
+ one read, so both of them end up in the search string. Fixes bug
+ reported by Clark Wang <dearvoid@gmail.com>
+ - _rl_isearch_dispatch: a couple of efficiency improvements when adding
+ characters to the isearch string
+
+ 7/24
+ ----
+lib/readline/isearch.c
+ - _rl_isearch_dispatch: save and restore cxt->mb and cxt->pmb
+ appropriately when in a multibyte locale
+
+doc/{bash.1,bashref.texi}
+ - correct description of {x}>file (and other redirection operators
+ that allocate a file descriptor) to note the the fd range is
+ greater than or equal to 10. Fixes problem reported by
+ Christian Ullrich
+
+lib/readline/signals.c
+ - rl_signal_handler: don't interrupt immediately if in callback mode
+
+lib/readline/callback.c
+ - rl_callback_read_char: install signal handlers only when readline
+ has control in callback mode, so readline's signal handlers aren't
+ called when the application is active (e.g., between the calls to
+ rl_callback_handler_install and rl_callback_read_char). If the
+ readline signal handlers only set a flag, which the application
+ doesn't know about, the signals will effectively be ignored until
+ the next time the application calls into the readline callback
+ interface. Fixes problem of calling unsafe functions from signal
+ handlers when in callback mode reported by Jan Kratochvil
+ <jan.kratochvil@redhat.com>
+
+execute_cmd.c
+ - fix_assignment_words: when in Posix mode, the `command' builtin
+ doesn't change whether or not the command name it protects is an
+ assignment builtin. One or more instances of `command'
+ preceding `export', for instance, doesn't make `export' treat its
+ assignment statement arguments differently. Posix interpretation
+ #351
+
+doc/{bash.1,bashref.texi}
+ - document new Posix-mode behavior of `command' when preceding builtins
+ that take assignment statements as arguments
+
+builtins/printf.def
+ - printstr: if fieldwidth or precision are < 0 or > INT_MAX when
+ supplied explicitly (since we take care of the `-' separately),
+ clamp at INT_MAX like when using getint(). Fixes issue reported
+ by Ralph Coredroy <ralph@inputplus.co.uk>
+
+ 7/25
+ ----
+lib/readline/chardefs.h
+ - isxdigit: don't define if compiling with c++; declared as a c++
+ template function. Fixes bug reported by Miroslav Lichvar
+ <mlichvar@redhat.com>
+
+builtins/printf.def
+ - getint: if garglist == 0, return whatever getintmax returns (0).
+ Fixes bug reported by Ralph Coredroy <ralph@inputplus.co.uk>
+
+ 7/28
+ ----
+doc/{bash.1,bashref.texi}
+ - minor changes to the descriptions of the cd and pushd builtins
+
+lib/sh/zread.c
+ - zsyncfd: change variable holding return value from lseek to
+ off_t. Bug report and fix from Gregory Margo <gmargo@pacbell.net>
free (temp);
}
-#if 0 /* changed for bash-4.2 Posix cd description steps 5-6 */
+#if 0
+ /* changed for bash-4.2 Posix cd description steps 5-6 */
/* POSIX.2 says that if `.' does not appear in $CDPATH, we don't
try the current directory, so we just punt now with an error
message if POSIXLY_CORRECT is non-zero. The check for cdpath[0]
--- /dev/null
+This file is cd.def, from which is created cd.c. It implements the
+builtins "cd" and "pwd" in Bash.
+
+Copyright (C) 1987-2010 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/>.
+
+$PRODUCES cd.c
+#include <config.h>
+
+#if defined (HAVE_UNISTD_H)
+# ifdef _MINIX
+# include <sys/types.h>
+# endif
+# include <unistd.h>
+#endif
+
+#include "../bashtypes.h"
+#include "posixdir.h"
+#include "posixstat.h"
+#ifndef _MINIX
+#include <sys/param.h>
+#endif
+
+#include <stdio.h>
+
+#include "../bashansi.h"
+#include "../bashintl.h"
+
+#include <errno.h>
+#include <tilde/tilde.h>
+
+#include "../shell.h"
+#include "../flags.h"
+#include "maxpath.h"
+#include "common.h"
+#include "bashgetopt.h"
+
+#if !defined (errno)
+extern int errno;
+#endif /* !errno */
+
+extern int posixly_correct;
+extern int array_needs_making;
+extern const char * const bash_getcwd_errstr;
+
+static int bindpwd __P((int));
+static int setpwd __P((char *));
+static char *resetpwd __P((char *));
+static int change_to_directory __P((char *, int));
+
+/* Change this to 1 to get cd spelling correction by default. */
+int cdspelling = 0;
+
+int cdable_vars;
+
+static int eflag; /* file scope so bindpwd() can see it */
+
+$BUILTIN cd
+$FUNCTION cd_builtin
+$SHORT_DOC cd [-L|[-P [-e]]] [dir]
+Change the shell working directory.
+
+Change the current directory to DIR. The default DIR is the value of the
+HOME shell variable.
+
+The variable CDPATH defines the search path for the directory containing
+DIR. Alternative directory names in CDPATH are separated by a colon (:).
+A null directory name is the same as the current directory. If DIR begins
+with a slash (/), then CDPATH is not used.
+
+If the directory is not found, and the shell option `cdable_vars' is set,
+the word is assumed to be a variable name. If that variable has a value,
+its value is used for DIR.
+
+Options:
+ -L force symbolic links to be followed
+ -P use the physical directory structure without following symbolic
+ links
+ -e if the -P option is supplied, and the current working directory
+ cannot be determined successfully, exit with a non-zero status
+
+The default is to follow symbolic links, as if `-L' were specified.
+
+Exit Status:
+Returns 0 if the directory is changed, and if $PWD is set successfully when
+-P is used; non-zero otherwise.
+$END
+
+/* Just set $PWD, don't change OLDPWD. Used by `pwd -P' in posix mode. */
+static int
+setpwd (dirname)
+ char *dirname;
+{
+ int old_anm;
+ SHELL_VAR *tvar;
+
+ old_anm = array_needs_making;
+ tvar = bind_variable ("PWD", dirname ? dirname : "", 0);
+ if (tvar && readonly_p (tvar))
+ return EXECUTION_FAILURE;
+ if (tvar && old_anm == 0 && array_needs_making && exported_p (tvar))
+ {
+ update_export_env_inplace ("PWD=", 4, dirname ? dirname : "");
+ array_needs_making = 0;
+ }
+ return EXECUTION_SUCCESS;
+}
+
+static int
+bindpwd (no_symlinks)
+ int no_symlinks;
+{
+ char *dirname, *pwdvar;
+ int old_anm, r;
+ SHELL_VAR *tvar;
+
+ r = sh_chkwrite (EXECUTION_SUCCESS);
+
+#define tcwd the_current_working_directory
+ dirname = tcwd ? (no_symlinks ? sh_physpath (tcwd, 0) : tcwd)
+ : get_working_directory ("cd");
+#undef tcwd
+
+ old_anm = array_needs_making;
+ pwdvar = get_string_value ("PWD");
+
+ tvar = bind_variable ("OLDPWD", pwdvar, 0);
+ if (tvar && readonly_p (tvar))
+ r = EXECUTION_FAILURE;
+
+ if (old_anm == 0 && array_needs_making && exported_p (tvar))
+ {
+ update_export_env_inplace ("OLDPWD=", 7, pwdvar);
+ array_needs_making = 0;
+ }
+
+ if (setpwd (dirname) == EXECUTION_FAILURE)
+ r = EXECUTION_FAILURE;
+ if (dirname == 0 && eflag)
+ r = EXECUTION_FAILURE;
+
+ if (dirname && dirname != the_current_working_directory)
+ free (dirname);
+
+ return (r);
+}
+
+/* Call get_working_directory to reset the value of
+ the_current_working_directory () */
+static char *
+resetpwd (caller)
+ char *caller;
+{
+ char *tdir;
+
+ FREE (the_current_working_directory);
+ the_current_working_directory = (char *)NULL;
+ tdir = get_working_directory (caller);
+ return (tdir);
+}
+
+#define LCD_DOVARS 0x001
+#define LCD_DOSPELL 0x002
+#define LCD_PRINTPATH 0x004
+#define LCD_FREEDIRNAME 0x008
+
+/* This builtin is ultimately the way that all user-visible commands should
+ change the current working directory. It is called by cd_to_string (),
+ so the programming interface is simple, and it handles errors and
+ restrictions properly. */
+int
+cd_builtin (list)
+ WORD_LIST *list;
+{
+ char *dirname, *cdpath, *path, *temp;
+ int path_index, no_symlinks, opt, lflag;
+
+#if defined (RESTRICTED_SHELL)
+ if (restricted)
+ {
+ sh_restricted ((char *)NULL);
+ return (EXECUTION_FAILURE);
+ }
+#endif /* RESTRICTED_SHELL */
+
+ eflag = 0;
+ no_symlinks = no_symbolic_links;
+ reset_internal_getopt ();
+ while ((opt = internal_getopt (list, "LP")) != -1)
+ {
+ switch (opt)
+ {
+ case 'P':
+ no_symlinks = 1;
+ break;
+ case 'L':
+ no_symlinks = 0;
+ break;
+ case 'e':
+ eflag = 1;
+ break;
+ default:
+ builtin_usage ();
+ return (EXECUTION_FAILURE);
+ }
+ }
+ list = loptend;
+
+ lflag = (cdable_vars ? LCD_DOVARS : 0) |
+ ((interactive && cdspelling) ? LCD_DOSPELL : 0);
+ if (eflag && no_symlinks == 0)
+ eflag = 0;
+
+ if (list == 0)
+ {
+ /* `cd' without arguments is equivalent to `cd $HOME' */
+ dirname = get_string_value ("HOME");
+
+ if (dirname == 0)
+ {
+ builtin_error (_("HOME not set"));
+ return (EXECUTION_FAILURE);
+ }
+ lflag = 0;
+ }
+ else if (list->word->word[0] == '-' && list->word->word[1] == '\0')
+ {
+ /* This is `cd -', equivalent to `cd $OLDPWD' */
+ dirname = get_string_value ("OLDPWD");
+
+ if (dirname == 0)
+ {
+ builtin_error (_("OLDPWD not set"));
+ return (EXECUTION_FAILURE);
+ }
+#if 0
+ lflag = interactive ? LCD_PRINTPATH : 0;
+#else
+ lflag = LCD_PRINTPATH; /* According to SUSv3 */
+#endif
+ }
+ else if (absolute_pathname (list->word->word))
+ dirname = list->word->word;
+ else if (privileged_mode == 0 && (cdpath = get_string_value ("CDPATH")))
+ {
+ dirname = list->word->word;
+
+ /* Find directory in $CDPATH. */
+ path_index = 0;
+ while (path = extract_colon_unit (cdpath, &path_index))
+ {
+ /* OPT is 1 if the path element is non-empty */
+ opt = path[0] != '\0';
+ temp = sh_makepath (path, dirname, MP_DOTILDE);
+ free (path);
+
+ if (change_to_directory (temp, no_symlinks))
+ {
+ /* POSIX.2 says that if a nonempty directory from CDPATH
+ is used to find the directory to change to, the new
+ directory name is echoed to stdout, whether or not
+ the shell is interactive. */
+ if (opt && (path = no_symlinks ? temp : the_current_working_directory))
+ printf ("%s\n", path);
+
+ free (temp);
+#if 0
+ /* Posix.2 says that after using CDPATH, the resultant
+ value of $PWD will not contain `.' or `..'. */
+ return (bindpwd (posixly_correct || no_symlinks));
+#else
+ return (bindpwd (no_symlinks));
+#endif
+ }
+ else
+ free (temp);
+ }
+
+#if 0 /* changed for bash-4.2 Posix cd description steps 5-6 */
+ /* POSIX.2 says that if `.' does not appear in $CDPATH, we don't
+ try the current directory, so we just punt now with an error
+ message if POSIXLY_CORRECT is non-zero. The check for cdpath[0]
+ is so we don't mistakenly treat a CDPATH value of "" as not
+ specifying the current directory. */
+ if (posixly_correct && cdpath[0])
+ {
+ builtin_error ("%s: %s", dirname, strerror (ENOENT));
+ return (EXECUTION_FAILURE);
+ }
+#endif
+ }
+ else
+ dirname = list->word->word;
+
+ /* When we get here, DIRNAME is the directory to change to. If we
+ chdir successfully, just return. */
+ if (change_to_directory (dirname, no_symlinks))
+ {
+ if (lflag & LCD_PRINTPATH)
+ printf ("%s\n", dirname);
+ return (bindpwd (no_symlinks));
+ }
+
+ /* If the user requests it, then perhaps this is the name of
+ a shell variable, whose value contains the directory to
+ change to. */
+ if (lflag & LCD_DOVARS)
+ {
+ temp = get_string_value (dirname);
+ if (temp && change_to_directory (temp, no_symlinks))
+ {
+ printf ("%s\n", temp);
+ return (bindpwd (no_symlinks));
+ }
+ }
+
+ /* If the user requests it, try to find a directory name similar in
+ spelling to the one requested, in case the user made a simple
+ typo. This is similar to the UNIX 8th and 9th Edition shells. */
+ if (lflag & LCD_DOSPELL)
+ {
+ temp = dirspell (dirname);
+ if (temp && change_to_directory (temp, no_symlinks))
+ {
+ printf ("%s\n", temp);
+ return (bindpwd (no_symlinks));
+ }
+ else
+ FREE (temp);
+ }
+
+ builtin_error ("%s: %s", dirname, strerror (errno));
+ return (EXECUTION_FAILURE);
+}
+
+$BUILTIN pwd
+$FUNCTION pwd_builtin
+$SHORT_DOC pwd [-LP]
+Print the name of the current working directory.
+
+Options:
+ -L print the value of $PWD if it names the current working
+ directory
+ -P print the physical directory, without any symbolic links
+
+By default, `pwd' behaves as if `-L' were specified.
+
+Exit Status:
+Returns 0 unless an invalid option is given or the current directory
+cannot be read.
+$END
+
+/* Non-zero means that pwd always prints the physical directory, without
+ symbolic links. */
+static int verbatim_pwd;
+
+/* Print the name of the current working directory. */
+int
+pwd_builtin (list)
+ WORD_LIST *list;
+{
+ char *directory;
+ int opt, pflag;
+
+ verbatim_pwd = no_symbolic_links;
+ pflag = 0;
+ reset_internal_getopt ();
+ while ((opt = internal_getopt (list, "LP")) != -1)
+ {
+ switch (opt)
+ {
+ case 'P':
+ verbatim_pwd = pflag = 1;
+ break;
+ case 'L':
+ verbatim_pwd = 0;
+ break;
+ default:
+ builtin_usage ();
+ return (EXECUTION_FAILURE);
+ }
+ }
+ list = loptend;
+
+#define tcwd the_current_working_directory
+
+ directory = tcwd ? (verbatim_pwd ? sh_physpath (tcwd, 0) : tcwd)
+ : get_working_directory ("pwd");
+
+ /* Try again using getcwd() if canonicalization fails (for instance, if
+ the file system has changed state underneath bash). */
+ if ((tcwd && directory == 0) ||
+ (posixly_correct && same_file (".", tcwd, (struct stat *)0, (struct stat *)0) == 0))
+ directory = resetpwd ("pwd");
+
+#undef tcwd
+
+ if (directory)
+ {
+ opt = EXECUTION_SUCCESS;
+ printf ("%s\n", directory);
+ /* This is dumb but posix-mandated. */
+ if (posixly_correct && pflag)
+ opt = setpwd (directory);
+ if (directory != the_current_working_directory)
+ free (directory);
+ return (sh_chkwrite (opt));
+ }
+ else
+ return (EXECUTION_FAILURE);
+}
+
+/* Do the work of changing to the directory NEWDIR. Handle symbolic
+ link following, etc. This function *must* return with
+ the_current_working_directory either set to NULL (in which case
+ getcwd() will eventually be called), or set to a string corresponding
+ to the working directory. Return 1 on success, 0 on failure. */
+
+static int
+change_to_directory (newdir, nolinks)
+ char *newdir;
+ int nolinks;
+{
+ char *t, *tdir;
+ int err, canon_failed, r, ndlen, dlen;
+
+ tdir = (char *)NULL;
+
+ if (the_current_working_directory == 0)
+ {
+ t = get_working_directory ("chdir");
+ FREE (t);
+ }
+
+ t = make_absolute (newdir, the_current_working_directory);
+
+ /* TDIR is either the canonicalized absolute pathname of NEWDIR
+ (nolinks == 0) or the absolute physical pathname of NEWDIR
+ (nolinks != 0). */
+ tdir = nolinks ? sh_physpath (t, 0)
+ : sh_canonpath (t, PATH_CHECKDOTDOT|PATH_CHECKEXISTS);
+
+ ndlen = strlen (newdir);
+ dlen = strlen (t);
+
+ /* Use the canonicalized version of NEWDIR, or, if canonicalization
+ failed, use the non-canonical form. */
+ canon_failed = 0;
+ if (tdir && *tdir)
+ free (t);
+ else
+ {
+ FREE (tdir);
+ tdir = t;
+ canon_failed = 1;
+ }
+
+ /* In POSIX mode, if we're resolving symlinks logically and sh_canonpath
+ returns NULL (because it checks the path, it will return NULL if the
+ resolved path doesn't exist), fail immediately. */
+ if (posixly_correct && nolinks == 0 && canon_failed && (errno != ENAMETOOLONG || ndlen > PATH_MAX))
+ {
+#if defined ENAMETOOLONG
+ if (errno != ENOENT && errno != ENAMETOOLONG)
+#else
+ if (errno != ENOENT)
+#endif
+ errno = ENOTDIR;
+ free (tdir);
+ return (0);
+ }
+
+ /* If the chdir succeeds, update the_current_working_directory. */
+ if (chdir (nolinks ? newdir : tdir) == 0)
+ {
+ /* If canonicalization failed, but the chdir succeeded, reset the
+ shell's idea of the_current_working_directory. */
+ if (canon_failed)
+ {
+ t = resetpwd ("cd");
+ if (t == 0)
+ set_working_directory (tdir);
+ }
+ else
+ set_working_directory (tdir);
+
+ free (tdir);
+ return (1);
+ }
+
+ /* We failed to change to the appropriate directory name. If we tried
+ what the user passed (nolinks != 0), punt now. */
+ if (nolinks)
+ {
+ free (tdir);
+ return (0);
+ }
+
+ err = errno;
+
+ /* We're not in physical mode (nolinks == 0), but we failed to change to
+ the canonicalized directory name (TDIR). Try what the user passed
+ verbatim. If we succeed, reinitialize the_current_working_directory. */
+ if (chdir (newdir) == 0)
+ {
+ t = resetpwd ("cd");
+ if (t == 0)
+ set_working_directory (tdir);
+ else
+ free (t);
+
+ r = 1;
+ }
+ else
+ {
+ errno = err;
+ r = 0;
+ }
+
+ free (tdir);
+ return r;
+}
#endif
int padlen, nc, ljust, i;
int fw, pr; /* fieldwidth and precision */
+ intmax_t mfw, mpr;
#if 0
if (string == 0 || *string == '\0')
ljust = fw = 0;
pr = -1;
+ mfw = 0;
+ mpr = -1;
/* skip flags */
while (strchr (SKIP1, *fmt))
fmt++;
}
- /* get fieldwidth, if present */
+ /* get fieldwidth, if present. rely on caller to clamp fieldwidth at INT_MAX */
if (*fmt == '*')
{
fmt++;
}
else if (DIGIT (*fmt))
{
- fw = *fmt++ - '0';
+ mfw = *fmt++ - '0';
while (DIGIT (*fmt))
- fw = (fw * 10) + (*fmt++ - '0');
+ mfw = (mfw * 10) + (*fmt++ - '0');
+ /* Error if fieldwidth > INT_MAX here? */
+ fw = (mfw < 0 || mfw > INT_MAX) ? INT_MAX : mfw;
}
/* get precision, if present */
}
else if (DIGIT (*fmt))
{
- pr = *fmt++ - '0';
+ mpr = *fmt++ - '0';
while (DIGIT (*fmt))
- pr = (pr * 10) + (*fmt++ - '0');
+ mpr = (mpr * 10) + (*fmt++ - '0');
+ /* Error if precision > INT_MAX here? */
+ pr = (mpr < 0 || mpr > INT_MAX) ? INT_MAX : mpr;
}
}
ret = getintmax ();
+ if (garglist == 0)
+ return ret;
+
if (ret > INT_MAX)
{
printf_erange (garglist->word->word);
--- /dev/null
+This file is printf.def, from which is created printf.c.
+It implements the builtin "printf" in Bash.
+
+Copyright (C) 1997-2010 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/>.
+
+$PRODUCES printf.c
+
+$BUILTIN printf
+$FUNCTION printf_builtin
+$SHORT_DOC printf [-v var] format [arguments]
+Formats and prints ARGUMENTS under control of the FORMAT.
+
+Options:
+ -v var assign the output to shell variable VAR rather than
+ display it on the standard output
+
+FORMAT is a character string which contains three types of objects: plain
+characters, which are simply copied to standard output; character escape
+sequences, which are converted and copied to the standard output; and
+format specifications, each of which causes printing of the next successive
+argument.
+
+In addition to the standard format specifications described in printf(1),
+printf interprets:
+
+ %b expand backslash escape sequences in the corresponding argument
+ %q quote the argument in a way that can be reused as shell input
+ %(fmt)T output the date-time string resulting from using FMT as a format
+ string for strftime(3)
+
+Exit Status:
+Returns success unless an invalid option is given or a write or assignment
+error occurs.
+$END
+
+#include <config.h>
+
+#include "../bashtypes.h"
+
+#include <errno.h>
+#if defined (HAVE_LIMITS_H)
+# include <limits.h>
+#else
+ /* Assume 32-bit ints. */
+# define INT_MAX 2147483647
+# define INT_MIN (-2147483647-1)
+#endif
+
+#if defined (PREFER_STDARG)
+# include <stdarg.h>
+#else
+# include <varargs.h>
+#endif
+
+#include <stdio.h>
+#include <chartypes.h>
+
+#ifdef HAVE_INTTYPES_H
+# include <inttypes.h>
+#endif
+
+#include "posixtime.h"
+#include "../bashansi.h"
+#include "../bashintl.h"
+
+#define NEED_STRFTIME_DECL
+
+#include "../shell.h"
+#include "shmbutil.h"
+#include "stdc.h"
+#include "bashgetopt.h"
+#include "common.h"
+
+#if defined (PRI_MACROS_BROKEN)
+# undef PRIdMAX
+#endif
+
+#if !defined (PRIdMAX)
+# if HAVE_LONG_LONG
+# define PRIdMAX "lld"
+# else
+# define PRIdMAX "ld"
+# endif
+#endif
+
+#if !defined (errno)
+extern int errno;
+#endif
+
+#define PC(c) \
+ do { \
+ char b[2]; \
+ tw++; \
+ b[0] = c; b[1] = '\0'; \
+ if (vflag) \
+ vbadd (b, 1); \
+ else \
+ putchar (c); \
+ } while (0)
+
+#define PF(f, func) \
+ do { \
+ int nw; \
+ clearerr (stdout); \
+ if (have_fieldwidth && have_precision) \
+ nw = vflag ? vbprintf (f, fieldwidth, precision, func) : printf (f, fieldwidth, precision, func); \
+ else if (have_fieldwidth) \
+ nw = vflag ? vbprintf (f, fieldwidth, func) : printf (f, fieldwidth, func); \
+ else if (have_precision) \
+ nw = vflag ? vbprintf (f, precision, func) : printf (f, precision, func); \
+ else \
+ nw = vflag ? vbprintf (f, func) : printf (f, func); \
+ tw += nw; \
+ if (ferror (stdout)) \
+ { \
+ sh_wrerror (); \
+ clearerr (stdout); \
+ return (EXECUTION_FAILURE); \
+ } \
+ } while (0)
+
+/* We free the buffer used by mklong() if it's `too big'. */
+#define PRETURN(value) \
+ do \
+ { \
+ if (vflag) \
+ { \
+ bind_printf_variable (vname, vbuf, 0); \
+ stupidly_hack_special_variables (vname); \
+ } \
+ if (conv_bufsize > 4096 ) \
+ { \
+ free (conv_buf); \
+ conv_bufsize = 0; \
+ conv_buf = 0; \
+ } \
+ if (vbsize > 4096) \
+ { \
+ free (vbuf); \
+ vbsize = 0; \
+ vbuf = 0; \
+ } \
+ else if (vbuf) \
+ vbuf[0] = 0; \
+ terminate_immediately--; \
+ if (ferror (stdout) == 0) \
+ fflush (stdout); \
+ if (ferror (stdout)) \
+ { \
+ sh_wrerror (); \
+ clearerr (stdout); \
+ return (EXECUTION_FAILURE); \
+ } \
+ return (value); \
+ } \
+ while (0)
+
+#define SKIP1 "#'-+ 0"
+#define LENMODS "hjlLtz"
+
+extern time_t shell_start_time;
+
+#if !HAVE_ASPRINTF
+extern int asprintf __P((char **, const char *, ...)) __attribute__((__format__ (printf, 2, 3)));
+#endif
+
+#if !HAVE_VSNPRINTF
+extern int vsnprintf __P((char *, size_t, const char *, va_list)) __attribute__((__format__ (printf, 3, 0)));
+#endif
+
+static void printf_erange __P((char *));
+static int printstr __P((char *, char *, int, int, int));
+static int tescape __P((char *, char *, int *, int *));
+static char *bexpand __P((char *, int, int *, int *));
+static char *vbadd __P((char *, int));
+static int vbprintf __P((const char *, ...)) __attribute__((__format__ (printf, 1, 2)));
+static char *mklong __P((char *, char *, size_t));
+static int getchr __P((void));
+static char *getstr __P((void));
+static int getint __P((void));
+static intmax_t getintmax __P((void));
+static uintmax_t getuintmax __P((void));
+static SHELL_VAR *bind_printf_variable __P((char *, char *, int));
+
+#if defined (HAVE_LONG_DOUBLE) && HAVE_DECL_STRTOLD && !defined(STRTOLD_BROKEN)
+typedef long double floatmax_t;
+# define FLOATMAX_CONV "L"
+# define strtofltmax strtold
+#else
+typedef double floatmax_t;
+# define FLOATMAX_CONV ""
+# define strtofltmax strtod
+#endif
+static floatmax_t getfloatmax __P((void));
+
+static intmax_t asciicode __P((void));
+
+static WORD_LIST *garglist;
+static int retval;
+static int conversion_error;
+
+/* printf -v var support */
+static int vflag = 0;
+static char *vbuf, *vname;
+static size_t vbsize;
+static int vblen;
+
+static intmax_t tw;
+
+static char *conv_buf;
+static size_t conv_bufsize;
+
+int
+printf_builtin (list)
+ WORD_LIST *list;
+{
+ int ch, fieldwidth, precision;
+ int have_fieldwidth, have_precision;
+ char convch, thisch, nextch, *format, *modstart, *fmt, *start;
+#if defined (HANDLE_MULTIBYTE)
+ char mbch[25]; /* 25 > MB_LEN_MAX, plus can handle 4-byte UTF-8 and large Unicode characters*/
+ int mbind, mblen;
+#endif
+
+ conversion_error = 0;
+ retval = EXECUTION_SUCCESS;
+
+ vflag = 0;
+
+ reset_internal_getopt ();
+ while ((ch = internal_getopt (list, "v:")) != -1)
+ {
+ switch (ch)
+ {
+ case 'v':
+ vname = list_optarg;
+#if defined (ARRAY_VARS)
+ if (legal_identifier (vname) || valid_array_reference (vname))
+#else
+ if (legal_identifier (vname))
+#endif
+ {
+ vflag = 1;
+ vblen = 0;
+ if (vbuf)
+ vbuf[0] = 0;
+ }
+ else
+ {
+ sh_invalidid (vname);
+ return (EX_USAGE);
+ }
+ break;
+ default:
+ builtin_usage ();
+ return (EX_USAGE);
+ }
+ }
+ list = loptend; /* skip over possible `--' */
+
+ if (list == 0)
+ {
+ builtin_usage ();
+ return (EX_USAGE);
+ }
+
+ if (list->word->word == 0 || list->word->word[0] == '\0')
+ return (EXECUTION_SUCCESS);
+
+ format = list->word->word;
+ tw = 0;
+
+ garglist = list->next;
+
+ /* If the format string is empty after preprocessing, return immediately. */
+ if (format == 0 || *format == 0)
+ return (EXECUTION_SUCCESS);
+
+ terminate_immediately++;
+
+ /* Basic algorithm is to scan the format string for conversion
+ specifications -- once one is found, find out if the field
+ width or precision is a '*'; if it is, gather up value. Note,
+ format strings are reused as necessary to use up the provided
+ arguments, arguments of zero/null string are provided to use
+ up the format string. */
+ do
+ {
+ tw = 0;
+ /* find next format specification */
+ for (fmt = format; *fmt; fmt++)
+ {
+ precision = fieldwidth = 0;
+ have_fieldwidth = have_precision = 0;
+
+ if (*fmt == '\\')
+ {
+ fmt++;
+ /* A NULL third argument to tescape means to bypass the
+ special processing for arguments to %b. */
+#if defined (HANDLE_MULTIBYTE)
+ /* Accommodate possible use of \u or \U, which can result in
+ multibyte characters */
+ memset (mbch, '\0', sizeof (mbch));
+ fmt += tescape (fmt, mbch, &mblen, (int *)NULL);
+ for (mbind = 0; mbind < mblen; mbind++)
+ PC (mbch[mbind]);
+#else
+ fmt += tescape (fmt, &nextch, (int *)NULL, (int *)NULL);
+ PC (nextch);
+#endif
+ fmt--; /* for loop will increment it for us again */
+ continue;
+ }
+
+ if (*fmt != '%')
+ {
+ PC (*fmt);
+ continue;
+ }
+
+ /* ASSERT(*fmt == '%') */
+ start = fmt++;
+
+ if (*fmt == '%') /* %% prints a % */
+ {
+ PC ('%');
+ continue;
+ }
+
+ /* found format specification, skip to field width */
+ for (; *fmt && strchr(SKIP1, *fmt); ++fmt)
+ ;
+
+ /* Skip optional field width. */
+ if (*fmt == '*')
+ {
+ fmt++;
+ have_fieldwidth = 1;
+ fieldwidth = getint ();
+ }
+ else
+ while (DIGIT (*fmt))
+ fmt++;
+
+ /* Skip optional '.' and precision */
+ if (*fmt == '.')
+ {
+ ++fmt;
+ if (*fmt == '*')
+ {
+ fmt++;
+ have_precision = 1;
+ precision = getint ();
+ }
+ else
+ {
+ /* Negative precisions are allowed but treated as if the
+ precision were missing; I would like to allow a leading
+ `+' in the precision number as an extension, but lots
+ of asprintf/fprintf implementations get this wrong. */
+#if 0
+ if (*fmt == '-' || *fmt == '+')
+#else
+ if (*fmt == '-')
+#endif
+ fmt++;
+ while (DIGIT (*fmt))
+ fmt++;
+ }
+ }
+
+ /* skip possible format modifiers */
+ modstart = fmt;
+ while (*fmt && strchr (LENMODS, *fmt))
+ fmt++;
+
+ if (*fmt == 0)
+ {
+ builtin_error (_("`%s': missing format character"), start);
+ PRETURN (EXECUTION_FAILURE);
+ }
+
+ convch = *fmt;
+ thisch = modstart[0];
+ nextch = modstart[1];
+ modstart[0] = convch;
+ modstart[1] = '\0';
+
+ switch(convch)
+ {
+ case 'c':
+ {
+ char p;
+
+ p = getchr ();
+ PF(start, p);
+ break;
+ }
+
+ case 's':
+ {
+ char *p;
+
+ p = getstr ();
+ PF(start, p);
+ break;
+ }
+
+ case '(':
+ {
+ char *timefmt, timebuf[128], *t;
+ int n;
+ intmax_t arg;
+ time_t secs;
+ struct tm *tm;
+
+ modstart[1] = nextch; /* restore char after left paren */
+ timefmt = xmalloc (strlen (fmt) + 3);
+ fmt++; /* skip over left paren */
+ for (t = timefmt, n = 1; *fmt; )
+ {
+ if (*fmt == '(')
+ n++;
+ else if (*fmt == ')')
+ n--;
+ if (n == 0)
+ break;
+ *t++ = *fmt++;
+ }
+ *t = '\0';
+ if (*++fmt != 'T')
+ {
+ builtin_warning (_("`%c': invalid time format specification"), *fmt);
+ fmt = start;
+ free (timefmt);
+ PC (*fmt);
+ continue;
+ }
+ if (timefmt[0] == '\0')
+ {
+ timefmt[0] = '%';
+ timefmt[1] = 'X'; /* locale-specific current time - should we use `+'? */
+ timefmt[2] = '\0';
+ }
+ /* argument is seconds since the epoch with special -1 and -2 */
+ arg = getintmax ();
+ if (arg == -1)
+ secs = NOW; /* roughly date +%s */
+ else if (arg == -2)
+ secs = shell_start_time; /* roughly $SECONDS */
+ else
+ secs = arg;
+#if defined (HAVE_TZSET)
+ sv_tz ("TZ"); /* XXX -- just make sure */
+#endif
+ tm = localtime (&secs);
+ n = strftime (timebuf, sizeof (timebuf), timefmt, tm);
+ free (timefmt);
+ if (n == 0)
+ timebuf[0] = '\0';
+ else
+ timebuf[sizeof(timebuf) - 1] = '\0';
+ /* convert to %s format that preserves fieldwidth and precision */
+ modstart[0] = 's';
+ modstart[1] = '\0';
+ n = printstr (start, timebuf, strlen (timebuf), fieldwidth, precision); /* XXX - %s for now */
+ if (n < 0)
+ {
+ if (ferror (stdout) == 0)
+ {
+ sh_wrerror ();
+ clearerr (stdout);
+ }
+ PRETURN (EXECUTION_FAILURE);
+ }
+ break;
+ }
+
+ case 'n':
+ {
+ char *var;
+
+ var = getstr ();
+ if (var && *var)
+ {
+ if (legal_identifier (var))
+ bind_var_to_int (var, tw);
+ else
+ {
+ sh_invalidid (var);
+ PRETURN (EXECUTION_FAILURE);
+ }
+ }
+ break;
+ }
+
+ case 'b': /* expand escapes in argument */
+ {
+ char *p, *xp;
+ int rlen, r;
+
+ p = getstr ();
+ ch = rlen = r = 0;
+ xp = bexpand (p, strlen (p), &ch, &rlen);
+
+ if (xp)
+ {
+ /* Have to use printstr because of possible NUL bytes
+ in XP -- printf does not handle that well. */
+ r = printstr (start, xp, rlen, fieldwidth, precision);
+ if (r < 0)
+ {
+ if (ferror (stdout) == 0)
+ {
+ sh_wrerror ();
+ clearerr (stdout);
+ }
+ retval = EXECUTION_FAILURE;
+ }
+ free (xp);
+ }
+
+ if (ch || r < 0)
+ PRETURN (retval);
+ break;
+ }
+
+ case 'q': /* print with shell quoting */
+ {
+ char *p, *xp;
+ int r;
+
+ r = 0;
+ p = getstr ();
+ if (p && *p == 0) /* XXX - getstr never returns null */
+ xp = savestring ("''");
+ else if (ansic_shouldquote (p))
+ xp = ansic_quote (p, 0, (int *)0);
+ else
+ xp = sh_backslash_quote (p);
+ if (xp)
+ {
+ /* Use printstr to get fieldwidth and precision right. */
+ r = printstr (start, xp, strlen (xp), fieldwidth, precision);
+ if (r < 0)
+ {
+ sh_wrerror ();
+ clearerr (stdout);
+ }
+ free (xp);
+ }
+
+ if (r < 0)
+ PRETURN (EXECUTION_FAILURE);
+ break;
+ }
+
+ case 'd':
+ case 'i':
+ {
+ char *f;
+ long p;
+ intmax_t pp;
+
+ p = pp = getintmax ();
+ if (p != pp)
+ {
+ f = mklong (start, PRIdMAX, sizeof (PRIdMAX) - 2);
+ PF (f, pp);
+ }
+ else
+ {
+ /* Optimize the common case where the integer fits
+ in "long". This also works around some long
+ long and/or intmax_t library bugs in the common
+ case, e.g. glibc 2.2 x86. */
+ f = mklong (start, "l", 1);
+ PF (f, p);
+ }
+ break;
+ }
+
+ case 'o':
+ case 'u':
+ case 'x':
+ case 'X':
+ {
+ char *f;
+ unsigned long p;
+ uintmax_t pp;
+
+ p = pp = getuintmax ();
+ if (p != pp)
+ {
+ f = mklong (start, PRIdMAX, sizeof (PRIdMAX) - 2);
+ PF (f, pp);
+ }
+ else
+ {
+ f = mklong (start, "l", 1);
+ PF (f, p);
+ }
+ break;
+ }
+
+ case 'e':
+ case 'E':
+ case 'f':
+ case 'F':
+ case 'g':
+ case 'G':
+#if defined (HAVE_PRINTF_A_FORMAT)
+ case 'a':
+ case 'A':
+#endif
+ {
+ char *f;
+ floatmax_t p;
+
+ p = getfloatmax ();
+ f = mklong (start, FLOATMAX_CONV, sizeof(FLOATMAX_CONV) - 1);
+ PF (f, p);
+ break;
+ }
+
+ /* We don't output unrecognized format characters; we print an
+ error message and return a failure exit status. */
+ default:
+ builtin_error (_("`%c': invalid format character"), convch);
+ PRETURN (EXECUTION_FAILURE);
+ }
+
+ modstart[0] = thisch;
+ modstart[1] = nextch;
+ }
+
+ if (ferror (stdout))
+ {
+ /* PRETURN will print error message. */
+ PRETURN (EXECUTION_FAILURE);
+ }
+ }
+ while (garglist && garglist != list->next);
+
+ if (conversion_error)
+ retval = EXECUTION_FAILURE;
+
+ PRETURN (retval);
+}
+
+static void
+printf_erange (s)
+ char *s;
+{
+ builtin_error (_("warning: %s: %s"), s, strerror(ERANGE));
+}
+
+/* We duplicate a lot of what printf(3) does here. */
+static int
+printstr (fmt, string, len, fieldwidth, precision)
+ char *fmt; /* format */
+ char *string; /* expanded string argument */
+ int len; /* length of expanded string */
+ int fieldwidth; /* argument for width of `*' */
+ int precision; /* argument for precision of `*' */
+{
+#if 0
+ char *s;
+#endif
+ int padlen, nc, ljust, i;
+ int fw, pr; /* fieldwidth and precision */
+ intmax_t mfw, mpr;
+
+#if 0
+ if (string == 0 || *string == '\0')
+#else
+ if (string == 0 || len == 0)
+#endif
+ return 0;
+
+#if 0
+ s = fmt;
+#endif
+ if (*fmt == '%')
+ fmt++;
+
+ ljust = fw = 0;
+ pr = -1;
+ mfw = 0;
+ mpr = -1;
+
+ /* skip flags */
+ while (strchr (SKIP1, *fmt))
+ {
+ if (*fmt == '-')
+ ljust = 1;
+ fmt++;
+ }
+
+ /* get fieldwidth, if present. rely on caller to clamp fieldwidth at INT_MAX */
+ if (*fmt == '*')
+ {
+ fmt++;
+ fw = fieldwidth;
+ if (fw < 0)
+ {
+ fw = -fw;
+ ljust = 1;
+ }
+ }
+ else if (DIGIT (*fmt))
+ {
+ mfw = *fmt++ - '0';
+ while (DIGIT (*fmt))
+ mfw = (mfw * 10) + (*fmt++ - '0');
+ fw = (mfw < 0 || mfw > INT_MAX) ? INT_MAX : mfw;
+ }
+
+ /* get precision, if present */
+ if (*fmt == '.')
+ {
+ fmt++;
+ if (*fmt == '*')
+ {
+ fmt++;
+ pr = precision;
+ }
+ else if (DIGIT (*fmt))
+ {
+ mpr = *fmt++ - '0';
+ while (DIGIT (*fmt))
+ mpr = (mpr * 10) + (*fmt++ - '0');
+ pr = (mpr < 0 || mpr > INT_MAX) ? INT_MAX : mpr;
+ }
+ }
+
+#if 0
+ /* If we remove this, get rid of `s'. */
+ if (*fmt != 'b' && *fmt != 'q')
+ {
+ internal_error ("format parsing problem: %s", s);
+ fw = pr = 0;
+ }
+#endif
+
+ /* chars from string to print */
+ nc = (pr >= 0 && pr <= len) ? pr : len;
+
+ padlen = fw - nc;
+ if (padlen < 0)
+ padlen = 0;
+ if (ljust)
+ padlen = -padlen;
+
+ /* leading pad characters */
+ for (; padlen > 0; padlen--)
+ PC (' ');
+
+ /* output NC characters from STRING */
+ for (i = 0; i < nc; i++)
+ PC (string[i]);
+
+ /* output any necessary trailing padding */
+ for (; padlen < 0; padlen++)
+ PC (' ');
+
+ return (ferror (stdout) ? -1 : 0);
+}
+
+/* Convert STRING by expanding the escape sequences specified by the
+ POSIX standard for printf's `%b' format string. If SAWC is non-null,
+ perform the processing appropriate for %b arguments. In particular,
+ recognize `\c' and use that as a string terminator. If we see \c, set
+ *SAWC to 1 before returning. LEN is the length of STRING. */
+
+/* Translate a single backslash-escape sequence starting at ESTART (the
+ character after the backslash) and return the number of characters
+ consumed by the sequence. CP is the place to return the translated
+ value. *SAWC is set to 1 if the escape sequence was \c, since that means
+ to short-circuit the rest of the processing. If SAWC is null, we don't
+ do the \c short-circuiting, and \c is treated as an unrecognized escape
+ sequence; we also bypass the other processing specific to %b arguments. */
+static int
+tescape (estart, cp, lenp, sawc)
+ char *estart;
+ char *cp;
+ int *lenp, *sawc;
+{
+ register char *p;
+ int temp, c, evalue;
+ unsigned long uvalue;
+
+ p = estart;
+ if (lenp)
+ *lenp = 1;
+
+ switch (c = *p++)
+ {
+#if defined (__STDC__)
+ case 'a': *cp = '\a'; break;
+#else
+ case 'a': *cp = '\007'; break;
+#endif
+
+ case 'b': *cp = '\b'; break;
+
+ case 'e':
+ case 'E': *cp = '\033'; break; /* ESC -- non-ANSI */
+
+ case 'f': *cp = '\f'; break;
+
+ case 'n': *cp = '\n'; break;
+
+ case 'r': *cp = '\r'; break;
+
+ case 't': *cp = '\t'; break;
+
+ case 'v': *cp = '\v'; break;
+
+ /* The octal escape sequences are `\0' followed by up to three octal
+ digits (if SAWC), or `\' followed by up to three octal digits (if
+ !SAWC). As an extension, we allow the latter form even if SAWC. */
+ case '0': case '1': case '2': case '3':
+ case '4': case '5': case '6': case '7':
+ evalue = OCTVALUE (c);
+ for (temp = 2 + (!evalue && !!sawc); ISOCTAL (*p) && temp--; p++)
+ evalue = (evalue * 8) + OCTVALUE (*p);
+ *cp = evalue & 0xFF;
+ break;
+
+ /* And, as another extension, we allow \xNN, where each N is a
+ hex digit. */
+ case 'x':
+ for (temp = 2, evalue = 0; ISXDIGIT ((unsigned char)*p) && temp--; p++)
+ evalue = (evalue * 16) + HEXVALUE (*p);
+ if (p == estart + 1)
+ {
+ builtin_error (_("missing hex digit for \\x"));
+ *cp = '\\';
+ return 0;
+ }
+ *cp = evalue & 0xFF;
+ break;
+
+#if defined (HANDLE_MULTIBYTE)
+ case 'u':
+ case 'U':
+ temp = (c == 'u') ? 4 : 8; /* \uNNNN \UNNNNNNNN */
+ for (uvalue = 0; ISXDIGIT ((unsigned char)*p) && temp--; p++)
+ uvalue = (uvalue * 16) + HEXVALUE (*p);
+ if (p == estart + 1)
+ {
+ builtin_error (_("missing unicode digit for \\%c"), c);
+ *cp = '\\';
+ return 0;
+ }
+ if (uvalue <= UCHAR_MAX)
+ *cp = uvalue;
+ else
+ {
+ temp = u32cconv (uvalue, cp);
+ cp[temp] = '\0';
+ if (lenp)
+ *lenp = temp;
+ }
+ break;
+#endif
+
+ case '\\': /* \\ -> \ */
+ *cp = c;
+ break;
+
+ /* SAWC == 0 means that \', \", and \? are recognized as escape
+ sequences, though the only processing performed is backslash
+ removal. */
+ case '\'': case '"': case '?':
+ if (!sawc)
+ *cp = c;
+ else
+ {
+ *cp = '\\';
+ return 0;
+ }
+ break;
+
+ case 'c':
+ if (sawc)
+ {
+ *sawc = 1;
+ break;
+ }
+ /* other backslash escapes are passed through unaltered */
+ default:
+ *cp = '\\';
+ return 0;
+ }
+ return (p - estart);
+}
+
+static char *
+bexpand (string, len, sawc, lenp)
+ char *string;
+ int len, *sawc, *lenp;
+{
+ int temp;
+ char *ret, *r, *s, c;
+#if defined (HANDLE_MULTIBYTE)
+ char mbch[25];
+ int mbind, mblen;
+#endif
+
+ if (string == 0 || len == 0)
+ {
+ if (sawc)
+ *sawc = 0;
+ if (lenp)
+ *lenp = 0;
+ return ((char *)NULL);
+ }
+
+ ret = (char *)xmalloc (len + 1);
+ for (r = ret, s = string; s && *s; )
+ {
+ c = *s++;
+ if (c != '\\' || *s == '\0')
+ {
+ *r++ = c;
+ continue;
+ }
+ temp = 0;
+#if defined (HANDLE_MULTIBYTE)
+ memset (mbch, '\0', sizeof (mbch));
+ s += tescape (s, mbch, &mblen, &temp);
+#else
+ s += tescape (s, &c, (int *)NULL, &temp);
+#endif
+ if (temp)
+ {
+ if (sawc)
+ *sawc = 1;
+ break;
+ }
+
+#if defined (HANDLE_MULTIBYTE)
+ for (mbind = 0; mbind < mblen; mbind++)
+ *r++ = mbch[mbind];
+#else
+ *r++ = c;
+#endif
+ }
+
+ *r = '\0';
+ if (lenp)
+ *lenp = r - ret;
+ return ret;
+}
+
+static char *
+vbadd (buf, blen)
+ char *buf;
+ int blen;
+{
+ size_t nlen;
+
+ nlen = vblen + blen + 1;
+ if (nlen >= vbsize)
+ {
+ vbsize = ((nlen + 63) >> 6) << 6;
+ vbuf = (char *)xrealloc (vbuf, vbsize);
+ }
+
+ if (blen == 1)
+ vbuf[vblen++] = buf[0];
+ else if (blen > 1)
+ {
+ FASTCOPY (buf, vbuf + vblen, blen);
+ vblen += blen;
+ }
+ vbuf[vblen] = '\0';
+
+#ifdef DEBUG
+ if (strlen (vbuf) != vblen)
+ internal_error ("printf:vbadd: vblen (%d) != strlen (vbuf) (%d)", vblen, (int)strlen (vbuf));
+#endif
+
+ return vbuf;
+}
+
+static int
+#if defined (PREFER_STDARG)
+vbprintf (const char *format, ...)
+#else
+vbprintf (format, va_alist)
+ const char *format;
+ va_dcl
+#endif
+{
+ va_list args;
+ size_t nlen;
+ int blen;
+
+ SH_VA_START (args, format);
+ blen = vsnprintf (vbuf + vblen, vbsize - vblen, format, args);
+ va_end (args);
+
+ nlen = vblen + blen + 1;
+ if (nlen >= vbsize)
+ {
+ vbsize = ((nlen + 63) >> 6) << 6;
+ vbuf = (char *)xrealloc (vbuf, vbsize);
+ SH_VA_START (args, format);
+ blen = vsnprintf (vbuf + vblen, vbsize - vblen, format, args);
+ va_end (args);
+ }
+
+ vblen += blen;
+ vbuf[vblen] = '\0';
+
+#ifdef DEBUG
+ if (strlen (vbuf) != vblen)
+ internal_error ("printf:vbadd: vblen (%d) != strlen (vbuf) (%d)", vblen, (int)strlen (vbuf));
+#endif
+
+ return (blen);
+}
+
+static char *
+mklong (str, modifiers, mlen)
+ char *str;
+ char *modifiers;
+ size_t mlen;
+{
+ size_t len, slen;
+
+ slen = strlen (str);
+ len = slen + mlen + 1;
+
+ if (len > conv_bufsize)
+ {
+ conv_bufsize = (((len + 1023) >> 10) << 10);
+ conv_buf = (char *)xrealloc (conv_buf, conv_bufsize);
+ }
+
+ FASTCOPY (str, conv_buf, slen - 1);
+ FASTCOPY (modifiers, conv_buf + slen - 1, mlen);
+
+ conv_buf[len - 2] = str[slen - 1];
+ conv_buf[len - 1] = '\0';
+ return (conv_buf);
+}
+
+static int
+getchr ()
+{
+ int ret;
+
+ if (garglist == 0)
+ return ('\0');
+
+ ret = (int)garglist->word->word[0];
+ garglist = garglist->next;
+ return ret;
+}
+
+static char *
+getstr ()
+{
+ char *ret;
+
+ if (garglist == 0)
+ return ("");
+
+ ret = garglist->word->word;
+ garglist = garglist->next;
+ return ret;
+}
+
+static int
+getint ()
+{
+ intmax_t ret;
+
+ ret = getintmax ();
+
+ if (garglist == 0)
+ return ret;
+
+ if (ret > INT_MAX)
+ {
+ printf_erange (garglist->word->word);
+ ret = INT_MAX;
+ }
+ else if (ret < INT_MIN)
+ {
+ printf_erange (garglist->word->word);
+ ret = INT_MIN;
+ }
+
+ return ((int)ret);
+}
+
+static intmax_t
+getintmax ()
+{
+ intmax_t ret;
+ char *ep;
+
+ if (garglist == 0)
+ return (0);
+
+ if (garglist->word->word[0] == '\'' || garglist->word->word[0] == '"')
+ return asciicode ();
+
+ errno = 0;
+ ret = strtoimax (garglist->word->word, &ep, 0);
+
+ if (*ep)
+ {
+ sh_invalidnum (garglist->word->word);
+ /* POSIX.2 says ``...a diagnostic message shall be written to standard
+ error, and the utility shall not exit with a zero exit status, but
+ shall continue processing any remaining operands and shall write the
+ value accumulated at the time the error was detected to standard
+ output.'' Yecch. */
+#if 0
+ ret = 0; /* return partially-converted value from strtoimax */
+#endif
+ conversion_error = 1;
+ }
+ else if (errno == ERANGE)
+ printf_erange (garglist->word->word);
+
+ garglist = garglist->next;
+ return (ret);
+}
+
+static uintmax_t
+getuintmax ()
+{
+ uintmax_t ret;
+ char *ep;
+
+ if (garglist == 0)
+ return (0);
+
+ if (garglist->word->word[0] == '\'' || garglist->word->word[0] == '"')
+ return asciicode ();
+
+ errno = 0;
+ ret = strtoumax (garglist->word->word, &ep, 0);
+
+ if (*ep)
+ {
+ sh_invalidnum (garglist->word->word);
+ /* Same POSIX.2 conversion error requirements as getintmax(). */
+ ret = 0;
+ conversion_error = 1;
+ }
+ else if (errno == ERANGE)
+ printf_erange (garglist->word->word);
+
+ garglist = garglist->next;
+ return (ret);
+}
+
+static floatmax_t
+getfloatmax ()
+{
+ floatmax_t ret;
+ char *ep;
+
+ if (garglist == 0)
+ return (0);
+
+ if (garglist->word->word[0] == '\'' || garglist->word->word[0] == '"')
+ return asciicode ();
+
+ errno = 0;
+ ret = strtofltmax (garglist->word->word, &ep);
+
+ if (*ep)
+ {
+ sh_invalidnum (garglist->word->word);
+ /* Same thing about POSIX.2 conversion error requirements. */
+ ret = 0;
+ conversion_error = 1;
+ }
+ else if (errno == ERANGE)
+ printf_erange (garglist->word->word);
+
+ garglist = garglist->next;
+ return (ret);
+}
+
+/* NO check is needed for garglist here. */
+static intmax_t
+asciicode ()
+{
+ register intmax_t ch;
+#if defined (HANDLE_MULTIBYTE)
+ wchar_t wc;
+ size_t mblength, slen;
+#endif
+ DECLARE_MBSTATE;
+
+#if defined (HANDLE_MULTIBYTE)
+ slen = strlen (garglist->word->word+1);
+ mblength = MBLEN (garglist->word->word+1, slen);
+ if (mblength > 1)
+ {
+ mblength = mbtowc (&wc, garglist->word->word+1, slen);
+ ch = wc; /* XXX */
+ }
+ else
+#endif
+ ch = (unsigned char)garglist->word->word[1];
+
+ garglist = garglist->next;
+ return (ch);
+}
+
+static SHELL_VAR *
+bind_printf_variable (name, value, flags)
+ char *name;
+ char *value;
+ int flags;
+{
+#if defined (ARRAY_VARS)
+ if (valid_array_reference (name) == 0)
+ return (bind_variable (name, value, flags));
+ else
+ return (assign_array_element (name, value, flags));
+#else /* !ARRAY_VARS */
+ return bind_variable (name, value, flags);
+#endif /* !ARRAY_VARS */
+}
.\" Case Western Reserve University
.\" chet@po.cwru.edu
.\"
-.\" Last Change: Thu Jul 7 07:26:51 EDT 2011
+.\" Last Change: Thu Jul 28 18:11:21 EDT 2011
.\"
.\" bash_builtins, strip all but Built-Ins section
.if \n(zZ=1 .ig zZ
.if \n(zY=1 .ig zY
-.TH BASH 1 "2011 July 7" "GNU Bash 4.2"
+.TH BASH 1 "2011 July 28" "GNU Bash 4.2"
.\"
.\" There's some problem with having a `@'
.\" in a tagged paragraph with the BSD man macros.
and
.B local
builtin commands.
+When in \fIposix mode\fP, these builtins may appear in a command after
+one or more instances of the \fBcommand\fP builtin and retain these
+assignment statement properties.
.PP
In the context where an assignment statement is assigning a value
to a shell variable or array index, the += operator can be used to
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
+than or equal to 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
status.
An argument of
.B \-
-is equivalent to
+is converted to
.SM
-.BR $OLDPWD .
+.B $OLDPWD
+before the directory change is attempted.
If a non-empty directory name from
.SM
.B CDPATH
Adds
.I dir
to the directory stack at the top, making it the
-new current working directory.
+new current working directory as if it had been supplied as the argument
+to the \fBcd\fP builtin.
.PD
.PP
If the
--- /dev/null
+.\"
+.\" MAN PAGE COMMENTS to
+.\"
+.\" Chet Ramey
+.\" Case Western Reserve University
+.\" chet@po.cwru.edu
+.\"
+.\" Last Change: Sun Jul 24 13:20:45 EDT 2011
+.\"
+.\" bash_builtins, strip all but Built-Ins section
+.if \n(zZ=1 .ig zZ
+.if \n(zY=1 .ig zY
+.TH BASH 1 "2011 July 24" "GNU Bash 4.2"
+.\"
+.\" There's some problem with having a `@'
+.\" in a tagged paragraph with the BSD man macros.
+.\" It has to do with `@' appearing in the }1 macro.
+.\" This is a problem on 4.3 BSD and Ultrix, but Sun
+.\" appears to have fixed it.
+.\" If you're seeing the characters
+.\" `@u-3p' appearing before the lines reading
+.\" `possible-hostname-completions
+.\" and `complete-hostname' down in READLINE,
+.\" then uncomment this redefinition.
+.\"
+.de }1
+.ds ]X \&\\*(]B\\
+.nr )E 0
+.if !"\\$1"" .nr )I \\$1n
+.}f
+.ll \\n(LLu
+.in \\n()Ru+\\n(INu+\\n()Iu
+.ti \\n(INu
+.ie !\\n()Iu+\\n()Ru-\w\a\\*(]X\au-3p \{\\*(]X
+.br\}
+.el \\*(]X\h\a|\\n()Iu+\\n()Ru\a\c
+.}f
+..
+.\"
+.\" File Name macro. This used to be `.PN', for Path Name,
+.\" but Sun doesn't seem to like that very much.
+.\"
+.de FN
+\fI\|\\$1\|\fP
+..
+.SH NAME
+bash \- GNU Bourne-Again SHell
+.SH SYNOPSIS
+.B bash
+[options]
+[file]
+.SH COPYRIGHT
+.if n Bash is Copyright (C) 1989-2011 by the Free Software Foundation, Inc.
+.if t Bash is Copyright \(co 1989-2011 by the Free Software Foundation, Inc.
+.SH DESCRIPTION
+.B Bash
+is an \fBsh\fR-compatible command language interpreter that
+executes commands read from the standard input or from a file.
+.B Bash
+also incorporates useful features from the \fIKorn\fP and \fIC\fP
+shells (\fBksh\fP and \fBcsh\fP).
+.PP
+.B Bash
+is intended to be a conformant implementation of the
+Shell and Utilities portion of the IEEE POSIX specification
+(IEEE Standard 1003.1).
+.B Bash
+can be configured to be POSIX-conformant by default.
+.SH OPTIONS
+All of the single-character shell options documented in the
+description of the \fBset\fR builtin command can be used as options
+when the shell is invoked.
+In addition, \fBbash\fR
+interprets the following options when it is invoked:
+.PP
+.PD 0
+.TP 10
+.BI \-c "\| string\^"
+If the
+.B \-c
+option is present, then commands are read from
+.IR string .
+If there are arguments after the
+.IR string ,
+they are assigned to the positional parameters, starting with
+.BR $0 .
+.TP
+.B \-i
+If the
+.B \-i
+option is present, the shell is
+.IR interactive .
+.TP
+.B \-l
+Make
+.B bash
+act as if it had been invoked as a login shell (see
+.SM
+.B INVOCATION
+below).
+.TP
+.B \-r
+If the
+.B \-r
+option is present, the shell becomes
+.I restricted
+(see
+.SM
+.B "RESTRICTED SHELL"
+below).
+.TP
+.B \-s
+If the
+.B \-s
+option is present, or if no arguments remain after option
+processing, then commands are read from the standard input.
+This option allows the positional parameters to be set
+when invoking an interactive shell.
+.TP
+.B \-D
+A list of all double-quoted strings preceded by \fB$\fP
+is printed on the standard output.
+These are the strings that
+are subject to language translation when the current locale
+is not \fBC\fP or \fBPOSIX\fP.
+This implies the \fB\-n\fP option; no commands will be executed.
+.TP
+.B [\-+]O [\fIshopt_option\fP]
+\fIshopt_option\fP is one of the shell options accepted by the
+\fBshopt\fP builtin (see
+.SM
+.B SHELL BUILTIN COMMANDS
+below).
+If \fIshopt_option\fP is present, \fB\-O\fP sets the value of that option;
+\fB+O\fP unsets it.
+If \fIshopt_option\fP is not supplied, the names and values of the shell
+options accepted by \fBshopt\fP are printed on the standard output.
+If the invocation option is \fB+O\fP, the output is displayed in a format
+that may be reused as input.
+.TP
+.B \-\-
+A
+.B \-\-
+signals the end of options and disables further option processing.
+Any arguments after the
+.B \-\-
+are treated as filenames and arguments. An argument of
+.B \-
+is equivalent to \fB\-\-\fP.
+.PD
+.PP
+.B Bash
+also interprets a number of multi-character options.
+These options must appear on the command line before the
+single-character options to be recognized.
+.PP
+.PD 0
+.TP
+.B \-\-debugger
+Arrange for the debugger profile to be executed before the shell
+starts.
+Turns on extended debugging mode (see the description of the
+.B extdebug
+option to the
+.B shopt
+builtin below).
+.TP
+.B \-\-dump\-po\-strings
+Equivalent to \fB\-D\fP, but the output is in the GNU \fIgettext\fP
+\fBpo\fP (portable object) file format.
+.TP
+.B \-\-dump\-strings
+Equivalent to \fB\-D\fP.
+.TP
+.B \-\-help
+Display a usage message on standard output and exit successfully.
+.TP
+\fB\-\-init\-file\fP \fIfile\fP
+.PD 0
+.TP
+\fB\-\-rcfile\fP \fIfile\fP
+.PD
+Execute commands from
+.I file
+instead of the standard personal initialization file
+.I ~/.bashrc
+if the shell is interactive (see
+.SM
+.B INVOCATION
+below).
+.TP
+.B \-\-login
+Equivalent to \fB\-l\fP.
+.TP
+.B \-\-noediting
+Do not use the GNU
+.B readline
+library to read command lines when the shell is interactive.
+.TP
+.B \-\-noprofile
+Do not read either the system-wide startup file
+.FN /etc/profile
+or any of the personal initialization files
+.IR ~/.bash_profile ,
+.IR ~/.bash_login ,
+or
+.IR ~/.profile .
+By default,
+.B bash
+reads these files when it is invoked as a login shell (see
+.SM
+.B INVOCATION
+below).
+.TP
+.B \-\-norc
+Do not read and execute the personal initialization file
+.I ~/.bashrc
+if the shell is interactive.
+This option is on by default if the shell is invoked as
+.BR sh .
+.TP
+.B \-\-posix
+Change the behavior of \fBbash\fP where the default operation differs
+from the POSIX standard to match the standard (\fIposix mode\fP).
+.TP
+.B \-\-restricted
+The shell becomes restricted (see
+.SM
+.B "RESTRICTED SHELL"
+below).
+.TP
+.B \-\-verbose
+Equivalent to \fB\-v\fP.
+.TP
+.B \-\-version
+Show version information for this instance of
+.B bash
+on the standard output and exit successfully.
+.PD
+.SH ARGUMENTS
+If arguments remain after option processing, and neither the
+.B \-c
+nor the
+.B \-s
+option has been supplied, the first argument is assumed to
+be the name of a file containing shell commands.
+If
+.B bash
+is invoked in this fashion,
+.B $0
+is set to the name of the file, and the positional parameters
+are set to the remaining arguments.
+.B Bash
+reads and executes commands from this file, then exits.
+\fBBash\fP's exit status is the exit status of the last command
+executed in the script.
+If no commands are executed, the exit status is 0.
+An attempt is first made to open the file in the current directory, and,
+if no file is found, then the shell searches the directories in
+.SM
+.B PATH
+for the script.
+.SH INVOCATION
+A \fIlogin shell\fP is one whose first character of argument zero is a
+.BR \- ,
+or one started with the
+.B \-\-login
+option.
+.PP
+An \fIinteractive\fP shell is one started without non-option arguments
+and without the
+.B \-c
+option
+whose standard input and error are
+both connected to terminals (as determined by
+.IR isatty (3)),
+or one started with the
+.B \-i
+option.
+.SM
+.B PS1
+is set and
+.B $\-
+includes
+.B i
+if
+.B bash
+is interactive,
+allowing a shell script or a startup file to test this state.
+.PP
+The following paragraphs describe how
+.B bash
+executes its startup files.
+If any of the files exist but cannot be read,
+.B bash
+reports an error.
+Tildes are expanded in file names as described below under
+.B "Tilde Expansion"
+in the
+.SM
+.B EXPANSION
+section.
+.PP
+When
+.B bash
+is invoked as an interactive login shell, or as a non-interactive shell
+with the \fB\-\-login\fP option, it first reads and
+executes commands from the file \fI/etc/profile\fP, if that
+file exists.
+After reading that file, it looks for \fI~/.bash_profile\fP,
+\fI~/.bash_login\fP, and \fI~/.profile\fP, in that order, and reads
+and executes commands from the first one that exists and is readable.
+The
+.B \-\-noprofile
+option may be used when the shell is started to inhibit this behavior.
+.PP
+When a login shell exits,
+.B bash
+reads and executes commands from the file \fI~/.bash_logout\fP, if it
+exists.
+.PP
+When an interactive shell that is not a login shell is started,
+.B bash
+reads and executes commands from \fI~/.bashrc\fP, if that file exists.
+This may be inhibited by using the
+.B \-\-norc
+option.
+The \fB\-\-rcfile\fP \fIfile\fP option will force
+.B bash
+to read and execute commands from \fIfile\fP instead of \fI~/.bashrc\fP.
+.PP
+When
+.B bash
+is started non-interactively, to run a shell script, for example, it
+looks for the variable
+.SM
+.B BASH_ENV
+in the environment, expands its value if it appears there, and uses the
+expanded value as the name of a file to read and execute.
+.B Bash
+behaves as if the following command were executed:
+.sp .5
+.RS
+.if t \f(CWif [ \-n "$BASH_ENV" ]; then . "$BASH_ENV"; fi\fP
+.if n if [ \-n "$BASH_ENV" ]; then . "$BASH_ENV"; fi
+.RE
+.sp .5
+but the value of the
+.SM
+.B PATH
+variable is not used to search for the file name.
+.PP
+If
+.B bash
+is invoked with the name
+.BR sh ,
+it tries to mimic the startup behavior of historical versions of
+.B sh
+as closely as possible,
+while conforming to the POSIX standard as well.
+When invoked as an interactive login shell, or a non-interactive
+shell with the \fB\-\-login\fP option, it first attempts to
+read and execute commands from
+.I /etc/profile
+and
+.IR ~/.profile ,
+in that order.
+The
+.B \-\-noprofile
+option may be used to inhibit this behavior.
+When invoked as an interactive shell with the name
+.BR sh ,
+.B bash
+looks for the variable
+.SM
+.BR ENV ,
+expands its value if it is defined, and uses the
+expanded value as the name of a file to read and execute.
+Since a shell invoked as
+.B sh
+does not attempt to read and execute commands from any other startup
+files, the
+.B \-\-rcfile
+option has no effect.
+A non-interactive shell invoked with the name
+.B sh
+does not attempt to read any other startup files.
+When invoked as
+.BR sh ,
+.B bash
+enters
+.I posix
+mode after the startup files are read.
+.PP
+When
+.B bash
+is started in
+.I posix
+mode, as with the
+.B \-\-posix
+command line option, it follows the POSIX standard for startup files.
+In this mode, interactive shells expand the
+.SM
+.B ENV
+variable and commands are read and executed from the file
+whose name is the expanded value.
+No other startup files are read.
+.PP
+.B Bash
+attempts to determine when it is being run with its standard input
+connected to a network connection, as when executed by the remote shell
+daemon, usually \fIrshd\fP, or the secure shell daemon \fIsshd\fP.
+If
+.B bash
+determines it is being run in this fashion, it reads and executes
+commands from \fI~/.bashrc\fP, if that file exists and is readable.
+It will not do this if invoked as \fBsh\fP.
+The
+.B \-\-norc
+option may be used to inhibit this behavior, and the
+.B \-\-rcfile
+option may be used to force another file to be read, but
+\fIrshd\fP does not generally invoke the shell with those options
+or allow them to be specified.
+.PP
+If the shell is started with the effective user (group) id not equal to the
+real user (group) id, and the \fB\-p\fP option is not supplied, no startup
+files are read, shell functions are not inherited from the environment, the
+.SM
+.BR SHELLOPTS ,
+.SM
+.BR BASHOPTS ,
+.SM
+.BR CDPATH ,
+and
+.SM
+.B GLOBIGNORE
+variables, if they appear in the environment, are ignored,
+and the effective user id is set to the real user id.
+If the \fB\-p\fP option is supplied at invocation, the startup behavior is
+the same, but the effective user id is not reset.
+.SH DEFINITIONS
+.PP
+The following definitions are used throughout the rest of this
+document.
+.PD 0
+.TP
+.B blank
+A space or tab.
+.TP
+.B word
+A sequence of characters considered as a single unit by the shell.
+Also known as a
+.BR token .
+.TP
+.B name
+A
+.I word
+consisting only of alphanumeric characters and underscores, and
+beginning with an alphabetic character or an underscore. Also
+referred to as an
+.BR identifier .
+.TP
+.B metacharacter
+A character that, when unquoted, separates words. One of the following:
+.br
+.RS
+.PP
+.if t \fB| & ; ( ) < > space tab\fP
+.if n \fB| & ; ( ) < > space tab\fP
+.RE
+.PP
+.TP
+.B control operator
+A \fItoken\fP that performs a control function. It is one of the following
+symbols:
+.RS
+.PP
+.if t \fB|| & && ; ;; ( ) | |& <newline>\fP
+.if n \fB|| & && ; ;; ( ) | |& <newline>\fP
+.RE
+.PD
+.SH "RESERVED WORDS"
+\fIReserved words\fP are words that have a special meaning to the shell.
+The following words are recognized as reserved when unquoted and either
+the first word of a simple command (see
+.SM
+.B SHELL GRAMMAR
+below) or the third word of a
+.B case
+or
+.B for
+command:
+.if t .RS
+.PP
+.B
+.if n ! case do done elif else esac fi for function if in select then until while { } time [[ ]]
+.if t ! case do done elif else esac fi for function if in select then until while { } time [[ ]]
+.if t .RE
+.SH "SHELL GRAMMAR"
+.SS Simple Commands
+.PP
+A \fIsimple command\fP is a sequence of optional variable assignments
+followed by \fBblank\fP-separated words and redirections, and
+terminated by a \fIcontrol operator\fP. The first word
+specifies the command to be executed, and is passed as argument zero.
+The remaining words are passed as arguments to the invoked command.
+.PP
+The return value of a \fIsimple command\fP is its exit status, or
+128+\fIn\^\fP if the command is terminated by signal
+.IR n .
+.SS Pipelines
+.PP
+A \fIpipeline\fP is a sequence of one or more commands separated by
+one of the control operators
+.B |
+or \fB|&\fP.
+The format for a pipeline is:
+.RS
+.PP
+[\fBtime\fP [\fB\-p\fP]] [ ! ] \fIcommand\fP [ [\fB|\fP\(bv\fB|&\fP] \fIcommand2\fP ... ]
+.RE
+.PP
+The standard output of
+.I command
+is connected via a pipe to the standard input of
+.IR command2 .
+This connection is performed before any redirections specified by the
+command (see
+.SM
+.B REDIRECTION
+below).
+If \fB|&\fP is used, the standard error of \fIcommand\fP is connected to
+\fIcommand2\fP's standard input through the pipe; it is shorthand for
+\fB2>&1 |\fP.
+This implicit redirection of the standard error is performed after any
+redirections specified by the command.
+.PP
+The return status of a pipeline is the exit status of the last
+command, unless the \fBpipefail\fP option is enabled.
+If \fBpipefail\fP is enabled, the pipeline's return status is the
+value of the last (rightmost) command to exit with a non-zero status,
+or zero if all commands exit successfully.
+If the reserved word
+.B !
+precedes a pipeline, the exit status of that pipeline is the logical
+negation of the exit status as described above.
+The shell waits for all commands in the pipeline to
+terminate before returning a value.
+.PP
+If the
+.B time
+reserved word precedes a pipeline, the elapsed as well as user and
+system time consumed by its execution are reported when the pipeline
+terminates.
+The \fB\-p\fP option changes the output format to that specified by POSIX.
+When the shell is in \fIposix mode\fP, it does not recognize
+\fBtime\fP as a reserved word if the next token begins with a `-'.
+The
+.SM
+.B TIMEFORMAT
+variable may be set to a format string that specifies how the timing
+information should be displayed; see the description of
+.SM
+.B TIMEFORMAT
+under
+.B "Shell Variables"
+below.
+.PP
+When the shell is in \fIposix mode\fP, \fBtime\fP
+may be followed by a newline. In this case, the shell displays the
+total user and system time consumed by the shell and its children.
+The
+.SM
+.B TIMEFORMAT
+variable may be used to specify the format of
+the time information.
+.PP
+Each command in a pipeline is executed as a separate process (i.e., in a
+subshell).
+.SS Lists
+.PP
+A \fIlist\fP is a sequence of one or more pipelines separated by one
+of the operators
+.BR ; ,
+.BR & ,
+.BR && ,
+or
+.BR || ,
+and optionally terminated by one of
+.BR ; ,
+.BR & ,
+or
+.BR <newline> .
+.PP
+Of these list operators,
+.B &&
+and
+.B ||
+have equal precedence, followed by
+.B ;
+and
+.BR & ,
+which have equal precedence.
+.PP
+A sequence of one or more newlines may appear in a \fIlist\fP instead
+of a semicolon to delimit commands.
+.PP
+If a command is terminated by the control operator
+.BR & ,
+the shell executes the command in the \fIbackground\fP
+in a subshell. The shell does not wait for the command to
+finish, and the return status is 0. Commands separated by a
+.B ;
+are executed sequentially; the shell waits for each
+command to terminate in turn. The return status is the
+exit status of the last command executed.
+.PP
+AND and OR lists are sequences of one of more pipelines separated by the
+\fB&&\fP and \fB||\fP control operators, respectively.
+AND and OR lists are executed with left associativity.
+An AND list has the form
+.RS
+.PP
+\fIcommand1\fP \fB&&\fP \fIcommand2\fP
+.RE
+.PP
+.I command2
+is executed if, and only if,
+.I command1
+returns an exit status of zero.
+.PP
+An OR list has the form
+.RS
+.PP
+\fIcommand1\fP \fB||\fP \fIcommand2\fP
+.PP
+.RE
+.PP
+.I command2
+is executed if and only if
+.I command1
+returns a non-zero exit status.
+The return status of
+AND and OR lists is the exit status of the last command
+executed in the list.
+.SS Compound Commands
+.PP
+A \fIcompound command\fP is one of the following.
+In most cases a \fIlist\fP in a command's description may be separated from
+the rest of the command by one or more newlines, and may be followed by a
+newline in place of a semicolon.
+.TP
+(\fIlist\fP)
+\fIlist\fP is executed in a subshell environment (see
+.SM
+\fBCOMMAND EXECUTION ENVIRONMENT\fP
+below).
+Variable assignments and builtin
+commands that affect the shell's environment do not remain in effect
+after the command completes. The return status is the exit status of
+\fIlist\fP.
+.TP
+{ \fIlist\fP; }
+\fIlist\fP is simply executed in the current shell environment.
+\fIlist\fP must be terminated with a newline or semicolon.
+This is known as a \fIgroup command\fP.
+The return status is the exit status of
+\fIlist\fP.
+Note that unlike the metacharacters \fB(\fP and \fB)\fP, \fB{\fP and
+\fB}\fP are \fIreserved words\fP and must occur where a reserved
+word is permitted to be recognized. Since they do not cause a word
+break, they must be separated from \fIlist\fP by whitespace or another
+shell metacharacter.
+.TP
+((\fIexpression\fP))
+The \fIexpression\fP is evaluated according to the rules described
+below under
+.SM
+.BR "ARITHMETIC EVALUATION" .
+If the value of the expression is non-zero, the return status is 0;
+otherwise the return status is 1. This is exactly equivalent to
+\fBlet "\fIexpression\fP"\fR.
+.TP
+\fB[[\fP \fIexpression\fP \fB]]\fP
+Return a status of 0 or 1 depending on the evaluation of
+the conditional expression \fIexpression\fP.
+Expressions are composed of the primaries described below under
+.SM
+.BR "CONDITIONAL EXPRESSIONS" .
+Word splitting and pathname expansion are not performed on the words
+between the \fB[[\fP and \fB]]\fP; tilde expansion, parameter and
+variable expansion, arithmetic expansion, command substitution, process
+substitution, and quote removal are performed.
+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.
+If the shell option
+.B nocasematch
+is enabled, the match is performed without regard to the case
+of alphabetic characters.
+The return value is 0 if the string matches (\fB==\fP) or does not match
+(\fB!=\fP) the pattern, and 1 otherwise.
+Any part of the pattern may be quoted to force the quoted portion
+to be matched as a string.
+.if t .sp 0.5
+.if n .sp 1
+An additional binary operator, \fB=~\fP, is available, with the same
+precedence as \fB==\fP and \fB!=\fP.
+When it is used, the string to the right of the operator is considered
+an extended regular expression and matched accordingly (as in \fIregex\fP(3)).
+The return value is 0 if the string matches
+the pattern, and 1 otherwise.
+If the regular expression is syntactically incorrect, the conditional
+expression's return value is 2.
+If the shell option
+.B nocasematch
+is enabled, the match is performed without regard to the case
+of alphabetic characters.
+Any part of the pattern may be quoted to force the quoted portion
+to be matched as a string.
+Substrings matched by parenthesized subexpressions within the regular
+expression are saved in the array variable
+.SM
+.BR BASH_REMATCH .
+The element of
+.SM
+.B BASH_REMATCH
+with index 0 is the portion of the string
+matching the entire regular expression.
+The element of
+.SM
+.B BASH_REMATCH
+with index \fIn\fP is the portion of the
+string matching the \fIn\fPth parenthesized subexpression.
+.if t .sp 0.5
+.if n .sp 1
+Expressions may be combined using the following operators, listed
+in decreasing order of precedence:
+.if t .sp 0.5
+.if n .sp 1
+.RS
+.PD 0
+.TP
+.B ( \fIexpression\fP )
+Returns the value of \fIexpression\fP.
+This may be used to override the normal precedence of operators.
+.TP
+.B ! \fIexpression\fP
+True if
+.I expression
+is false.
+.TP
+\fIexpression1\fP \fB&&\fP \fIexpression2\fP
+True if both
+.I expression1
+and
+.I expression2
+are true.
+.TP
+\fIexpression1\fP \fB||\fP \fIexpression2\fP
+True if either
+.I expression1
+or
+.I expression2
+is true.
+.PD
+.LP
+The \fB&&\fP and \fB||\fP
+operators do not evaluate \fIexpression2\fP if the value of
+\fIexpression1\fP is sufficient to determine the return value of
+the entire conditional expression.
+.RE
+.TP
+\fBfor\fP \fIname\fP [ [ \fBin\fP [ \fIword ...\fP ] ] ; ] \fBdo\fP \fIlist\fP ; \fBdone\fP
+The list of words following \fBin\fP is expanded, generating a list
+of items.
+The variable \fIname\fP is set to each element of this list
+in turn, and \fIlist\fP is executed each time.
+If the \fBin\fP \fIword\fP is omitted, the \fBfor\fP command executes
+\fIlist\fP once for each positional parameter that is set (see
+.SM
+.B PARAMETERS
+below).
+The return status is the exit status of the last command that executes.
+If the expansion of the items following \fBin\fP results in an empty
+list, no commands are executed, and the return status is 0.
+.TP
+\fBfor\fP (( \fIexpr1\fP ; \fIexpr2\fP ; \fIexpr3\fP )) ; \fBdo\fP \fIlist\fP ; \fBdone\fP
+First, the arithmetic expression \fIexpr1\fP is evaluated according
+to the rules described below under
+.SM
+.BR "ARITHMETIC EVALUATION" .
+The arithmetic expression \fIexpr2\fP is then evaluated repeatedly
+until it evaluates to zero.
+Each time \fIexpr2\fP evaluates to a non-zero value, \fIlist\fP is
+executed and the arithmetic expression \fIexpr3\fP is evaluated.
+If any expression is omitted, it behaves as if it evaluates to 1.
+The return value is the exit status of the last command in \fIlist\fP
+that is executed, or false if any of the expressions is invalid.
+.TP
+\fBselect\fP \fIname\fP [ \fBin\fP \fIword\fP ] ; \fBdo\fP \fIlist\fP ; \fBdone\fP
+The list of words following \fBin\fP is expanded, generating a list
+of items. The set of expanded words is printed on the standard
+error, each preceded by a number. If the \fBin\fP
+\fIword\fP is omitted, the positional parameters are printed (see
+.SM
+.B PARAMETERS
+below). The
+.SM
+.B PS3
+prompt is then displayed and a line read from the standard input.
+If the line consists of a number corresponding to one of
+the displayed words, then the value of
+.I name
+is set to that word. If the line is empty, the words and prompt
+are displayed again. If EOF is read, the command completes. Any
+other value read causes
+.I name
+to be set to null. The line read is saved in the variable
+.SM
+.BR REPLY .
+The
+.I list
+is executed after each selection until a
+.B break
+command is executed.
+The exit status of
+.B select
+is the exit status of the last command executed in
+.IR list ,
+or zero if no commands were executed.
+.TP
+\fBcase\fP \fIword\fP \fBin\fP [ [(] \fIpattern\fP [ \fB|\fP \fIpattern\fP ] \
+... ) \fIlist\fP ;; ] ... \fBesac\fP
+A \fBcase\fP command first expands \fIword\fP, and tries to match
+it against each \fIpattern\fP in turn, using the same matching rules
+as for pathname expansion (see
+.B Pathname Expansion
+below).
+The \fIword\fP is expanded using tilde
+expansion, parameter and variable expansion, arithmetic substitution,
+command substitution, process substitution and quote removal.
+Each \fIpattern\fP examined is expanded using tilde
+expansion, parameter and variable expansion, arithmetic substitution,
+command substitution, and process substitution.
+If the shell option
+.B nocasematch
+is enabled, the match is performed without regard to the case
+of alphabetic characters.
+When a match is found, the corresponding \fIlist\fP is executed.
+If the \fB;;\fP operator is used, no subsequent matches are attempted after
+the first pattern match.
+Using \fB;&\fP in place of \fB;;\fP causes execution to continue with
+the \fIlist\fP associated with the next set of patterns.
+Using \fB;;&\fP in place of \fB;;\fP causes the shell to test the next
+pattern list in the statement, if any, and execute any associated \fIlist\fP
+on a successful match.
+The exit status is zero if no
+pattern matches. Otherwise, it is the exit status of the
+last command executed in \fIlist\fP.
+.TP
+\fBif\fP \fIlist\fP; \fBthen\fP \fIlist;\fP \
+[ \fBelif\fP \fIlist\fP; \fBthen\fP \fIlist\fP; ] ... \
+[ \fBelse\fP \fIlist\fP; ] \fBfi\fP
+The
+.B if
+.I list
+is executed. If its exit status is zero, the
+\fBthen\fP \fIlist\fP is executed. Otherwise, each \fBelif\fP
+\fIlist\fP is executed in turn, and if its exit status is zero,
+the corresponding \fBthen\fP \fIlist\fP is executed and the
+command completes. Otherwise, the \fBelse\fP \fIlist\fP is
+executed, if present. The exit status is the exit status of the
+last command executed, or zero if no condition tested true.
+.TP
+\fBwhile\fP \fIlist-1\fP; \fBdo\fP \fIlist-2\fP; \fBdone\fP
+.PD 0
+.TP
+\fBuntil\fP \fIlist-1\fP; \fBdo\fP \fIlist-2\fP; \fBdone\fP
+.PD
+The \fBwhile\fP command continuously executes the list
+\fIlist-2\fP as long as the last command in the list \fIlist-1\fP returns
+an exit status of zero. The \fBuntil\fP command is identical
+to the \fBwhile\fP command, except that the test is negated;
+.I list-2
+is executed as long as the last command in
+.I list-1
+returns a non-zero exit status.
+The exit status of the \fBwhile\fP and \fBuntil\fP commands
+is the exit status
+of the last command executed in \fIlist-2\fP, or zero if
+none was executed.
+.SS Coprocesses
+.PP
+A \fIcoprocess\fP is a shell command preceded by the \fBcoproc\fP reserved
+word.
+A coprocess is executed asynchronously in a subshell, as if the command
+had been terminated with the \fB&\fP control operator, with a two-way pipe
+established between the executing shell and the coprocess.
+.PP
+The format for a coprocess is:
+.RS
+.PP
+\fBcoproc\fP [\fINAME\fP] \fIcommand\fP [\fIredirections\fP]
+.RE
+.PP
+This creates a coprocess named \fINAME\fP.
+If \fINAME\fP is not supplied, the default name is \fBCOPROC\fP.
+\fINAME\fP must not be supplied if \fIcommand\fP is a \fIsimple
+command\fP (see above); otherwise, it is interpreted as the first word
+of the simple command.
+When the coproc is executed, the shell creates an array variable (see
+.B Arrays
+below) named \fINAME\fP in the context of the executing shell.
+The standard output of
+.I command
+is connected via a pipe to a file descriptor in the executing shell,
+and that file descriptor is assigned to \fINAME\fP[0].
+The standard input of
+.I command
+is connected via a pipe to a file descriptor in the executing shell,
+and that file descriptor is assigned to \fINAME\fP[1].
+This pipe is established before any redirections specified by the
+command (see
+.SM
+.B REDIRECTION
+below).
+The file descriptors can be utilized as arguments to shell commands
+and redirections using standard word expansions.
+The process ID of the shell spawned to execute the coprocess is
+available as the value of the variable \fINAME\fP_PID.
+The \fBwait\fP
+builtin command may be used to wait for the coprocess to terminate.
+.PP
+The return status of a coprocess is the exit status of \fIcommand\fP.
+.SS Shell Function Definitions
+.PP
+A shell function is an object that is called like a simple command and
+executes a compound command with a new set of positional parameters.
+Shell functions are declared as follows:
+.TP
+\fIname\fP () \fIcompound\-command\fP [\fIredirection\fP]
+.PD 0
+.TP
+\fBfunction\fP \fIname\fP [()] \fIcompound\-command\fP [\fIredirection\fP]
+.PD
+This defines a function named \fIname\fP.
+The reserved word \fBfunction\fP is optional.
+If the \fBfunction\fP reserved word is supplied, the parentheses are optional.
+The \fIbody\fP of the function is the compound command
+.I compound\-command
+(see \fBCompound Commands\fP above).
+That command is usually a \fIlist\fP of commands between { and }, but
+may be any command listed under \fBCompound Commands\fP above.
+\fIcompound\-command\fP is executed whenever \fIname\fP is specified as the
+name of a simple command.
+Any redirections (see
+.SM
+.B REDIRECTION
+below) specified when a function is defined are performed
+when the function is executed.
+The exit status of a function definition is zero unless a syntax error
+occurs or a readonly function with the same name already exists.
+When executed, the exit status of a function is the exit status of the
+last command executed in the body. (See
+.SM
+.B FUNCTIONS
+below.)
+.SH COMMENTS
+In a non-interactive shell, or an interactive shell in which the
+.B interactive_comments
+option to the
+.B shopt
+builtin is enabled (see
+.SM
+.B "SHELL BUILTIN COMMANDS"
+below), a word beginning with
+.B #
+causes that word and all remaining characters on that line to
+be ignored. An interactive shell without the
+.B interactive_comments
+option enabled does not allow comments. The
+.B interactive_comments
+option is on by default in interactive shells.
+.SH QUOTING
+\fIQuoting\fP is used to remove the special meaning of certain
+characters or words to the shell. Quoting can be used to
+disable special treatment for special characters, to prevent
+reserved words from being recognized as such, and to prevent
+parameter expansion.
+.PP
+Each of the \fImetacharacters\fP listed above under
+.SM
+.B DEFINITIONS
+has special meaning to the shell and must be quoted if it is to
+represent itself.
+.PP
+When the command history expansion facilities are being used
+(see
+.SM
+.B HISTORY EXPANSION
+below), the
+\fIhistory expansion\fP character, usually \fB!\fP, must be quoted
+to prevent history expansion.
+.PP
+There are three quoting mechanisms: the
+.IR "escape character" ,
+single quotes, and double quotes.
+.PP
+A non-quoted backslash (\fB\e\fP) is the
+.IR "escape character" .
+It preserves the literal value of the next character that follows,
+with the exception of <newline>. If a \fB\e\fP<newline> pair
+appears, and the backslash is not itself quoted, the \fB\e\fP<newline>
+is treated as a line continuation (that is, it is removed from the
+input stream and effectively ignored).
+.PP
+Enclosing characters in single quotes preserves the literal value
+of each character within the quotes. A single quote may not occur
+between single quotes, even when preceded by a backslash.
+.PP
+Enclosing characters in double quotes preserves the literal value
+of all characters within the quotes, with the exception of
+.BR $ ,
+.BR \` ,
+.BR \e ,
+and, when history expansion is enabled,
+.BR ! .
+The characters
+.B $
+and
+.B \`
+retain their special meaning within double quotes. The backslash
+retains its special meaning only when followed by one of the following
+characters:
+.BR $ ,
+.BR \` ,
+\^\fB"\fP\^,
+.BR \e ,
+or
+.BR <newline> .
+A double quote may be quoted within double quotes by preceding it with
+a backslash.
+If enabled, history expansion will be performed unless an
+.B !
+appearing in double quotes is escaped using a backslash.
+The backslash preceding the
+.B !
+is not removed.
+.PP
+The special parameters
+.B *
+and
+.B @
+have special meaning when in double
+quotes (see
+.SM
+.B PARAMETERS
+below).
+.PP
+Words of the form \fB$\fP\(aq\fIstring\fP\(aq are treated specially. The
+word expands to \fIstring\fP, with backslash-escaped characters replaced
+as specified by the ANSI C standard. Backslash escape sequences, if
+present, are decoded as follows:
+.RS
+.PD 0
+.TP
+.B \ea
+alert (bell)
+.TP
+.B \eb
+backspace
+.TP
+.B \ee
+.TP
+.B \eE
+an escape character
+.TP
+.B \ef
+form feed
+.TP
+.B \en
+new line
+.TP
+.B \er
+carriage return
+.TP
+.B \et
+horizontal tab
+.TP
+.B \ev
+vertical tab
+.TP
+.B \e\e
+backslash
+.TP
+.B \e\(aq
+single quote
+.TP
+.B \e\(dq
+double quote
+.TP
+.B \e\fInnn\fP
+the eight-bit character whose value is the octal value \fInnn\fP
+(one to three digits)
+.TP
+.B \ex\fIHH\fP
+the eight-bit character whose value is the hexadecimal value \fIHH\fP
+(one or two hex digits)
+.TP
+.B \eu\fIHHHH\fP
+the Unicode (ISO/IEC 10646) character whose value is the hexadecimal value
+\fIHHHH\fP (one to four hex digits)
+.TP
+.B \eU\fIHHHHHHHH\fP
+the Unicode (ISO/IEC 10646) character whose value is the hexadecimal value
+\fIHHHHHHHH\fP (one to eight hex digits)
+.TP
+.B \ec\fIx\fP
+a control-\fIx\fP character
+.PD
+.RE
+.LP
+The expanded result is single-quoted, as if the dollar sign had
+not been present.
+.PP
+A double-quoted string preceded by a dollar sign (\fB$\fP\(dq\fIstring\fP\(dq)
+will cause the string to be translated according to the current locale.
+If the current locale is \fBC\fP or \fBPOSIX\fP, the dollar sign
+is ignored.
+If the string is translated and replaced, the replacement is
+double-quoted.
+.SH PARAMETERS
+A
+.I parameter
+is an entity that stores values.
+It can be a
+.IR name ,
+a number, or one of the special characters listed below under
+.BR "Special Parameters" .
+A
+.I variable
+is a parameter denoted by a
+.IR name .
+A variable has a \fIvalue\fP and zero or more \fIattributes\fP.
+Attributes are assigned using the
+.B declare
+builtin command (see
+.B declare
+below in
+.SM
+.BR "SHELL BUILTIN COMMANDS" ).
+.PP
+A parameter is set if it has been assigned a value. The null string is
+a valid value. Once a variable is set, it may be unset only by using
+the
+.B unset
+builtin command (see
+.SM
+.B SHELL BUILTIN COMMANDS
+below).
+.PP
+A
+.I variable
+may be assigned to by a statement of the form
+.RS
+.PP
+\fIname\fP=[\fIvalue\fP]
+.RE
+.PP
+If
+.I value
+is not given, the variable is assigned the null string. All
+.I values
+undergo tilde expansion, parameter and variable expansion,
+command substitution, arithmetic expansion, and quote
+removal (see
+.SM
+.B EXPANSION
+below). If the variable has its
+.B integer
+attribute set, then
+.I value
+is evaluated as an arithmetic expression even if the $((...)) expansion is
+not used (see
+.B "Arithmetic Expansion"
+below).
+Word splitting is not performed, with the exception
+of \fB"$@"\fP as explained below under
+.BR "Special Parameters" .
+Pathname expansion is not performed.
+Assignment statements may also appear as arguments to the
+.BR alias ,
+.BR declare ,
+.BR typeset ,
+.BR export ,
+.BR readonly ,
+and
+.B local
+builtin commands.
+When in \fIposix mode\fP, these builtins may appear in a command after
+one or more instances of the \fBcommand\fP builtin and retain these
+assignment statement properties.
+.PP
+In the context where an assignment statement is assigning a value
+to a shell variable or array index, the += operator can be used to
+append to or add to the variable's previous value.
+When += is applied to a variable for which the \fIinteger\fP attribute has been
+set, \fIvalue\fP is evaluated as an arithmetic expression and added to the
+variable's current value, which is also evaluated.
+When += is applied to an array variable using compound assignment (see
+.B Arrays
+below), the
+variable's value is not unset (as it is when using =), and new values are
+appended to the array beginning at one greater than the array's maximum index
+(for indexed arrays) or added as additional key\-value pairs in an
+associative array.
+When applied to a string-valued variable, \fIvalue\fP is expanded and
+appended to the variable's value.
+.SS Positional Parameters
+.PP
+A
+.I positional parameter
+is a parameter denoted by one or more
+digits, other than the single digit 0. Positional parameters are
+assigned from the shell's arguments when it is invoked,
+and may be reassigned using the
+.B set
+builtin command. Positional parameters may not be assigned to
+with assignment statements. The positional parameters are
+temporarily replaced when a shell function is executed (see
+.SM
+.B FUNCTIONS
+below).
+.PP
+When a positional parameter consisting of more than a single
+digit is expanded, it must be enclosed in braces (see
+.SM
+.B EXPANSION
+below).
+.SS Special Parameters
+.PP
+The shell treats several parameters specially. These parameters may
+only be referenced; assignment to them is not allowed.
+.PD 0
+.TP
+.B *
+Expands to the positional parameters, starting from one. When the
+expansion occurs within double quotes, it expands to a single word
+with the value of each parameter separated by the first character
+of the
+.SM
+.B IFS
+special variable. That is, "\fB$*\fP" is equivalent
+to "\fB$1\fP\fIc\fP\fB$2\fP\fIc\fP\fB...\fP", where
+.I c
+is the first character of the value of the
+.SM
+.B IFS
+variable. If
+.SM
+.B IFS
+is unset, the parameters are separated by spaces.
+If
+.SM
+.B IFS
+is null, the parameters are joined without intervening separators.
+.TP
+.B @
+Expands to the positional parameters, starting from one. When the
+expansion occurs within double quotes, each parameter expands to a
+separate word. That is, "\fB$@\fP" is equivalent to
+"\fB$1\fP" "\fB$2\fP" ...
+If the double-quoted expansion occurs within a word, the expansion of
+the first parameter is joined with the beginning part of the original
+word, and the expansion of the last parameter is joined with the last
+part of the original word.
+When there are no positional parameters, "\fB$@\fP" and
+.B $@
+expand to nothing (i.e., they are removed).
+.TP
+.B #
+Expands to the number of positional parameters in decimal.
+.TP
+.B ?
+Expands to the exit status of the most recently executed foreground
+pipeline.
+.TP
+.B \-
+Expands to the current option flags as specified upon invocation,
+by the
+.B set
+builtin command, or those set by the shell itself
+(such as the
+.B \-i
+option).
+.TP
+.B $
+Expands to the process ID of the shell. In a () subshell, it
+expands to the process ID of the current shell, not the
+subshell.
+.TP
+.B !
+Expands to the process ID of the most recently executed background
+(asynchronous) command.
+.TP
+.B 0
+Expands to the name of the shell or shell script. This is set at
+shell initialization. If
+.B bash
+is invoked with a file of commands,
+.B $0
+is set to the name of that file. If
+.B bash
+is started with the
+.B \-c
+option, then
+.B $0
+is set to the first argument after the string to be
+executed, if one is present. Otherwise, it is set
+to the file name used to invoke
+.BR bash ,
+as given by argument zero.
+.TP
+.B _
+At shell startup, set to the absolute pathname used to invoke the
+shell or shell script being executed as passed in the environment
+or argument list.
+Subsequently, expands to the last argument to the previous command,
+after expansion.
+Also set to the full pathname used to invoke each command executed
+and placed in the environment exported to that command.
+When checking mail, this parameter holds the name of the mail file
+currently being checked.
+.PD
+.SS Shell Variables
+.PP
+The following variables are set by the shell:
+.PP
+.PD 0
+.TP
+.B BASH
+Expands to the full file name used to invoke this instance of
+.BR bash .
+.TP
+.B BASHOPTS
+A colon-separated list of enabled shell options. Each word in
+the list is a valid argument for the
+.B \-s
+option to the
+.B shopt
+builtin command (see
+.SM
+.B "SHELL BUILTIN COMMANDS"
+below). The options appearing in
+.SM
+.B BASHOPTS
+are those reported as
+.I on
+by \fBshopt\fP.
+If this variable is in the environment when
+.B bash
+starts up, each shell option in the list will be enabled before
+reading any startup files.
+This variable is read-only.
+.TP
+.B BASHPID
+Expands to the process ID of the current \fBbash\fP process.
+This differs from \fB$$\fP under certain circumstances, such as subshells
+that do not require \fBbash\fP to be re-initialized.
+.TP
+.B BASH_ALIASES
+An associative array variable whose members correspond to the internal
+list of aliases as maintained by the \fBalias\fP builtin.
+Elements added to this array appear in the alias list; unsetting array
+elements cause aliases to be removed from the alias list.
+.TP
+.B BASH_ARGC
+An array variable whose values are the number of parameters in each
+frame of the current \fBbash\fP execution call stack.
+The number of
+parameters to the current subroutine (shell function or script executed
+with \fB.\fP or \fBsource\fP) is at the top of the stack.
+When a subroutine is executed, the number of parameters passed is pushed onto
+.SM
+.BR BASH_ARGC .
+The shell sets
+.SM
+.B BASH_ARGC
+only when in extended debugging mode (see the description of the
+.B extdebug
+option to the
+.B shopt
+builtin below)
+.TP
+.B BASH_ARGV
+An array variable containing all of the parameters in the current \fBbash\fP
+execution call stack. The final parameter of the last subroutine call
+is at the top of the stack; the first parameter of the initial call is
+at the bottom. When a subroutine is executed, the parameters supplied
+are pushed onto
+.SM
+.BR BASH_ARGV .
+The shell sets
+.SM
+.B BASH_ARGV
+only when in extended debugging mode
+(see the description of the
+.B extdebug
+option to the
+.B shopt
+builtin below)
+.TP
+.B BASH_CMDS
+An associative array variable whose members correspond to the internal
+hash table of commands as maintained by the \fBhash\fP builtin.
+Elements added to this array appear in the hash table; unsetting array
+elements cause commands to be removed from the hash table.
+.TP
+.B BASH_COMMAND
+The command currently being executed or about to be executed, unless the
+shell is executing a command as the result of a trap,
+in which case it is the command executing at the time of the trap.
+.TP
+.B BASH_EXECUTION_STRING
+The command argument to the \fB\-c\fP invocation option.
+.TP
+.B BASH_LINENO
+An array variable whose members are the line numbers in source files
+where each corresponding member of
+.SM
+.B FUNCNAME
+was invoked.
+\fB${BASH_LINENO[\fP\fI$i\fP\fB]}\fP is the line number in the source
+file (\fB${BASH_SOURCE[\fP\fI$i+1\fP\fB]}\fP) where
+\fB${FUNCNAME[\fP\fI$i\fP\fB]}\fP was called
+(or \fB${BASH_LINENO[\fP\fI$i-1\fP\fB]}\fP if referenced within another
+shell function).
+Use
+.SM
+.B LINENO
+to obtain the current line number.
+.TP
+.B BASH_REMATCH
+An array variable whose members are assigned by the \fB=~\fP binary
+operator to the \fB[[\fP conditional command.
+The element with index 0 is the portion of the string
+matching the entire regular expression.
+The element with index \fIn\fP is the portion of the
+string matching the \fIn\fPth parenthesized subexpression.
+This variable is read-only.
+.TP
+.B BASH_SOURCE
+An array variable whose members are the source filenames
+where the corresponding shell function names in the
+.SM
+.B FUNCNAME
+array variable are defined.
+The shell function
+\fB${FUNCNAME[\fP\fI$i\fP\fB]}\fP is defined in the file
+\fB${BASH_SOURCE[\fP\fI$i\fP\fB]}\fP and called from
+\fB${BASH_SOURCE[\fP\fI$i+1\fP\fB]}\fP.
+.TP
+.B BASH_SUBSHELL
+Incremented by one within each subshell or subshell environment when
+the shell begins executing in that environment.
+The initial value is 0.
+.TP
+.B BASH_VERSINFO
+A readonly array variable whose members hold version information for
+this instance of
+.BR bash .
+The values assigned to the array members are as follows:
+.sp .5
+.RS
+.TP 24
+.B BASH_VERSINFO[\fR0\fP]
+The major version number (the \fIrelease\fP).
+.TP
+.B BASH_VERSINFO[\fR1\fP]
+The minor version number (the \fIversion\fP).
+.TP
+.B BASH_VERSINFO[\fR2\fP]
+The patch level.
+.TP
+.B BASH_VERSINFO[\fR3\fP]
+The build version.
+.TP
+.B BASH_VERSINFO[\fR4\fP]
+The release status (e.g., \fIbeta1\fP).
+.TP
+.B BASH_VERSINFO[\fR5\fP]
+The value of
+.SM
+.BR MACHTYPE .
+.RE
+.TP
+.B BASH_VERSION
+Expands to a string describing the version of this instance of
+.BR bash .
+.TP
+.B COMP_CWORD
+An index into \fB${COMP_WORDS}\fP of the word containing the current
+cursor position.
+This variable is available only in shell functions invoked by the
+programmable completion facilities (see \fBProgrammable Completion\fP
+below).
+.TP
+.B COMP_KEY
+The key (or final key of a key sequence) used to invoke the current
+completion function.
+.TP
+.B COMP_LINE
+The current command line.
+This variable is available only in shell functions and external
+commands invoked by the
+programmable completion facilities (see \fBProgrammable Completion\fP
+below).
+.TP
+.B COMP_POINT
+The index of the current cursor position relative to the beginning of
+the current command.
+If the current cursor position is at the end of the current command,
+the value of this variable is equal to \fB${#COMP_LINE}\fP.
+This variable is available only in shell functions and external
+commands invoked by the
+programmable completion facilities (see \fBProgrammable Completion\fP
+below).
+.TP
+.B COMP_TYPE
+Set to an integer value corresponding to the type of completion attempted
+that caused a completion function to be called:
+\fITAB\fP, for normal completion,
+\fI?\fP, for listing completions after successive tabs,
+\fI!\fP, for listing alternatives on partial word completion,
+\fI@\fP, to list completions if the word is not unmodified,
+or
+\fI%\fP, for menu completion.
+This variable is available only in shell functions and external
+commands invoked by the
+programmable completion facilities (see \fBProgrammable Completion\fP
+below).
+.TP
+.B COMP_WORDBREAKS
+The set of characters that the \fBreadline\fP library treats as word
+separators when performing word completion.
+If
+.SM
+.B COMP_WORDBREAKS
+is unset, it loses its special properties, even if it is
+subsequently reset.
+.TP
+.B COMP_WORDS
+An array variable (see \fBArrays\fP below) consisting of the individual
+words in the current command line.
+The line is split into words as \fBreadline\fP would split it, using
+.SM
+.B COMP_WORDBREAKS
+as described above.
+This variable is available only in shell functions invoked by the
+programmable completion facilities (see \fBProgrammable Completion\fP
+below).
+.TP
+.B COPROC
+An array variable (see \fBArrays\fP below) created to hold the file descriptors
+for output from and input to an unnamed coprocess (see \fBCoprocesses\fP
+above).
+.TP
+.B DIRSTACK
+An array variable (see
+.B Arrays
+below) containing the current contents of the directory stack.
+Directories appear in the stack in the order they are displayed by the
+.B dirs
+builtin.
+Assigning to members of this array variable may be used to modify
+directories already in the stack, but the
+.B pushd
+and
+.B popd
+builtins must be used to add and remove directories.
+Assignment to this variable will not change the current directory.
+If
+.SM
+.B DIRSTACK
+is unset, it loses its special properties, even if it is
+subsequently reset.
+.TP
+.B EUID
+Expands to the effective user ID of the current user, initialized at
+shell startup. This variable is readonly.
+.TP
+.B FUNCNAME
+An array variable containing the names of all shell functions
+currently in the execution call stack.
+The element with index 0 is the name of any currently-executing
+shell function.
+The bottom-most element (the one with the highest index) is
+.if t \f(CW"main"\fP.
+.if n "main".
+This variable exists only when a shell function is executing.
+Assignments to
+.SM
+.B FUNCNAME
+have no effect and return an error status.
+If
+.SM
+.B FUNCNAME
+is unset, it loses its special properties, even if it is
+subsequently reset.
+.if t .sp 0.5
+.if n .sp 1
+This variable can be used with \fBBASH_LINENO\fP and \fBBASH_SOURCE\fP.
+Each element of \fBFUNCNAME\fP has corresponding elements in
+\fBBASH_LINENO\fP and \fBBASH_SOURCE\fP to describe the call stack.
+For instance, \fB${FUNCNAME[\fP\fI$i\fP\fB]}\fP was called from the file
+\fB${BASH_SOURCE[\fP\fI$i+1\fP\fB]}\fP at line number
+\fB${BASH_LINENO[\fP\fI$i\fP\fB]}\fP.
+The \fBcaller\fP builtin displays the current call stack using this
+information.
+.TP
+.B GROUPS
+An array variable containing the list of groups of which the current
+user is a member.
+Assignments to
+.SM
+.B GROUPS
+have no effect and return an error status.
+If
+.SM
+.B GROUPS
+is unset, it loses its special properties, even if it is
+subsequently reset.
+.TP
+.B HISTCMD
+The history number, or index in the history list, of the current
+command.
+If
+.SM
+.B HISTCMD
+is unset, it loses its special properties, even if it is
+subsequently reset.
+.TP
+.B HOSTNAME
+Automatically set to the name of the current host.
+.TP
+.B HOSTTYPE
+Automatically set to a string that uniquely
+describes the type of machine on which
+.B bash
+is executing.
+The default is system-dependent.
+.TP
+.B LINENO
+Each time this parameter is referenced, the shell substitutes
+a decimal number representing the current sequential line number
+(starting with 1) within a script or function. When not in a
+script or function, the value substituted is not guaranteed to
+be meaningful.
+If
+.SM
+.B LINENO
+is unset, it loses its special properties, even if it is
+subsequently reset.
+.TP
+.B MACHTYPE
+Automatically set to a string that fully describes the system
+type on which
+.B bash
+is executing, in the standard GNU \fIcpu-company-system\fP format.
+The default is system-dependent.
+.TP
+.B MAPFILE
+An array variable (see \fBArrays\fP below) created to hold the text
+read by the \fBmapfile\fP builtin when no variable name is supplied.
+.TP
+.B OLDPWD
+The previous working directory as set by the
+.B cd
+command.
+.TP
+.B OPTARG
+The value of the last option argument processed by the
+.B getopts
+builtin command (see
+.SM
+.B SHELL BUILTIN COMMANDS
+below).
+.TP
+.B OPTIND
+The index of the next argument to be processed by the
+.B getopts
+builtin command (see
+.SM
+.B SHELL BUILTIN COMMANDS
+below).
+.TP
+.B OSTYPE
+Automatically set to a string that
+describes the operating system on which
+.B bash
+is executing.
+The default is system-dependent.
+.TP
+.B PIPESTATUS
+An array variable (see
+.B Arrays
+below) containing a list of exit status values from the processes
+in the most-recently-executed foreground pipeline (which may
+contain only a single command).
+.TP
+.B PPID
+The process ID of the shell's parent. This variable is readonly.
+.TP
+.B PWD
+The current working directory as set by the
+.B cd
+command.
+.TP
+.B RANDOM
+Each time this parameter is referenced, a random integer between
+0 and 32767 is
+generated. The sequence of random numbers may be initialized by assigning
+a value to
+.SM
+.BR RANDOM .
+If
+.SM
+.B RANDOM
+is unset, it loses its special properties, even if it is
+subsequently reset.
+.TP
+.B READLINE_LINE
+The contents of the
+.B readline
+line buffer, for use with
+.if t \f(CWbind -x\fP
+.if n "bind -x"
+(see
+.SM
+.B "SHELL BUILTIN COMMANDS"
+below).
+.TP
+.B READLINE_POINT
+The position of the insertion point in the
+.B readline
+line buffer, for use with
+.if t \f(CWbind -x\fP
+.if n "bind -x"
+(see
+.SM
+.B "SHELL BUILTIN COMMANDS"
+below).
+.TP
+.B REPLY
+Set to the line of input read by the
+.B read
+builtin command when no arguments are supplied.
+.TP
+.B SECONDS
+Each time this parameter is
+referenced, the number of seconds since shell invocation is returned. If a
+value is assigned to
+.SM
+.BR SECONDS ,
+the value returned upon subsequent
+references is
+the number of seconds since the assignment plus the value assigned.
+If
+.SM
+.B SECONDS
+is unset, it loses its special properties, even if it is
+subsequently reset.
+.TP
+.B SHELLOPTS
+A colon-separated list of enabled shell options. Each word in
+the list is a valid argument for the
+.B \-o
+option to the
+.B set
+builtin command (see
+.SM
+.B "SHELL BUILTIN COMMANDS"
+below). The options appearing in
+.SM
+.B SHELLOPTS
+are those reported as
+.I on
+by \fBset \-o\fP.
+If this variable is in the environment when
+.B bash
+starts up, each shell option in the list will be enabled before
+reading any startup files.
+This variable is read-only.
+.TP
+.B SHLVL
+Incremented by one each time an instance of
+.B bash
+is started.
+.TP
+.B UID
+Expands to the user ID of the current user, initialized at shell startup.
+This variable is readonly.
+.PD
+.PP
+The following variables are used by the shell. In some cases,
+.B bash
+assigns a default value to a variable; these cases are noted
+below.
+.PP
+.PD 0
+.TP
+.B BASH_ENV
+If this parameter is set when \fBbash\fP is executing a shell script,
+its value is interpreted as a filename containing commands to
+initialize the shell, as in
+.IR ~/.bashrc .
+The value of
+.SM
+.B BASH_ENV
+is subjected to parameter expansion, command substitution, and arithmetic
+expansion before being interpreted as a file name.
+.SM
+.B PATH
+is not used to search for the resultant file name.
+.TP
+.B BASH_XTRACEFD
+If set to an integer corresponding to a valid file descriptor, \fBbash\fP
+will write the trace output generated when
+.if t \f(CWset -x\fP
+.if n \fIset -x\fP
+is enabled to that file descriptor.
+The file descriptor is closed when
+.SM
+.B BASH_XTRACEFD
+is unset or assigned a new value.
+Unsetting
+.SM
+.B BASH_XTRACEFD
+or assigning it the empty string causes the
+trace output to be sent to the standard error.
+Note that setting
+.SM
+.B BASH_XTRACEFD
+to 2 (the standard error file
+descriptor) and then unsetting it will result in the standard error
+being closed.
+.TP
+.B CDPATH
+The search path for the
+.B cd
+command.
+This is a colon-separated list of directories in which the shell looks
+for destination directories specified by the
+.B cd
+command.
+A sample value is
+.if t \f(CW".:~:/usr"\fP.
+.if n ".:~:/usr".
+.TP
+.B COLUMNS
+Used by the \fBselect\fP compound command to determine the terminal width
+when printing selection lists. Automatically set in an interactive shell
+upon receipt of a
+.SM
+.BR SIGWINCH .
+.TP
+.B COMPREPLY
+An array variable from which \fBbash\fP reads the possible completions
+generated by a shell function invoked by the programmable completion
+facility (see \fBProgrammable Completion\fP below).
+.TP
+.B EMACS
+If \fBbash\fP finds this variable in the environment when the shell starts
+with value
+.if t \f(CWt\fP,
+.if n "t",
+it assumes that the shell is running in an Emacs shell buffer and disables
+line editing.
+.TP
+.B ENV
+Similar to
+.SM
+.BR BASH_ENV ;
+used when the shell is invoked in POSIX mode.
+.TP
+.B FCEDIT
+The default editor for the
+.B fc
+builtin command.
+.TP
+.B FIGNORE
+A colon-separated list of suffixes to ignore when performing
+filename completion (see
+.SM
+.B READLINE
+below).
+A filename whose suffix matches one of the entries in
+.SM
+.B FIGNORE
+is excluded from the list of matched filenames.
+A sample value is
+.if t \f(CW".o:~"\fP.
+.if n ".o:~".
+.TP
+.B FUNCNEST
+If set to a numeric value greater than 0, defines a maximum function
+nesting level. Function invocations that exceed this nesting level
+will cause the current command to abort.
+.TP
+.B GLOBIGNORE
+A colon-separated list of patterns defining the set of filenames to
+be ignored by pathname expansion.
+If a filename matched by a pathname expansion pattern also matches one
+of the patterns in
+.SM
+.BR GLOBIGNORE ,
+it is removed from the list of matches.
+.TP
+.B HISTCONTROL
+A colon-separated list of values controlling how commands are saved on
+the history list.
+If the list of values includes
+.IR ignorespace ,
+lines which begin with a
+.B space
+character are not saved in the history list.
+A value of
+.I ignoredups
+causes lines matching the previous history entry to not be saved.
+A value of
+.I ignoreboth
+is shorthand for \fIignorespace\fP and \fIignoredups\fP.
+A value of
+.IR erasedups
+causes all previous lines matching the current line to be removed from
+the history list before that line is saved.
+Any value not in the above list is ignored.
+If
+.SM
+.B HISTCONTROL
+is unset, or does not include a valid value,
+all lines read by the shell parser are saved on the history list,
+subject to the value of
+.SM
+.BR HISTIGNORE .
+The second and subsequent lines of a multi-line compound command are
+not tested, and are added to the history regardless of the value of
+.SM
+.BR HISTCONTROL .
+.TP
+.B HISTFILE
+The name of the file in which command history is saved (see
+.SM
+.B HISTORY
+below). The default value is \fI~/.bash_history\fP. If unset, the
+command history is not saved when an interactive shell exits.
+.TP
+.B HISTFILESIZE
+The maximum number of lines contained in the history file. When this
+variable is assigned a value, the history file is truncated, if
+necessary, by removing the oldest entries,
+to contain no more than that number of lines. The default
+value is 500. The history file is also truncated to this size after
+writing it when an interactive shell exits.
+.TP
+.B HISTIGNORE
+A colon-separated list of patterns used to decide which command lines
+should be saved on the history list. Each pattern is anchored at the
+beginning of the line and must match the complete line (no implicit
+`\fB*\fP' is appended). Each pattern is tested against the line
+after the checks specified by
+.SM
+.B HISTCONTROL
+are applied.
+In addition to the normal shell pattern matching characters, `\fB&\fP'
+matches the previous history line. `\fB&\fP' may be escaped using a
+backslash; the backslash is removed before attempting a match.
+The second and subsequent lines of a multi-line compound command are
+not tested, and are added to the history regardless of the value of
+.SM
+.BR HISTIGNORE .
+.TP
+.B HISTSIZE
+The number of commands to remember in the command history (see
+.SM
+.B HISTORY
+below). The default value is 500.
+.TP
+.B HISTTIMEFORMAT
+If this variable is set and not null, its value is used as a format string
+for \fIstrftime\fP(3) to print the time stamp associated with each history
+entry displayed by the \fBhistory\fP builtin.
+If this variable is set, time stamps are written to the history file so
+they may be preserved across shell sessions.
+This uses the history comment character to distinguish timestamps from
+other history lines.
+.TP
+.B HOME
+The home directory of the current user; the default argument for the
+\fBcd\fP builtin command.
+The value of this variable is also used when performing tilde expansion.
+.TP
+.B HOSTFILE
+Contains the name of a file in the same format as
+.FN /etc/hosts
+that should be read when the shell needs to complete a
+hostname.
+The list of possible hostname completions may be changed while the
+shell is running;
+the next time hostname completion is attempted after the
+value is changed,
+.B bash
+adds the contents of the new file to the existing list.
+If
+.SM
+.B HOSTFILE
+is set, but has no value, or does not name a readable file,
+\fBbash\fP attempts to read
+.FN /etc/hosts
+to obtain the list of possible hostname completions.
+When
+.SM
+.B HOSTFILE
+is unset, the hostname list is cleared.
+.TP
+.B IFS
+The
+.I Internal Field Separator
+that is used
+for word splitting after expansion and to
+split lines into words with the
+.B read
+builtin command. The default value is
+``<space><tab><newline>''.
+.TP
+.B IGNOREEOF
+Controls the
+action of an interactive shell on receipt of an
+.SM
+.B EOF
+character as the sole input. If set, the value is the number of
+consecutive
+.SM
+.B EOF
+characters which must be
+typed as the first characters on an input line before
+.B bash
+exits. If the variable exists but does not have a numeric value, or
+has no value, the default value is 10. If it does not exist,
+.SM
+.B EOF
+signifies the end of input to the shell.
+.TP
+.B INPUTRC
+The filename for the
+.B readline
+startup file, overriding the default of
+.FN ~/.inputrc
+(see
+.SM
+.B READLINE
+below).
+.TP
+.B LANG
+Used to determine the locale category for any category not specifically
+selected with a variable starting with \fBLC_\fP.
+.TP
+.B LC_ALL
+This variable overrides the value of
+.SM
+.B LANG
+and any other
+\fBLC_\fP variable specifying a locale category.
+.TP
+.B LC_COLLATE
+This variable determines the collation order used when sorting the
+results of pathname expansion, and determines the behavior of range
+expressions, equivalence classes, and collating sequences within
+pathname expansion and pattern matching.
+.TP
+.B LC_CTYPE
+This variable determines the interpretation of characters and the
+behavior of character classes within pathname expansion and pattern
+matching.
+.TP
+.B LC_MESSAGES
+This variable determines the locale used to translate double-quoted
+strings preceded by a \fB$\fP.
+.TP
+.B LC_NUMERIC
+This variable determines the locale category used for number formatting.
+.TP
+.B LINES
+Used by the \fBselect\fP compound command to determine the column length
+for printing selection lists. Automatically set by an interactive shell
+upon receipt of a
+.SM
+.BR SIGWINCH .
+.TP
+.B MAIL
+If this parameter is set to a file or directory name and the
+.SM
+.B MAILPATH
+variable is not set,
+.B bash
+informs the user of the arrival of mail in the specified file or
+Maildir-format directory.
+.TP
+.B MAILCHECK
+Specifies how
+often (in seconds)
+.B bash
+checks for mail. The default is 60 seconds. When it is time to check
+for mail, the shell does so before displaying the primary prompt.
+If this variable is unset, or set to a value that is not a number
+greater than or equal to zero, the shell disables mail checking.
+.TP
+.B MAILPATH
+A colon-separated list of file names to be checked for mail.
+The message to be printed when mail arrives in a particular file
+may be specified by separating the file name from the message with a `?'.
+When used in the text of the message, \fB$_\fP expands to the name of
+the current mailfile.
+Example:
+.RS
+.PP
+\fBMAILPATH\fP=\(aq/var/mail/bfox?"You have mail":~/shell\-mail?"$_ has mail!"\(aq
+.PP
+.B Bash
+supplies a default value for this variable, but the location of the user
+mail files that it uses is system dependent (e.g., /var/mail/\fB$USER\fP).
+.RE
+.TP
+.B OPTERR
+If set to the value 1,
+.B bash
+displays error messages generated by the
+.B getopts
+builtin command (see
+.SM
+.B SHELL BUILTIN COMMANDS
+below).
+.SM
+.B OPTERR
+is initialized to 1 each time the shell is invoked or a shell
+script is executed.
+.TP
+.B PATH
+The search path for commands. It
+is a colon-separated list of directories in which
+the shell looks for commands (see
+.SM
+.B COMMAND EXECUTION
+below).
+A zero-length (null) directory name in the value of
+.SM
+.B PATH
+indicates the current directory.
+A null directory name may appear as two adjacent colons, or as an initial
+or trailing colon.
+The default path is system-dependent,
+and is set by the administrator who installs
+.BR bash .
+A common value is
+.if t \f(CW/usr/local/bin:/usr/local/sbin:/usr/bin:/usr/sbin:/bin:/sbin\fP.
+.if n ``/usr/local/bin:/usr/local/sbin:/usr/bin:/usr/sbin:/bin:/sbin''.
+.TP
+.B POSIXLY_CORRECT
+If this variable is in the environment when \fBbash\fP starts, the shell
+enters \fIposix mode\fP before reading the startup files, as if the
+.B \-\-posix
+invocation option had been supplied. If it is set while the shell is
+running, \fBbash\fP enables \fIposix mode\fP, as if the command
+.if t \f(CWset -o posix\fP
+.if n \fIset -o posix\fP
+had been executed.
+.TP
+.B PROMPT_COMMAND
+If set, the value is executed as a command prior to issuing each primary
+prompt.
+.TP
+.B PROMPT_DIRTRIM
+If set to a number greater than zero, the value is used as the number of
+trailing directory components to retain when expanding the \fB\ew\fP and
+\fB\eW\fP prompt string escapes (see
+.SM
+.B PROMPTING
+below). Characters removed are replaced with an ellipsis.
+.TP
+.B PS1
+The value of this parameter is expanded (see
+.SM
+.B PROMPTING
+below) and used as the primary prompt string. The default value is
+``\fB\es\-\ev\e$ \fP''.
+.TP
+.B PS2
+The value of this parameter is expanded as with
+.SM
+.B PS1
+and used as the secondary prompt string. The default is
+``\fB> \fP''.
+.TP
+.B PS3
+The value of this parameter is used as the prompt for the
+.B select
+command (see
+.SM
+.B SHELL GRAMMAR
+above).
+.TP
+.B PS4
+The value of this parameter is expanded as with
+.SM
+.B PS1
+and the value is printed before each command
+.B bash
+displays during an execution trace. The first character of
+.SM
+.B PS4
+is replicated multiple times, as necessary, to indicate multiple
+levels of indirection. The default is ``\fB+ \fP''.
+.TP
+.B SHELL
+The full pathname to the shell is kept in this environment variable.
+If it is not set when the shell starts,
+.B bash
+assigns to it the full pathname of the current user's login shell.
+.TP
+.B TIMEFORMAT
+The value of this parameter is used as a format string specifying
+how the timing information for pipelines prefixed with the
+.B time
+reserved word should be displayed.
+The \fB%\fP character introduces an escape sequence that is
+expanded to a time value or other information.
+The escape sequences and their meanings are as follows; the
+braces denote optional portions.
+.sp .5
+.RS
+.PD 0
+.TP 10
+.B %%
+A literal \fB%\fP.
+.TP
+.B %[\fIp\fP][l]R
+The elapsed time in seconds.
+.TP
+.B %[\fIp\fP][l]U
+The number of CPU seconds spent in user mode.
+.TP
+.B %[\fIp\fP][l]S
+The number of CPU seconds spent in system mode.
+.TP
+.B %P
+The CPU percentage, computed as (%U + %S) / %R.
+.PD
+.RE
+.IP
+The optional \fIp\fP is a digit specifying the \fIprecision\fP,
+the number of fractional digits after a decimal point.
+A value of 0 causes no decimal point or fraction to be output.
+At most three places after the decimal point may be specified;
+values of \fIp\fP greater than 3 are changed to 3.
+If \fIp\fP is not specified, the value 3 is used.
+.IP
+The optional \fBl\fP specifies a longer format, including
+minutes, of the form \fIMM\fPm\fISS\fP.\fIFF\fPs.
+The value of \fIp\fP determines whether or not the fraction is
+included.
+.IP
+If this variable is not set, \fBbash\fP acts as if it had the
+value \fB$\(aq\enreal\et%3lR\enuser\et%3lU\ensys\t%3lS\(aq\fP.
+If the value is null, no timing information is displayed.
+A trailing newline is added when the format string is displayed.
+.PD 0
+.TP
+.B TMOUT
+If set to a value greater than zero,
+.SM
+.B TMOUT
+is treated as the
+default timeout for the \fBread\fP builtin.
+The \fBselect\fP command terminates if input does not arrive
+after
+.SM
+.B TMOUT
+seconds when input is coming from a terminal.
+In an interactive shell, the value is interpreted as the
+number of seconds to wait for input after issuing the primary prompt.
+.B Bash
+terminates after waiting for that number of seconds if input does
+not arrive.
+.TP
+.B TMPDIR
+If set, \fBbash\fP uses its value as the name of a directory in which
+\fBbash\fP creates temporary files for the shell's use.
+.TP
+.B auto_resume
+This variable controls how the shell interacts with the user and
+job control. If this variable is set, single word simple
+commands without redirections are treated as candidates for resumption
+of an existing stopped job. There is no ambiguity allowed; if there is
+more than one job beginning with the string typed, the job most recently
+accessed is selected. The
+.I name
+of a stopped job, in this context, is the command line used to
+start it.
+If set to the value
+.IR exact ,
+the string supplied must match the name of a stopped job exactly;
+if set to
+.IR substring ,
+the string supplied needs to match a substring of the name of a
+stopped job. The
+.I substring
+value provides functionality analogous to the
+.B %?
+job identifier (see
+.SM
+.B JOB CONTROL
+below). If set to any other value, the supplied string must
+be a prefix of a stopped job's name; this provides functionality
+analogous to the \fB%\fP\fIstring\fP job identifier.
+.TP
+.B histchars
+The two or three characters which control history expansion
+and tokenization (see
+.SM
+.B HISTORY EXPANSION
+below). The first character is the \fIhistory expansion\fP character,
+the character which signals the start of a history
+expansion, normally `\fB!\fP'.
+The second character is the \fIquick substitution\fP
+character, which is used as shorthand for re-running the previous
+command entered, substituting one string for another in the command.
+The default is `\fB^\fP'.
+The optional third character is the character
+which indicates that the remainder of the line is a comment when found
+as the first character of a word, normally `\fB#\fP'. The history
+comment character causes history substitution to be skipped for the
+remaining words on the line. It does not necessarily cause the shell
+parser to treat the rest of the line as a comment.
+.PD
+.SS Arrays
+.B Bash
+provides one-dimensional indexed and associative array variables.
+Any variable may be used as an indexed array; the
+.B declare
+builtin will explicitly declare an array.
+There is no maximum
+limit on the size of an array, nor any requirement that members
+be indexed or assigned contiguously.
+Indexed arrays are referenced using integers (including arithmetic
+expressions) and are zero-based; associative arrays are referenced
+using arbitrary strings.
+.PP
+An indexed array is created automatically if any variable is assigned to
+using the syntax \fIname\fP[\fIsubscript\fP]=\fIvalue\fP. The
+.I subscript
+is treated as an arithmetic expression that must evaluate to a number.
+To explicitly declare an indexed array, use
+.B declare \-a \fIname\fP
+(see
+.SM
+.B SHELL BUILTIN COMMANDS
+below).
+.B declare \-a \fIname\fP[\fIsubscript\fP]
+is also accepted; the \fIsubscript\fP is ignored.
+.PP
+Associative arrays are created using
+.BR "declare \-A \fIname\fP" .
+.PP
+Attributes may be
+specified for an array variable using the
+.B declare
+and
+.B readonly
+builtins. Each attribute applies to all members of an array.
+.PP
+Arrays are assigned to using compound assignments of the form
+\fIname\fP=\fB(\fPvalue\fI1\fP ... value\fIn\fP\fB)\fP, where each
+\fIvalue\fP is of the form [\fIsubscript\fP]=\fIstring\fP.
+Indexed array assignments do not require the bracket and subscript.
+When assigning to indexed arrays, if the optional brackets and subscript
+are supplied, that index is assigned to;
+otherwise the index of the element assigned is the last index assigned
+to by the statement plus one. Indexing starts at zero.
+.PP
+When assigning to an associative array, the subscript is required.
+.PP
+This syntax is also accepted by the
+.B declare
+builtin. Individual array elements may be assigned to using the
+\fIname\fP[\fIsubscript\fP]=\fIvalue\fP syntax introduced above.
+.PP
+Any element of an array may be referenced using
+${\fIname\fP[\fIsubscript\fP]}. The braces are required to avoid
+conflicts with pathname expansion. If
+\fIsubscript\fP is \fB@\fP or \fB*\fP, the word expands to
+all members of \fIname\fP. These subscripts differ only when the
+word appears within double quotes. If the word is double-quoted,
+${\fIname\fP[*]} expands to a single
+word with the value of each array member separated by the first
+character of the
+.SM
+.B IFS
+special variable, and ${\fIname\fP[@]} expands each element of
+\fIname\fP to a separate word. When there are no array members,
+${\fIname\fP[@]} expands to nothing.
+If the double-quoted expansion occurs within a word, the expansion of
+the first parameter is joined with the beginning part of the original
+word, and the expansion of the last parameter is joined with the last
+part of the original word.
+This is analogous to the expansion
+of the special parameters \fB*\fP and \fB@\fP (see
+.B Special Parameters
+above). ${#\fIname\fP[\fIsubscript\fP]} expands to the length of
+${\fIname\fP[\fIsubscript\fP]}. If \fIsubscript\fP is \fB*\fP or
+\fB@\fP, the expansion is the number of elements in the array.
+Referencing an array variable without a subscript is equivalent to
+referencing the array with a subscript of 0.
+If the
+.I subscript
+used to reference an element of an indexed array
+evaluates to a number less than zero, it is used as
+an offset from one greater than the array's maximum index (so a subcript
+of -1 refers to the last element of the array).
+.PP
+An array variable is considered set if a subscript has been assigned a
+value. The null string is a valid value.
+.PP
+The
+.B unset
+builtin is used to destroy arrays. \fBunset\fP \fIname\fP[\fIsubscript\fP]
+destroys the array element at index \fIsubscript\fP.
+Care must be taken to avoid unwanted side effects caused by pathname
+expansion.
+\fBunset\fP \fIname\fP, where \fIname\fP is an array, or
+\fBunset\fP \fIname\fP[\fIsubscript\fP], where
+\fIsubscript\fP is \fB*\fP or \fB@\fP, removes the entire array.
+.PP
+The
+.BR declare ,
+.BR local ,
+and
+.B readonly
+builtins each accept a
+.B \-a
+option to specify an indexed array and a
+.B \-A
+option to specify an associative array.
+If both options are supplied,
+.B \-A
+takes precedence.
+The
+.B read
+builtin accepts a
+.B \-a
+option to assign a list of words read from the standard input
+to an array. The
+.B set
+and
+.B declare
+builtins display array values in a way that allows them to be
+reused as assignments.
+.SH EXPANSION
+Expansion is performed on the command line after it has been split into
+words. There are seven kinds of expansion performed:
+.IR "brace expansion" ,
+.IR "tilde expansion" ,
+.IR "parameter and variable expansion" ,
+.IR "command substitution" ,
+.IR "arithmetic expansion" ,
+.IR "word splitting" ,
+and
+.IR "pathname expansion" .
+.PP
+The order of expansions is: brace expansion, tilde expansion,
+parameter, variable and arithmetic expansion and
+command substitution
+(done in a left-to-right fashion), word splitting, and pathname
+expansion.
+.PP
+On systems that can support it, there is an additional expansion
+available: \fIprocess substitution\fP.
+.PP
+Only brace expansion, word splitting, and pathname expansion
+can change the number of words of the expansion; other expansions
+expand a single word to a single word.
+The only exceptions to this are the expansions of
+"\fB$@\fP" and "\fB${\fP\fIname\fP\fB[@]}\fP"
+as explained above (see
+.SM
+.BR PARAMETERS ).
+.SS Brace Expansion
+.PP
+.I "Brace expansion"
+is a mechanism by which arbitrary strings
+may be generated. This mechanism is similar to
+\fIpathname expansion\fP, but the filenames generated
+need not exist. Patterns to be brace expanded take
+the form of an optional
+.IR preamble ,
+followed by either a series of comma-separated strings or
+a sequence expression between a pair of braces, followed by
+an optional
+.IR postscript .
+The preamble is prefixed to each string contained
+within the braces, and the postscript is then appended
+to each resulting string, expanding left to right.
+.PP
+Brace expansions may be nested. The results of each expanded
+string are not sorted; left to right order is preserved.
+For example, a\fB{\fPd,c,b\fB}\fPe expands into `ade ace abe'.
+.PP
+A sequence expression takes the form
+\fB{\fP\fIx\fP\fB..\fP\fIy\fP\fB[..\fP\fIincr\fP\fB]}\fP,
+where \fIx\fP and \fIy\fP are either integers or single characters,
+and \fIincr\fP, an optional increment, is an integer.
+When integers are supplied, the expression expands to each number between
+\fIx\fP and \fIy\fP, inclusive.
+Supplied integers may be prefixed with \fI0\fP to force each term to have the
+same width. When either \fIx\fP or \fPy\fP begins with a zero, the shell
+attempts to force all generated terms to contain the same number of digits,
+zero-padding where necessary.
+When characters are supplied, the expression expands to each character
+lexicographically between \fIx\fP and \fIy\fP, inclusive. Note that
+both \fIx\fP and \fIy\fP must be of the same type.
+When the increment is supplied, it is used as the difference between
+each term. The default increment is 1 or -1 as appropriate.
+.PP
+Brace expansion is performed before any other expansions,
+and any characters special to other expansions are preserved
+in the result. It is strictly textual.
+.B Bash
+does not apply any syntactic interpretation to the context of the
+expansion or the text between the braces.
+.PP
+A correctly-formed brace expansion must contain unquoted opening
+and closing braces, and at least one unquoted comma or a valid
+sequence expression.
+Any incorrectly formed brace expansion is left unchanged.
+A \fB{\fP or \fB,\fP may be quoted with a backslash to prevent its
+being considered part of a brace expression.
+To avoid conflicts with parameter expansion, the string \fB${\fP
+is not considered eligible for brace expansion.
+.PP
+This construct is typically used as shorthand when the common
+prefix of the strings to be generated is longer than in the
+above example:
+.RS
+.PP
+mkdir /usr/local/src/bash/{old,new,dist,bugs}
+.RE
+or
+.RS
+chown root /usr/{ucb/{ex,edit},lib/{ex?.?*,how_ex}}
+.RE
+.PP
+Brace expansion introduces a slight incompatibility with
+historical versions of
+.BR sh .
+.B sh
+does not treat opening or closing braces specially when they
+appear as part of a word, and preserves them in the output.
+.B Bash
+removes braces from words as a consequence of brace
+expansion. For example, a word entered to
+.B sh
+as \fIfile{1,2}\fP
+appears identically in the output. The same word is
+output as
+.I file1 file2
+after expansion by
+.BR bash .
+If strict compatibility with
+.B sh
+is desired, start
+.B bash
+with the
+.B +B
+option or disable brace expansion with the
+.B +B
+option to the
+.B set
+command (see
+.SM
+.B SHELL BUILTIN COMMANDS
+below).
+.SS Tilde Expansion
+.PP
+If a word begins with an unquoted tilde character (`\fB~\fP'), all of
+the characters preceding the first unquoted slash (or all characters,
+if there is no unquoted slash) are considered a \fItilde-prefix\fP.
+If none of the characters in the tilde-prefix are quoted, the
+characters in the tilde-prefix following the tilde are treated as a
+possible \fIlogin name\fP.
+If this login name is the null string, the tilde is replaced with the
+value of the shell parameter
+.SM
+.BR HOME .
+If
+.SM
+.B HOME
+is unset, the home directory of the user executing the shell is
+substituted instead.
+Otherwise, the tilde-prefix is replaced with the home directory
+associated with the specified login name.
+.PP
+If the tilde-prefix is a `~+', the value of the shell variable
+.SM
+.B PWD
+replaces the tilde-prefix.
+If the tilde-prefix is a `~\-', the value of the shell variable
+.SM
+.BR OLDPWD ,
+if it is set, is substituted.
+If the characters following the tilde in the tilde-prefix consist
+of a number \fIN\fP, optionally prefixed
+by a `+' or a `\-', the tilde-prefix is replaced with the corresponding
+element from the directory stack, as it would be displayed by the
+.B dirs
+builtin invoked with the tilde-prefix as an argument.
+If the characters following the tilde in the tilde-prefix consist of a
+number without a leading `+' or `\-', `+' is assumed.
+.PP
+If the login name is invalid, or the tilde expansion fails, the word
+is unchanged.
+.PP
+Each variable assignment is checked for unquoted tilde-prefixes immediately
+following a
+.B :
+or the first
+.BR = .
+In these cases, tilde expansion is also performed.
+Consequently, one may use file names with tildes in assignments to
+.SM
+.BR PATH ,
+.SM
+.BR MAILPATH ,
+and
+.SM
+.BR CDPATH ,
+and the shell assigns the expanded value.
+.SS Parameter Expansion
+.PP
+The `\fB$\fP' character introduces parameter expansion,
+command substitution, or arithmetic expansion. The parameter name
+or symbol to be expanded may be enclosed in braces, which
+are optional but serve to protect the variable to be expanded from
+characters immediately following it which could be
+interpreted as part of the name.
+.PP
+When braces are used, the matching ending brace is the first `\fB}\fP'
+not escaped by a backslash or within a quoted string, and not within an
+embedded arithmetic expansion, command substitution, or parameter
+expansion.
+.PP
+.PD 0
+.TP
+${\fIparameter\fP}
+The value of \fIparameter\fP is substituted. The braces are required
+when
+.I parameter
+is a positional parameter with more than one digit,
+or when
+.I parameter
+is followed by a character which is not to be
+interpreted as part of its name.
+.PD
+.PP
+If the first character of \fIparameter\fP is an exclamation point (\fB!\fP),
+a level of variable indirection is introduced.
+\fBBash\fP uses the value of the variable formed from the rest of
+\fIparameter\fP as the name of the variable; this variable is then
+expanded and that value is used in the rest of the substitution, rather
+than the value of \fIparameter\fP itself.
+This is known as \fIindirect expansion\fP.
+The exceptions to this are the expansions of ${\fB!\fP\fIprefix\fP\fB*\fP} and
+${\fB!\fP\fIname\fP[\fI@\fP]} described below.
+The exclamation point must immediately follow the left brace in order to
+introduce indirection.
+.PP
+In each of the cases below, \fIword\fP is subject to tilde expansion,
+parameter expansion, command substitution, and arithmetic expansion.
+.PP
+When not performing substring expansion, using the forms documented below,
+\fBbash\fP tests for a parameter that is unset or null. Omitting the colon
+results in a test only for a parameter that is unset.
+.PP
+.PD 0
+.TP
+${\fIparameter\fP\fB:\-\fP\fIword\fP}
+\fBUse Default Values\fP. If
+.I parameter
+is unset or null, the expansion of
+.I word
+is substituted. Otherwise, the value of
+.I parameter
+is substituted.
+.TP
+${\fIparameter\fP\fB:=\fP\fIword\fP}
+\fBAssign Default Values\fP.
+If
+.I parameter
+is unset or null, the expansion of
+.I word
+is assigned to
+.IR parameter .
+The value of
+.I parameter
+is then substituted. Positional parameters and special parameters may
+not be assigned to in this way.
+.TP
+${\fIparameter\fP\fB:?\fP\fIword\fP}
+\fBDisplay Error if Null or Unset\fP.
+If
+.I parameter
+is null or unset, the expansion of \fIword\fP (or a message to that effect
+if
+.I word
+is not present) is written to the standard error and the shell, if it
+is not interactive, exits. Otherwise, the value of \fIparameter\fP is
+substituted.
+.TP
+${\fIparameter\fP\fB:+\fP\fIword\fP}
+\fBUse Alternate Value\fP.
+If
+.I parameter
+is null or unset, nothing is substituted, otherwise the expansion of
+.I word
+is substituted.
+.TP
+${\fIparameter\fP\fB:\fP\fIoffset\fP}
+.PD 0
+.TP
+${\fIparameter\fP\fB:\fP\fIoffset\fP\fB:\fP\fIlength\fP}
+.PD
+\fBSubstring Expansion\fP.
+Expands to up to \fIlength\fP characters of \fIparameter\fP
+starting at the character specified by \fIoffset\fP.
+If \fIlength\fP is omitted, expands to the substring of
+\fIparameter\fP starting at the character specified by \fIoffset\fP.
+\fIlength\fP and \fIoffset\fP are arithmetic expressions (see
+.SM
+.B
+ARITHMETIC EVALUATION
+below).
+If \fIoffset\fP evaluates to a number less than zero, the value
+is used as an offset from the end of the value of \fIparameter\fP.
+If \fIlength\fP evaluates to a number less than zero, and \fIparameter\fP
+is not \fB@\fP and not an indexed or associative array, it is interpreted
+as an offset from the end of the value of \fIparameter\fP rather than
+a number of characters, and the expansion is the characters between the
+two offsets.
+If \fIparameter\fP is \fB@\fP, the result is \fIlength\fP positional
+parameters beginning at \fIoffset\fP.
+If \fIparameter\fP is an indexed array name subscripted by @ or *,
+the result is the \fIlength\fP
+members of the array beginning with ${\fIparameter\fP[\fIoffset\fP]}.
+A negative \fIoffset\fP is taken relative to one greater than the maximum
+index of the specified array.
+Substring expansion applied to an associative array produces undefined
+results.
+Note that a negative offset must be separated from the colon by at least
+one space to avoid being confused with the :- expansion.
+Substring indexing is zero-based unless the positional parameters
+are used, in which case the indexing starts at 1 by default.
+If \fIoffset\fP is 0, and the positional parameters are used, \fB$0\fP is
+prefixed to the list.
+.TP
+${\fB!\fP\fIprefix\fP\fB*\fP}
+.PD 0
+.TP
+${\fB!\fP\fIprefix\fP\fB@\fP}
+.PD
+\fBNames matching prefix\fP.
+Expands to the names of variables whose names begin with \fIprefix\fP,
+separated by the first character of the
+.SM
+.B IFS
+special variable.
+When \fI@\fP is used and the expansion appears within double quotes, each
+variable name expands to a separate word.
+.TP
+${\fB!\fP\fIname\fP[\fI@\fP]}
+.PD 0
+.TP
+${\fB!\fP\fIname\fP[\fI*\fP]}
+.PD
+\fBList of array keys\fP.
+If \fIname\fP is an array variable, expands to the list of array indices
+(keys) assigned in \fIname\fP.
+If \fIname\fP is not an array, expands to 0 if \fIname\fP is set and null
+otherwise.
+When \fI@\fP is used and the expansion appears within double quotes, each
+key expands to a separate word.
+.TP
+${\fB#\fP\fIparameter\fP}
+\fBParameter length\fP.
+The length in characters of the value of \fIparameter\fP is substituted.
+If
+.I parameter
+is
+.B *
+or
+.BR @ ,
+the value substituted is the number of positional parameters.
+If
+.I parameter
+is an array name subscripted by
+.B *
+or
+.BR @ ,
+the value substituted is the number of elements in the array.
+.TP
+${\fIparameter\fP\fB#\fP\fIword\fP}
+.PD 0
+.TP
+${\fIparameter\fP\fB##\fP\fIword\fP}
+.PD
+\fBRemove matching prefix pattern\fP.
+The
+.I word
+is expanded to produce a pattern just as in pathname
+expansion. If the pattern matches the beginning of
+the value of
+.IR parameter ,
+then the result of the expansion is the expanded value of
+.I parameter
+with the shortest matching pattern (the ``\fB#\fP'' case) or the
+longest matching pattern (the ``\fB##\fP'' case) deleted.
+If
+.I parameter
+is
+.B @
+or
+.BR * ,
+the pattern removal operation is applied to each positional
+parameter in turn, and the expansion is the resultant list.
+If
+.I parameter
+is an array variable subscripted with
+.B @
+or
+.BR * ,
+the pattern removal operation is applied to each member of the
+array in turn, and the expansion is the resultant list.
+.TP
+${\fIparameter\fP\fB%\fP\fIword\fP}
+.PD 0
+.TP
+${\fIparameter\fP\fB%%\fP\fIword\fP}
+.PD
+\fBRemove matching suffix pattern\fP.
+The \fIword\fP is expanded to produce a pattern just as in
+pathname expansion.
+If the pattern matches a trailing portion of the expanded value of
+.IR parameter ,
+then the result of the expansion is the expanded value of
+.I parameter
+with the shortest matching pattern (the ``\fB%\fP'' case) or the
+longest matching pattern (the ``\fB%%\fP'' case) deleted.
+If
+.I parameter
+is
+.B @
+or
+.BR * ,
+the pattern removal operation is applied to each positional
+parameter in turn, and the expansion is the resultant list.
+If
+.I parameter
+is an array variable subscripted with
+.B @
+or
+.BR * ,
+the pattern removal operation is applied to each member of the
+array in turn, and the expansion is the resultant list.
+.TP
+${\fIparameter\fP\fB/\fP\fIpattern\fP\fB/\fP\fIstring\fP}
+\fBPattern substitution\fP.
+The \fIpattern\fP is expanded to produce a pattern just as in
+pathname expansion.
+\fIParameter\fP is expanded and the longest match of \fIpattern\fP
+against its value is replaced with \fIstring\fP.
+If \fIpattern\fP begins with \fB/\fP, all matches of \fIpattern\fP are
+replaced with \fIstring\fP. Normally only the first match is replaced.
+If \fIpattern\fP begins with \fB#\fP, it must match at the beginning
+of the expanded value of \fIparameter\fP.
+If \fIpattern\fP begins with \fB%\fP, it must match at the end
+of the expanded value of \fIparameter\fP.
+If \fIstring\fP is null, matches of \fIpattern\fP are deleted
+and the \fB/\fP following \fIpattern\fP may be omitted.
+If
+.I parameter
+is
+.B @
+or
+.BR * ,
+the substitution operation is applied to each positional
+parameter in turn, and the expansion is the resultant list.
+If
+.I parameter
+is an array variable subscripted with
+.B @
+or
+.BR * ,
+the substitution operation is applied to each member of the
+array in turn, and the expansion is the resultant list.
+.TP
+${\fIparameter\fP\fB^\fP\fIpattern\fP}
+.PD 0
+.TP
+${\fIparameter\fP\fB^^\fP\fIpattern\fP}
+.TP
+${\fIparameter\fP\fB,\fP\fIpattern\fP}
+.TP
+${\fIparameter\fP\fB,,\fP\fIpattern\fP}
+.PD
+\fBCase modification\fP.
+This expansion modifies the case of alphabetic characters in \fIparameter\fP.
+The \fIpattern\fP is expanded to produce a pattern just as in
+pathname expansion.
+The \fB^\fP operator converts lowercase letters matching \fIpattern\fP
+to uppercase; the \fB,\fP operator converts matching uppercase letters
+to lowercase.
+The \fB^^\fP and \fB,,\fP expansions convert each matched character in the
+expanded value; the \fB^\fP and \fB,\fP expansions match and convert only
+the first character in the expanded value.
+If \fIpattern\fP is omitted, it is treated like a \fB?\fP, which matches
+every character.
+If
+.I parameter
+is
+.B @
+or
+.BR * ,
+the case modification operation is applied to each positional
+parameter in turn, and the expansion is the resultant list.
+If
+.I parameter
+is an array variable subscripted with
+.B @
+or
+.BR * ,
+the case modification operation is applied to each member of the
+array in turn, and the expansion is the resultant list.
+.SS Command Substitution
+.PP
+\fICommand substitution\fP allows the output of a command to replace
+the command name. There are two forms:
+.RS
+.PP
+\fB$(\fP\fIcommand\fP\|\fB)\fP
+.RE
+or
+.RS
+\fB\`\fP\fIcommand\fP\fB\`\fP
+.RE
+.PP
+.B Bash
+performs the expansion by executing \fIcommand\fP and
+replacing the command substitution with the standard output of the
+command, with any trailing newlines deleted.
+Embedded newlines are not deleted, but they may be removed during
+word splitting.
+The command substitution \fB$(cat \fIfile\fP)\fR can be replaced by
+the equivalent but faster \fB$(< \fIfile\fP)\fR.
+.PP
+When the old-style backquote form of substitution is used,
+backslash retains its literal meaning except when followed by
+.BR $ ,
+.BR \` ,
+or
+.BR \e .
+The first backquote not preceded by a backslash terminates the
+command substitution.
+When using the $(\^\fIcommand\fP\|) form, all characters between the
+parentheses make up the command; none are treated specially.
+.PP
+Command substitutions may be nested. To nest when using the backquoted form,
+escape the inner backquotes with backslashes.
+.PP
+If the substitution appears within double quotes, word splitting and
+pathname expansion are not performed on the results.
+.SS Arithmetic Expansion
+.PP
+Arithmetic expansion allows the evaluation of an arithmetic expression
+and the substitution of the result. The format for arithmetic expansion is:
+.RS
+.PP
+\fB$((\fP\fIexpression\fP\fB))\fP
+.RE
+.PP
+The
+.I expression
+is treated as if it were within double quotes, but a double quote
+inside the parentheses is not treated specially.
+All tokens in the expression undergo parameter expansion, string
+expansion, command substitution, and quote removal.
+Arithmetic expansions may be nested.
+.PP
+The evaluation is performed according to the rules listed below under
+.SM
+.BR "ARITHMETIC EVALUATION" .
+If
+.I expression
+is invalid,
+.B bash
+prints a message indicating failure and no substitution occurs.
+.SS Process Substitution
+.PP
+\fIProcess substitution\fP is supported on systems that support named
+pipes (\fIFIFOs\fP) or the \fB/dev/fd\fP method of naming open files.
+It takes the form of
+\fB<(\fP\fIlist\^\fP\fB)\fP
+or
+\fB>(\fP\fIlist\^\fP\fB)\fP.
+The process \fIlist\fP is run with its input or output connected to a
+\fIFIFO\fP or some file in \fB/dev/fd\fP. The name of this file is
+passed as an argument to the current command as the result of the
+expansion. If the \fB>(\fP\fIlist\^\fP\fB)\fP form is used, writing to
+the file will provide input for \fIlist\fP. If the
+\fB<(\fP\fIlist\^\fP\fB)\fP form is used, the file passed as an
+argument should be read to obtain the output of \fIlist\fP.
+.PP
+When available, process substitution is performed
+simultaneously with parameter and variable expansion,
+command substitution,
+and arithmetic expansion.
+.SS Word Splitting
+.PP
+The shell scans the results of
+parameter expansion,
+command substitution,
+and
+arithmetic expansion
+that did not occur within double quotes for
+.IR "word splitting" .
+.PP
+The shell treats each character of
+.SM
+.B IFS
+as a delimiter, and splits the results of the other
+expansions into words on these characters. If
+.SM
+.B IFS
+is unset, or its
+value is exactly
+.BR <space><tab><newline> ,
+the default, then
+sequences of
+.BR <space> ,
+.BR <tab> ,
+and
+.B <newline>
+at the beginning and end of the results of the previous
+expansions are ignored, and
+any sequence of
+.SM
+.B IFS
+characters not at the beginning or end serves to delimit words.
+If
+.SM
+.B IFS
+has a value other than the default, then sequences of
+the whitespace characters
+.B space
+and
+.B tab
+are ignored at the beginning and end of the
+word, as long as the whitespace character is in the
+value of
+.SM
+.BR IFS
+(an
+.SM
+.B IFS
+whitespace character).
+Any character in
+.SM
+.B IFS
+that is not
+.SM
+.B IFS
+whitespace, along with any adjacent
+.SM
+.B IFS
+whitespace characters, delimits a field.
+A sequence of
+.SM
+.B IFS
+whitespace characters is also treated as a delimiter.
+If the value of
+.SM
+.B IFS
+is null, no word splitting occurs.
+.PP
+Explicit null arguments (\^\f3"\^"\fP or \^\f3\(aq\^\(aq\fP\^) are retained.
+Unquoted implicit null arguments, resulting from the expansion of
+parameters that have no values, are removed.
+If a parameter with no value is expanded within double quotes, a
+null argument results and is retained.
+.PP
+Note that if no expansion occurs, no splitting
+is performed.
+.SS Pathname Expansion
+.PP
+After word splitting,
+unless the
+.B \-f
+option has been set,
+.B bash
+scans each word for the characters
+.BR * ,
+.BR ? ,
+and
+.BR [ .
+If one of these characters appears, then the word is
+regarded as a
+.IR pattern ,
+and replaced with an alphabetically sorted list of
+file names matching the pattern
+(see
+.SM
+.B "Pattern Matching"
+below).
+If no matching file names are found,
+and the shell option
+.B nullglob
+is not enabled, the word is left unchanged.
+If the
+.B nullglob
+option is set, and no matches are found,
+the word is removed.
+If the
+.B failglob
+shell option is set, and no matches are found, an error message
+is printed and the command is not executed.
+If the shell option
+.B nocaseglob
+is enabled, the match is performed without regard to the case
+of alphabetic characters.
+When a pattern is used for pathname expansion,
+the character
+.B ``.''
+at the start of a name or immediately following a slash
+must be matched explicitly, unless the shell option
+.B dotglob
+is set.
+When matching a pathname, the slash character must always be
+matched explicitly.
+In other cases, the
+.B ``.''
+character is not treated specially.
+See the description of
+.B shopt
+below under
+.SM
+.B SHELL BUILTIN COMMANDS
+for a description of the
+.BR nocaseglob ,
+.BR nullglob ,
+.BR failglob ,
+and
+.B dotglob
+shell options.
+.PP
+The
+.SM
+.B GLOBIGNORE
+shell variable may be used to restrict the set of file names matching a
+.IR pattern .
+If
+.SM
+.B GLOBIGNORE
+is set, each matching file name that also matches one of the patterns in
+.SM
+.B GLOBIGNORE
+is removed from the list of matches.
+The file names
+.B ``.''
+and
+.B ``..''
+are always ignored when
+.SM
+.B GLOBIGNORE
+is set and not null. However, setting
+.SM
+.B GLOBIGNORE
+to a non-null value has the effect of enabling the
+.B dotglob
+shell option, so all other file names beginning with a
+.B ``.''
+will match.
+To get the old behavior of ignoring file names beginning with a
+.BR ``.'' ,
+make
+.B ``.*''
+one of the patterns in
+.SM
+.BR GLOBIGNORE .
+The
+.B dotglob
+option is disabled when
+.SM
+.B GLOBIGNORE
+is unset.
+.PP
+\fBPattern Matching\fP
+.PP
+Any character that appears in a pattern, other than the special pattern
+characters described below, matches itself. The NUL character may not
+occur in a pattern. A backslash escapes the following character; the
+escaping backslash is discarded when matching.
+The special pattern characters must be quoted if
+they are to be matched literally.
+.PP
+The special pattern characters have the following meanings:
+.PP
+.PD 0
+.RS
+.TP
+.B *
+Matches any string, including the null string.
+When the \fBglobstar\fP shell option is enabled, and \fB*\fP is used in
+a pathname expansion context, two adjacent \fB*\fPs used as a single
+pattern will match all files and zero or more directories and
+subdirectories.
+If followed by a \fB/\fP, two adjacent \fB*\fPs will match only directories
+and subdirectories.
+.TP
+.B ?
+Matches any single character.
+.TP
+.B [...]
+Matches any one of the enclosed characters. A pair of characters
+separated by a hyphen denotes a
+\fIrange expression\fP;
+any character that sorts between those two characters, inclusive,
+using the current locale's collating sequence and character set,
+is matched. If the first character following the
+.B [
+is a
+.B !
+or a
+.B ^
+then any character not enclosed is matched.
+The sorting order of characters in range expressions is determined by
+the current locale and the values of the
+.SM
+.B LC_COLLATE
+or
+.SM
+.B LC_ALL
+shell variables, if set.
+To obtain the traditional interpretation of range expressions, where
+.B [a\-d]
+is equivalent to
+.BR [abcd] ,
+set value of the
+.B LC_ALL
+shell variable to
+.BR C ,
+or enable the
+.B globasciiranges
+shell option.
+A
+.B \-
+may be matched by including it as the first or last character
+in the set.
+A
+.B ]
+may be matched by including it as the first character
+in the set.
+.br
+.if t .sp 0.5
+.if n .sp 1
+Within
+.B [
+and
+.BR ] ,
+\fIcharacter classes\fP can be specified using the syntax
+\fB[:\fP\fIclass\fP\fB:]\fP, where \fIclass\fP is one of the
+following classes defined in the POSIX standard:
+.PP
+.RS
+.B
+.if n alnum alpha ascii blank cntrl digit graph lower print punct space upper word xdigit
+.if t alnum alpha ascii blank cntrl digit graph lower print punct space upper word xdigit
+.br
+A character class matches any character belonging to that class.
+The \fBword\fP character class matches letters, digits, and the character _.
+.br
+.if t .sp 0.5
+.if n .sp 1
+Within
+.B [
+and
+.BR ] ,
+an \fIequivalence class\fP can be specified using the syntax
+\fB[=\fP\fIc\fP\fB=]\fP, which matches all characters with the
+same collation weight (as defined by the current locale) as
+the character \fIc\fP.
+.br
+.if t .sp 0.5
+.if n .sp 1
+Within
+.B [
+and
+.BR ] ,
+the syntax \fB[.\fP\fIsymbol\fP\fB.]\fP matches the collating symbol
+\fIsymbol\fP.
+.RE
+.RE
+.PD
+.PP
+If the \fBextglob\fP shell option is enabled using the \fBshopt\fP
+builtin, several extended pattern matching operators are recognized.
+In the following description, a \fIpattern-list\fP is a list of one
+or more patterns separated by a \fB|\fP.
+Composite patterns may be formed using one or more of the following
+sub-patterns:
+.sp 1
+.PD 0
+.RS
+.TP
+\fB?(\fP\^\fIpattern-list\^\fP\fB)\fP
+Matches zero or one occurrence of the given patterns
+.TP
+\fB*(\fP\^\fIpattern-list\^\fP\fB)\fP
+Matches zero or more occurrences of the given patterns
+.TP
+\fB+(\fP\^\fIpattern-list\^\fP\fB)\fP
+Matches one or more occurrences of the given patterns
+.TP
+\fB@(\fP\^\fIpattern-list\^\fP\fB)\fP
+Matches one of the given patterns
+.TP
+\fB!(\fP\^\fIpattern-list\^\fP\fB)\fP
+Matches anything except one of the given patterns
+.RE
+.PD
+.SS Quote Removal
+.PP
+After the preceding expansions, all unquoted occurrences of the
+characters
+.BR \e ,
+.BR \(aq ,
+and \^\f3"\fP\^ that did not result from one of the above
+expansions are removed.
+.SH REDIRECTION
+Before a command is executed, its input and output
+may be
+.I redirected
+using a special notation interpreted by the shell.
+Redirection may also be used to open and close files for the
+current shell execution environment. The following redirection
+operators may precede or appear anywhere within a
+.I simple command
+or may follow a
+.IR command .
+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 or equal to 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 < ,
+the redirection refers to the standard input (file descriptor
+0). If the first character of the redirection operator is
+.BR > ,
+the redirection refers to the standard output (file descriptor
+1).
+.PP
+The word following the redirection operator in the following
+descriptions, unless otherwise noted, is subjected to brace expansion,
+tilde expansion, parameter expansion, command substitution, arithmetic
+expansion, quote removal, pathname expansion, and word splitting.
+If it expands to more than one word,
+.B bash
+reports an error.
+.PP
+Note that the order of redirections is significant. For example,
+the command
+.RS
+.PP
+ls \fB>\fP dirlist 2\fB>&\fP1
+.RE
+.PP
+directs both standard output and standard error to the file
+.IR dirlist ,
+while the command
+.RS
+.PP
+ls 2\fB>&\fP1 \fB>\fP dirlist
+.RE
+.PP
+directs only the standard output to file
+.IR dirlist ,
+because the standard error was duplicated from the standard output
+before the standard output was redirected to
+.IR dirlist .
+.PP
+\fBBash\fP handles several filenames specially when they are used in
+redirections, as described in the following table:
+.RS
+.PP
+.PD 0
+.TP
+.B /dev/fd/\fIfd\fP
+If \fIfd\fP is a valid integer, file descriptor \fIfd\fP is duplicated.
+.TP
+.B /dev/stdin
+File descriptor 0 is duplicated.
+.TP
+.B /dev/stdout
+File descriptor 1 is duplicated.
+.TP
+.B /dev/stderr
+File descriptor 2 is duplicated.
+.TP
+.B /dev/tcp/\fIhost\fP/\fIport\fP
+If \fIhost\fP is a valid hostname or Internet address, and \fIport\fP
+is an integer port number or service name, \fBbash\fP attempts to open
+a TCP connection to the corresponding socket.
+.TP
+.B /dev/udp/\fIhost\fP/\fIport\fP
+If \fIhost\fP is a valid hostname or Internet address, and \fIport\fP
+is an integer port number or service name, \fBbash\fP attempts to open
+a UDP connection to the corresponding socket.
+.PD
+.RE
+.PP
+A failure to open or create a file causes the redirection to fail.
+.PP
+Redirections using file descriptors greater than 9 should be used with
+care, as they may conflict with file descriptors the shell uses
+internally.
+.SS Redirecting Input
+.PP
+Redirection of input causes the file whose name results from
+the expansion of
+.I word
+to be opened for reading on file descriptor
+.IR n ,
+or the standard input (file descriptor 0) if
+.I n
+is not specified.
+.PP
+The general format for redirecting input is:
+.RS
+.PP
+[\fIn\fP]\fB<\fP\fIword\fP
+.RE
+.SS Redirecting Output
+.PP
+Redirection of output causes the file whose name results from
+the expansion of
+.I word
+to be opened for writing on file descriptor
+.IR n ,
+or the standard output (file descriptor 1) if
+.I n
+is not specified. If the file does not exist it is created;
+if it does exist it is truncated to zero size.
+.PP
+The general format for redirecting output is:
+.RS
+.PP
+[\fIn\fP]\fB>\fP\fIword\fP
+.RE
+.PP
+If the redirection operator is
+.BR > ,
+and the
+.B noclobber
+option to the
+.B set
+builtin has been enabled, the redirection will fail if the file
+whose name results from the expansion of \fIword\fP exists and is
+a regular file.
+If the redirection operator is
+.BR >| ,
+or the redirection operator is
+.B >
+and the
+.B noclobber
+option to the
+.B set
+builtin command is not enabled, the redirection is attempted even
+if the file named by \fIword\fP exists.
+.SS Appending Redirected Output
+.PP
+Redirection of output in this fashion
+causes the file whose name results from
+the expansion of
+.I word
+to be opened for appending on file descriptor
+.IR n ,
+or the standard output (file descriptor 1) if
+.I n
+is not specified. If the file does not exist it is created.
+.PP
+The general format for appending output is:
+.RS
+.PP
+[\fIn\fP]\fB>>\fP\fIword\fP
+.RE
+.PP
+.SS Redirecting Standard Output and Standard Error
+.PP
+This construct allows both the
+standard output (file descriptor 1) and
+the standard error output (file descriptor 2)
+to be redirected to the file whose name is the
+expansion of
+.IR word .
+.PP
+There are two formats for redirecting standard output and
+standard error:
+.RS
+.PP
+\fB&>\fP\fIword\fP
+.RE
+and
+.RS
+\fB>&\fP\fIword\fP
+.RE
+.PP
+Of the two forms, the first is preferred.
+This is semantically equivalent to
+.RS
+.PP
+\fB>\fP\fIword\fP 2\fB>&\fP1
+.RE
+.PP
+(see \fBDuplicating File Descriptors\fP below).
+.SS Appending Standard Output and Standard Error
+.PP
+This construct allows both the
+standard output (file descriptor 1) and
+the standard error output (file descriptor 2)
+to be appended to the file whose name is the
+expansion of
+.IR word .
+.PP
+The format for appending standard output and standard error is:
+.RS
+.PP
+\fB&>>\fP\fIword\fP
+.RE
+.PP
+This is semantically equivalent to
+.RS
+.PP
+\fB>>\fP\fIword\fP 2\fB>&\fP1
+.RE
+.PP
+(see \fBDuplicating File Descriptors\fP below).
+.SS Here Documents
+.PP
+This type of redirection instructs the shell to read input from the
+current source until a line containing only
+.I delimiter
+(with no trailing blanks)
+is seen. All of
+the lines read up to that point are then used as the standard
+input for a command.
+.PP
+The format of here-documents is:
+.RS
+.PP
+.nf
+\fB<<\fP[\fB\-\fP]\fIword\fP
+ \fIhere-document\fP
+\fIdelimiter\fP
+.fi
+.RE
+.PP
+No parameter expansion, command substitution, arithmetic expansion,
+or pathname expansion is performed on
+.IR word .
+If any characters in
+.I word
+are quoted, the
+.I delimiter
+is the result of quote removal on
+.IR word ,
+and the lines in the here-document are not expanded.
+If \fIword\fP is unquoted,
+all lines of the here-document are subjected to parameter expansion,
+command substitution, and arithmetic expansion. In the latter
+case, the character sequence
+.B \e<newline>
+is ignored, and
+.B \e
+must be used to quote the characters
+.BR \e ,
+.BR $ ,
+and
+.BR \` .
+.PP
+If the redirection operator is
+.BR <<\- ,
+then all leading tab characters are stripped from input lines and the
+line containing
+.IR delimiter .
+This allows
+here-documents within shell scripts to be indented in a
+natural fashion.
+.SS "Here Strings"
+A variant of here documents, the format is:
+.RS
+.PP
+.nf
+\fB<<<\fP\fIword\fP
+.fi
+.RE
+.PP
+The \fIword\fP
+is expanded as described above, with the exception that
+pathname expansion is not applied, and supplied as a single string
+to the command on its standard input.
+.SS "Duplicating File Descriptors"
+.PP
+The redirection operator
+.RS
+.PP
+[\fIn\fP]\fB<&\fP\fIword\fP
+.RE
+.PP
+is used to duplicate input file descriptors.
+If
+.I word
+expands to one or more digits, the file descriptor denoted by
+.I n
+is made to be a copy of that file descriptor.
+If the digits in
+.I word
+do not specify a file descriptor open for input, a redirection error occurs.
+If
+.I word
+evaluates to
+.BR \- ,
+file descriptor
+.I n
+is closed. If
+.I n
+is not specified, the standard input (file descriptor 0) is used.
+.PP
+The operator
+.RS
+.PP
+[\fIn\fP]\fB>&\fP\fIword\fP
+.RE
+.PP
+is used similarly to duplicate output file descriptors. If
+.I n
+is not specified, the standard output (file descriptor 1) is used.
+If the digits in
+.I word
+do not specify a file descriptor open for output, a redirection error occurs.
+As a special case, if \fIn\fP is omitted, and \fIword\fP does not
+expand to one or more digits, the standard output and standard
+error are redirected as described previously.
+.SS "Moving File Descriptors"
+.PP
+The redirection operator
+.RS
+.PP
+[\fIn\fP]\fB<&\fP\fIdigit\fP\fB\-\fP
+.RE
+.PP
+moves the file descriptor \fIdigit\fP to file descriptor
+.IR n ,
+or the standard input (file descriptor 0) if \fIn\fP is not specified.
+\fIdigit\fP is closed after being duplicated to \fIn\fP.
+.PP
+Similarly, the redirection operator
+.RS
+.PP
+[\fIn\fP]\fB>&\fP\fIdigit\fP\fB\-\fP
+.RE
+.PP
+moves the file descriptor \fIdigit\fP to file descriptor
+.IR n ,
+or the standard output (file descriptor 1) if \fIn\fP is not specified.
+.SS "Opening File Descriptors for Reading and Writing"
+.PP
+The redirection operator
+.RS
+.PP
+[\fIn\fP]\fB<>\fP\fIword\fP
+.RE
+.PP
+causes the file whose name is the expansion of
+.I word
+to be opened for both reading and writing on file descriptor
+.IR n ,
+or on file descriptor 0 if
+.I n
+is not specified. If the file does not exist, it is created.
+.SH ALIASES
+\fIAliases\fP allow a string to be substituted for a word when it is used
+as the first word of a simple command.
+The shell maintains a list of aliases that may be set and unset with the
+.B alias
+and
+.B unalias
+builtin commands (see
+.SM
+.B SHELL BUILTIN COMMANDS
+below).
+The first word of each simple command, if unquoted,
+is checked to see if it has an
+alias. If so, that word is replaced by the text of the alias.
+The characters \fB/\fP, \fB$\fP, \fB\`\fP, and \fB=\fP and
+any of the shell \fImetacharacters\fP or quoting characters
+listed above may not appear in an alias name.
+The replacement text may contain any valid shell input,
+including shell metacharacters.
+The first word of the replacement text is tested
+for aliases, but a word that is identical to an alias being expanded
+is not expanded a second time.
+This means that one may alias
+.B ls
+to
+.BR "ls \-F" ,
+for instance, and
+.B bash
+does not try to recursively expand the replacement text.
+If the last character of the alias value is a
+.IR blank ,
+then the next command
+word following the alias is also checked for alias expansion.
+.PP
+Aliases are created and listed with the
+.B alias
+command, and removed with the
+.B unalias
+command.
+.PP
+There is no mechanism for using arguments in the replacement text.
+If arguments are needed, a shell function should be used (see
+.SM
+.B FUNCTIONS
+below).
+.PP
+Aliases are not expanded when the shell is not interactive, unless
+the
+.B expand_aliases
+shell option is set using
+.B shopt
+(see the description of
+.B shopt
+under
+.SM
+\fBSHELL BUILTIN COMMANDS\fP
+below).
+.PP
+The rules concerning the definition and use of aliases are
+somewhat confusing.
+.B Bash
+always reads at least one complete line
+of input before executing any
+of the commands on that line. Aliases are expanded when a
+command is read, not when it is executed. Therefore, an
+alias definition appearing on the same line as another
+command does not take effect until the next line of input is read.
+The commands following the alias definition
+on that line are not affected by the new alias.
+This behavior is also an issue when functions are executed.
+Aliases are expanded when a function definition is read,
+not when the function is executed, because a function definition
+is itself a compound command. As a consequence, aliases
+defined in a function are not available until after that
+function is executed. To be safe, always put
+alias definitions on a separate line, and do not use
+.B alias
+in compound commands.
+.PP
+For almost every purpose, aliases are superseded by
+shell functions.
+.SH FUNCTIONS
+A shell function, defined as described above under
+.SM
+.BR "SHELL GRAMMAR" ,
+stores a series of commands for later execution.
+When the name of a shell function is used as a simple command name,
+the list of commands associated with that function name is executed.
+Functions are executed in the context of the
+current shell; no new process is created to interpret
+them (contrast this with the execution of a shell script).
+When a function is executed, the arguments to the
+function become the positional parameters
+during its execution.
+The special parameter
+.B #
+is updated to reflect the change. Special parameter \fB0\fP
+is unchanged.
+The first element of the
+.SM
+.B FUNCNAME
+variable is set to the name of the function while the function
+is executing.
+.PP
+All other aspects of the shell execution
+environment are identical between a function and its caller
+with these exceptions: the
+.SM
+.B DEBUG
+and
+.B RETURN
+traps (see the description of the
+.B trap
+builtin under
+.SM
+.B SHELL BUILTIN COMMANDS
+below) are not inherited unless the function has been given the
+\fBtrace\fP attribute (see the description of the
+.SM
+.B declare
+builtin below) or the
+\fB\-o functrace\fP shell option has been enabled with
+the \fBset\fP builtin
+(in which case all functions inherit the \fBDEBUG\fP and \fBRETURN\fP traps),
+and the
+.SM
+.B ERR
+trap is not inherited unless the \fB\-o errtrace\fP shell option has
+been enabled.
+.PP
+Variables local to the function may be declared with the
+.B local
+builtin command. Ordinarily, variables and their values
+are shared between the function and its caller.
+.PP
+The \fBFUNCNEST\fP variable, if set to a numeric value greater
+than 0, defines a maximum function nesting level. Function
+invocations that exceed the limit cause the entire command to
+abort.
+.PP
+If the builtin command
+.B return
+is executed in a function, the function completes and
+execution resumes with the next command after the function
+call.
+Any command associated with the \fBRETURN\fP trap is executed
+before execution resumes.
+When a function completes, the values of the
+positional parameters and the special parameter
+.B #
+are restored to the values they had prior to the function's
+execution.
+.PP
+Function names and definitions may be listed with the
+.B \-f
+option to the
+.B declare
+or
+.B typeset
+builtin commands. The
+.B \-F
+option to
+.B declare
+or
+.B typeset
+will list the function names only
+(and optionally the source file and line number, if the \fBextdebug\fP
+shell option is enabled).
+Functions may be exported so that subshells
+automatically have them defined with the
+.B \-f
+option to the
+.B export
+builtin.
+A function definition may be deleted using the \fB\-f\fP option to
+the
+.B unset
+builtin.
+Note that shell functions and variables with the same name may result
+in multiple identically-named entries in the environment passed to the
+shell's children.
+Care should be taken in cases where this may cause a problem.
+.PP
+Functions may be recursive.
+The \fBFUNCNEST\fP variable may be used to limit the depth of the
+function call stack and restrict the number of function invocations.
+By default, no limit is imposed on the number of recursive calls.
+.SH "ARITHMETIC EVALUATION"
+The shell allows arithmetic expressions to be evaluated, under
+certain circumstances (see the \fBlet\fP and \fBdeclare\fP builtin
+commands and \fBArithmetic Expansion\fP).
+Evaluation is done in fixed-width integers with no check for overflow,
+though division by 0 is trapped and flagged as an error.
+The operators and their precedence, associativity, and values
+are the same as in the C language.
+The following list of operators is grouped into levels of
+equal-precedence operators.
+The levels are listed in order of decreasing precedence.
+.PP
+.PD 0
+.TP
+.B \fIid\fP++ \fIid\fP\-\-
+variable post-increment and post-decrement
+.TP
+.B ++\fIid\fP \-\-\fIid\fP
+variable pre-increment and pre-decrement
+.TP
+.B \- +
+unary minus and plus
+.TP
+.B ! ~
+logical and bitwise negation
+.TP
+.B **
+exponentiation
+.TP
+.B * / %
+multiplication, division, remainder
+.TP
+.B + \-
+addition, subtraction
+.TP
+.B << >>
+left and right bitwise shifts
+.TP
+.B <= >= < >
+comparison
+.TP
+.B == !=
+equality and inequality
+.TP
+.B &
+bitwise AND
+.TP
+.B ^
+bitwise exclusive OR
+.TP
+.B |
+bitwise OR
+.TP
+.B &&
+logical AND
+.TP
+.B ||
+logical OR
+.TP
+.B \fIexpr\fP?\fIexpr\fP:\fIexpr\fP
+conditional operator
+.TP
+.B = *= /= %= += \-= <<= >>= &= ^= |=
+assignment
+.TP
+.B \fIexpr1\fP , \fIexpr2\fP
+comma
+.PD
+.PP
+Shell variables are allowed as operands; parameter expansion is
+performed before the expression is evaluated.
+Within an expression, shell variables may also be referenced by name
+without using the parameter expansion syntax.
+A shell variable that is null or unset evaluates to 0 when referenced
+by name without using the parameter expansion syntax.
+The value of a variable is evaluated as an arithmetic expression
+when it is referenced, or when a variable which has been given the
+\fIinteger\fP attribute using \fBdeclare -i\fP is assigned a value.
+A null value evaluates to 0.
+A shell variable need not have its \fIinteger\fP attribute
+turned on to be used in an expression.
+.PP
+Constants with a leading 0 are interpreted as octal numbers.
+A leading 0x or 0X denotes hexadecimal.
+Otherwise, numbers take the form [\fIbase#\fP]n, where the optional \fIbase\fP
+is a decimal number between 2 and 64 representing the arithmetic
+base, and \fIn\fP is a number in that base.
+If \fIbase#\fP is omitted, then base 10 is used.
+The digits greater than 9 are represented by the lowercase letters,
+the uppercase letters, @, and _, in that order.
+If \fIbase\fP is less than or equal to 36, lowercase and uppercase
+letters may be used interchangeably to represent numbers between 10
+and 35.
+.PP
+Operators are evaluated in order of precedence. Sub-expressions in
+parentheses are evaluated first and may override the precedence
+rules above.
+.SH "CONDITIONAL EXPRESSIONS"
+Conditional expressions are used by the \fB[[\fP compound command and
+the \fBtest\fP and \fB[\fP builtin commands to test file attributes
+and perform string and arithmetic comparisons.
+Expressions are formed from the following unary or binary primaries.
+If any \fIfile\fP argument to one of the primaries is of the form
+\fI/dev/fd/n\fP, then file descriptor \fIn\fP is checked.
+If the \fIfile\fP argument to one of the primaries is one of
+\fI/dev/stdin\fP, \fI/dev/stdout\fP, or \fI/dev/stderr\fP, file
+descriptor 0, 1, or 2, respectively, is checked.
+.PP
+Unless otherwise specified, primaries that operate on files follow symbolic
+links and operate on the target of the link, rather than the link itself.
+.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.
+The \fBtest\fP command sorts using ASCII ordering.
+.sp 1
+.PD 0
+.TP
+.B \-a \fIfile\fP
+True if \fIfile\fP exists.
+.TP
+.B \-b \fIfile\fP
+True if \fIfile\fP exists and is a block special file.
+.TP
+.B \-c \fIfile\fP
+True if \fIfile\fP exists and is a character special file.
+.TP
+.B \-d \fIfile\fP
+True if \fIfile\fP exists and is a directory.
+.TP
+.B \-e \fIfile\fP
+True if \fIfile\fP exists.
+.TP
+.B \-f \fIfile\fP
+True if \fIfile\fP exists and is a regular file.
+.TP
+.B \-g \fIfile\fP
+True if \fIfile\fP exists and is set-group-id.
+.TP
+.B \-h \fIfile\fP
+True if \fIfile\fP exists and is a symbolic link.
+.TP
+.B \-k \fIfile\fP
+True if \fIfile\fP exists and its ``sticky'' bit is set.
+.TP
+.B \-p \fIfile\fP
+True if \fIfile\fP exists and is a named pipe (FIFO).
+.TP
+.B \-r \fIfile\fP
+True if \fIfile\fP exists and is readable.
+.TP
+.B \-s \fIfile\fP
+True if \fIfile\fP exists and has a size greater than zero.
+.TP
+.B \-t \fIfd\fP
+True if file descriptor
+.I fd
+is open and refers to a terminal.
+.TP
+.B \-u \fIfile\fP
+True if \fIfile\fP exists and its set-user-id bit is set.
+.TP
+.B \-w \fIfile\fP
+True if \fIfile\fP exists and is writable.
+.TP
+.B \-x \fIfile\fP
+True if \fIfile\fP exists and is executable.
+.TP
+.B \-G \fIfile\fP
+True if \fIfile\fP exists and is owned by the effective group id.
+.TP
+.B \-L \fIfile\fP
+True if \fIfile\fP exists and is a symbolic link.
+.TP
+.B \-N \fIfile\fP
+True if \fIfile\fP exists and has been modified since it was last read.
+.TP
+.B \-O \fIfile\fP
+True if \fIfile\fP exists and is owned by the effective user id.
+.TP
+.B \-S \fIfile\fP
+True if \fIfile\fP exists and is a socket.
+.TP
+\fIfile1\fP \fB\-ef\fP \fIfile2\fP
+True if \fIfile1\fP and \fIfile2\fP refer to the same device and
+inode numbers.
+.TP
+\fIfile1\fP \-\fBnt\fP \fIfile2\fP
+True if \fIfile1\fP is newer (according to modification date) than \fIfile2\fP,
+or if \fIfile1\fP exists and \fPfile2\fP does not.
+.TP
+\fIfile1\fP \-\fBot\fP \fIfile2\fP
+True if \fIfile1\fP is older than \fIfile2\fP, or if \fIfile2\fP exists
+and \fIfile1\fP does not.
+.TP
+.B \-o \fIoptname\fP
+True if the shell option
+.I optname
+is enabled.
+See the list of options under the description of the
+.B \-o
+option to the
+.B set
+builtin below.
+.TP
+.B \-v \fIvarname\fP
+True if the shell variable
+.I varname
+is set (has been assigned a value).
+.TP
+.B \-z \fIstring\fP
+True if the length of \fIstring\fP is zero.
+.TP
+\fIstring\fP
+.PD 0
+.TP
+.B \-n \fIstring\fP
+.PD
+True if the length of
+.I string
+is non-zero.
+.TP
+\fIstring1\fP \fB==\fP \fIstring2\fP
+.PD 0
+.TP
+\fIstring1\fP \fB=\fP \fIstring2\fP
+.PD
+True if the strings are equal. \fB=\fP should be used
+with the \fBtest\fP command for POSIX conformance.
+.TP
+\fIstring1\fP \fB!=\fP \fIstring2\fP
+True if the strings are not equal.
+.TP
+\fIstring1\fP \fB<\fP \fIstring2\fP
+True if \fIstring1\fP sorts before \fIstring2\fP lexicographically.
+.TP
+\fIstring1\fP \fB>\fP \fIstring2\fP
+True if \fIstring1\fP sorts after \fIstring2\fP lexicographically.
+.TP
+.I \fIarg1\fP \fBOP\fP \fIarg2\fP
+.SM
+.B OP
+is one of
+.BR \-eq ,
+.BR \-ne ,
+.BR \-lt ,
+.BR \-le ,
+.BR \-gt ,
+or
+.BR \-ge .
+These arithmetic binary operators return true if \fIarg1\fP
+is equal to, not equal to, less than, less than or equal to,
+greater than, or greater than or equal to \fIarg2\fP, respectively.
+.I Arg1
+and
+.I arg2
+may be positive or negative integers.
+.PD
+.SH "SIMPLE COMMAND EXPANSION"
+When a simple command is executed, the shell performs the following
+expansions, assignments, and redirections, from left to right.
+.IP 1.
+The words that the parser has marked as variable assignments (those
+preceding the command name) and redirections are saved for later
+processing.
+.IP 2.
+The words that are not variable assignments or redirections are
+expanded. If any words remain after expansion, the first word
+is taken to be the name of the command and the remaining words are
+the arguments.
+.IP 3.
+Redirections are performed as described above under
+.SM
+.BR REDIRECTION .
+.IP 4.
+The text after the \fB=\fP in each variable assignment undergoes tilde
+expansion, parameter expansion, command substitution, arithmetic expansion,
+and quote removal before being assigned to the variable.
+.PP
+If no command name results, the variable assignments affect the current
+shell environment. Otherwise, the variables are added to the environment
+of the executed command and do not affect the current shell environment.
+If any of the assignments attempts to assign a value to a readonly variable,
+an error occurs, and the command exits with a non-zero status.
+.PP
+If no command name results, redirections are performed, but do not
+affect the current shell environment. A redirection error causes the
+command to exit with a non-zero status.
+.PP
+If there is a command name left after expansion, execution proceeds as
+described below. Otherwise, the command exits. If one of the expansions
+contained a command substitution, the exit status of the command is
+the exit status of the last command substitution performed. If there
+were no command substitutions, the command exits with a status of zero.
+.SH "COMMAND EXECUTION"
+After a command has been split into words, if it results in a
+simple command and an optional list of arguments, the following
+actions are taken.
+.PP
+If the command name contains no slashes, the shell attempts to
+locate it. If there exists a shell function by that name, that
+function is invoked as described above in
+.SM
+.BR FUNCTIONS .
+If the name does not match a function, the shell searches for
+it in the list of shell builtins. If a match is found, that
+builtin is invoked.
+.PP
+If the name is neither a shell function nor a builtin,
+and contains no slashes,
+.B bash
+searches each element of the
+.SM
+.B PATH
+for a directory containing an executable file by that name.
+.B Bash
+uses a hash table to remember the full pathnames of executable
+files (see
+.B hash
+under
+.SM
+.B "SHELL BUILTIN COMMANDS"
+below).
+A full search of the directories in
+.SM
+.B PATH
+is performed only if the command is not found in the hash table.
+If the search is unsuccessful, the shell searches for a defined shell
+function named \fBcommand_not_found_handle\fP.
+If that function exists, it is invoked with the original command and
+the original command's arguments as its arguments, and the function's
+exit status becomes the exit status of the shell.
+If that function is not defined, the shell prints an error
+message and returns an exit status of 127.
+.PP
+If the search is successful, or if the command name contains
+one or more slashes, the shell executes the named program in a
+separate execution environment.
+Argument 0 is set to the name given, and the remaining arguments
+to the command are set to the arguments given, if any.
+.PP
+If this execution fails because the file is not in executable
+format, and the file is not a directory, it is assumed to be
+a \fIshell script\fP, a file
+containing shell commands. A subshell is spawned to execute
+it. This subshell reinitializes itself, so
+that the effect is as if a new shell had been invoked
+to handle the script, with the exception that the locations of
+commands remembered by the parent (see
+.B hash
+below under
+.SM
+\fBSHELL BUILTIN COMMANDS\fP)
+are retained by the child.
+.PP
+If the program is a file beginning with
+.BR #! ,
+the remainder of the first line specifies an interpreter
+for the program. The shell executes the
+specified interpreter on operating systems that do not
+handle this executable format themselves. The arguments to the
+interpreter consist of a single optional argument following the
+interpreter name on the first line of the program, followed
+by the name of the program, followed by the command
+arguments, if any.
+.SH COMMAND EXECUTION ENVIRONMENT
+The shell has an \fIexecution environment\fP, which consists of the
+following:
+.IP \(bu
+open files inherited by the shell at invocation, as modified by
+redirections supplied to the \fBexec\fP builtin
+.IP \(bu
+the current working directory as set by \fBcd\fP, \fBpushd\fP, or
+\fBpopd\fP, or inherited by the shell at invocation
+.IP \(bu
+the file creation mode mask as set by \fBumask\fP or inherited from
+the shell's parent
+.IP \(bu
+current traps set by \fBtrap\fP
+.IP \(bu
+shell parameters that are set by variable assignment or with \fBset\fP
+or inherited from the shell's parent in the environment
+.IP \(bu
+shell functions defined during execution or inherited from the shell's
+parent in the environment
+.IP \(bu
+options enabled at invocation (either by default or with command-line
+arguments) or by \fBset\fP
+.IP \(bu
+options enabled by \fBshopt\fP
+.IP \(bu
+shell aliases defined with \fBalias\fP
+.IP \(bu
+various process IDs, including those of background jobs, the value
+of \fB$$\fP, and the value of
+.SM
+.B PPID
+.PP
+When a simple command other than a builtin or shell function
+is to be executed, it
+is invoked in a separate execution environment that consists of
+the following. Unless otherwise noted, the values are inherited
+from the shell.
+.if n .sp 1
+.IP \(bu
+the shell's open files, plus any modifications and additions specified
+by redirections to the command
+.IP \(bu
+the current working directory
+.IP \(bu
+the file creation mode mask
+.IP \(bu
+shell variables and functions marked for export, along with variables
+exported for the command, passed in the environment
+.IP \(bu
+traps caught by the shell are reset to the values inherited from the
+shell's parent, and traps ignored by the shell are ignored
+.PP
+A command invoked in this separate environment cannot affect the
+shell's execution environment.
+.PP
+Command substitution, commands grouped with parentheses,
+and asynchronous commands are invoked in a
+subshell environment that is a duplicate of the shell environment,
+except that traps caught by the shell are reset to the values
+that the shell inherited from its parent at invocation. Builtin
+commands that are invoked as part of a pipeline are also executed in a
+subshell environment. Changes made to the subshell environment
+cannot affect the shell's execution environment.
+.PP
+Subshells spawned to execute command substitutions inherit the value of
+the \fB\-e\fP option from the parent shell. When not in \fIposix\fP mode,
+\fBbash\fP clears the \fB\-e\fP option in such subshells.
+.PP
+If a command is followed by a \fB&\fP and job control is not active, the
+default standard input for the command is the empty file \fI/dev/null\fP.
+Otherwise, the invoked command inherits the file descriptors of the calling
+shell as modified by redirections.
+.SH ENVIRONMENT
+When a program is invoked it is given an array of strings
+called the
+.IR environment .
+This is a list of
+\fIname\fP\-\fIvalue\fP pairs, of the form
+.IR "name\fR=\fPvalue" .
+.PP
+The shell provides several ways to manipulate the environment.
+On invocation, the shell scans its own environment and
+creates a parameter for each name found, automatically marking
+it for
+.I export
+to child processes. Executed commands inherit the environment.
+The
+.B export
+and
+.B declare \-x
+commands allow parameters and functions to be added to and
+deleted from the environment. If the value of a parameter
+in the environment is modified, the new value becomes part
+of the environment, replacing the old. The environment
+inherited by any executed command consists of the shell's
+initial environment, whose values may be modified in the shell,
+less any pairs removed by the
+.B unset
+command, plus any additions via the
+.B export
+and
+.B declare \-x
+commands.
+.PP
+The environment for any
+.I simple command
+or function may be augmented temporarily by prefixing it with
+parameter assignments, as described above in
+.SM
+.BR PARAMETERS .
+These assignment statements affect only the environment seen
+by that command.
+.PP
+If the
+.B \-k
+option is set (see the
+.B set
+builtin command below), then
+.I all
+parameter assignments are placed in the environment for a command,
+not just those that precede the command name.
+.PP
+When
+.B bash
+invokes an external command, the variable
+.B _
+is set to the full file name of the command and passed to that
+command in its environment.
+.SH "EXIT STATUS"
+.PP
+The exit status of an executed command is the value returned by the
+\fIwaitpid\fP system call or equivalent function. Exit statuses
+fall between 0 and 255, though, as explained below, the shell may
+use values above 125 specially. Exit statuses from shell builtins and
+compound commands are also limited to this range. Under certain
+circumstances, the shell will use special values to indicate specific
+failure modes.
+.PP
+For the shell's purposes, a command which exits with a
+zero exit status has succeeded. An exit status of zero
+indicates success. A non-zero exit status indicates failure.
+When a command terminates on a fatal signal \fIN\fP, \fBbash\fP uses
+the value of 128+\fIN\fP as the exit status.
+.PP
+If a command is not found, the child process created to
+execute it returns a status of 127. If a command is found
+but is not executable, the return status is 126.
+.PP
+If a command fails because of an error during expansion or redirection,
+the exit status is greater than zero.
+.PP
+Shell builtin commands return a status of 0 (\fItrue\fP) if
+successful, and non-zero (\fIfalse\fP) if an error occurs
+while they execute.
+All builtins return an exit status of 2 to indicate incorrect usage.
+.PP
+\fBBash\fP itself returns the exit status of the last command
+executed, unless a syntax error occurs, in which case it exits
+with a non-zero value. See also the \fBexit\fP builtin
+command below.
+.SH SIGNALS
+When \fBbash\fP is interactive, in the absence of any traps, it ignores
+.SM
+.B SIGTERM
+(so that \fBkill 0\fP does not kill an interactive shell),
+and
+.SM
+.B SIGINT
+is caught and handled (so that the \fBwait\fP builtin is interruptible).
+In all cases, \fBbash\fP ignores
+.SM
+.BR SIGQUIT .
+If job control is in effect,
+.B bash
+ignores
+.SM
+.BR SIGTTIN ,
+.SM
+.BR SIGTTOU ,
+and
+.SM
+.BR SIGTSTP .
+.PP
+Non-builtin commands run by \fBbash\fP have signal handlers
+set to the values inherited by the shell from its parent.
+When job control is not in effect, asynchronous commands
+ignore
+.SM
+.B SIGINT
+and
+.SM
+.B SIGQUIT
+in addition to these inherited handlers.
+Commands run as a result of command substitution ignore the
+keyboard-generated job control signals
+.SM
+.BR SIGTTIN ,
+.SM
+.BR SIGTTOU ,
+and
+.SM
+.BR SIGTSTP .
+.PP
+The shell exits by default upon receipt of a
+.SM
+.BR SIGHUP .
+Before exiting, an interactive shell resends the
+.SM
+.B SIGHUP
+to all jobs, running or stopped.
+Stopped jobs are sent
+.SM
+.B SIGCONT
+to ensure that they receive the
+.SM
+.BR SIGHUP .
+To prevent the shell from
+sending the signal to a particular job, it should be removed from the
+jobs table with the
+.B disown
+builtin (see
+.SM
+.B "SHELL BUILTIN COMMANDS"
+below) or marked
+to not receive
+.SM
+.B SIGHUP
+using
+.BR "disown \-h" .
+.PP
+If the
+.B huponexit
+shell option has been set with
+.BR shopt ,
+.B bash
+sends a
+.SM
+.B SIGHUP
+to all jobs when an interactive login shell exits.
+.PP
+If \fBbash\fP is waiting for a command to complete and receives a signal
+for which a trap has been set, the trap will not be executed until
+the command completes.
+When \fBbash\fP is waiting for an asynchronous command via the \fBwait\fP
+builtin, the reception of a signal for which a trap has been set will
+cause the \fBwait\fP builtin to return immediately with an exit status
+greater than 128, immediately after which the trap is executed.
+.SH "JOB CONTROL"
+.I Job control
+refers to the ability to selectively stop (\fIsuspend\fP)
+the execution of processes and continue (\fIresume\fP)
+their execution at a later point. A user typically employs
+this facility via an interactive interface supplied jointly
+by the operating system kernel's terminal driver and
+.BR bash .
+.PP
+The shell associates a
+.I job
+with each pipeline. It keeps a table of currently executing
+jobs, which may be listed with the
+.B jobs
+command. When
+.B bash
+starts a job asynchronously (in the
+.IR background ),
+it prints a line that looks like:
+.RS
+.PP
+[1] 25647
+.RE
+.PP
+indicating that this job is job number 1 and that the process ID
+of the last process in the pipeline associated with this job is 25647.
+All of the processes in a single pipeline are members of the same job.
+.B Bash
+uses the
+.I job
+abstraction as the basis for job control.
+.PP
+To facilitate the implementation of the user interface to job
+control, the operating system maintains the notion of a \fIcurrent terminal
+process group ID\fP. Members of this process group (processes whose
+process group ID is equal to the current terminal process group ID)
+receive keyboard-generated signals such as
+.SM
+.BR SIGINT .
+These processes are said to be in the
+.IR foreground .
+.I Background
+processes are those whose process group ID differs from the terminal's;
+such processes are immune to keyboard-generated signals.
+Only foreground processes are allowed to read from or, if the
+user so specifies with \f(CWstty tostop\fP, write to the
+terminal.
+Background processes which attempt to read from (write to when
+\f(CWstty tostop\fP is in effect) the
+terminal are sent a
+.SM
+.B SIGTTIN (SIGTTOU)
+signal by the kernel's terminal driver,
+which, unless caught, suspends the process.
+.PP
+If the operating system on which
+.B bash
+is running supports
+job control,
+.B bash
+contains facilities to use it.
+Typing the
+.I suspend
+character (typically
+.BR ^Z ,
+Control-Z) while a process is running
+causes that process to be stopped and returns control to
+.BR bash .
+Typing the
+.I "delayed suspend"
+character (typically
+.BR ^Y ,
+Control-Y) causes the process to be stopped when it
+attempts to read input from the terminal, and control to
+be returned to
+.BR bash .
+The user may then manipulate the state of this job, using the
+.B bg
+command to continue it in the background, the
+.B fg
+command to continue it in the foreground, or
+the
+.B kill
+command to kill it. A \fB^Z\fP takes effect immediately,
+and has the additional side effect of causing pending output
+and typeahead to be discarded.
+.PP
+There are a number of ways to refer to a job in the shell.
+The character
+.B %
+introduces a job specification (\fIjobspec\fP). Job number
+.I n
+may be referred to as
+.BR %n .
+A job may also be referred to using a prefix of the name used to
+start it, or using a substring that appears in its command line.
+For example,
+.B %ce
+refers to a stopped
+.B ce
+job. If a prefix matches more than one job,
+.B bash
+reports an error. Using
+.BR %?ce ,
+on the other hand, refers to any job containing the string
+.B ce
+in its command line. If the substring matches more than one job,
+.B bash
+reports an error. The symbols
+.B %%
+and
+.B %+
+refer to the shell's notion of the
+.IR "current job" ,
+which is the last job stopped while it was in
+the foreground or started in the background.
+The
+.I "previous job"
+may be referenced using
+.BR %\- .
+If there is only a single job, \fB%+\fP and \fB%\-\fP can both be used
+to refer to that job.
+In output pertaining to jobs (e.g., the output of the
+.B jobs
+command), the current job is always flagged with a
+.BR + ,
+and the previous job with a
+.BR \- .
+A single % (with no accompanying job specification) also refers to the
+current job.
+.PP
+Simply naming a job can be used to bring it into the
+foreground:
+.B %1
+is a synonym for
+\fB``fg %1''\fP,
+bringing job 1 from the background into the foreground.
+Similarly,
+.B ``%1 &''
+resumes job 1 in the background, equivalent to
+\fB``bg %1''\fP.
+.PP
+The shell learns immediately whenever a job changes state.
+Normally,
+.B bash
+waits until it is about to print a prompt before reporting
+changes in a job's status so as to not interrupt
+any other output. If the
+.B \-b
+option to the
+.B set
+builtin command
+is enabled,
+.B bash
+reports such changes immediately.
+Any trap on
+.SM
+.B SIGCHLD
+is executed for each child that exits.
+.PP
+If an attempt to exit
+.B bash
+is made while jobs are stopped (or, if the \fBcheckjobs\fP shell option has
+been enabled using the \fBshopt\fP builtin, running), the shell prints a
+warning message, and, if the \fBcheckjobs\fP option is enabled, lists the
+jobs and their statuses.
+The
+.B jobs
+command may then be used to inspect their status.
+If a second attempt to exit is made without an intervening command,
+the shell does not print another warning, and any stopped
+jobs are terminated.
+.SH PROMPTING
+When executing interactively,
+.B bash
+displays the primary prompt
+.SM
+.B PS1
+when it is ready to read a command, and the secondary prompt
+.SM
+.B PS2
+when it needs more input to complete a command.
+.B Bash
+allows these prompt strings to be customized by inserting a number of
+backslash-escaped special characters that are decoded as follows:
+.RS
+.PD 0
+.TP
+.B \ea
+an ASCII bell character (07)
+.TP
+.B \ed
+the date in "Weekday Month Date" format (e.g., "Tue May 26")
+.TP
+.B \eD{\fIformat\fP}
+the \fIformat\fP is passed to \fIstrftime\fP(3) and the result is inserted
+into the prompt string; an empty \fIformat\fP results in a locale-specific
+time representation. The braces are required
+.TP
+.B \ee
+an ASCII escape character (033)
+.TP
+.B \eh
+the hostname up to the first `.'
+.TP
+.B \eH
+the hostname
+.TP
+.B \ej
+the number of jobs currently managed by the shell
+.TP
+.B \el
+the basename of the shell's terminal device name
+.TP
+.B \en
+newline
+.TP
+.B \er
+carriage return
+.TP
+.B \es
+the name of the shell, the basename of
+.B $0
+(the portion following the final slash)
+.TP
+.B \et
+the current time in 24-hour HH:MM:SS format
+.TP
+.B \eT
+the current time in 12-hour HH:MM:SS format
+.TP
+.B \e@
+the current time in 12-hour am/pm format
+.TP
+.B \eA
+the current time in 24-hour HH:MM format
+.TP
+.B \eu
+the username of the current user
+.TP
+.B \ev
+the version of \fBbash\fP (e.g., 2.00)
+.TP
+.B \eV
+the release of \fBbash\fP, version + patch level (e.g., 2.00.0)
+.TP
+.B \ew
+the current working directory, with
+.SM
+.B $HOME
+abbreviated with a tilde
+(uses the value of the
+.SM
+.B PROMPT_DIRTRIM
+variable)
+.TP
+.B \eW
+the basename of the current working directory, with
+.SM
+.B $HOME
+abbreviated with a tilde
+.TP
+.B \e!
+the history number of this command
+.TP
+.B \e#
+the command number of this command
+.TP
+.B \e$
+if the effective UID is 0, a
+.BR # ,
+otherwise a
+.B $
+.TP
+.B \e\fInnn\fP
+the character corresponding to the octal number \fInnn\fP
+.TP
+.B \e\e
+a backslash
+.TP
+.B \e[
+begin a sequence of non-printing characters, which could be used to
+embed a terminal control sequence into the prompt
+.TP
+.B \e]
+end a sequence of non-printing characters
+.PD
+.RE
+.PP
+The command number and the history number are usually different:
+the history number of a command is its position in the history
+list, which may include commands restored from the history file
+(see
+.SM
+.B HISTORY
+below), while the command number is the position in the sequence
+of commands executed during the current shell session.
+After the string is decoded, it is expanded via
+parameter expansion, command substitution, arithmetic
+expansion, and quote removal, subject to the value of the
+.B promptvars
+shell option (see the description of the
+.B shopt
+command under
+.SM
+.B "SHELL BUILTIN COMMANDS"
+below).
+.SH READLINE
+This is the library that handles reading input when using an interactive
+shell, unless the
+.B \-\-noediting
+option is given at shell invocation.
+Line editing is also used when using the \fB\-e\fP option to the
+\fBread\fP builtin.
+By default, the line editing commands are similar to those of Emacs.
+A vi-style line editing interface is also available.
+Line editing can be enabled at any time using the
+.B \-o emacs
+or
+.B \-o vi
+options to the
+.B set
+builtin (see
+.SM
+.B SHELL BUILTIN COMMANDS
+below).
+To turn off line editing after the shell is running, use the
+.B +o emacs
+or
+.B +o vi
+options to the
+.B set
+builtin.
+.SS "Readline Notation"
+.PP
+In this section, the Emacs-style notation is used to denote
+keystrokes. Control keys are denoted by C\-\fIkey\fR, e.g., C\-n
+means Control\-N. Similarly,
+.I meta
+keys are denoted by M\-\fIkey\fR, so M\-x means Meta\-X. (On keyboards
+without a
+.I meta
+key, M\-\fIx\fP means ESC \fIx\fP, i.e., press the Escape key
+then the
+.I x
+key. This makes ESC the \fImeta prefix\fP.
+The combination M\-C\-\fIx\fP means ESC\-Control\-\fIx\fP,
+or press the Escape key
+then hold the Control key while pressing the
+.I x
+key.)
+.PP
+Readline commands may be given numeric
+.IR arguments ,
+which normally act as a repeat count.
+Sometimes, however, it is the sign of the argument that is significant.
+Passing a negative argument to a command that acts in the forward
+direction (e.g., \fBkill\-line\fP) causes that command to act in a
+backward direction.
+Commands whose behavior with arguments deviates from this are noted
+below.
+.PP
+When a command is described as \fIkilling\fP text, the text
+deleted is saved for possible future retrieval
+(\fIyanking\fP). The killed text is saved in a
+\fIkill ring\fP. Consecutive kills cause the text to be
+accumulated into one unit, which can be yanked all at once.
+Commands which do not kill text separate the chunks of text
+on the kill ring.
+.SS "Readline Initialization"
+.PP
+Readline is customized by putting commands in an initialization
+file (the \fIinputrc\fP file).
+The name of this file is taken from the value of the
+.SM
+.B INPUTRC
+variable. If that variable is unset, the default is
+.IR ~/.inputrc .
+When a program which uses the readline library starts up, the
+initialization file is read, and the key bindings and variables
+are set.
+There are only a few basic constructs allowed in the
+readline initialization file.
+Blank lines are ignored.
+Lines beginning with a \fB#\fP are comments.
+Lines beginning with a \fB$\fP indicate conditional constructs.
+Other lines denote key bindings and variable settings.
+.PP
+The default key-bindings may be changed with an
+.I inputrc
+file.
+Other programs that use this library may add their own commands
+and bindings.
+.PP
+For example, placing
+.RS
+.PP
+M\-Control\-u: universal\-argument
+.RE
+or
+.RS
+C\-Meta\-u: universal\-argument
+.RE
+into the
+.I inputrc
+would make M\-C\-u execute the readline command
+.IR universal\-argument .
+.PP
+The following symbolic character names are recognized:
+.IR RUBOUT ,
+.IR DEL ,
+.IR ESC ,
+.IR LFD ,
+.IR NEWLINE ,
+.IR RET ,
+.IR RETURN ,
+.IR SPC ,
+.IR SPACE ,
+and
+.IR TAB .
+.PP
+In addition to command names, readline allows keys to be bound
+to a string that is inserted when the key is pressed (a \fImacro\fP).
+.SS "Readline Key Bindings"
+.PP
+The syntax for controlling key bindings in the
+.I inputrc
+file is simple. All that is required is the name of the
+command or the text of a macro and a key sequence to which
+it should be bound. The name may be specified in one of two ways:
+as a symbolic key name, possibly with \fIMeta\-\fP or \fIControl\-\fP
+prefixes, or as a key sequence.
+.PP
+When using the form \fBkeyname\fP:\^\fIfunction\-name\fP or \fImacro\fP,
+.I keyname
+is the name of a key spelled out in English. For example:
+.sp
+.RS
+Control-u: universal\-argument
+.br
+Meta-Rubout: backward-kill-word
+.br
+Control-o: "> output"
+.RE
+.LP
+In the above example,
+.I C\-u
+is bound to the function
+.BR universal\-argument ,
+.I M\-DEL
+is bound to the function
+.BR backward\-kill\-word ,
+and
+.I C\-o
+is bound to run the macro
+expressed on the right hand side (that is, to insert the text
+.if t \f(CW> output\fP
+.if n ``> output''
+into the line).
+.PP
+In the second form, \fB"keyseq"\fP:\^\fIfunction\-name\fP or \fImacro\fP,
+.B keyseq
+differs from
+.B keyname
+above in that strings denoting
+an entire key sequence may be specified by placing the sequence
+within double quotes. Some GNU Emacs style key escapes can be
+used, as in the following example, but the symbolic character names
+are not recognized.
+.sp
+.RS
+"\eC\-u": universal\-argument
+.br
+"\eC\-x\eC\-r": re\-read\-init\-file
+.br
+"\ee[11~": "Function Key 1"
+.RE
+.PP
+In this example,
+.I C\-u
+is again bound to the function
+.BR universal\-argument .
+.I "C\-x C\-r"
+is bound to the function
+.BR re\-read\-init\-file ,
+and
+.I "ESC [ 1 1 ~"
+is bound to insert the text
+.if t \f(CWFunction Key 1\fP.
+.if n ``Function Key 1''.
+.PP
+The full set of GNU Emacs style escape sequences is
+.RS
+.PD 0
+.TP
+.B \eC\-
+control prefix
+.TP
+.B \eM\-
+meta prefix
+.TP
+.B \ee
+an escape character
+.TP
+.B \e\e
+backslash
+.TP
+.B \e"
+literal "
+.TP
+.B \e\(aq
+literal \(aq
+.RE
+.PD
+.PP
+In addition to the GNU Emacs style escape sequences, a second
+set of backslash escapes is available:
+.RS
+.PD 0
+.TP
+.B \ea
+alert (bell)
+.TP
+.B \eb
+backspace
+.TP
+.B \ed
+delete
+.TP
+.B \ef
+form feed
+.TP
+.B \en
+newline
+.TP
+.B \er
+carriage return
+.TP
+.B \et
+horizontal tab
+.TP
+.B \ev
+vertical tab
+.TP
+.B \e\fInnn\fP
+the eight-bit character whose value is the octal value \fInnn\fP
+(one to three digits)
+.TP
+.B \ex\fIHH\fP
+the eight-bit character whose value is the hexadecimal value \fIHH\fP
+(one or two hex digits)
+.RE
+.PD
+.PP
+When entering the text of a macro, single or double quotes must
+be used to indicate a macro definition.
+Unquoted text is assumed to be a function name.
+In the macro body, the backslash escapes described above are expanded.
+Backslash will quote any other character in the macro text,
+including " and \(aq.
+.PP
+.B Bash
+allows the current readline key bindings to be displayed or modified
+with the
+.B bind
+builtin command. The editing mode may be switched during interactive
+use by using the
+.B \-o
+option to the
+.B set
+builtin command (see
+.SM
+.B SHELL BUILTIN COMMANDS
+below).
+.SS "Readline Variables"
+.PP
+Readline has variables that can be used to further customize its
+behavior. A variable may be set in the
+.I inputrc
+file with a statement of the form
+.RS
+.PP
+\fBset\fP \fIvariable\-name\fP \fIvalue\fP
+.RE
+.PP
+Except where noted, readline variables can take the values
+.B On
+or
+.B Off
+(without regard to case).
+Unrecognized variable names are ignored.
+When a variable value is read, empty or null values, "on" (case-insensitive),
+and "1" are equivalent to \fBOn\fP. All other values are equivalent to
+\fBOff\fP.
+The variables and their default values are:
+.PP
+.PD 0
+.TP
+.B bell\-style (audible)
+Controls what happens when readline wants to ring the terminal bell.
+If set to \fBnone\fP, readline never rings the bell. If set to
+\fBvisible\fP, readline uses a visible bell if one is available.
+If set to \fBaudible\fP, readline attempts to ring the terminal's bell.
+.TP
+.B bind\-tty\-special\-chars (On)
+If set to \fBOn\fP, readline attempts to bind the control characters
+treated specially by the kernel's terminal driver to their readline
+equivalents.
+.TP
+.B comment\-begin (``#'')
+The string that is inserted when the readline
+.B insert\-comment
+command is executed.
+This command is bound to
+.B M\-#
+in emacs mode and to
+.B #
+in vi command mode.
+.TP
+.B completion\-ignore\-case (Off)
+If set to \fBOn\fP, readline performs filename matching and completion
+in a case\-insensitive fashion.
+.TP
+.B completion\-prefix\-display\-length (0)
+The length in characters of the common prefix of a list of possible
+completions that is displayed without modification. When set to a
+value greater than zero, common prefixes longer than this value are
+replaced with an ellipsis when displaying possible completions.
+.TP
+.B completion\-query\-items (100)
+This determines when the user is queried about viewing
+the number of possible completions
+generated by the \fBpossible\-completions\fP command.
+It may be set to any integer value greater than or equal to
+zero. If the number of possible completions is greater than
+or equal to the value of this variable, the user is asked whether
+or not he wishes to view them; otherwise they are simply listed
+on the terminal.
+.TP
+.B convert\-meta (On)
+If set to \fBOn\fP, readline will convert characters with the
+eighth bit set to an ASCII key sequence
+by stripping the eighth bit and prefixing an
+escape character (in effect, using escape as the \fImeta prefix\fP).
+.TP
+.B disable\-completion (Off)
+If set to \fBOn\fP, readline will inhibit word completion. Completion
+characters will be inserted into the line as if they had been
+mapped to \fBself-insert\fP.
+.TP
+.B editing\-mode (emacs)
+Controls whether readline begins with a set of key bindings similar
+to \fIEmacs\fP or \fIvi\fP.
+.B editing\-mode
+can be set to either
+.B emacs
+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
+arrow keys.
+.TP
+.B enable\-meta\-key (On)
+When set to \fBOn\fP, readline will try to enable any meta modifier
+key the terminal claims to support when it is called. On many terminals,
+the meta key is used to send eight-bit characters.
+.TP
+.B expand\-tilde (Off)
+If set to \fBOn\fP, tilde expansion is performed when readline
+attempts word completion.
+.TP
+.B history\-preserve\-point (Off)
+If set to \fBOn\fP, the history code attempts to place point at the
+same location on each history line retrieved with \fBprevious-history\fP
+or \fBnext-history\fP.
+.TP
+.B history\-size (0)
+Set the maximum number of history entries saved in the history list. If
+set to zero, the number of entries in the history list is not limited.
+.TP
+.B horizontal\-scroll\-mode (Off)
+When set to \fBOn\fP, makes readline use a single line for display,
+scrolling the input horizontally on a single screen line when it
+becomes longer than the screen width rather than wrapping to a new line.
+.TP
+.B input\-meta (Off)
+If set to \fBOn\fP, readline will enable eight-bit input (that is,
+it will not strip the high bit from the characters it reads),
+regardless of what the terminal claims it can support. The name
+.B meta\-flag
+is a synonym for this variable.
+.TP
+.B isearch\-terminators (``C\-[C\-J'')
+The string of characters that should terminate an incremental
+search without subsequently executing the character as a command.
+If this variable has not been given a value, the characters
+\fIESC\fP and \fIC\-J\fP will terminate an incremental search.
+.TP
+.B keymap (emacs)
+Set the current readline keymap. The set of valid keymap names is
+\fIemacs, emacs\-standard, emacs\-meta, emacs\-ctlx, vi,
+vi\-command\fP, and
+.IR vi\-insert .
+\fIvi\fP is equivalent to \fIvi\-command\fP; \fIemacs\fP is
+equivalent to \fIemacs\-standard\fP. The default value is
+.IR emacs ;
+the value of
+.B editing\-mode
+also affects the default keymap.
+.TP
+.B mark\-directories (On)
+If set to \fBOn\fP, completed directory names have a slash
+appended.
+.TP
+.B mark\-modified\-lines (Off)
+If set to \fBOn\fP, history lines that have been modified are displayed
+with a preceding asterisk (\fB*\fP).
+.TP
+.B mark\-symlinked\-directories (Off)
+If set to \fBOn\fP, completed names which are symbolic links to directories
+have a slash appended (subject to the value of
+\fBmark\-directories\fP).
+.TP
+.B match\-hidden\-files (On)
+This variable, when set to \fBOn\fP, causes readline to match files whose
+names begin with a `.' (hidden files) when performing filename
+completion.
+If set to \fBOff\fP, the leading `.' must be
+supplied by the user in the filename to be completed.
+.TP
+.B menu\-complete\-display\-prefix (Off)
+If set to \fBOn\fP, menu completion displays the common prefix of the
+list of possible completions (which may be empty) before cycling through
+the list.
+.TP
+.B output\-meta (Off)
+If set to \fBOn\fP, readline will display characters with the
+eighth bit set directly rather than as a meta-prefixed escape
+sequence.
+.TP
+.B page\-completions (On)
+If set to \fBOn\fP, readline uses an internal \fImore\fP-like pager
+to display a screenful of possible completions at a time.
+.TP
+.B print\-completions\-horizontally (Off)
+If set to \fBOn\fP, readline will display completions with matches
+sorted horizontally in alphabetical order, rather than down the screen.
+.TP
+.B revert\-all\-at\-newline (Off)
+If set to \fBOn\fP, readline will undo all changes to history lines
+before returning when \fBaccept\-line\fP is executed. By default,
+history lines may be modified and retain individual undo lists across
+calls to \fBreadline\fP.
+.TP
+.B show\-all\-if\-ambiguous (Off)
+This alters the default behavior of the completion functions. If
+set to
+.BR On ,
+words which have more than one possible completion cause the
+matches to be listed immediately instead of ringing the bell.
+.TP
+.B show\-all\-if\-unmodified (Off)
+This alters the default behavior of the completion functions in
+a fashion similar to \fBshow\-all\-if\-ambiguous\fP.
+If set to
+.BR On ,
+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.
+.TP
+.B skip\-completed\-text (Off)
+If set to \fBOn\fP, 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.
+.TP
+.B visible\-stats (Off)
+If set to \fBOn\fP, a character denoting a file's type as reported
+by \fIstat\fP(2) is appended to the filename when listing possible
+completions.
+.PD
+.SS "Readline Conditional Constructs"
+.PP
+Readline implements a facility similar in spirit to the conditional
+compilation features of the C preprocessor which allows key
+bindings and variable settings to be performed as the result
+of tests. There are four parser directives used.
+.IP \fB$if\fP
+The
+.B $if
+construct allows bindings to be made based on the
+editing mode, the terminal being used, or the application using
+readline. The text of the test extends to the end of the line;
+no characters are required to isolate it.
+.RS
+.IP \fBmode\fP
+The \fBmode=\fP form of the \fB$if\fP directive is used to test
+whether readline is in emacs or vi mode.
+This may be used in conjunction
+with the \fBset keymap\fP command, for instance, to set bindings in
+the \fIemacs\-standard\fP and \fIemacs\-ctlx\fP keymaps only if
+readline is starting out in emacs mode.
+.IP \fBterm\fP
+The \fBterm=\fP form may be used to include terminal-specific
+key bindings, perhaps to bind the key sequences output by the
+terminal's function keys. The word on the right side of the
+.B =
+is tested against the both full name of the terminal and the portion
+of the terminal name before the first \fB\-\fP. This allows
+.I sun
+to match both
+.I sun
+and
+.IR sun\-cmd ,
+for instance.
+.IP \fBapplication\fP
+The \fBapplication\fP construct is used to include
+application-specific settings. Each program using the readline
+library sets the \fIapplication name\fP, and an initialization
+file can test for a particular value.
+This could be used to bind key sequences to functions useful for
+a specific program. For instance, the following command adds a
+key sequence that quotes the current or previous word in \fBbash\fP:
+.sp 1
+.RS
+.nf
+\fB$if\fP Bash
+# Quote the current or previous word
+"\eC\-xq": "\eeb\e"\eef\e""
+\fB$endif\fP
+.fi
+.RE
+.RE
+.IP \fB$endif\fP
+This command, as seen in the previous example, terminates an
+\fB$if\fP command.
+.IP \fB$else\fP
+Commands in this branch of the \fB$if\fP directive are executed if
+the test fails.
+.IP \fB$include\fP
+This directive takes a single filename as an argument and reads commands
+and bindings from that file. For example, the following directive
+would read \fI/etc/inputrc\fP:
+.sp 1
+.RS
+.nf
+\fB$include\fP \^ \fI/etc/inputrc\fP
+.fi
+.RE
+.SS Searching
+.PP
+Readline provides commands for searching through the command history
+(see
+.SM
+.B HISTORY
+below) for lines containing a specified string.
+There are two search modes:
+.I incremental
+and
+.IR non-incremental .
+.PP
+Incremental searches begin before the user has finished typing the
+search string.
+As each character of the search string is typed, readline displays
+the next entry from the history matching the string typed so far.
+An incremental search requires only as many characters as needed to
+find the desired history entry.
+The characters present in the value of the \fBisearch-terminators\fP
+variable are used to terminate an incremental search.
+If that variable has not been assigned a value the Escape and
+Control-J characters will terminate an incremental search.
+Control-G will abort an incremental search and restore the original
+line.
+When the search is terminated, the history entry containing the
+search string becomes the current line.
+.PP
+To find other matching entries in the history list, type Control-S or
+Control-R as appropriate.
+This will search backward or forward in the history for the next
+entry matching the search string typed so far.
+Any other key sequence bound to a readline command will terminate
+the search and execute that command.
+For instance, a \fInewline\fP will terminate the search and accept
+the line, thereby executing the command from the history list.
+.PP
+Readline remembers the last incremental search string. If two
+Control-Rs are typed without any intervening characters defining a
+new search string, any remembered search string is used.
+.PP
+Non-incremental searches read the entire search string before starting
+to search for matching history lines. The search string may be
+typed by the user or be part of the contents of the current line.
+.SS "Readline Command Names"
+.PP
+The following is a list of the names of the commands and the default
+key sequences to which they are bound.
+Command names without an accompanying key sequence are unbound by default.
+In the following descriptions, \fIpoint\fP refers to the current cursor
+position, and \fImark\fP refers to a cursor position saved by the
+\fBset\-mark\fP command.
+The text between the point and mark is referred to as the \fIregion\fP.
+.SS Commands for Moving
+.PP
+.PD 0
+.TP
+.B beginning\-of\-line (C\-a)
+Move to the start of the current line.
+.TP
+.B end\-of\-line (C\-e)
+Move to the end of the line.
+.TP
+.B forward\-char (C\-f)
+Move forward a character.
+.TP
+.B backward\-char (C\-b)
+Move back a character.
+.TP
+.B forward\-word (M\-f)
+Move forward to the end of the next word. Words are composed of
+alphanumeric characters (letters and digits).
+.TP
+.B backward\-word (M\-b)
+Move back to the start of the current or previous word.
+Words are composed of alphanumeric characters (letters and digits).
+.TP
+.B shell\-forward\-word
+Move forward to the end of the next word.
+Words are delimited by non-quoted shell metacharacters.
+.TP
+.B shell\-backward\-word
+Move back to the start of the current or previous word.
+Words are delimited by non-quoted shell metacharacters.
+.TP
+.B clear\-screen (C\-l)
+Clear the screen leaving the current line at the top of the screen.
+With an argument, refresh the current line without clearing the
+screen.
+.TP
+.B redraw\-current\-line
+Refresh the current line.
+.PD
+.SS Commands for Manipulating the History
+.PP
+.PD 0
+.TP
+.B accept\-line (Newline, Return)
+Accept the line regardless of where the cursor is. If this line is
+non-empty, add it to the history list according to the state of the
+.SM
+.B HISTCONTROL
+variable. If the line is a modified history
+line, then restore the history line to its original state.
+.TP
+.B previous\-history (C\-p)
+Fetch the previous command from the history list, moving back in
+the list.
+.TP
+.B next\-history (C\-n)
+Fetch the next command from the history list, moving forward in the
+list.
+.TP
+.B beginning\-of\-history (M\-<)
+Move to the first line in the history.
+.TP
+.B end\-of\-history (M\->)
+Move to the end of the input history, i.e., the line currently being
+entered.
+.TP
+.B reverse\-search\-history (C\-r)
+Search backward starting at the current line and moving `up' through
+the history as necessary. This is an incremental search.
+.TP
+.B forward\-search\-history (C\-s)
+Search forward starting at the current line and moving `down' through
+the history as necessary. This is an incremental search.
+.TP
+.B non\-incremental\-reverse\-search\-history (M\-p)
+Search backward through the history starting at the current line
+using a non-incremental search for a string supplied by the user.
+.TP
+.B non\-incremental\-forward\-search\-history (M\-n)
+Search forward through the history using a non-incremental search for
+a string supplied by the user.
+.TP
+.B history\-search\-forward
+Search forward through the history for the string of characters
+between the start of the current line and the point.
+This is a non-incremental search.
+.TP
+.B history\-search\-backward
+Search backward through the history for the string of characters
+between the start of the current line and the point.
+This is a non-incremental search.
+.TP
+.B yank\-nth\-arg (M\-C\-y)
+Insert the first argument to the previous command (usually
+the second word on the previous line) at point.
+With an argument
+.IR n ,
+insert the \fIn\fPth word from the previous command (the words
+in the previous command begin with word 0). A negative argument
+inserts the \fIn\fPth word from the end of the previous command.
+Once the argument \fIn\fP is computed, the argument is extracted
+as if the "!\fIn\fP" history expansion had been specified.
+.TP
+.B
+yank\-last\-arg (M\-.\^, M\-_\^)
+Insert the last argument to the previous command (the last word of
+the previous history entry).
+With a numeric argument, behave exactly like \fByank\-nth\-arg\fP.
+Successive calls to \fByank\-last\-arg\fP move back through the history
+list, inserting the last word (or the word specified by the argument to
+the first call) of each line in turn.
+Any numeric argument supplied to these successive calls determines
+the direction to move through the history. A negative argument switches
+the direction through the history (back or forward).
+The history expansion facilities are used to extract the last argument,
+as if the "!$" history expansion had been specified.
+.TP
+.B shell\-expand\-line (M\-C\-e)
+Expand the line as the shell does. This
+performs alias and history expansion as well as all of the shell
+word expansions. See
+.SM
+.B HISTORY EXPANSION
+below for a description of history expansion.
+.TP
+.B history\-expand\-line (M\-^)
+Perform history expansion on the current line.
+See
+.SM
+.B HISTORY EXPANSION
+below for a description of history expansion.
+.TP
+.B magic\-space
+Perform history expansion on the current line and insert a space.
+See
+.SM
+.B HISTORY EXPANSION
+below for a description of history expansion.
+.TP
+.B alias\-expand\-line
+Perform alias expansion on the current line.
+See
+.SM
+.B ALIASES
+above for a description of alias expansion.
+.TP
+.B history\-and\-alias\-expand\-line
+Perform history and alias expansion on the current line.
+.TP
+.B insert\-last\-argument (M\-.\^, M\-_\^)
+A synonym for \fByank\-last\-arg\fP.
+.TP
+.B operate\-and\-get\-next (C\-o)
+Accept the current line for execution and fetch the next line
+relative to the current line from the history for editing. Any
+argument is ignored.
+.TP
+.B edit\-and\-execute\-command (C\-xC\-e)
+Invoke an editor on the current command line, and execute the result as shell
+commands.
+\fBBash\fP attempts to invoke
+.SM
+.BR $VISUAL ,
+.SM
+.BR $EDITOR ,
+and \fIemacs\fP as the editor, in that order.
+.PD
+.SS Commands for Changing Text
+.PP
+.PD 0
+.TP
+.B delete\-char (C\-d)
+Delete the character at point. If point is at the
+beginning of the line, there are no characters in the line, and
+the last character typed was not bound to \fBdelete\-char\fP,
+then return
+.SM
+.BR EOF .
+.TP
+.B backward\-delete\-char (Rubout)
+Delete the character behind the cursor. When given a numeric argument,
+save the deleted text on the kill ring.
+.TP
+.B forward\-backward\-delete\-char
+Delete the character under the cursor, unless the cursor is at the
+end of the line, in which case the character behind the cursor is
+deleted.
+.TP
+.B quoted\-insert (C\-q, C\-v)
+Add the next character typed to the line verbatim. This is
+how to insert characters like \fBC\-q\fP, for example.
+.TP
+.B tab\-insert (C\-v TAB)
+Insert a tab character.
+.TP
+.B self\-insert (a,\ b,\ A,\ 1,\ !,\ ...)
+Insert the character typed.
+.TP
+.B transpose\-chars (C\-t)
+Drag the character before point forward over the character at point,
+moving point forward as well.
+If point is at the end of the line, then this transposes
+the two characters before point.
+Negative arguments have no effect.
+.TP
+.B transpose\-words (M\-t)
+Drag the word before point past the word after point,
+moving point over that word as well.
+If point is at the end of the line, this transposes
+the last two words on the line.
+.TP
+.B upcase\-word (M\-u)
+Uppercase the current (or following) word. With a negative argument,
+uppercase the previous word, but do not move point.
+.TP
+.B downcase\-word (M\-l)
+Lowercase the current (or following) word. With a negative argument,
+lowercase the previous word, but do not move point.
+.TP
+.B capitalize\-word (M\-c)
+Capitalize the current (or following) word. With a negative argument,
+capitalize the previous word, but do not move point.
+.TP
+.B overwrite\-mode
+Toggle overwrite mode. With an explicit positive numeric argument,
+switches to overwrite mode. With an explicit non-positive numeric
+argument, switches to insert mode. This command affects only
+\fBemacs\fP mode; \fBvi\fP mode does overwrite differently.
+Each call to \fIreadline()\fP starts in insert mode.
+In overwrite mode, characters bound to \fBself\-insert\fP replace
+the text at point rather than pushing the text to the right.
+Characters bound to \fBbackward\-delete\-char\fP replace the character
+before point with a space. By default, this command is unbound.
+.PD
+.SS Killing and Yanking
+.PP
+.PD 0
+.TP
+.B kill\-line (C\-k)
+Kill the text from point to the end of the line.
+.TP
+.B backward\-kill\-line (C\-x Rubout)
+Kill backward to the beginning of the line.
+.TP
+.B unix\-line\-discard (C\-u)
+Kill backward from point to the beginning of the line.
+The killed text is saved on the kill-ring.
+.\" There is no real difference between this and backward-kill-line
+.TP
+.B kill\-whole\-line
+Kill all characters on the current line, no matter where point is.
+.TP
+.B kill\-word (M\-d)
+Kill from point to the end of the current word, or if between
+words, to the end of the next word.
+Word boundaries are the same as those used by \fBforward\-word\fP.
+.TP
+.B backward\-kill\-word (M\-Rubout)
+Kill the word behind point.
+Word boundaries are the same as those used by \fBbackward\-word\fP.
+.TP
+.B shell\-kill\-word (M\-d)
+Kill from point to the end of the current word, or if between
+words, to the end of the next word.
+Word boundaries are the same as those used by \fBshell\-forward\-word\fP.
+.TP
+.B shell\-backward\-kill\-word (M\-Rubout)
+Kill the word behind point.
+Word boundaries are the same as those used by \fBshell\-backward\-word\fP.
+.TP
+.B unix\-word\-rubout (C\-w)
+Kill the word behind point, using white space as a word boundary.
+The killed text is saved on the kill-ring.
+.TP
+.B unix\-filename\-rubout
+Kill the word behind point, using white space and the slash character
+as the word boundaries.
+The killed text is saved on the kill-ring.
+.TP
+.B delete\-horizontal\-space (M\-\e)
+Delete all spaces and tabs around point.
+.TP
+.B kill\-region
+Kill the text in the current region.
+.TP
+.B copy\-region\-as\-kill
+Copy the text in the region to the kill buffer.
+.TP
+.B copy\-backward\-word
+Copy the word before point to the kill buffer.
+The word boundaries are the same as \fBbackward\-word\fP.
+.TP
+.B copy\-forward\-word
+Copy the word following point to the kill buffer.
+The word boundaries are the same as \fBforward\-word\fP.
+.TP
+.B yank (C\-y)
+Yank the top of the kill ring into the buffer at point.
+.TP
+.B yank\-pop (M\-y)
+Rotate the kill ring, and yank the new top. Only works following
+.B yank
+or
+.BR yank\-pop .
+.PD
+.SS Numeric Arguments
+.PP
+.PD 0
+.TP
+.B digit\-argument (M\-0, M\-1, ..., M\-\-)
+Add this digit to the argument already accumulating, or start a new
+argument. M\-\- starts a negative argument.
+.TP
+.B universal\-argument
+This is another way to specify an argument.
+If this command is followed by one or more digits, optionally with a
+leading minus sign, those digits define the argument.
+If the command is followed by digits, executing
+.B universal\-argument
+again ends the numeric argument, but is otherwise ignored.
+As a special case, if this command is immediately followed by a
+character that is neither a digit or minus sign, the argument count
+for the next command is multiplied by four.
+The argument count is initially one, so executing this function the
+first time makes the argument count four, a second time makes the
+argument count sixteen, and so on.
+.PD
+.SS Completing
+.PP
+.PD 0
+.TP
+.B complete (TAB)
+Attempt to perform completion on the text before point.
+.B Bash
+attempts completion treating the text as a variable (if the
+text begins with \fB$\fP), username (if the text begins with
+\fB~\fP), hostname (if the text begins with \fB@\fP), or
+command (including aliases and functions) in turn. If none
+of these produces a match, filename completion is attempted.
+.TP
+.B possible\-completions (M\-?)
+List the possible completions of the text before point.
+.TP
+.B insert\-completions (M\-*)
+Insert all completions of the text before point
+that would have been generated by
+\fBpossible\-completions\fP.
+.TP
+.B menu\-complete
+Similar to \fBcomplete\fP, but replaces the word to be completed
+with a single match from the list of possible completions.
+Repeated execution of \fBmenu\-complete\fP steps through the list
+of possible completions, inserting each match in turn.
+At the end of the list of completions, the bell is rung
+(subject to the setting of \fBbell\-style\fP)
+and the original text is restored.
+An argument of \fIn\fP moves \fIn\fP positions forward in the list
+of matches; a negative argument may be used to move backward
+through the list.
+This command is intended to be bound to \fBTAB\fP, but is unbound
+by default.
+.TP
+.B menu\-complete\-backward
+Identical to \fBmenu\-complete\fP, but moves backward through the list
+of possible completions, as if \fBmenu\-complete\fP had been given a
+negative argument. This command is unbound by default.
+.TP
+.B delete\-char\-or\-list
+Deletes the character under the cursor if not at the beginning or
+end of the line (like \fBdelete\-char\fP).
+If at the end of the line, behaves identically to
+\fBpossible\-completions\fP.
+This command is unbound by default.
+.TP
+.B complete\-filename (M\-/)
+Attempt filename completion on the text before point.
+.TP
+.B possible\-filename\-completions (C\-x /)
+List the possible completions of the text before point,
+treating it as a filename.
+.TP
+.B complete\-username (M\-~)
+Attempt completion on the text before point, treating
+it as a username.
+.TP
+.B possible\-username\-completions (C\-x ~)
+List the possible completions of the text before point,
+treating it as a username.
+.TP
+.B complete\-variable (M\-$)
+Attempt completion on the text before point, treating
+it as a shell variable.
+.TP
+.B possible\-variable\-completions (C\-x $)
+List the possible completions of the text before point,
+treating it as a shell variable.
+.TP
+.B complete\-hostname (M\-@)
+Attempt completion on the text before point, treating
+it as a hostname.
+.TP
+.B possible\-hostname\-completions (C\-x @)
+List the possible completions of the text before point,
+treating it as a hostname.
+.TP
+.B complete\-command (M\-!)
+Attempt completion on the text before point, treating
+it as a command name. Command completion attempts to
+match the text against aliases, reserved words, shell
+functions, shell builtins, and finally executable filenames,
+in that order.
+.TP
+.B possible\-command\-completions (C\-x !)
+List the possible completions of the text before point,
+treating it as a command name.
+.TP
+.B dynamic\-complete\-history (M\-TAB)
+Attempt completion on the text before point, comparing
+the text against lines from the history list for possible
+completion matches.
+.TP
+.B dabbrev\-expand
+Attempt menu completion on the text before point, comparing
+the text against lines from the history list for possible
+completion matches.
+.TP
+.B complete\-into\-braces (M\-{)
+Perform filename completion and insert the list of possible completions
+enclosed within braces so the list is available to the shell (see
+.B Brace Expansion
+above).
+.PD
+.SS Keyboard Macros
+.PP
+.PD 0
+.TP
+.B start\-kbd\-macro (C\-x (\^)
+Begin saving the characters typed into the current keyboard macro.
+.TP
+.B end\-kbd\-macro (C\-x )\^)
+Stop saving the characters typed into the current keyboard macro
+and store the definition.
+.TP
+.B call\-last\-kbd\-macro (C\-x e)
+Re-execute the last keyboard macro defined, by making the characters
+in the macro appear as if typed at the keyboard.
+.PD
+.SS Miscellaneous
+.PP
+.PD 0
+.TP
+.B re\-read\-init\-file (C\-x C\-r)
+Read in the contents of the \fIinputrc\fP file, and incorporate
+any bindings or variable assignments found there.
+.TP
+.B abort (C\-g)
+Abort the current editing command and
+ring the terminal's bell (subject to the setting of
+.BR bell\-style ).
+.TP
+.B do\-uppercase\-version (M\-a, M\-b, M\-\fIx\fP, ...)
+If the metafied character \fIx\fP is lowercase, run the command
+that is bound to the corresponding uppercase character.
+.TP
+.B prefix\-meta (ESC)
+Metafy the next character typed.
+.SM
+.B ESC
+.B f
+is equivalent to
+.BR Meta\-f .
+.TP
+.B undo (C\-_, C\-x C\-u)
+Incremental undo, separately remembered for each line.
+.TP
+.B revert\-line (M\-r)
+Undo all changes made to this line. This is like executing the
+.B undo
+command enough times to return the line to its initial state.
+.TP
+.B tilde\-expand (M\-&)
+Perform tilde expansion on the current word.
+.TP
+.B set\-mark (C\-@, M\-<space>)
+Set the mark to the point. If a
+numeric argument is supplied, the mark is set to that position.
+.TP
+.B exchange\-point\-and\-mark (C\-x C\-x)
+Swap the point with the mark. The current cursor position is set to
+the saved position, and the old cursor position is saved as the mark.
+.TP
+.B character\-search (C\-])
+A character is read and point is moved to the next occurrence of that
+character. A negative count searches for previous occurrences.
+.TP
+.B character\-search\-backward (M\-C\-])
+A character is read and point is moved to the previous occurrence of that
+character. A negative count searches for subsequent occurrences.
+.TP
+.B skip\-csi\-sequence
+Read enough characters to consume a multi-key sequence such as those
+defined for keys like Home and End. Such sequences begin with a
+Control Sequence Indicator (CSI), usually ESC\-[. If this sequence is
+bound to "\e[", keys producing such sequences will have no effect
+unless explicitly bound to a readline command, instead of inserting
+stray characters into the editing buffer. This is unbound by default,
+but usually bound to ESC\-[.
+.TP
+.B insert\-comment (M\-#)
+Without a numeric argument, the value of the readline
+.B comment\-begin
+variable is inserted at the beginning of the current line.
+If a numeric argument is supplied, this command acts as a toggle: if
+the characters at the beginning of the line do not match the value
+of \fBcomment\-begin\fP, the value is inserted, otherwise
+the characters in \fBcomment\-begin\fP are deleted from the beginning of
+the line.
+In either case, the line is accepted as if a newline had been typed.
+The default value of
+\fBcomment\-begin\fP causes this command to make the current line
+a shell comment.
+If a numeric argument causes the comment character to be removed, the line
+will be executed by the shell.
+.TP
+.B glob\-complete\-word (M\-g)
+The word before point is treated as a pattern for pathname expansion,
+with an asterisk implicitly appended. This pattern is used to
+generate a list of matching file names for possible completions.
+.TP
+.B glob\-expand\-word (C\-x *)
+The word before point is treated as a pattern for pathname expansion,
+and the list of matching file names is inserted, replacing the word.
+If a numeric argument is supplied, an asterisk is appended before
+pathname expansion.
+.TP
+.B glob\-list\-expansions (C\-x g)
+The list of expansions that would have been generated by
+.B glob\-expand\-word
+is displayed, and the line is redrawn.
+If a numeric argument is supplied, an asterisk is appended before
+pathname expansion.
+.TP
+.B dump\-functions
+Print all of the functions and their key bindings to the
+readline output stream. If a numeric argument is supplied,
+the output is formatted in such a way that it can be made part
+of an \fIinputrc\fP file.
+.TP
+.B dump\-variables
+Print all of the settable readline variables and their values to the
+readline output stream. If a numeric argument is supplied,
+the output is formatted in such a way that it can be made part
+of an \fIinputrc\fP file.
+.TP
+.B dump\-macros
+Print all of the readline key sequences bound to macros and the
+strings they output. If a numeric argument is supplied,
+the output is formatted in such a way that it can be made part
+of an \fIinputrc\fP file.
+.TP
+.B display\-shell\-version (C\-x C\-v)
+Display version information about the current instance of
+.BR bash .
+.PD
+.SS Programmable Completion
+.PP
+When word completion is attempted for an argument to a command for
+which a completion specification (a \fIcompspec\fP) has been defined
+using the \fBcomplete\fP builtin (see
+.SM
+.B "SHELL BUILTIN COMMANDS"
+below), the programmable completion facilities are invoked.
+.PP
+First, the command name is identified.
+If the command word is the empty string (completion attempted at the
+beginning of an empty line), any compspec defined with
+the \fB\-E\fP option to \fBcomplete\fP is used.
+If a compspec has been defined for that command, the
+compspec is used to generate the list of possible completions for the word.
+If the command word is a full pathname, a compspec for the full
+pathname is searched for first.
+If no compspec is found for the full pathname, an attempt is made to
+find a compspec for the portion following the final slash.
+If those searches do not result in a compspec, any compspec defined with
+the \fB\-D\fP option to \fBcomplete\fP is used as the default.
+.PP
+Once a compspec has been found, it is used to generate the list of
+matching words.
+If a compspec is not found, the default \fBbash\fP completion as
+described above under \fBCompleting\fP is performed.
+.PP
+First, the actions specified by the compspec are used.
+Only matches which are prefixed by the word being completed are
+returned.
+When the
+.B \-f
+or
+.B \-d
+option is used for filename or directory name completion, the shell
+variable
+.SM
+.B FIGNORE
+is used to filter the matches.
+.PP
+Any completions specified by a pathname expansion pattern to the
+\fB\-G\fP option are generated next.
+The words generated by the pattern need not match the word
+being completed.
+The
+.SM
+.B GLOBIGNORE
+shell variable is not used to filter the matches, but the
+.SM
+.B FIGNORE
+variable is used.
+.PP
+Next, the string specified as the argument to the \fB\-W\fP option
+is considered.
+The string is first split using the characters in the
+.SM
+.B IFS
+special variable as delimiters.
+Shell quoting is honored.
+Each word is then expanded using
+brace expansion, tilde expansion, parameter and variable expansion,
+command substitution, and arithmetic expansion,
+as described above under
+.SM
+.BR EXPANSION .
+The results are split using the rules described above under
+\fBWord Splitting\fP.
+The results of the expansion are prefix-matched against the word being
+completed, and the matching words become the possible completions.
+.PP
+After these matches have been generated, any shell function or command
+specified with the \fB\-F\fP and \fB\-C\fP options is invoked.
+When the command or function is invoked, the
+.SM
+.BR COMP_LINE ,
+.SM
+.BR COMP_POINT ,
+.SM
+.BR COMP_KEY ,
+and
+.SM
+.B COMP_TYPE
+variables are assigned values as described above under
+\fBShell Variables\fP.
+If a shell function is being invoked, the
+.SM
+.B COMP_WORDS
+and
+.SM
+.B COMP_CWORD
+variables are also set.
+When the function or command is invoked, the first argument is the
+name of the command whose arguments are being completed, the
+second argument is the word being completed, and the third argument
+is the word preceding the word being completed on the current command line.
+No filtering of the generated completions against the word being completed
+is performed; the function or command has complete freedom in generating
+the matches.
+.PP
+Any function specified with \fB\-F\fP is invoked first.
+The function may use any of the shell facilities, including the
+\fBcompgen\fP builtin described below, to generate the matches.
+It must put the possible completions in the
+.SM
+.B COMPREPLY
+array variable.
+.PP
+Next, any command specified with the \fB\-C\fP option is invoked
+in an environment equivalent to command substitution.
+It should print a list of completions, one per line, to the
+standard output.
+Backslash may be used to escape a newline, if necessary.
+.PP
+After all of the possible completions are generated, any filter
+specified with the \fB\-X\fP option is applied to the list.
+The filter is a pattern as used for pathname expansion; a \fB&\fP
+in the pattern is replaced with the text of the word being completed.
+A literal \fB&\fP may be escaped with a backslash; the backslash
+is removed before attempting a match.
+Any completion that matches the pattern will be removed from the list.
+A leading \fB!\fP negates the pattern; in this case any completion
+not matching the pattern will be removed.
+.PP
+Finally, any prefix and suffix specified with the \fB\-P\fP and \fB\-S\fP
+options are added to each member of the completion list, and the result is
+returned to the readline completion code as the list of possible
+completions.
+.PP
+If the previously-applied actions do not generate any matches, and the
+\fB\-o dirnames\fP option was supplied to \fBcomplete\fP when the
+compspec was defined, directory name completion is attempted.
+.PP
+If the \fB\-o plusdirs\fP option was supplied to \fBcomplete\fP when the
+compspec was defined, directory name completion is attempted and any
+matches are added to the results of the other actions.
+.PP
+By default, if a compspec is found, whatever it generates is returned
+to the completion code as the full set of possible completions.
+The default \fBbash\fP completions are not attempted, and the readline
+default of filename completion is disabled.
+If the \fB\-o bashdefault\fP option was supplied to \fBcomplete\fP when
+the compspec was defined, the \fBbash\fP default completions are attempted
+if the compspec generates no matches.
+If the \fB\-o default\fP option was supplied to \fBcomplete\fP when the
+compspec was defined, readline's default completion will be performed
+if the compspec (and, if attempted, the default \fBbash\fP completions)
+generate no matches.
+.PP
+When a compspec indicates that directory name completion is desired,
+the programmable completion functions force readline to append a slash
+to completed names which are symbolic links to directories, subject to
+the value of the \fBmark\-directories\fP readline variable, regardless
+of the setting of the \fBmark-symlinked\-directories\fP readline variable.
+.PP
+There is some support for dynamically modifying completions. This is
+most useful when used in combination with a default completion specified
+with \fBcomplete -D\fP.
+It's possible for shell functions executed as completion
+handlers to indicate that completion should be retried by returning an
+exit status of 124. If a shell function returns 124, and changes
+the compspec associated with the command on which completion is being
+attempted (supplied as the first argument when the function is executed),
+programmable completion restarts from the beginning, with an
+attempt to find a new compspec for that command. This allows a set of
+completions to be built dynamically as completion is attempted, rather than
+being loaded all at once.
+.PP
+For instance, assuming that there is a library of compspecs, each kept in a
+file corresponding to the name of the command, the following default
+completion function would load completions dynamically:
+.PP
+\f(CW_completion_loader()
+.br
+{
+.br
+ . "/etc/bash_completion.d/$1.sh" >/dev/null 2>&1 && return 124
+.br
+}
+.br
+complete -D -F _completion_loader
+.br
+\fP
+.SH HISTORY
+When the
+.B \-o history
+option to the
+.B set
+builtin is enabled, the shell provides access to the
+\fIcommand history\fP,
+the list of commands previously typed.
+The value of the
+.SM
+.B HISTSIZE
+variable is used as the
+number of commands to save in a history list.
+The text of the last
+.SM
+.B HISTSIZE
+commands (default 500) is saved. The shell
+stores each command in the history list prior to parameter and
+variable expansion (see
+.SM
+.B EXPANSION
+above) but after history expansion is performed, subject to the
+values of the shell variables
+.SM
+.B HISTIGNORE
+and
+.SM
+.BR HISTCONTROL .
+.PP
+On startup, the history is initialized from the file named by
+the variable
+.SM
+.B HISTFILE
+(default \fI~/.bash_history\fP).
+The file named by the value of
+.SM
+.B HISTFILE
+is truncated, if necessary, to contain no more than
+the number of lines specified by the value of
+.SM
+.BR HISTFILESIZE .
+When the history file is read,
+lines beginning with the history comment character followed immediately
+by a digit are interpreted as timestamps for the preceding history line.
+These timestamps are optionally displayed depending on the value of the
+.SM
+.B HISTTIMEFORMAT
+variable.
+When an interactive shell exits, the last
+.SM
+.B $HISTSIZE
+lines are copied from the history list to
+.SM
+.BR $HISTFILE .
+If the
+.B histappend
+shell option is enabled
+(see the description of
+.B shopt
+under
+.SM
+.B "SHELL BUILTIN COMMANDS"
+below), the lines are appended to the history file,
+otherwise the history file is overwritten.
+If
+.SM
+.B HISTFILE
+is unset, or if the history file is unwritable, the history is
+not saved.
+If the
+.SM
+.B HISTTIMEFORMAT
+variable is set, time stamps are written to the history file, marked
+with the history comment character, so
+they may be preserved across shell sessions.
+This uses the history comment character to distinguish timestamps from
+other history lines.
+After saving the history, the history file is truncated
+to contain no more than
+.SM
+.B HISTFILESIZE
+lines. If
+.SM
+.B HISTFILESIZE
+is not set, no truncation is performed.
+.PP
+The builtin command
+.B fc
+(see
+.SM
+.B SHELL BUILTIN COMMANDS
+below) may be used to list or edit and re-execute a portion of
+the history list.
+The
+.B history
+builtin may be used to display or modify the history list and
+manipulate the history file.
+When using command-line editing, search commands
+are available in each editing mode that provide access to the
+history list.
+.PP
+The shell allows control over which commands are saved on the history
+list. The
+.SM
+.B HISTCONTROL
+and
+.SM
+.B HISTIGNORE
+variables may be set to cause the shell to save only a subset of the
+commands entered.
+The
+.B cmdhist
+shell option, if enabled, causes the shell to attempt to save each
+line of a multi-line command in the same history entry, adding
+semicolons where necessary to preserve syntactic correctness.
+The
+.B lithist
+shell option causes the shell to save the command with embedded newlines
+instead of semicolons. See the description of the
+.B shopt
+builtin below under
+.SM
+.B "SHELL BUILTIN COMMANDS"
+for information on setting and unsetting shell options.
+.SH "HISTORY EXPANSION"
+.PP
+The shell supports a history expansion feature that
+is similar to the history expansion in
+.BR csh.
+This section describes what syntax features are available. This
+feature is enabled by default for interactive shells, and can be
+disabled using the
+.B \+H
+option to the
+.B set
+builtin command (see
+.SM
+.B SHELL BUILTIN COMMANDS
+below). Non-interactive shells do not perform history expansion
+by default.
+.PP
+History expansions introduce words from the history list into
+the input stream, making it easy to repeat commands, insert the
+arguments to a previous command into the current input line, or
+fix errors in previous commands quickly.
+.PP
+History expansion is performed immediately after a complete line
+is read, before the shell breaks it into words.
+It takes place in two parts.
+The first is to determine which line from the history list
+to use during substitution.
+The second is to select portions of that line for inclusion into
+the current one.
+The line selected from the history is the \fIevent\fP,
+and the portions of that line that are acted upon are \fIwords\fP.
+Various \fImodifiers\fP are available to manipulate the selected words.
+The line is broken into words in the same fashion as when reading input,
+so that several \fImetacharacter\fP-separated words surrounded by
+quotes are considered one word.
+History expansions are introduced by the appearance of the
+history expansion character, which is \^\fB!\fP\^ by default.
+Only backslash (\^\fB\e\fP\^) and single quotes can quote
+the history expansion character.
+.PP
+Several characters inhibit history expansion if found immediately
+following the history expansion character, even if it is unquoted:
+space, tab, newline, carriage return, and \fB=\fP.
+If the \fBextglob\fP shell option is enabled, \fB(\fP will also
+inhibit expansion.
+.PP
+Several shell options settable with the
+.B shopt
+builtin may be used to tailor the behavior of history expansion.
+If the
+.B histverify
+shell option is enabled (see the description of the
+.B shopt
+builtin below), and
+.B readline
+is being used, history substitutions are not immediately passed to
+the shell parser.
+Instead, the expanded line is reloaded into the
+.B readline
+editing buffer for further modification.
+If
+.B readline
+is being used, and the
+.B histreedit
+shell option is enabled, a failed history substitution will be reloaded
+into the
+.B readline
+editing buffer for correction.
+The
+.B \-p
+option to the
+.B history
+builtin command may be used to see what a history expansion will
+do before using it.
+The
+.B \-s
+option to the
+.B history
+builtin may be used to add commands to the end of the history list
+without actually executing them, so that they are available for
+subsequent recall.
+.PP
+The shell allows control of the various characters used by the
+history expansion mechanism (see the description of
+.B histchars
+above under
+.BR "Shell Variables" ).
+The shell uses
+the history comment character to mark history timestamps when
+writing the history file.
+.SS Event Designators
+.PP
+An event designator is a reference to a command line entry in the
+history list.
+Unless the reference is absolute, events are relative to the current
+position in the history list.
+.PP
+.PD 0
+.TP
+.B !
+Start a history substitution, except when followed by a
+.BR blank ,
+newline, carriage return, =
+or ( (when the \fBextglob\fP shell option is enabled using
+the \fBshopt\fP builtin).
+.TP
+.B !\fIn\fR
+Refer to command line
+.IR n .
+.TP
+.B !\-\fIn\fR
+Refer to the current command minus
+.IR n .
+.TP
+.B !!
+Refer to the previous command. This is a synonym for `!\-1'.
+.TP
+.B !\fIstring\fR
+Refer to the most recent command preceding the current position in the
+history list starting with
+.IR string .
+.TP
+.B !?\fIstring\fR\fB[?]\fR
+Refer to the most recent command preceding the current postition in the
+history list containing
+.IR string .
+The trailing \fB?\fP may be omitted if
+.I string
+is followed immediately by a newline.
+.TP
+.B \d\s+2^\s-2\u\fIstring1\fP\d\s+2^\s-2\u\fIstring2\fP\d\s+2^\s-2\u
+Quick substitution. Repeat the previous command, replacing
+.I string1
+with
+.IR string2 .
+Equivalent to
+``!!:s/\fIstring1\fP/\fIstring2\fP/''
+(see \fBModifiers\fP below).
+.TP
+.B !#
+The entire command line typed so far.
+.PD
+.SS Word Designators
+.PP
+Word designators are used to select desired words from the event.
+A
+.B :
+separates the event specification from the word designator.
+It may be omitted if the word designator begins with a
+.BR ^ ,
+.BR $ ,
+.BR * ,
+.BR \- ,
+or
+.BR % .
+Words are numbered from the beginning of the line,
+with the first word being denoted by 0 (zero).
+Words are inserted into the current line separated by single spaces.
+.PP
+.PD 0
+.TP
+.B 0 (zero)
+The zeroth word. For the shell, this is the command
+word.
+.TP
+.I n
+The \fIn\fRth word.
+.TP
+.B ^
+The first argument. That is, word 1.
+.TP
+.B $
+The last argument.
+.TP
+.B %
+The word matched by the most recent `?\fIstring\fR?' search.
+.TP
+.I x\fB\-\fPy
+A range of words; `\-\fIy\fR' abbreviates `0\-\fIy\fR'.
+.TP
+.B *
+All of the words but the zeroth. This is a synonym
+for `\fI1\-$\fP'. It is not an error to use
+.B *
+if there is just one
+word in the event; the empty string is returned in that case.
+.TP
+.B x*
+Abbreviates \fIx\-$\fP.
+.TP
+.B x\-
+Abbreviates \fIx\-$\fP like \fBx*\fP, but omits the last word.
+.PD
+.PP
+If a word designator is supplied without an event specification, the
+previous command is used as the event.
+.SS Modifiers
+.PP
+After the optional word designator, there may appear a sequence of
+one or more of the following modifiers, each preceded by a `:'.
+.PP
+.PD 0
+.PP
+.TP
+.B h
+Remove a trailing file name component, leaving only the head.
+.TP
+.B t
+Remove all leading file name components, leaving the tail.
+.TP
+.B r
+Remove a trailing suffix of the form \fI.xxx\fP, leaving the
+basename.
+.TP
+.B e
+Remove all but the trailing suffix.
+.TP
+.B p
+Print the new command but do not execute it.
+.TP
+.B q
+Quote the substituted words, escaping further substitutions.
+.TP
+.B x
+Quote the substituted words as with
+.BR q ,
+but break into words at
+.B blanks
+and newlines.
+.TP
+.B s/\fIold\fP/\fInew\fP/
+Substitute
+.I new
+for the first occurrence of
+.I old
+in the event line. Any delimiter can be used in place of /. The
+final delimiter is optional if it is the last character of the
+event line. The delimiter may be quoted in
+.I old
+and
+.I new
+with a single backslash. If & appears in
+.IR new ,
+it is replaced by
+.IR old .
+A single backslash will quote the &. If
+.I old
+is null, it is set to the last
+.I old
+substituted, or, if no previous history substitutions took place,
+the last
+.I string
+in a
+.B !?\fIstring\fR\fB[?]\fR
+search.
+.TP
+.B &
+Repeat the previous substitution.
+.TP
+.B g
+Cause changes to be applied over the entire event line. This is
+used in conjunction with `\fB:s\fP' (e.g., `\fB:gs/\fIold\fP/\fInew\fP/\fR')
+or `\fB:&\fP'. If used with
+`\fB:s\fP', any delimiter can be used
+in place of /, and the final delimiter is optional
+if it is the last character of the event line.
+An \fBa\fP may be used as a synonym for \fBg\fP.
+.TP
+.B G
+Apply the following `\fBs\fP' modifier once to each word in the event line.
+.PD
+.SH "SHELL BUILTIN COMMANDS"
+.\" start of bash_builtins
+.zZ
+.PP
+Unless otherwise noted, each builtin command documented in this
+section as accepting options preceded by
+.B \-
+accepts
+.B \-\-
+to signify the end of the options.
+The \fB:\fP, \fBtrue\fP, \fBfalse\fP, and \fBtest\fP builtins
+do not accept options and do not treat \fB\-\-\fP specially.
+The \fBexit\fP, \fBlogout\fP, \fBbreak\fP, \fBcontinue\fP, \fBlet\fP,
+and \fBshift\fP builtins accept and process arguments beginning with
+\fB\-\fP without requiring \fB\-\-\fP.
+Other builtins that accept arguments but are not specified as accepting
+options interpret arguments beginning with \fB\-\fP as invalid options and
+require \fB\-\-\fP to prevent this interpretation.
+.sp .5
+.PD 0
+.TP
+\fB:\fP [\fIarguments\fP]
+.PD
+No effect; the command does nothing beyond expanding
+.I arguments
+and performing any specified
+redirections. A zero exit code is returned.
+.TP
+\fB .\| \fP \fIfilename\fP [\fIarguments\fP]
+.PD 0
+.TP
+\fBsource\fP \fIfilename\fP [\fIarguments\fP]
+.PD
+Read and execute commands from
+.I filename
+in the current
+shell environment and return the exit status of the last command
+executed from
+.IR filename .
+If
+.I filename
+does not contain a slash, file names in
+.SM
+.B PATH
+are used to find the directory containing
+.IR filename .
+The file searched for in
+.SM
+.B PATH
+need not be executable.
+When \fBbash\fP is not in \fIposix mode\fP, the current directory is
+searched if no file is found in
+.SM
+.BR PATH .
+If the
+.B sourcepath
+option to the
+.B shopt
+builtin command is turned off, the
+.SM
+.B PATH
+is not searched.
+If any \fIarguments\fP are supplied, they become the positional
+parameters when \fIfilename\fP is executed. Otherwise the positional
+parameters are unchanged.
+The return status is the status of the last command exited within
+the script (0 if no commands are executed), and false if
+.I filename
+is not found or cannot be read.
+.TP
+\fBalias\fP [\fB\-p\fP] [\fIname\fP[=\fIvalue\fP] ...]
+\fBAlias\fP with no arguments or with the
+.B \-p
+option prints the list of aliases in the form
+\fBalias\fP \fIname\fP=\fIvalue\fP on standard output.
+When arguments are supplied, an alias is defined for
+each \fIname\fP whose \fIvalue\fP is given.
+A trailing space in \fIvalue\fP causes the next word to be
+checked for alias substitution when the alias is expanded.
+For each \fIname\fP in the argument list for which no \fIvalue\fP
+is supplied, the name and value of the alias is printed.
+\fBAlias\fP returns true unless a \fIname\fP is given for which
+no alias has been defined.
+.TP
+\fBbg\fP [\fIjobspec\fP ...]
+Resume each suspended job \fIjobspec\fP in the background, as if it
+had been started with
+.BR & .
+If
+.I jobspec
+is not present, the shell's notion of the \fIcurrent job\fP is used.
+.B bg
+.I jobspec
+returns 0 unless run when job control is disabled or, when run with
+job control enabled, any specified \fIjobspec\fP was not found
+or was started without job control.
+.TP
+\fBbind\fP [\fB\-m\fP \fIkeymap\fP] [\fB\-lpsvPSV\fP]
+.PD 0
+.TP
+\fBbind\fP [\fB\-m\fP \fIkeymap\fP] [\fB\-q\fP \fIfunction\fP] [\fB\-u\fP \fIfunction\fP] [\fB\-r\fP \fIkeyseq\fP]
+.TP
+\fBbind\fP [\fB\-m\fP \fIkeymap\fP] \fB\-f\fP \fIfilename\fP
+.TP
+\fBbind\fP [\fB\-m\fP \fIkeymap\fP] \fB\-x\fP \fIkeyseq\fP:\fIshell\-command\fP
+.TP
+\fBbind\fP [\fB\-m\fP \fIkeymap\fP] \fIkeyseq\fP:\fIfunction\-name\fP
+.TP
+\fBbind\fP \fIreadline\-command\fP
+.PD
+Display current
+.B readline
+key and function bindings, bind a key sequence to a
+.B readline
+function or macro, or set a
+.B readline
+variable.
+Each non-option argument is a command as it would appear in
+.IR .inputrc ,
+but each binding or command must be passed as a separate argument;
+e.g., '"\eC\-x\eC\-r": re\-read\-init\-file'.
+Options, if supplied, have the following meanings:
+.RS
+.PD 0
+.TP
+.B \-m \fIkeymap\fP
+Use
+.I keymap
+as the keymap to be affected by the subsequent bindings.
+Acceptable
+.I keymap
+names are
+\fIemacs, emacs\-standard, emacs\-meta, emacs\-ctlx, vi,
+vi\-move, vi\-command\fP, and
+.IR vi\-insert .
+\fIvi\fP is equivalent to \fIvi\-command\fP; \fIemacs\fP is
+equivalent to \fIemacs\-standard\fP.
+.TP
+.B \-l
+List the names of all \fBreadline\fP functions.
+.TP
+.B \-p
+Display \fBreadline\fP function names and bindings in such a way
+that they can be re-read.
+.TP
+.B \-P
+List current \fBreadline\fP function names and bindings.
+.TP
+.B \-s
+Display \fBreadline\fP key sequences bound to macros and the strings
+they output in such a way that they can be re-read.
+.TP
+.B \-S
+Display \fBreadline\fP key sequences bound to macros and the strings
+they output.
+.TP
+.B \-v
+Display \fBreadline\fP variable names and values in such a way that they
+can be re-read.
+.TP
+.B \-V
+List current \fBreadline\fP variable names and values.
+.TP
+.B \-f \fIfilename\fP
+Read key bindings from \fIfilename\fP.
+.TP
+.B \-q \fIfunction\fP
+Query about which keys invoke the named \fIfunction\fP.
+.TP
+.B \-u \fIfunction\fP
+Unbind all keys bound to the named \fIfunction\fP.
+.TP
+.B \-r \fIkeyseq\fP
+Remove any current binding for \fIkeyseq\fP.
+.TP
+.B \-x \fIkeyseq\fP:\fIshell\-command\fP
+Cause \fIshell\-command\fP to be executed whenever \fIkeyseq\fP is
+entered.
+When \fIshell\-command\fP is executed, the shell sets the
+.SM
+.B READLINE_LINE
+variable to the contents of the \fBreadline\fP line buffer and the
+.SM
+.B READLINE_POINT
+variable to the current location of the insertion point.
+If the executed command changes the value of
+.SM
+.B READLINE_LINE
+or
+.SM
+.BR READLINE_POINT ,
+those new values will be reflected in the editing state.
+.PD
+.PP
+The return value is 0 unless an unrecognized option is given or an
+error occurred.
+.RE
+.TP
+\fBbreak\fP [\fIn\fP]
+Exit from within a
+.BR for ,
+.BR while ,
+.BR until ,
+or
+.B select
+loop. If \fIn\fP is specified, break \fIn\fP levels.
+.I n
+must be \(>= 1. If
+.I n
+is greater than the number of enclosing loops, all enclosing loops
+are exited.
+The return value is 0 unless \fIn\fP is not greater than or equal to 1.
+.TP
+\fBbuiltin\fP \fIshell\-builtin\fP [\fIarguments\fP]
+Execute the specified shell builtin, passing it
+.IR arguments ,
+and return its exit status.
+This is useful when defining a
+function whose name is the same as a shell builtin,
+retaining the functionality of the builtin within the function.
+The \fBcd\fP builtin is commonly redefined this way.
+The return status is false if
+.I shell\-builtin
+is not a shell builtin command.
+.TP
+\fBcaller\fP [\fIexpr\fP]
+Returns the context of any active subroutine call (a shell function or
+a script executed with the \fB.\fP or \fBsource\fP builtins).
+Without \fIexpr\fP, \fBcaller\fP displays the line number and source
+filename of the current subroutine call.
+If a non-negative integer is supplied as \fIexpr\fP, \fBcaller\fP
+displays the line number, subroutine name, and source file corresponding
+to that position in the current execution call stack. This extra
+information may be used, for example, to print a stack trace. The
+current frame is frame 0.
+The return value is 0 unless the shell is not executing a subroutine
+call or \fIexpr\fP does not correspond to a valid position in the
+call stack.
+.TP
+\fBcd\fP [\fB\-L\fP|[\fB\-P\fP [\fB\-e\fP]]] [\fIdir\fP]
+Change the current directory to \fIdir\fP. The variable
+.SM
+.B HOME
+is the
+default
+.IR dir .
+The variable
+.SM
+.B CDPATH
+defines the search path for the directory containing
+.IR dir .
+Alternative directory names in
+.SM
+.B CDPATH
+are separated by a colon (:). A null directory name in
+.SM
+.B CDPATH
+is the same as the current directory, i.e., ``\fB.\fP''. If
+.I dir
+begins with a slash (/),
+then
+.SM
+.B CDPATH
+is not used. The
+.B \-P
+option says to use the physical directory structure instead of
+following symbolic links (see also the
+.B \-P
+option to the
+.B set
+builtin command); the
+.B \-L
+option forces symbolic links to be followed.
+If the
+.B \-e
+option is supplied with
+.BR \-P ,
+and the current working directory cannot be successfully determined
+after a successful directory change, \fBcd\fP will return an unsuccessful
+status.
+An argument of
+.B \-
+is converted to
+.SM
+.B $OLDPWD
+before the directory change is attempted.
+If a non-empty directory name from
+.SM
+.B CDPATH
+is used, or if
+\fB\-\fP is the first argument, and the directory change is
+successful, the absolute pathname of the new working directory is
+written to the standard output.
+The return value is true if the directory was successfully changed;
+false otherwise.
+.TP
+\fBcommand\fP [\fB\-pVv\fP] \fIcommand\fP [\fIarg\fP ...]
+Run
+.I command
+with
+.I args
+suppressing the normal shell function lookup. Only builtin
+commands or commands found in the
+.SM
+.B PATH
+are executed. If the
+.B \-p
+option is given, the search for
+.I command
+is performed using a default value for
+.SM
+.B PATH
+that is guaranteed to find all of the standard utilities.
+If either the
+.B \-V
+or
+.B \-v
+option is supplied, a description of
+.I command
+is printed. The
+.B \-v
+option causes a single word indicating the command or file name
+used to invoke
+.I command
+to be displayed; the
+.B \-V
+option produces a more verbose description.
+If the
+.B \-V
+or
+.B \-v
+option is supplied, the exit status is 0 if
+.I command
+was found, and 1 if not. If neither option is supplied and
+an error occurred or
+.I command
+cannot be found, the exit status is 127. Otherwise, the exit status of the
+.B command
+builtin is the exit status of
+.IR command .
+.TP
+\fBcompgen\fP [\fIoption\fP] [\fIword\fP]
+Generate possible completion matches for \fIword\fP according to
+the \fIoption\fPs, which may be any option accepted by the
+.B complete
+builtin with the exception of \fB\-p\fP and \fB\-r\fP, and write
+the matches to the standard output.
+When using the \fB\-F\fP or \fB\-C\fP options, the various shell variables
+set by the programmable completion facilities, while available, will not
+have useful values.
+.sp 1
+The matches will be generated in the same way as if the programmable
+completion code had generated them directly from a completion specification
+with the same flags.
+If \fIword\fP is specified, only those completions matching \fIword\fP
+will be displayed.
+.sp 1
+The return value is true unless an invalid option is supplied, or no
+matches were generated.
+.TP
+\fBcomplete\fP [\fB\-abcdefgjksuv\fP] [\fB\-o\fP \fIcomp-option\fP] [\fB\-DE\fP] [\fB\-A\fP \fIaction\fP] [\fB\-G\fP \fIglobpat\fP] [\fB\-W\fP \fIwordlist\fP] [\fB\-F\fP \fIfunction\fP] [\fB\-C\fP \fIcommand\fP]
+.br
+[\fB\-X\fP \fIfilterpat\fP] [\fB\-P\fP \fIprefix\fP] [\fB\-S\fP \fIsuffix\fP] \fIname\fP [\fIname ...\fP]
+.PD 0
+.TP
+\fBcomplete\fP \fB\-pr\fP [\fB\-DE\fP] [\fIname\fP ...]
+.PD
+Specify how arguments to each \fIname\fP should be completed.
+If the \fB\-p\fP option is supplied, or if no options are supplied,
+existing completion specifications are printed in a way that allows
+them to be reused as input.
+The \fB\-r\fP option removes a completion specification for
+each \fIname\fP, or, if no \fIname\fPs are supplied, all
+completion specifications.
+The \fB\-D\fP option indicates that the remaining options and actions should
+apply to the ``default'' command completion; that is, completion attempted
+on a command for which no completion has previously been defined.
+The \fB\-E\fP option indicates that the remaining options and actions should
+apply to ``empty'' command completion; that is, completion attempted on a
+blank line.
+.sp 1
+The process of applying these completion specifications when word completion
+is attempted is described above under \fBProgrammable Completion\fP.
+.sp 1
+Other options, if specified, have the following meanings.
+The arguments to the \fB\-G\fP, \fB\-W\fP, and \fB\-X\fP options
+(and, if necessary, the \fB\-P\fP and \fB\-S\fP options)
+should be quoted to protect them from expansion before the
+.B complete
+builtin is invoked.
+.RS
+.PD 0
+.TP 8
+\fB\-o\fP \fIcomp-option\fP
+The \fIcomp-option\fP controls several aspects of the compspec's behavior
+beyond the simple generation of completions.
+\fIcomp-option\fP may be one of:
+.RS
+.TP 8
+.B bashdefault
+Perform the rest of the default \fBbash\fP completions if the compspec
+generates no matches.
+.TP 8
+.B default
+Use readline's default filename completion if the compspec generates
+no matches.
+.TP 8
+.B dirnames
+Perform directory name completion if the compspec generates no matches.
+.TP 8
+.B filenames
+Tell readline that the compspec generates filenames, so it can perform any
+filename\-specific processing (like adding a slash to directory names,
+quoting special characters, or suppressing trailing spaces).
+Intended to be used with shell functions.
+.TP 8
+.B nospace
+Tell readline not to append a space (the default) to words completed at
+the end of the line.
+.TP 8
+.B plusdirs
+After any matches defined by the compspec are generated,
+directory name completion is attempted and any
+matches are added to the results of the other actions.
+.RE
+.TP 8
+\fB\-A\fP \fIaction\fP
+The \fIaction\fP may be one of the following to generate a list of possible
+completions:
+.RS
+.TP 8
+.B alias
+Alias names. May also be specified as \fB\-a\fP.
+.TP 8
+.B arrayvar
+Array variable names.
+.TP 8
+.B binding
+\fBReadline\fP key binding names.
+.TP 8
+.B builtin
+Names of shell builtin commands. May also be specified as \fB\-b\fP.
+.TP 8
+.B command
+Command names. May also be specified as \fB\-c\fP.
+.TP 8
+.B directory
+Directory names. May also be specified as \fB\-d\fP.
+.TP 8
+.B disabled
+Names of disabled shell builtins.
+.TP 8
+.B enabled
+Names of enabled shell builtins.
+.TP 8
+.B export
+Names of exported shell variables. May also be specified as \fB\-e\fP.
+.TP 8
+.B file
+File names. May also be specified as \fB\-f\fP.
+.TP 8
+.B function
+Names of shell functions.
+.TP 8
+.B group
+Group names. May also be specified as \fB\-g\fP.
+.TP 8
+.B helptopic
+Help topics as accepted by the \fBhelp\fP builtin.
+.TP 8
+.B hostname
+Hostnames, as taken from the file specified by the
+.SM
+.B HOSTFILE
+shell variable.
+.TP 8
+.B job
+Job names, if job control is active. May also be specified as \fB\-j\fP.
+.TP 8
+.B keyword
+Shell reserved words. May also be specified as \fB\-k\fP.
+.TP 8
+.B running
+Names of running jobs, if job control is active.
+.TP 8
+.B service
+Service names. May also be specified as \fB\-s\fP.
+.TP 8
+.B setopt
+Valid arguments for the \fB\-o\fP option to the \fBset\fP builtin.
+.TP 8
+.B shopt
+Shell option names as accepted by the \fBshopt\fP builtin.
+.TP 8
+.B signal
+Signal names.
+.TP 8
+.B stopped
+Names of stopped jobs, if job control is active.
+.TP 8
+.B user
+User names. May also be specified as \fB\-u\fP.
+.TP 8
+.B variable
+Names of all shell variables. May also be specified as \fB\-v\fP.
+.RE
+.TP 8
+\fB\-C\fP \fIcommand\fP
+\fIcommand\fP is executed in a subshell environment, and its output is
+used as the possible completions.
+.TP 8
+\fB\-F\fP \fIfunction\fP
+The shell function \fIfunction\fP is executed in the current shell
+environment.
+When it finishes, the possible completions are retrieved from the value
+of the
+.SM
+.B COMPREPLY
+array variable.
+.TP 8
+\fB\-G\fP \fIglobpat\fP
+The pathname expansion pattern \fIglobpat\fP is expanded to generate
+the possible completions.
+.TP 8
+\fB\-P\fP \fIprefix\fP
+\fIprefix\fP is added at the beginning of each possible completion
+after all other options have been applied.
+.TP 8
+\fB\-S\fP \fIsuffix\fP
+\fIsuffix\fP is appended to each possible completion
+after all other options have been applied.
+.TP 8
+\fB\-W\fP \fIwordlist\fP
+The \fIwordlist\fP is split using the characters in the
+.SM
+.B IFS
+special variable as delimiters, and each resultant word is expanded.
+The possible completions are the members of the resultant list which
+match the word being completed.
+.TP 8
+\fB\-X\fP \fIfilterpat\fP
+\fIfilterpat\fP is a pattern as used for pathname expansion.
+It is applied to the list of possible completions generated by the
+preceding options and arguments, and each completion matching
+\fIfilterpat\fP is removed from the list.
+A leading \fB!\fP in \fIfilterpat\fP negates the pattern; in this
+case, any completion not matching \fIfilterpat\fP is removed.
+.PD
+.PP
+The return value is true unless an invalid option is supplied, an option
+other than \fB\-p\fP or \fB\-r\fP is supplied without a \fIname\fP
+argument, an attempt is made to remove a completion specification for
+a \fIname\fP for which no specification exists, or
+an error occurs adding a completion specification.
+.RE
+.TP
+\fBcompopt\fP [\fB\-o\fP \fIoption\fP] [\fB\-DE\fP] [\fB+o\fP \fIoption\fP] [\fIname\fP]
+Modify completion options for each \fIname\fP according to the
+\fIoption\fPs, or for the
+currently-executing completion if no \fIname\fPs are supplied.
+If no \fIoption\fPs are given, display the completion options for each
+\fIname\fP or the current completion.
+The possible values of \fIoption\fP are those valid for the \fBcomplete\fP
+builtin described above.
+The \fB\-D\fP option indicates that the remaining options should
+apply to the ``default'' command completion; that is, completion attempted
+on a command for which no completion has previously been defined.
+The \fB\-E\fP option indicates that the remaining options should
+apply to ``empty'' command completion; that is, completion attempted on a
+blank line.
+.sp 1
+The return value is true unless an invalid option is supplied, an attempt
+is made to modify the options for a \fIname\fP for which no completion
+specification exists, or an output error occurs.
+.TP
+\fBcontinue\fP [\fIn\fP]
+Resume the next iteration of the enclosing
+.BR for ,
+.BR while ,
+.BR until ,
+or
+.B select
+loop.
+If
+.I n
+is specified, resume at the \fIn\fPth enclosing loop.
+.I n
+must be \(>= 1. If
+.I n
+is greater than the number of enclosing loops, the last enclosing loop
+(the ``top-level'' loop) is resumed.
+The return value is 0 unless \fIn\fP is not greater than or equal to 1.
+.TP
+\fBdeclare\fP [\fB\-aAfFgilrtux\fP] [\fB\-p\fP] [\fIname\fP[=\fIvalue\fP] ...]
+.PD 0
+.TP
+\fBtypeset\fP [\fB\-aAfFgilrtux\fP] [\fB\-p\fP] [\fIname\fP[=\fIvalue\fP] ...]
+.PD
+Declare variables and/or give them attributes.
+If no \fIname\fPs are given then display the values of variables.
+The
+.B \-p
+option will display the attributes and values of each
+.IR name .
+When
+.B \-p
+is used with \fIname\fP arguments, additional options are ignored.
+When
+.B \-p
+is supplied without \fIname\fP arguments, it will display the attributes
+and values of all variables having the attributes specified by the
+additional options.
+If no other options are supplied with \fB\-p\fP, \fBdeclare\fP will display
+the attributes and values of all shell variables. The \fB\-f\fP option
+will restrict the display to shell functions.
+The
+.B \-F
+option inhibits the display of function definitions; only the
+function name and attributes are printed.
+If the \fBextdebug\fP shell option is enabled using \fBshopt\fP,
+the source file name and line number where the function is defined
+are displayed as well. The
+.B \-F
+option implies
+.BR \-f .
+The
+.B \-g
+option forces variables to be created or modified at the global scope,
+even when \fBdeclare\fP is executed in a shell function.
+It is ignored in all other cases.
+The following options can
+be used to restrict output to variables with the specified attribute or
+to give variables attributes:
+.RS
+.PD 0
+.TP
+.B \-a
+Each \fIname\fP is an indexed array variable (see
+.B Arrays
+above).
+.TP
+.B \-A
+Each \fIname\fP is an associative array variable (see
+.B Arrays
+above).
+.TP
+.B \-f
+Use function names only.
+.TP
+.B \-i
+The variable is treated as an integer; arithmetic evaluation (see
+.SM
+.B "ARITHMETIC EVALUATION"
+above) is performed when the variable is assigned a value.
+.TP
+.B \-l
+When the variable is assigned a value, all upper-case characters are
+converted to lower-case.
+The upper-case attribute is disabled.
+.TP
+.B \-r
+Make \fIname\fPs readonly. These names cannot then be assigned values
+by subsequent assignment statements or unset.
+.TP
+.B \-t
+Give each \fIname\fP the \fItrace\fP attribute.
+Traced functions inherit the \fBDEBUG\fP and \fBRETURN\fP traps from
+the calling shell.
+The trace attribute has no special meaning for variables.
+.TP
+.B \-u
+When the variable is assigned a value, all lower-case characters are
+converted to upper-case.
+The lower-case attribute is disabled.
+.TP
+.B \-x
+Mark \fIname\fPs for export to subsequent commands via the environment.
+.PD
+.PP
+Using `+' instead of `\-'
+turns off the attribute instead,
+with the exceptions that \fB+a\fP
+may not be used to destroy an array variable and \fB+r\fP will not
+remove the readonly attribute.
+When used in a function, makes each
+\fIname\fP local, as with the
+.B local
+command,
+unless the \fB\-g\fP option is supplied,
+If a variable name is followed by =\fIvalue\fP, the value of
+the variable is set to \fIvalue\fP.
+The return value is 0 unless an invalid option is encountered,
+an attempt is made to define a function using
+.if n ``\-f foo=bar'',
+.if t \f(CW\-f foo=bar\fP,
+an attempt is made to assign a value to a readonly variable,
+an attempt is made to assign a value to an array variable without
+using the compound assignment syntax (see
+.B Arrays
+above), one of the \fInames\fP is not a valid shell variable name,
+an attempt is made to turn off readonly status for a readonly variable,
+an attempt is made to turn off array status for an array variable,
+or an attempt is made to display a non-existent function with \fB\-f\fP.
+.RE
+.TP
+.B dirs [+\fIn\fP] [\-\fIn\fP] [\fB\-clpv\fP]
+Without options, displays the list of currently remembered directories.
+The default display is on a single line with directory names separated
+by spaces.
+Directories are added to the list with the
+.B pushd
+command; the
+.B popd
+command removes entries from the list.
+.RS
+.PD 0
+.TP
+\fB+\fP\fIn\fP
+Displays the \fIn\fPth entry counting from the left of the list
+shown by
+.B dirs
+when invoked without options, starting with zero.
+.TP
+\fB\-\fP\fIn\fP
+Displays the \fIn\fPth entry counting from the right of the list
+shown by
+.B dirs
+when invoked without options, starting with zero.
+.TP
+.B \-c
+Clears the directory stack by deleting all of the entries.
+.TP
+.B \-l
+Produces a longer listing; the default listing format uses a
+tilde to denote the home directory.
+.TP
+.B \-p
+Print the directory stack with one entry per line.
+.TP
+.B \-v
+Print the directory stack with one entry per line,
+prefixing each entry with its index in the stack.
+.PD
+.PP
+The return value is 0 unless an
+invalid option is supplied or \fIn\fP indexes beyond the end
+of the directory stack.
+.RE
+.TP
+\fBdisown\fP [\fB\-ar\fP] [\fB\-h\fP] [\fIjobspec\fP ...]
+Without options, each
+.I jobspec
+is removed from the table of active jobs.
+If
+.I jobspec
+is not present, and neither \fB\-a\fP nor \fB\-r\fP is supplied,
+the shell's notion of the \fIcurrent job\fP is used.
+If the \fB\-h\fP option is given, each
+.I jobspec
+is not removed from the table, but is marked so that
+.SM
+.B SIGHUP
+is not sent to the job if the shell receives a
+.SM
+.BR SIGHUP .
+If no
+.I jobspec
+is present, and neither the
+.B \-a
+nor the
+.B \-r
+option is supplied, the \fIcurrent job\fP is used.
+If no
+.I jobspec
+is supplied, the
+.B \-a
+option means to remove or mark all jobs; the
+.B \-r
+option without a
+.I jobspec
+argument restricts operation to running jobs.
+The return value is 0 unless a
+.I jobspec
+does not specify a valid job.
+.TP
+\fBecho\fP [\fB\-neE\fP] [\fIarg\fP ...]
+Output the \fIarg\fPs, separated by spaces, followed by a newline.
+The return status is 0 unless a write error occurs.
+If \fB\-n\fP is specified, the trailing newline is
+suppressed. If the \fB\-e\fP option is given, interpretation of
+the following backslash-escaped characters is enabled. The
+.B \-E
+option disables the interpretation of these escape characters,
+even on systems where they are interpreted by default.
+The \fBxpg_echo\fP shell option may be used to
+dynamically determine whether or not \fBecho\fP expands these
+escape characters by default.
+.B echo
+does not interpret \fB\-\-\fP to mean the end of options.
+.B echo
+interprets the following escape sequences:
+.RS
+.PD 0
+.TP
+.B \ea
+alert (bell)
+.TP
+.B \eb
+backspace
+.TP
+.B \ec
+suppress further output
+.TP
+.B \ee
+.TP
+.B \eE
+an escape character
+.TP
+.B \ef
+form feed
+.TP
+.B \en
+new line
+.TP
+.B \er
+carriage return
+.TP
+.B \et
+horizontal tab
+.TP
+.B \ev
+vertical tab
+.TP
+.B \e\e
+backslash
+.TP
+.B \e0\fInnn\fP
+the eight-bit character whose value is the octal value \fInnn\fP
+(zero to three octal digits)
+.TP
+.B \ex\fIHH\fP
+the eight-bit character whose value is the hexadecimal value \fIHH\fP
+(one or two hex digits)
+.TP
+.B \eu\fIHHHH\fP
+the Unicode (ISO/IEC 10646) character whose value is the hexadecimal value
+\fIHHHH\fP (one to four hex digits)
+.TP
+.B \eU\fIHHHHHHHH\fP
+the Unicode (ISO/IEC 10646) character whose value is the hexadecimal value
+\fIHHHHHHHH\fP (one to eight hex digits)
+.PD
+.RE
+.TP
+\fBenable\fP [\fB\-a\fP] [\fB\-dnps\fP] [\fB\-f\fP \fIfilename\fP] [\fIname\fP ...]
+Enable and disable builtin shell commands.
+Disabling a builtin allows a disk command which has the same name
+as a shell builtin to be executed without specifying a full pathname,
+even though the shell normally searches for builtins before disk commands.
+If \fB\-n\fP is used, each \fIname\fP
+is disabled; otherwise,
+\fInames\fP are enabled. For example, to use the
+.B test
+binary found via the
+.SM
+.B PATH
+instead of the shell builtin version, run
+.if t \f(CWenable -n test\fP.
+.if n ``enable -n test''.
+The
+.B \-f
+option means to load the new builtin command
+.I name
+from shared object
+.IR filename ,
+on systems that support dynamic loading. The
+.B \-d
+option will delete a builtin previously loaded with
+.BR \-f .
+If no \fIname\fP arguments are given, or if the
+.B \-p
+option is supplied, a list of shell builtins is printed.
+With no other option arguments, the list consists of all enabled
+shell builtins.
+If \fB\-n\fP is supplied, only disabled builtins are printed.
+If \fB\-a\fP is supplied, the list printed includes all builtins, with an
+indication of whether or not each is enabled.
+If \fB\-s\fP is supplied, the output is restricted to the POSIX
+\fIspecial\fP builtins.
+The return value is 0 unless a
+.I name
+is not a shell builtin or there is an error loading a new builtin
+from a shared object.
+.TP
+\fBeval\fP [\fIarg\fP ...]
+The \fIarg\fPs are read and concatenated together into a single
+command. This command is then read and executed by the shell, and
+its exit status is returned as the value of
+.BR eval .
+If there are no
+.IR args ,
+or only null arguments,
+.B eval
+returns 0.
+.TP
+\fBexec\fP [\fB\-cl\fP] [\fB\-a\fP \fIname\fP] [\fIcommand\fP [\fIarguments\fP]]
+If
+.I command
+is specified, it replaces the shell.
+No new process is created. The
+.I arguments
+become the arguments to \fIcommand\fP.
+If the
+.B \-l
+option is supplied,
+the shell places a dash at the beginning of the zeroth argument passed to
+.IR command .
+This is what
+.IR login (1)
+does. The
+.B \-c
+option causes
+.I command
+to be executed with an empty environment. If
+.B \-a
+is supplied, the shell passes
+.I name
+as the zeroth argument to the executed command. If
+.I command
+cannot be executed for some reason, a non-interactive shell exits,
+unless the shell option
+.B execfail
+is enabled, in which case it returns failure.
+An interactive shell returns failure if the file cannot be executed.
+If
+.I command
+is not specified, any redirections take effect in the current shell,
+and the return status is 0. If there is a redirection error, the
+return status is 1.
+.TP
+\fBexit\fP [\fIn\fP]
+Cause the shell to exit
+with a status of \fIn\fP. If
+.I n
+is omitted, the exit status
+is that of the last command executed.
+A trap on
+.SM
+.B EXIT
+is executed before the shell terminates.
+.TP
+\fBexport\fP [\fB\-fn\fP\^] [\fIname\fP[=\fIword\fP]] ...
+.PD 0
+.TP
+.B export \-p
+.PD
+The supplied
+.I names
+are marked for automatic export to the environment of
+subsequently executed commands. If the
+.B \-f
+option is given,
+the
+.I names
+refer to functions.
+If no
+.I names
+are given, or if the
+.B \-p
+option is supplied, a list
+of all names that are exported in this shell is printed.
+The
+.B \-n
+option causes the export property to be removed from each
+\fIname\fP.
+If a variable name is followed by =\fIword\fP, the value of
+the variable is set to \fIword\fP.
+.B export
+returns an exit status of 0 unless an invalid option is
+encountered,
+one of the \fInames\fP is not a valid shell variable name, or
+.B \-f
+is supplied with a
+.I name
+that is not a function.
+.TP
+\fBfc\fP [\fB\-e\fP \fIename\fP] [\fB\-lnr\fP] [\fIfirst\fP] [\fIlast\fP]
+.PD 0
+.TP
+\fBfc\fP \fB\-s\fP [\fIpat\fP=\fIrep\fP] [\fIcmd\fP]
+.PD
+Fix Command. In the first form, a range of commands from
+.I first
+to
+.I last
+is selected from the history list.
+.I First
+and
+.I last
+may be specified as a string (to locate the last command beginning
+with that string) or as a number (an index into the history list,
+where a negative number is used as an offset from the current
+command number). If
+.I last
+is not specified it is set to
+the current command for listing (so that
+.if n ``fc \-l \-10''
+.if t \f(CWfc \-l \-10\fP
+prints the last 10 commands) and to
+.I first
+otherwise.
+If
+.I first
+is not specified it is set to the previous
+command for editing and \-16 for listing.
+.sp 1
+The
+.B \-n
+option suppresses
+the command numbers when listing. The
+.B \-r
+option reverses the order of
+the commands. If the
+.B \-l
+option is given,
+the commands are listed on
+standard output. Otherwise, the editor given by
+.I ename
+is invoked
+on a file containing those commands. If
+.I ename
+is not given, the
+value of the
+.SM
+.B FCEDIT
+variable is used, and
+the value of
+.SM
+.B EDITOR
+if
+.SM
+.B FCEDIT
+is not set. If neither variable is set,
+.FN vi
+is used. When editing is complete, the edited commands are
+echoed and executed.
+.sp 1
+In the second form, \fIcommand\fP is re-executed after each instance
+of \fIpat\fP is replaced by \fIrep\fP.
+A useful alias to use with this is
+.if n ``r="fc -s"'',
+.if t \f(CWr='fc \-s'\fP,
+so that typing
+.if n ``r cc''
+.if t \f(CWr cc\fP
+runs the last command beginning with
+.if n ``cc''
+.if t \f(CWcc\fP
+and typing
+.if n ``r''
+.if t \f(CWr\fP
+re-executes the last command.
+.sp 1
+If the first form is used, the return value is 0 unless an invalid
+option is encountered or
+.I first
+or
+.I last
+specify history lines out of range.
+If the
+.B \-e
+option is supplied, the return value is the value of the last
+command executed or failure if an error occurs with the temporary
+file of commands. If the second form is used, the return status
+is that of the command re-executed, unless
+.I cmd
+does not specify a valid history line, in which case
+.B fc
+returns failure.
+.TP
+\fBfg\fP [\fIjobspec\fP]
+Resume
+.I jobspec
+in the foreground, and make it the current job.
+If
+.I jobspec
+is not present, the shell's notion of the \fIcurrent job\fP is used.
+The return value is that of the command placed into the foreground,
+or failure if run when job control is disabled or, when run with
+job control enabled, if
+.I jobspec
+does not specify a valid job or
+.I jobspec
+specifies a job that was started without job control.
+.TP
+\fBgetopts\fP \fIoptstring\fP \fIname\fP [\fIargs\fP]
+.B getopts
+is used by shell procedures to parse positional parameters.
+.I optstring
+contains the option characters to be recognized; if a character
+is followed by a colon, the option is expected to have an
+argument, which should be separated from it by white space.
+The colon and question mark characters may not be used as
+option characters.
+Each time it is invoked,
+.B getopts
+places the next option in the shell variable
+.IR name ,
+initializing
+.I name
+if it does not exist,
+and the index of the next argument to be processed into the
+variable
+.SM
+.BR OPTIND .
+.SM
+.B OPTIND
+is initialized to 1 each time the shell or a shell script
+is invoked. When an option requires an argument,
+.B getopts
+places that argument into the variable
+.SM
+.BR OPTARG .
+The shell does not reset
+.SM
+.B OPTIND
+automatically; it must be manually reset between multiple
+calls to
+.B getopts
+within the same shell invocation if a new set of parameters
+is to be used.
+.sp 1
+When the end of options is encountered, \fBgetopts\fP exits with a
+return value greater than zero.
+.SM
+.B OPTIND
+is set to the index of the first non-option argument,
+and \fIname\fP is set to ?.
+.sp 1
+.B getopts
+normally parses the positional parameters, but if more arguments are
+given in
+.IR args ,
+.B getopts
+parses those instead.
+.sp 1
+.B getopts
+can report errors in two ways. If the first character of
+.I optstring
+is a colon,
+.I silent
+error reporting is used. In normal operation diagnostic messages
+are printed when invalid options or missing option arguments are
+encountered.
+If the variable
+.SM
+.B OPTERR
+is set to 0, no error messages will be displayed, even if the first
+character of
+.I optstring
+is not a colon.
+.sp 1
+If an invalid option is seen,
+.B getopts
+places ? into
+.I name
+and, if not silent,
+prints an error message and unsets
+.SM
+.BR OPTARG .
+If
+.B getopts
+is silent,
+the option character found is placed in
+.SM
+.B OPTARG
+and no diagnostic message is printed.
+.sp 1
+If a required argument is not found, and
+.B getopts
+is not silent,
+a question mark (\^\fB?\fP\^) is placed in
+.IR name ,
+.SM
+.B OPTARG
+is unset, and a diagnostic message is printed.
+If
+.B getopts
+is silent, then a colon (\^\fB:\fP\^) is placed in
+.I name
+and
+.SM
+.B OPTARG
+is set to the option character found.
+.sp 1
+.B getopts
+returns true if an option, specified or unspecified, is found.
+It returns false if the end of options is encountered or an
+error occurs.
+.TP
+\fBhash\fP [\fB\-lr\fP] [\fB\-p\fP \fIfilename\fP] [\fB\-dt\fP] [\fIname\fP]
+Each time \fBhash\fP is invoked,
+the full pathname of the command
+.I name
+is determined by searching
+the directories in
+.B $PATH
+and remembered. Any previously-remembered pathname is discarded.
+If the
+.B \-p
+option is supplied, no path search is performed, and
+.I filename
+is used as the full file name of the command.
+The
+.B \-r
+option causes the shell to forget all
+remembered locations.
+The
+.B \-d
+option causes the shell to forget the remembered location of each \fIname\fP.
+If the
+.B \-t
+option is supplied, the full pathname to which each \fIname\fP corresponds
+is printed. If multiple \fIname\fP arguments are supplied with \fB\-t\fP,
+the \fIname\fP is printed before the hashed full pathname.
+The
+.B \-l
+option causes output to be displayed in a format that may be reused as input.
+If no arguments are given, or if only \fB\-l\fP is supplied,
+information about remembered commands is printed.
+The return status is true unless a
+.I name
+is not found or an invalid option is supplied.
+.TP
+\fBhelp\fP [\fB\-dms\fP] [\fIpattern\fP]
+Display helpful information about builtin commands. If
+.I pattern
+is specified,
+.B help
+gives detailed help on all commands matching
+.IR pattern ;
+otherwise help for all the builtins and shell control structures
+is printed.
+.RS
+.PD 0
+.TP
+.B \-d
+Display a short description of each \fIpattern\fP
+.TP
+.B \-m
+Display the description of each \fIpattern\fP in a manpage-like format
+.TP
+.B \-s
+Display only a short usage synopsis for each \fIpattern\fP
+.PD
+.PP
+The return status is 0 unless no command matches
+.IR pattern .
+.RE
+.TP
+\fBhistory [\fIn\fP]
+.PD 0
+.TP
+\fBhistory\fP \fB\-c\fP
+.TP
+\fBhistory \-d\fP \fIoffset\fP
+.TP
+\fBhistory\fP \fB\-anrw\fP [\fIfilename\fP]
+.TP
+\fBhistory\fP \fB\-p\fP \fIarg\fP [\fIarg ...\fP]
+.TP
+\fBhistory\fP \fB\-s\fP \fIarg\fP [\fIarg ...\fP]
+.PD
+With no options, display the command
+history list with line numbers. Lines listed
+with a
+.B *
+have been modified. An argument of
+.I n
+lists only the last
+.I n
+lines.
+If the shell variable
+.SM
+.B HISTTIMEFORMAT
+is set and not null,
+it is used as a format string for \fIstrftime\fP(3) to display
+the time stamp associated with each displayed history entry.
+No intervening blank is printed between the formatted time stamp
+and the history line.
+If \fIfilename\fP is supplied, it is used as the
+name of the history file; if not, the value of
+.SM
+.B HISTFILE
+is used. Options, if supplied, have the following meanings:
+.RS
+.PD 0
+.TP
+.B \-c
+Clear the history list by deleting all the entries.
+.TP
+\fB\-d\fP \fIoffset\fP
+Delete the history entry at position \fIoffset\fP.
+.TP
+.B \-a
+Append the ``new'' history lines (history lines entered since the
+beginning of the current \fBbash\fP session) to the history file.
+.TP
+.B \-n
+Read the history lines not already read from the history
+file into the current history list. These are lines
+appended to the history file since the beginning of the
+current \fBbash\fP session.
+.TP
+.B \-r
+Read the contents of the history file
+and use them as the current history.
+.TP
+.B \-w
+Write the current history to the history file, overwriting the
+history file's contents.
+.TP
+.B \-p
+Perform history substitution on the following \fIargs\fP and display
+the result on the standard output.
+Does not store the results in the history list.
+Each \fIarg\fP must be quoted to disable normal history expansion.
+.TP
+.B \-s
+Store the
+.I args
+in the history list as a single entry. The last command in the
+history list is removed before the
+.I args
+are added.
+.PD
+.PP
+If the
+.SM
+.B HISTTIMEFORMAT
+variable is set, the time stamp information
+associated with each history entry is written to the history file,
+marked with the history comment character.
+When the history file is read, lines beginning with the history
+comment character followed immediately by a digit are interpreted
+as timestamps for the previous history line.
+The return value is 0 unless an invalid option is encountered, an
+error occurs while reading or writing the history file, an invalid
+\fIoffset\fP is supplied as an argument to \fB\-d\fP, or the
+history expansion supplied as an argument to \fB\-p\fP fails.
+.RE
+.TP
+\fBjobs\fP [\fB\-lnprs\fP] [ \fIjobspec\fP ... ]
+.PD 0
+.TP
+\fBjobs\fP \fB\-x\fP \fIcommand\fP [ \fIargs\fP ... ]
+.PD
+The first form lists the active jobs. The options have the following
+meanings:
+.RS
+.PD 0
+.TP
+.B \-l
+List process IDs
+in addition to the normal information.
+.TP
+.B \-n
+Display information only about jobs that have changed status since
+the user was last notified of their status.
+.TP
+.B \-p
+List only the process ID of the job's process group
+leader.
+.TP
+.B \-r
+Restrict output to running jobs.
+.TP
+.B \-s
+Restrict output to stopped jobs.
+.PD
+.PP
+If
+.I jobspec
+is given, output is restricted to information about that job.
+The return status is 0 unless an invalid option is encountered
+or an invalid
+.I jobspec
+is supplied.
+.PP
+If the
+.B \-x
+option is supplied,
+.B jobs
+replaces any
+.I jobspec
+found in
+.I command
+or
+.I args
+with the corresponding process group ID, and executes
+.I command
+passing it
+.IR args ,
+returning its exit status.
+.RE
+.TP
+\fBkill\fP [\fB\-s\fP \fIsigspec\fP | \fB\-n\fP \fIsignum\fP | \fB\-\fP\fIsigspec\fP] [\fIpid\fP | \fIjobspec\fP] ...
+.PD 0
+.TP
+\fBkill\fP \fB\-l\fP [\fIsigspec\fP | \fIexit_status\fP]
+.PD
+Send the signal named by
+.I sigspec
+or
+.I signum
+to the processes named by
+.I pid
+or
+.IR jobspec .
+.I sigspec
+is either a case-insensitive signal name such as
+.SM
+.B SIGKILL
+(with or without the
+.SM
+.B SIG
+prefix) or a signal number;
+.I signum
+is a signal number.
+If
+.I sigspec
+is not present, then
+.SM
+.B SIGTERM
+is assumed.
+An argument of
+.B \-l
+lists the signal names.
+If any arguments are supplied when
+.B \-l
+is given, the names of the signals corresponding to the arguments are
+listed, and the return status is 0.
+The \fIexit_status\fP argument to
+.B \-l
+is a number specifying either a signal number or the exit status of
+a process terminated by a signal.
+.B kill
+returns true if at least one signal was successfully sent, or false
+if an error occurs or an invalid option is encountered.
+.TP
+\fBlet\fP \fIarg\fP [\fIarg\fP ...]
+Each
+.I arg
+is an arithmetic expression to be evaluated (see
+.SM
+.B "ARITHMETIC EVALUATION"
+above).
+If the last
+.I arg
+evaluates to 0,
+.B let
+returns 1; 0 is returned otherwise.
+.TP
+\fBlocal\fP [\fIoption\fP] [\fIname\fP[=\fIvalue\fP] ...]
+For each argument, a local variable named
+.I name
+is created, and assigned
+.IR value .
+The \fIoption\fP can be any of the options accepted by \fBdeclare\fP.
+When
+.B local
+is used within a function, it causes the variable
+.I name
+to have a visible scope restricted to that function and its children.
+With no operands,
+.B local
+writes a list of local variables to the standard output. It is
+an error to use
+.B local
+when not within a function. The return status is 0 unless
+.B local
+is used outside a function, an invalid
+.I name
+is supplied, or
+\fIname\fP is a readonly variable.
+.TP
+.B logout
+Exit a login shell.
+.TP
+\fBmapfile\fP [\fB\-n\fP \fIcount\fP] [\fB\-O\fP \fIorigin\fP] [\fB\-s\fP \fIcount\fP] [\fB\-t\fP] [\fB\-u\fP \fIfd\fP] [\fB\-C\fP \fIcallback\fP] [\fB\-c\fP \fIquantum\fP] [\fIarray\fP]
+.PD 0
+.TP
+\fBreadarray\fP [\fB\-n\fP \fIcount\fP] [\fB\-O\fP \fIorigin\fP] [\fB\-s\fP \fIcount\fP] [\fB\-t\fP] [\fB\-u\fP \fIfd\fP] [\fB\-C\fP \fIcallback\fP] [\fB\-c\fP \fIquantum\fP] [\fIarray\fP]
+.PD
+Read lines from the standard input into the indexed array variable
+.IR array ,
+or from file descriptor
+.IR fd
+if the
+.B \-u
+option is supplied.
+The variable
+.SM
+.B MAPFILE
+is the default \fIarray\fP.
+Options, if supplied, have the following meanings:
+.RS
+.PD 0
+.TP
+.B \-n
+Copy at most
+.I count
+lines. If \fIcount\fP is 0, all lines are copied.
+.TP
+.B \-O
+Begin assigning to
+.I array
+at index
+.IR origin .
+The default index is 0.
+.TP
+.B \-s
+Discard the first \fIcount\fP lines read.
+.TP
+.B \-t
+Remove a trailing newline from each line read.
+.TP
+.B \-u
+Read lines from file descriptor \fIfd\fP instead of the standard input.
+.TP
+.B \-C
+Evaluate
+.I callback
+each time \fIquantum\fP lines are read. The \fB\-c\fP option specifies
+.IR quantum .
+.TP
+.B \-c
+Specify the number of lines read between each call to
+.IR callback .
+.PD
+.PP
+If
+.B \-C
+is specified without
+.BR \-c ,
+the default quantum is 5000.
+When \fIcallback\fP is evaluated, it is supplied the index of the next
+array element to be assigned and the line to be assigned to that element
+as additional arguments.
+\fIcallback\fP is evaluated after the line is read but before the
+array element is assigned.
+.PP
+If not supplied with an explicit origin, \fBmapfile\fP will clear \fIarray\fP
+before assigning to it.
+.PP
+\fBmapfile\fP returns successfully unless an invalid option or option
+argument is supplied, \fIarray\fP is invalid or unassignable, or if
+\fIarray\fP is not an indexed array.
+.RE
+.TP
+\fBpopd\fP [\-\fBn\fP] [+\fIn\fP] [\-\fIn\fP]
+Removes entries from the directory stack. With no arguments,
+removes the top directory from the stack, and performs a
+.B cd
+to the new top directory.
+Arguments, if supplied, have the following meanings:
+.RS
+.PD 0
+.TP
+.B \-n
+Suppresses the normal change of directory when removing directories
+from the stack, so that only the stack is manipulated.
+.TP
+\fB+\fP\fIn\fP
+Removes the \fIn\fPth entry counting from the left of the list
+shown by
+.BR dirs ,
+starting with zero. For example:
+.if n ``popd +0''
+.if t \f(CWpopd +0\fP
+removes the first directory,
+.if n ``popd +1''
+.if t \f(CWpopd +1\fP
+the second.
+.TP
+\fB\-\fP\fIn\fP
+Removes the \fIn\fPth entry counting from the right of the list
+shown by
+.BR dirs ,
+starting with zero. For example:
+.if n ``popd -0''
+.if t \f(CWpopd -0\fP
+removes the last directory,
+.if n ``popd -1''
+.if t \f(CWpopd -1\fP
+the next to last.
+.PD
+.PP
+If the
+.B popd
+command is successful, a
+.B dirs
+is performed as well, and the return status is 0.
+.B popd
+returns false if an invalid option is encountered, the directory stack
+is empty, a non-existent directory stack entry is specified, or the
+directory change fails.
+.RE
+.TP
+\fBprintf\fP [\fB\-v\fP \fIvar\fP] \fIformat\fP [\fIarguments\fP]
+Write the formatted \fIarguments\fP to the standard output under the
+control of the \fIformat\fP.
+The \fB\-v\fP option causes the output to be assigned to the variable
+\fIvar\fP rather than being printed to the standard output.
+.sp 1
+The \fIformat\fP is a character string which contains three types of objects:
+plain characters, which are simply copied to standard output, character
+escape sequences, which are converted and copied to the standard output, and
+format specifications, each of which causes printing of the next successive
+\fIargument\fP.
+In addition to the standard \fIprintf\fP(1) format specifications,
+\fBprintf\fP interprets the following extensions:
+.RS
+.PD 0
+.TP
+.B %b
+causes
+\fBprintf\fP to expand backslash escape sequences in the corresponding
+\fIargument\fP (except that \fB\ec\fP terminates output, backslashes in
+\fB\e\(aq\fP, \fB\e"\fP, and \fB\e?\fP are not removed, and octal escapes
+beginning with \fB\e0\fP may contain up to four digits).
+.TP
+.B %q
+causes \fBprintf\fP to output the corresponding
+\fIargument\fP in a format that can be reused as shell input.
+.TP
+.B %(\fIdatefmt\fP)T
+causes \fBprintf\fP to output the date-time string resulting from using
+\fIdatefmt\fP as a format string for \fIstrftime\fP(3). The corresponding
+\fIargument\fP is an integer representing the number of seconds since the
+epoch. Two special argument values may be used: -1 represents the current
+time, and -2 represents the time the shell was invoked.
+.PD
+.PP
+Arguments to non-string format specifiers are treated as C constants,
+except that a leading plus or minus sign is allowed, and if the leading
+character is a single or double quote, the value is the ASCII value of
+the following character.
+.PP
+The \fIformat\fP is reused as necessary to consume all of the \fIarguments\fP.
+If the \fIformat\fP requires more \fIarguments\fP than are supplied, the
+extra format specifications behave as if a zero value or null string, as
+appropriate, had been supplied.
+The return value is zero on success, non-zero on failure.
+.RE
+.TP
+\fBpushd\fP [\fB\-n\fP] [+\fIn\fP] [\-\fIn\fP]
+.PD 0
+.TP
+\fBpushd\fP [\fB\-n\fP] [\fIdir\fP]
+.PD
+Adds a directory to the top of the directory stack, or rotates
+the stack, making the new top of the stack the current working
+directory. With no arguments, exchanges the top two directories
+and returns 0, unless the directory stack is empty.
+Arguments, if supplied, have the following meanings:
+.RS
+.PD 0
+.TP
+.B \-n
+Suppresses the normal change of directory when adding directories
+to the stack, so that only the stack is manipulated.
+.TP
+\fB+\fP\fIn\fP
+Rotates the stack so that the \fIn\fPth directory
+(counting from the left of the list shown by
+.BR dirs ,
+starting with zero)
+is at the top.
+.TP
+\fB\-\fP\fIn\fP
+Rotates the stack so that the \fIn\fPth directory
+(counting from the right of the list shown by
+.BR dirs ,
+starting with zero) is at the top.
+.TP
+.I dir
+Adds
+.I dir
+to the directory stack at the top, making it the
+new current working directory as if it had been supplied as the argument
+to the \fBcd\fP builtin.
+.PD
+.PP
+If the
+.B pushd
+command is successful, a
+.B dirs
+is performed as well.
+If the first form is used,
+.B pushd
+returns 0 unless the cd to
+.I dir
+fails. With the second form,
+.B pushd
+returns 0 unless the directory stack is empty,
+a non-existent directory stack element is specified,
+or the directory change to the specified new current directory
+fails.
+.RE
+.TP
+\fBpwd\fP [\fB\-LP\fP]
+Print the absolute pathname of the current working directory.
+The pathname printed contains no symbolic links if the
+.B \-P
+option is supplied or the
+.B \-o physical
+option to the
+.B set
+builtin command is enabled.
+If the
+.B \-L
+option is used, the pathname printed may contain symbolic links.
+The return status is 0 unless an error occurs while
+reading the name of the current directory or an
+invalid option is supplied.
+.TP
+\fBread\fP [\fB\-ers\fP] [\fB\-a\fP \fIaname\fP] [\fB\-d\fP \fIdelim\fP] [\fB\-i\fP \fItext\fP] [\fB\-n\fP \fInchars\fP] [\fB\-N\fP \fInchars\fP] [\fB\-p\fP \fIprompt\fP] [\fB\-t\fP \fItimeout\fP] [\fB\-u\fP \fIfd\fP] [\fIname\fP ...]
+One line is read from the standard input, or from the file descriptor
+\fIfd\fP supplied as an argument to the \fB\-u\fP option, and the first word
+is assigned to the first
+.IR name ,
+the second word to the second
+.IR name ,
+and so on, with leftover words and their intervening separators assigned
+to the last
+.IR name .
+If there are fewer words read from the input stream than names,
+the remaining names are assigned empty values.
+The characters in
+.SM
+.B IFS
+are used to split the line into words.
+The backslash character (\fB\e\fP) may be used to remove any special
+meaning for the next character read and for line continuation.
+Options, if supplied, have the following meanings:
+.RS
+.PD 0
+.TP
+.B \-a \fIaname\fP
+The words are assigned to sequential indices
+of the array variable
+.IR aname ,
+starting at 0.
+.I aname
+is unset before any new values are assigned.
+Other \fIname\fP arguments are ignored.
+.TP
+.B \-d \fIdelim\fP
+The first character of \fIdelim\fP is used to terminate the input line,
+rather than newline.
+.TP
+.B \-e
+If the standard input
+is coming from a terminal,
+.B readline
+(see
+.SM
+.B READLINE
+above) is used to obtain the line.
+Readline uses the current (or default, if line editing was not previously
+active) editing settings.
+.TP
+.B \-i \fItext\fP
+If
+.B readline
+is being used to read the line, \fItext\fP is placed into the editing
+buffer before editing begins.
+.TP
+.B \-n \fInchars\fP
+\fBread\fP returns after reading \fInchars\fP characters rather than
+waiting for a complete line of input, but honor a delimiter if fewer
+than \fInchars\fP characters are read before the delimiter.
+.TP
+.B \-N \fInchars\fP
+\fBread\fP returns after reading exactly \fInchars\fP characters rather
+than waiting for a complete line of input, unless EOF is encountered or
+\fBread\fP times out.
+Delimiter characters encountered in the input are
+not treated specially and do not cause \fBread\fP to return until
+\fInchars\fP characters are read.
+.TP
+.B \-p \fIprompt\fP
+Display \fIprompt\fP on standard error, without a
+trailing newline, before attempting to read any input. The prompt
+is displayed only if input is coming from a terminal.
+.TP
+.B \-r
+Backslash does not act as an escape character.
+The backslash is considered to be part of the line.
+In particular, a backslash-newline pair may not be used as a line
+continuation.
+.TP
+.B \-s
+Silent mode. If input is coming from a terminal, characters are
+not echoed.
+.TP
+.B \-t \fItimeout\fP
+Cause \fBread\fP to time out and return failure if a complete line of
+input is not read within \fItimeout\fP seconds.
+\fItimeout\fP may be a decimal number with a fractional portion following
+the decimal point.
+This option is only effective if \fBread\fP is reading input from a
+terminal, pipe, or other special file; it has no effect when reading
+from regular files.
+If \fItimeout\fP is 0, \fBread\fP returns success if input is available on
+the specified file descriptor, failure otherwise.
+The exit status is greater than 128 if the timeout is exceeded.
+.TP
+.B \-u \fIfd\fP
+Read input from file descriptor \fIfd\fP.
+.PD
+.PP
+If no
+.I names
+are supplied, the line read is assigned to the variable
+.SM
+.BR REPLY .
+The return code is zero, unless end-of-file is encountered, \fBread\fP
+times out (in which case the return code is greater than 128), or an
+invalid file descriptor is supplied as the argument to \fB\-u\fP.
+.RE
+.TP
+\fBreadonly\fP [\fB\-aAf\fP] [\fB\-p\fP] [\fIname\fP[=\fIword\fP] ...]
+.PD
+The given
+\fInames\fP are marked readonly; the values of these
+.I names
+may not be changed by subsequent assignment.
+If the
+.B \-f
+option is supplied, the functions corresponding to the
+\fInames\fP are so
+marked.
+The
+.B \-a
+option restricts the variables to indexed arrays; the
+.B \-A
+option restricts the variables to associative arrays.
+If both options are supplied,
+.B \-A
+takes precedence.
+If no
+.I name
+arguments are given, or if the
+.B \-p
+option is supplied, a list of all readonly names is printed.
+The other options may be used to restrict the output to a subset of
+the set of readonly names.
+The
+.B \-p
+option causes output to be displayed in a format that
+may be reused as input.
+If a variable name is followed by =\fIword\fP, the value of
+the variable is set to \fIword\fP.
+The return status is 0 unless an invalid option is encountered,
+one of the
+.I names
+is not a valid shell variable name, or
+.B \-f
+is supplied with a
+.I name
+that is not a function.
+.TP
+\fBreturn\fP [\fIn\fP]
+Causes a function to exit with the return value specified by
+.IR n .
+If
+.I n
+is omitted, the return status is that of the last command
+executed in the function body. If used outside a function,
+but during execution of a script by the
+.B .
+(\fBsource\fP) command, it causes the shell to stop executing
+that script and return either
+.I n
+or the exit status of the last command executed within the
+script as the exit status of the script. If used outside a
+function and not during execution of a script by \fB.\fP\^,
+the return status is false.
+Any command associated with the \fBRETURN\fP trap is executed
+before execution resumes after the function or script.
+.TP
+\fBset\fP [\fB\-\-abefhkmnptuvxBCEHPT\fP] [\fB\-o\fP \fIoption\-name\fP] [\fIarg\fP ...]
+.PD 0
+.TP
+\fBset\fP [\fB+abefhkmnptuvxBCEHPT\fP] [\fB+o\fP \fIoption\-name\fP] [\fIarg\fP ...]
+.PD
+Without options, the name and value of each shell variable are displayed
+in a format that can be reused as input
+for setting or resetting the currently-set variables.
+Read-only variables cannot be reset.
+In \fIposix mode\fP, only shell variables are listed.
+The output is sorted according to the current locale.
+When options are specified, they set or unset shell attributes.
+Any arguments remaining after option processing are treated
+as values for the positional parameters and are assigned, in order, to
+.BR $1 ,
+.BR $2 ,
+.B ...
+.BR $\fIn\fP .
+Options, if specified, have the following meanings:
+.RS
+.PD 0
+.TP 8
+.B \-a
+Automatically mark variables and functions which are modified or
+created for export to the environment of subsequent commands.
+.TP 8
+.B \-b
+Report the status of terminated background jobs
+immediately, rather than before the next primary prompt. This is
+effective only when job control is enabled.
+.TP 8
+.B \-e
+Exit immediately if a \fIpipeline\fP (which may consist of a single
+\fIsimple command\fP), a \fIsubshell\fP command enclosed in parentheses,
+or one of the commands executed as part of a command list enclosed
+by braces (see
+.SM
+.B SHELL GRAMMAR
+above) exits with a non-zero status.
+The shell does not exit if the
+command that fails is part of the command list immediately following a
+.B while
+or
+.B until
+keyword,
+part of the test following the
+.B if
+or
+.B elif
+reserved words, part of any command executed in a
+.B &&
+or
+.B ||
+list except the command following the final \fB&&\fP or \fB||\fP,
+any command in a pipeline but the last,
+or if the command's return value is
+being inverted with
+.BR ! .
+A trap on \fBERR\fP, if set, is executed before the shell exits.
+This option applies to the shell environment and each subshell environment
+separately (see
+.SM
+.B "COMMAND EXECUTION ENVIRONMENT"
+above), and may cause
+subshells to exit before executing all the commands in the subshell.
+.TP 8
+.B \-f
+Disable pathname expansion.
+.TP 8
+.B \-h
+Remember the location of commands as they are looked up for execution.
+This is enabled by default.
+.TP 8
+.B \-k
+All arguments in the form of assignment statements
+are placed in the environment for a command, not just
+those that precede the command name.
+.TP 8
+.B \-m
+Monitor mode. Job control is enabled. This option is on
+by default for interactive shells on systems that support
+it (see
+.SM
+.B JOB CONTROL
+above).
+All processes run in a separate process group.
+When a background job completes, the shell prints a line
+containing its exit status.
+.TP 8
+.B \-n
+Read commands but do not execute them. This may be used to
+check a shell script for syntax errors. This is ignored by
+interactive shells.
+.TP 8
+.B \-o \fIoption\-name\fP
+The \fIoption\-name\fP can be one of the following:
+.RS
+.TP 8
+.B allexport
+Same as
+.BR \-a .
+.TP 8
+.B braceexpand
+Same as
+.BR \-B .
+.TP 8
+.B emacs
+Use an emacs-style command line editing interface. This is enabled
+by default when the shell is interactive, unless the shell is started
+with the
+.B \-\-noediting
+option.
+This also affects the editing interface used for \fBread \-e\fP.
+.TP 8
+.B errexit
+Same as
+.BR \-e .
+.TP 8
+.B errtrace
+Same as
+.BR \-E .
+.TP 8
+.B functrace
+Same as
+.BR \-T .
+.TP 8
+.B hashall
+Same as
+.BR \-h .
+.TP 8
+.B histexpand
+Same as
+.BR \-H .
+.TP 8
+.B history
+Enable command history, as described above under
+.SM
+.BR HISTORY .
+This option is on by default in interactive shells.
+.TP 8
+.B ignoreeof
+The effect is as if the shell command
+.if t \f(CWIGNOREEOF=10\fP
+.if n ``IGNOREEOF=10''
+had been executed
+(see
+.B Shell Variables
+above).
+.TP 8
+.B keyword
+Same as
+.BR \-k .
+.TP 8
+.B monitor
+Same as
+.BR \-m .
+.TP 8
+.B noclobber
+Same as
+.BR \-C .
+.TP 8
+.B noexec
+Same as
+.BR \-n .
+.TP 8
+.B noglob
+Same as
+.BR \-f .
+.TP 8
+.B nolog
+Currently ignored.
+.TP 8
+.B notify
+Same as
+.BR \-b .
+.TP 8
+.B nounset
+Same as
+.BR \-u .
+.TP 8
+.B onecmd
+Same as
+.BR \-t .
+.TP 8
+.B physical
+Same as
+.BR \-P .
+.TP 8
+.B pipefail
+If set, the return value of a pipeline is the value of the last
+(rightmost) command to exit with a non-zero status, or zero if all
+commands in the pipeline exit successfully.
+This option is disabled by default.
+.TP 8
+.B posix
+Change the behavior of
+.B bash
+where the default operation differs
+from the POSIX standard to match the standard (\fIposix mode\fP).
+.TP 8
+.B privileged
+Same as
+.BR \-p .
+.TP 8
+.B verbose
+Same as
+.BR \-v .
+.TP 8
+.B vi
+Use a vi-style command line editing interface.
+This also affects the editing interface used for \fBread \-e\fP.
+.TP 8
+.B xtrace
+Same as
+.BR \-x .
+.sp .5
+.PP
+If
+.B \-o
+is supplied with no \fIoption\-name\fP, the values of the current options are
+printed.
+If
+.B +o
+is supplied with no \fIoption\-name\fP, a series of
+.B set
+commands to recreate the current option settings is displayed on
+the standard output.
+.RE
+.TP 8
+.B \-p
+Turn on
+.I privileged
+mode. In this mode, the
+.SM
+.B $ENV
+and
+.SM
+.B $BASH_ENV
+files are not processed, shell functions are not inherited from the
+environment, and the
+.SM
+.BR SHELLOPTS ,
+.SM
+.BR BASHOPTS ,
+.SM
+.BR CDPATH ,
+and
+.SM
+.B GLOBIGNORE
+variables, if they appear in the environment, are ignored.
+If the shell is started with the effective user (group) id not equal to the
+real user (group) id, and the \fB\-p\fP option is not supplied, these actions
+are taken and the effective user id is set to the real user id.
+If the \fB\-p\fP option is supplied at startup, the effective user id is
+not reset.
+Turning this option off causes the effective user
+and group ids to be set to the real user and group ids.
+.TP 8
+.B \-t
+Exit after reading and executing one command.
+.TP 8
+.B \-u
+Treat unset variables and parameters other than the special
+parameters "@" and "*" as an error when performing
+parameter expansion. If expansion is attempted on an
+unset variable or parameter, the shell prints an error message, and,
+if not interactive, exits with a non-zero status.
+.TP 8
+.B \-v
+Print shell input lines as they are read.
+.TP 8
+.B \-x
+After expanding each \fIsimple command\fP,
+\fBfor\fP command, \fBcase\fP command, \fBselect\fP command, or
+arithmetic \fBfor\fP command, display the expanded value of
+.SM
+.BR PS4 ,
+followed by the command and its expanded arguments
+or associated word list.
+.TP 8
+.B \-B
+The shell performs brace expansion (see
+.B Brace Expansion
+above). This is on by default.
+.TP 8
+.B \-C
+If set,
+.B bash
+does not overwrite an existing file with the
+.BR > ,
+.BR >& ,
+and
+.B <>
+redirection operators. This may be overridden when
+creating output files by using the redirection operator
+.B >|
+instead of
+.BR > .
+.TP 8
+.B \-E
+If set, any trap on \fBERR\fP is inherited by shell functions, command
+substitutions, and commands executed in a subshell environment.
+The \fBERR\fP trap is normally not inherited in such cases.
+.TP 8
+.B \-H
+Enable
+.B !
+style history substitution. This option is on by
+default when the shell is interactive.
+.TP 8
+.B \-P
+If set, the shell does not follow symbolic links when executing
+commands such as
+.B cd
+that change the current working directory. It uses the
+physical directory structure instead. By default,
+.B bash
+follows the logical chain of directories when performing commands
+which change the current directory.
+.TP 8
+.B \-T
+If set, any traps on \fBDEBUG\fP and \fBRETURN\fP are inherited by shell
+functions, command substitutions, and commands executed in a
+subshell environment.
+The \fBDEBUG\fP and \fBRETURN\fP traps are normally not inherited
+in such cases.
+.TP 8
+.B \-\-
+If no arguments follow this option, then the positional parameters are
+unset. Otherwise, the positional parameters are set to the
+\fIarg\fPs, even if some of them begin with a
+.BR \- .
+.TP 8
+.B \-
+Signal the end of options, cause all remaining \fIarg\fPs to be
+assigned to the positional parameters. The
+.B \-x
+and
+.B \-v
+options are turned off.
+If there are no \fIarg\fPs,
+the positional parameters remain unchanged.
+.PD
+.PP
+The options are off by default unless otherwise noted.
+Using + rather than \- causes these options to be turned off.
+The options can also be specified as arguments to an invocation of
+the shell.
+The current set of options may be found in
+.BR $\- .
+The return status is always true unless an invalid option is encountered.
+.RE
+.TP
+\fBshift\fP [\fIn\fP]
+The positional parameters from \fIn\fP+1 ... are renamed to
+.B $1
+.B ....
+Parameters represented by the numbers \fB$#\fP
+down to \fB$#\fP\-\fIn\fP+1 are unset.
+.I n
+must be a non-negative number less than or equal to \fB$#\fP.
+If
+.I n
+is 0, no parameters are changed.
+If
+.I n
+is not given, it is assumed to be 1.
+If
+.I n
+is greater than \fB$#\fP, the positional parameters are not changed.
+The return status is greater than zero if
+.I n
+is greater than
+.B $#
+or less than zero; otherwise 0.
+.TP
+\fBshopt\fP [\fB\-pqsu\fP] [\fB\-o\fP] [\fIoptname\fP ...]
+Toggle the values of variables controlling optional shell behavior.
+With no options, or with the
+.B \-p
+option, a list of all settable options is displayed, with
+an indication of whether or not each is set.
+The \fB\-p\fP option causes output to be displayed in a form that
+may be reused as input.
+Other options have the following meanings:
+.RS
+.PD 0
+.TP
+.B \-s
+Enable (set) each \fIoptname\fP.
+.TP
+.B \-u
+Disable (unset) each \fIoptname\fP.
+.TP
+.B \-q
+Suppresses normal output (quiet mode); the return status indicates
+whether the \fIoptname\fP is set or unset.
+If multiple \fIoptname\fP arguments are given with
+.BR \-q ,
+the return status is zero if all \fIoptnames\fP are enabled; non-zero
+otherwise.
+.TP
+.B \-o
+Restricts the values of \fIoptname\fP to be those defined for the
+.B \-o
+option to the
+.B set
+builtin.
+.PD
+.PP
+If either
+.B \-s
+or
+.B \-u
+is used with no \fIoptname\fP arguments, the display is limited to
+those options which are set or unset, respectively.
+Unless otherwise noted, the \fBshopt\fP options are disabled (unset)
+by default.
+.PP
+The return status when listing options is zero if all \fIoptnames\fP
+are enabled, non-zero otherwise. When setting or unsetting options,
+the return status is zero unless an \fIoptname\fP is not a valid shell
+option.
+.PP
+The list of \fBshopt\fP options is:
+.if t .sp .5v
+.if n .sp 1v
+.PD 0
+.TP 8
+.B autocd
+If set, a command name that is the name of a directory is executed as if
+it were the argument to the \fBcd\fP command.
+This option is only used by interactive shells.
+.TP 8
+.B cdable_vars
+If set, an argument to the
+.B cd
+builtin command that
+is not a directory is assumed to be the name of a variable whose
+value is the directory to change to.
+.TP 8
+.B cdspell
+If set, minor errors in the spelling of a directory component in a
+.B cd
+command will be corrected.
+The errors checked for are transposed characters,
+a missing character, and one character too many.
+If a correction is found, the corrected file name is printed,
+and the command proceeds.
+This option is only used by interactive shells.
+.TP 8
+.B checkhash
+If set, \fBbash\fP checks that a command found in the hash
+table exists before trying to execute it. If a hashed command no
+longer exists, a normal path search is performed.
+.TP 8
+.B checkjobs
+If set, \fBbash\fP lists the status of any stopped and running jobs before
+exiting an interactive shell. If any jobs are running, this causes
+the exit to be deferred until a second exit is attempted without an
+intervening command (see
+.SM
+.B "JOB CONTROL"
+above). The shell always
+postpones exiting if any jobs are stopped.
+.TP 8
+.B checkwinsize
+If set, \fBbash\fP checks the window size after each command
+and, if necessary, updates the values of
+.SM
+.B LINES
+and
+.SM
+.BR COLUMNS .
+.TP 8
+.B cmdhist
+If set,
+.B bash
+attempts to save all lines of a multiple-line
+command in the same history entry. This allows
+easy re-editing of multi-line commands.
+.TP 8
+.B compat31
+If set,
+.B bash
+changes its behavior to that of version 3.1 with respect to quoted
+arguments to the \fB[[\fP conditional command's \fB=~\fP operator.
+.TP 8
+.B compat32
+If set,
+.B bash
+changes its behavior to that of version 3.2 with respect to locale-specific
+string comparison when using the \fB[[\fP
+conditional command's \fB<\fP and \fB>\fP operators.
+Bash versions prior to bash-4.1 use ASCII collation and
+.IR strcmp (3);
+bash-4.1 and later
+use the current locale's collation sequence and
+.IR strcoll (3).
+.TP 8
+.B compat40
+If set,
+.B bash
+changes its behavior to that of version 4.0 with respect to locale-specific
+string comparison when using the \fB[[\fP
+conditional command's \fB<\fP and \fB>\fP operators (see previous item)
+and the effect of interrupting a command list.
+.TP 8
+.B compat41
+If set,
+.BR bash ,
+when in posix mode, treats a single quote in a double-quoted
+parameter expansion as a special character. The single quotes must match
+(an even number) and the characters between the single quotes are considered
+quoted. This is the behavior of posix mode through version 4.1.
+The default bash behavior remains as in previous versions.
+.TP 8
+.B direxpand
+If set,
+.B bash
+replaces directory names with the results of word expansion when performing
+filename completion. This changes the contents of the readline editing
+buffer.
+If not set,
+.B bash
+attempts to preserve what the user typed.
+.TP 8
+.B dirspell
+If set,
+.B bash
+attempts spelling correction on directory names during word completion
+if the directory name initially supplied does not exist.
+.TP 8
+.B dotglob
+If set,
+.B bash
+includes filenames beginning with a `.' in the results of pathname
+expansion.
+.TP 8
+.B execfail
+If set, a non-interactive shell will not exit if
+it cannot execute the file specified as an argument to the
+.B exec
+builtin command. An interactive shell does not exit if
+.B exec
+fails.
+.TP 8
+.B expand_aliases
+If set, aliases are expanded as described above under
+.SM
+.BR ALIASES .
+This option is enabled by default for interactive shells.
+.TP 8
+.B extdebug
+If set, behavior intended for use by debuggers is enabled:
+.RS
+.TP
+.B 1.
+The \fB\-F\fP option to the \fBdeclare\fP builtin displays the source
+file name and line number corresponding to each function name supplied
+as an argument.
+.TP
+.B 2.
+If the command run by the \fBDEBUG\fP trap returns a non-zero value, the
+next command is skipped and not executed.
+.TP
+.B 3.
+If the command run by the \fBDEBUG\fP trap returns a value of 2, and the
+shell is executing in a subroutine (a shell function or a shell script
+executed by the \fB.\fP or \fBsource\fP builtins), a call to
+\fBreturn\fP is simulated.
+.TP
+.B 4.
+.SM
+.B BASH_ARGC
+and
+.SM
+.B BASH_ARGV
+are updated as described in their descriptions above.
+.TP
+.B 5.
+Function tracing is enabled: command substitution, shell functions, and
+subshells invoked with \fB(\fP \fIcommand\fP \fB)\fP inherit the
+\fBDEBUG\fP and \fBRETURN\fP traps.
+.TP
+.B 6.
+Error tracing is enabled: command substitution, shell functions, and
+subshells invoked with \fB(\fP \fIcommand\fP \fB)\fP inherit the
+\fBERR\fP trap.
+.RE
+.TP 8
+.B extglob
+If set, the extended pattern matching features described above under
+\fBPathname Expansion\fP are enabled.
+.TP 8
+.B extquote
+If set, \fB$\fP\(aq\fIstring\fP\(aq and \fB$\fP"\fIstring\fP" quoting is
+performed within \fB${\fP\fIparameter\fP\fB}\fP expansions
+enclosed in double quotes. This option is enabled by default.
+.TP 8
+.B failglob
+If set, patterns which fail to match filenames during pathname expansion
+result in an expansion error.
+.TP 8
+.B force_fignore
+If set, the suffixes specified by the
+.SM
+.B FIGNORE
+shell variable
+cause words to be ignored when performing word completion even if
+the ignored words are the only possible completions.
+See
+.SM
+\fBSHELL VARIABLES\fP
+above for a description of
+.SM
+.BR FIGNORE .
+This option is enabled by default.
+.TP 8
+.B globasciiranges
+If set, range expressions used in pattern matching (see
+.SM
+.B Pattern Matching
+above) behave as if in the traditional C locale when performing
+comparisons. That is, the current locale's collating sequence
+is not taken into account, so
+.B b
+will not collate between
+.B A
+and
+.BR B ,
+and upper-case and lower-case ASCII characters will collate together.
+.TP 8
+.B globstar
+If set, the pattern \fB**\fP used in a pathname expansion context will
+match all files and zero or more directories and subdirectories.
+If the pattern is followed by a \fB/\fP, only directories and
+subdirectories match.
+.TP 8
+.B gnu_errfmt
+If set, shell error messages are written in the standard GNU error
+message format.
+.TP 8
+.B histappend
+If set, the history list is appended to the file named by the value
+of the
+.SM
+.B HISTFILE
+variable when the shell exits, rather than overwriting the file.
+.TP 8
+.B histreedit
+If set, and
+.B readline
+is being used, a user is given the opportunity to re-edit a
+failed history substitution.
+.TP 8
+.B histverify
+If set, and
+.B readline
+is being used, the results of history substitution are not immediately
+passed to the shell parser. Instead, the resulting line is loaded into
+the \fBreadline\fP editing buffer, allowing further modification.
+.TP 8
+.B hostcomplete
+If set, and
+.B readline
+is being used, \fBbash\fP will attempt to perform hostname completion when a
+word containing a \fB@\fP is being completed (see
+.B Completing
+under
+.SM
+.B READLINE
+above).
+This is enabled by default.
+.TP 8
+.B huponexit
+If set, \fBbash\fP will send
+.SM
+.B SIGHUP
+to all jobs when an interactive login shell exits.
+.TP 8
+.B interactive_comments
+If set, allow a word beginning with
+.B #
+to cause that word and all remaining characters on that
+line to be ignored in an interactive shell (see
+.SM
+.B COMMENTS
+above). This option is enabled by default.
+.TP 8
+.B lastpipe
+If set, and job control is not active, the shell runs the last command of
+a pipeline not executed in the background in the current shell environment.
+.TP 8
+.B lithist
+If set, and the
+.B cmdhist
+option is enabled, multi-line commands are saved to the history with
+embedded newlines rather than using semicolon separators where possible.
+.TP 8
+.B login_shell
+The shell sets this option if it is started as a login shell (see
+.SM
+.B "INVOCATION"
+above).
+The value may not be changed.
+.TP 8
+.B mailwarn
+If set, and a file that \fBbash\fP is checking for mail has been
+accessed since the last time it was checked, the message ``The mail in
+\fImailfile\fP has been read'' is displayed.
+.TP 8
+.B no_empty_cmd_completion
+If set, and
+.B readline
+is being used,
+.B bash
+will not attempt to search the
+.SM
+.B PATH
+for possible completions when
+completion is attempted on an empty line.
+.TP 8
+.B nocaseglob
+If set,
+.B bash
+matches filenames in a case\-insensitive fashion when performing pathname
+expansion (see
+.B Pathname Expansion
+above).
+.TP 8
+.B nocasematch
+If set,
+.B bash
+matches patterns in a case\-insensitive fashion when performing matching
+while executing \fBcase\fP or \fB[[\fP conditional commands.
+.TP 8
+.B nullglob
+If set,
+.B bash
+allows patterns which match no
+files (see
+.B Pathname Expansion
+above)
+to expand to a null string, rather than themselves.
+.TP 8
+.B progcomp
+If set, the programmable completion facilities (see
+\fBProgrammable Completion\fP above) are enabled.
+This option is enabled by default.
+.TP 8
+.B promptvars
+If set, prompt strings undergo
+parameter expansion, command substitution, arithmetic
+expansion, and quote removal after being expanded as described in
+.SM
+.B PROMPTING
+above. This option is enabled by default.
+.TP 8
+.B restricted_shell
+The shell sets this option if it is started in restricted mode (see
+.SM
+.B "RESTRICTED SHELL"
+below).
+The value may not be changed.
+This is not reset when the startup files are executed, allowing
+the startup files to discover whether or not a shell is restricted.
+.TP 8
+.B shift_verbose
+If set, the
+.B shift
+builtin prints an error message when the shift count exceeds the
+number of positional parameters.
+.TP 8
+.B sourcepath
+If set, the
+\fBsource\fP (\fB.\fP) builtin uses the value of
+.SM
+.B PATH
+to find the directory containing the file supplied as an argument.
+This option is enabled by default.
+.TP 8
+.B xpg_echo
+If set, the \fBecho\fP builtin expands backslash-escape sequences
+by default.
+.RE
+.PD
+.TP
+\fBsuspend\fP [\fB\-f\fP]
+Suspend the execution of this shell until it receives a
+.SM
+.B SIGCONT
+signal. A login shell cannot be suspended; the
+.B \-f
+option can be used to override this and force the suspension.
+The return status is 0 unless the shell is a login shell and
+.B \-f
+is not supplied, or if job control is not enabled.
+.TP
+\fBtest\fP \fIexpr\fP
+.PD 0
+.TP
+\fB[\fP \fIexpr\fP \fB]\fP
+Return a status of 0 or 1 depending on
+the evaluation of the conditional expression
+.IR expr .
+Each operator and operand must be a separate argument.
+Expressions are composed of the primaries described above under
+.SM
+.BR "CONDITIONAL EXPRESSIONS" .
+\fBtest\fP does not accept any options, nor does it accept and ignore
+an argument of \fB\-\-\fP as signifying the end of options.
+.if t .sp 0.5
+.if n .sp 1
+Expressions may be combined using the following operators, listed
+in decreasing order of precedence.
+The evaluation depends on the number of arguments; see below.
+Operator precedence is used when there are five or more arguments.
+.RS
+.PD 0
+.TP
+.B ! \fIexpr\fP
+True if
+.I expr
+is false.
+.TP
+.B ( \fIexpr\fP )
+Returns the value of \fIexpr\fP.
+This may be used to override the normal precedence of operators.
+.TP
+\fIexpr1\fP \-\fBa\fP \fIexpr2\fP
+True if both
+.I expr1
+and
+.I expr2
+are true.
+.TP
+\fIexpr1\fP \-\fBo\fP \fIexpr2\fP
+True if either
+.I expr1
+or
+.I expr2
+is true.
+.PD
+.PP
+\fBtest\fP and \fB[\fP evaluate conditional
+expressions using a set of rules based on the number of arguments.
+.if t .sp 0.5
+.if n .sp 1
+.PD 0
+.TP
+0 arguments
+The expression is false.
+.TP
+1 argument
+The expression is true if and only if the argument is not null.
+.TP
+2 arguments
+If the first argument is \fB!\fP, the expression is true if and
+only if the second argument is null.
+If the first argument is one of the unary conditional operators listed above
+under
+.SM
+.BR "CONDITIONAL EXPRESSIONS" ,
+the expression is true if the unary test is true.
+If the first argument is not a valid unary conditional operator, the expression
+is false.
+.TP
+3 arguments
+The following conditions are applied in the order listed.
+If the second argument is one of the binary conditional operators listed above
+under
+.SM
+.BR "CONDITIONAL EXPRESSIONS" ,
+the result of the expression is the result of the binary test using
+the first and third arguments as operands.
+The \fB\-a\fP and \fB\-o\fP operators are considered binary operators
+when there are three arguments.
+If the first argument is \fB!\fP, the value is the negation of
+the two-argument test using the second and third arguments.
+If the first argument is exactly \fB(\fP and the third argument is
+exactly \fB)\fP, the result is the one-argument test of the second
+argument.
+Otherwise, the expression is false.
+.TP
+4 arguments
+If the first argument is \fB!\fP, the result is the negation of
+the three-argument expression composed of the remaining arguments.
+Otherwise, the expression is parsed and evaluated according to
+precedence using the rules listed above.
+.TP
+5 or more arguments
+The expression is parsed and evaluated according to precedence
+using the rules listed above.
+.if t .sp 0.5
+.if n .sp 1
+.LP
+When used with \fBtest\fP or \fB[\fP, the \fB<\fP and \fB>\fP operators
+sort lexicographically using ASCII ordering.
+.RE
+.PD
+.TP
+.B times
+Print the accumulated user and system times for the shell and
+for processes run from the shell. The return status is 0.
+.TP
+\fBtrap\fP [\fB\-lp\fP] [[\fIarg\fP] \fIsigspec\fP ...]
+The command
+.I arg
+is to be read and executed when the shell receives
+signal(s)
+.IR sigspec .
+If
+.I arg
+is absent (and there is a single \fIsigspec\fP) or
+.BR \- ,
+each specified signal is
+reset to its original disposition (the value it had
+upon entrance to the shell).
+If
+.I arg
+is the null string the signal specified by each
+.I sigspec
+is ignored by the shell and by the commands it invokes.
+If
+.I arg
+is not present and
+.B \-p
+has been supplied, then the trap commands associated with each
+.I sigspec
+are displayed.
+If no arguments are supplied or if only
+.B \-p
+is given,
+.B trap
+prints the list of commands associated with each signal.
+The
+.B \-l
+option causes the shell to print a list of signal names and
+their corresponding numbers.
+Each
+.I sigspec
+is either
+a signal name defined in <\fIsignal.h\fP>, or a signal number.
+Signal names are case insensitive and the
+.SM
+.B SIG
+prefix is optional.
+.if t .sp 0.5
+.if n .sp 1
+If a
+.I sigspec
+is
+.SM
+.B EXIT
+(0) the command
+.I arg
+is executed on exit from the shell.
+If a
+.I sigspec
+is
+.SM
+.BR DEBUG ,
+the command
+.I arg
+is executed before every \fIsimple command\fP, \fIfor\fP command,
+\fIcase\fP command, \fIselect\fP command, every arithmetic \fIfor\fP
+command, and before the first command executes in a shell function (see
+.SM
+.B SHELL GRAMMAR
+above).
+Refer to the description of the \fBextdebug\fP option to the
+\fBshopt\fP builtin for details of its effect on the \fBDEBUG\fP trap.
+If a
+.I sigspec
+is
+.SM
+.BR RETURN ,
+the command
+.I arg
+is executed each time a shell function or a script executed with
+the \fB.\fP or \fBsource\fP builtins finishes executing.
+.if t .sp 0.5
+.if n .sp 1
+If a
+.I sigspec
+is
+.SM
+.BR ERR ,
+the command
+.I arg
+is executed whenever a simple command has a non\-zero exit status,
+subject to the following conditions.
+The
+.SM
+.B ERR
+trap is not executed if the failed
+command is part of the command list immediately following a
+.B while
+or
+.B until
+keyword,
+part of the test in an
+.I if
+statement, part of a command executed in a
+.B &&
+or
+.B ||
+list, or if the command's return value is
+being inverted via
+.BR ! .
+These are the same conditions obeyed by the \fBerrexit\fP option.
+.if t .sp 0.5
+.if n .sp 1
+Signals ignored upon entry to the shell cannot be trapped or reset.
+Trapped signals that are not being ignored are reset to their original
+values in a subshell or subshell environment when one is created.
+The return status is false if any
+.I sigspec
+is invalid; otherwise
+.B trap
+returns true.
+.TP
+\fBtype\fP [\fB\-aftpP\fP] \fIname\fP [\fIname\fP ...]
+With no options,
+indicate how each
+.I name
+would be interpreted if used as a command name.
+If the
+.B \-t
+option is used,
+.B type
+prints a string which is one of
+.IR alias ,
+.IR keyword ,
+.IR function ,
+.IR builtin ,
+or
+.I file
+if
+.I name
+is an alias, shell reserved word, function, builtin, or disk file,
+respectively.
+If the
+.I name
+is not found, then nothing is printed, and an exit status of false
+is returned.
+If the
+.B \-p
+option is used,
+.B type
+either returns the name of the disk file
+that would be executed if
+.I name
+were specified as a command name,
+or nothing if
+.if t \f(CWtype -t name\fP
+.if n ``type -t name''
+would not return
+.IR file .
+The
+.B \-P
+option forces a
+.SM
+.B PATH
+search for each \fIname\fP, even if
+.if t \f(CWtype -t name\fP
+.if n ``type -t name''
+would not return
+.IR file .
+If a command is hashed,
+.B \-p
+and
+.B \-P
+print the hashed value, not necessarily the file that appears
+first in
+.SM
+.BR PATH .
+If the
+.B \-a
+option is used,
+.B type
+prints all of the places that contain
+an executable named
+.IR name .
+This includes aliases and functions,
+if and only if the
+.B \-p
+option is not also used.
+The table of hashed commands is not consulted
+when using
+.BR \-a .
+The
+.B \-f
+option suppresses shell function lookup, as with the \fBcommand\fP builtin.
+.B type
+returns true if all of the arguments are found, false if
+any are not found.
+.TP
+\fBulimit\fP [\fB\-HSTabcdefilmnpqrstuvx\fP [\fIlimit\fP]]
+Provides control over the resources available to the shell and to
+processes started by it, on systems that allow such control.
+The \fB\-H\fP and \fB\-S\fP options specify that the hard or soft limit is
+set for the given resource.
+A hard limit cannot be increased by a non-root user once it is set;
+a soft limit may be increased up to the value of the hard limit.
+If neither \fB\-H\fP nor \fB\-S\fP is specified, both the soft and hard
+limits are set.
+The value of
+.I limit
+can be a number in the unit specified for the resource
+or one of the special values
+.BR hard ,
+.BR soft ,
+or
+.BR unlimited ,
+which stand for the current hard limit, the current soft limit, and
+no limit, respectively.
+If
+.I limit
+is omitted, the current value of the soft limit of the resource is
+printed, unless the \fB\-H\fP option is given. When more than one
+resource is specified, the limit name and unit are printed before the value.
+Other options are interpreted as follows:
+.RS
+.PD 0
+.TP
+.B \-a
+All current limits are reported
+.TP
+.B \-b
+The maximum socket buffer size
+.TP
+.B \-c
+The maximum size of core files created
+.TP
+.B \-d
+The maximum size of a process's data segment
+.TP
+.B \-e
+The maximum scheduling priority ("nice")
+.TP
+.B \-f
+The maximum size of files written by the shell and its children
+.TP
+.B \-i
+The maximum number of pending signals
+.TP
+.B \-l
+The maximum size that may be locked into memory
+.TP
+.B \-m
+The maximum resident set size (many systems do not honor this limit)
+.TP
+.B \-n
+The maximum number of open file descriptors (most systems do not
+allow this value to be set)
+.TP
+.B \-p
+The pipe size in 512-byte blocks (this may not be set)
+.TP
+.B \-q
+The maximum number of bytes in POSIX message queues
+.TP
+.B \-r
+The maximum real-time scheduling priority
+.TP
+.B \-s
+The maximum stack size
+.TP
+.B \-t
+The maximum amount of cpu time in seconds
+.TP
+.B \-u
+The maximum number of processes available to a single user
+.TP
+.B \-v
+The maximum amount of virtual memory available to the shell and, on
+some systems, to its children
+.TP
+.B \-x
+The maximum number of file locks
+.TP
+.B \-T
+The maximum number of threads
+.PD
+.PP
+If
+.I limit
+is given, it is the new value of the specified resource (the
+.B \-a
+option is display only).
+If no option is given, then
+.B \-f
+is assumed. Values are in 1024-byte increments, except for
+.BR \-t ,
+which is in seconds,
+.BR \-p ,
+which is in units of 512-byte blocks,
+and
+.BR \-T ,
+.BR \-b ,
+.BR \-n ,
+and
+.BR \-u ,
+which are unscaled values.
+The return status is 0 unless an invalid option or argument is supplied,
+or an error occurs while setting a new limit.
+.RE
+.TP
+\fBumask\fP [\fB\-p\fP] [\fB\-S\fP] [\fImode\fP]
+The user file-creation mask is set to
+.IR mode .
+If
+.I mode
+begins with a digit, it
+is interpreted as an octal number; otherwise
+it is interpreted as a symbolic mode mask similar
+to that accepted by
+.IR chmod (1).
+If
+.I mode
+is omitted, the current value of the mask is printed.
+The
+.B \-S
+option causes the mask to be printed in symbolic form; the
+default output is an octal number.
+If the
+.B \-p
+option is supplied, and
+.I mode
+is omitted, the output is in a form that may be reused as input.
+The return status is 0 if the mode was successfully changed or if
+no \fImode\fP argument was supplied, and false otherwise.
+.TP
+\fBunalias\fP [\-\fBa\fP] [\fIname\fP ...]
+Remove each \fIname\fP from the list of defined aliases. If
+.B \-a
+is supplied, all alias definitions are removed. The return
+value is true unless a supplied
+.I name
+is not a defined alias.
+.TP
+\fBunset\fP [\-\fBfv\fP] [\fIname\fP ...]
+For each
+.IR name ,
+remove the corresponding variable or function.
+If the
+.B \-v
+option is given, each
+.I name
+refers to a shell variable, and that variable is removed.
+Read-only variables may not be unset.
+If
+.B \-f
+is specified, each
+.I name
+refers to a shell function, and the function definition
+is removed.
+If no options are supplied, each \fIname\fP refers to a variable; if
+there is no variable by that name, any function with that name is
+unset.
+Each unset variable or function is removed from the environment
+passed to subsequent commands.
+If any of
+.SM
+.BR COMP_WORDBREAKS ,
+.SM
+.BR RANDOM ,
+.SM
+.BR SECONDS ,
+.SM
+.BR LINENO ,
+.SM
+.BR HISTCMD ,
+.SM
+.BR FUNCNAME ,
+.SM
+.BR GROUPS ,
+or
+.SM
+.B DIRSTACK
+are unset, they lose their special properties, even if they are
+subsequently reset. The exit status is true unless a
+.I name
+is readonly.
+.TP
+\fBwait\fP [\fIn ...\fP]
+Wait for each specified process and return its termination status.
+Each
+.I n
+may be a process
+ID or a job specification; if a job spec is given, all processes
+in that job's pipeline are waited for. If
+.I n
+is not given, all currently active child processes
+are waited for, and the return status is zero. If
+.I n
+specifies a non-existent process or job, the return status is
+127. Otherwise, the return status is the exit status of the last
+process or job waited for.
+.\" bash_builtins
+.if \n(zZ=1 .ig zZ
+.SH "RESTRICTED SHELL"
+.\" rbash.1
+.zY
+.PP
+If
+.B bash
+is started with the name
+.BR rbash ,
+or the
+.B \-r
+option is supplied at invocation,
+the shell becomes restricted.
+A restricted shell is used to
+set up an environment more controlled than the standard shell.
+It behaves identically to
+.B bash
+with the exception that the following are disallowed or not performed:
+.IP \(bu
+changing directories with \fBcd\fP
+.IP \(bu
+setting or unsetting the values of
+.SM
+.BR SHELL ,
+.SM
+.BR PATH ,
+.SM
+.BR ENV ,
+or
+.SM
+.B BASH_ENV
+.IP \(bu
+specifying command names containing
+.B /
+.IP \(bu
+specifying a file name containing a
+.B /
+as an argument to the
+.B .
+builtin command
+.IP \(bu
+specifying a filename containing a slash as an argument to the
+.B \-p
+option to the
+.B hash
+builtin command
+.IP \(bu
+importing function definitions from the shell environment at startup
+.IP \(bu
+parsing the value of
+.SM
+.B SHELLOPTS
+from the shell environment at startup
+.IP \(bu
+redirecting output using the >, >|, <>, >&, &>, and >> redirection operators
+.IP \(bu
+using the
+.B exec
+builtin command to replace the shell with another command
+.IP \(bu
+adding or deleting builtin commands with the
+.B \-f
+and
+.B \-d
+options to the
+.B enable
+builtin command
+.IP \(bu
+using the \fBenable\fP builtin command to enable disabled shell builtins
+.IP \(bu
+specifying the
+.B \-p
+option to the
+.B command
+builtin command
+.IP \(bu
+turning off restricted mode with
+\fBset +r\fP or \fBset +o restricted\fP.
+.PP
+These restrictions are enforced after any startup files are read.
+.PP
+.ie \n(zY=1 When a command that is found to be a shell script is executed,
+.el \{ When a command that is found to be a shell script is executed
+(see
+.SM
+.B "COMMAND EXECUTION"
+above),
+\}
+.B rbash
+turns off any restrictions in the shell spawned to execute the
+script.
+.\" end of rbash.1
+.if \n(zY=1 .ig zY
+.SH "SEE ALSO"
+.PD 0
+.TP
+\fIBash Reference Manual\fP, Brian Fox and Chet Ramey
+.TP
+\fIThe Gnu Readline Library\fP, Brian Fox and Chet Ramey
+.TP
+\fIThe Gnu History Library\fP, Brian Fox and Chet Ramey
+.TP
+\fIPortable Operating System Interface (POSIX) Part 2: Shell and Utilities\fP, IEEE
+.TP
+\fIsh\fP(1), \fIksh\fP(1), \fIcsh\fP(1)
+.TP
+\fIemacs\fP(1), \fIvi\fP(1)
+.TP
+\fIreadline\fP(3)
+.PD
+.SH FILES
+.PD 0
+.TP
+.FN /bin/bash
+The \fBbash\fP executable
+.TP
+.FN /etc/profile
+The systemwide initialization file, executed for login shells
+.TP
+.FN ~/.bash_profile
+The personal initialization file, executed for login shells
+.TP
+.FN ~/.bashrc
+The individual per-interactive-shell startup file
+.TP
+.FN ~/.bash_logout
+The individual login shell cleanup file, executed when a login shell exits
+.TP
+.FN ~/.inputrc
+Individual \fIreadline\fP initialization file
+.PD
+.SH AUTHORS
+Brian Fox, Free Software Foundation
+.br
+bfox@gnu.org
+.PP
+Chet Ramey, Case Western Reserve University
+.br
+chet.ramey@case.edu
+.SH BUG REPORTS
+If you find a bug in
+.B bash,
+you should report it. But first, you should
+make sure that it really is a bug, and that it appears in the latest
+version of
+.BR bash .
+The latest version is always available from
+\fIftp://ftp.gnu.org/pub/gnu/bash/\fP.
+.PP
+Once you have determined that a bug actually exists, use the
+.I bashbug
+command to submit a bug report.
+If you have a fix, you are encouraged to mail that as well!
+Suggestions and `philosophical' bug reports may be mailed
+to \fIbug-bash@gnu.org\fP or posted to the Usenet
+newsgroup
+.BR gnu.bash.bug .
+.PP
+ALL bug reports should include:
+.PP
+.PD 0
+.TP 20
+The version number of \fBbash\fR
+.TP
+The hardware and operating system
+.TP
+The compiler used to compile
+.TP
+A description of the bug behaviour
+.TP
+A short script or `recipe' which exercises the bug
+.PD
+.PP
+.I bashbug
+inserts the first three items automatically into the template
+it provides for filing a bug report.
+.PP
+Comments and bug reports concerning
+this manual page should be directed to
+.IR chet.ramey@case.edu .
+.SH BUGS
+.PP
+It's too big and too slow.
+.PP
+There are some subtle differences between
+.B bash
+and traditional versions of
+.BR sh ,
+mostly because of the
+.SM
+.B POSIX
+specification.
+.PP
+Aliases are confusing in some uses.
+.PP
+Shell builtin commands and functions are not stoppable/restartable.
+.PP
+Compound commands and command sequences of the form `a ; b ; c'
+are not handled gracefully when process suspension is attempted.
+When a process is stopped, the shell immediately executes the next
+command in the sequence.
+It suffices to place the sequence of commands between
+parentheses to force it into a subshell, which may be stopped as
+a unit.
+.PP
+Array variables may not (yet) be exported.
+.PP
+There may be only one active coprocess at a time.
+.zZ
+.zY
@code{alias},
@code{declare}, @code{typeset}, @code{export}, @code{readonly},
and @code{local} builtin commands.
+When in @sc{posix} mode (@pxref{Bash POSIX Mode}), these builtins may appear
+in a command after one or more instances of the @code{command} builtin
+and retain these assignment statement properties.
In the context where an assignment statement is assigning a value
to a shell variable or array index (@pxref{Arrays}), the @samp{+=}
and the current working directory cannot be successfully determined
after a successful directory change, @code{cd} will return an unsuccessful
status.
-If @var{directory} is @samp{-}, it is equivalent to @env{$OLDPWD}.
+If @var{directory} is @samp{-}, it is converted to @env{$OLDPWD}
+before the directory change is attempted.
If a non-empty directory name from @env{CDPATH} is used, or if
@samp{-} is the first argument, and the directory change is
Tilde expansion is only performed on assignments preceding a command
name, rather than on all assignment statements on the line.
+@item
+The @code{command} builtin does not prevent builtins that take assignment
+statements as arguments from expanding them as assignment statements;
+when not in POSIX mode, assignment builtins lose their assignment
+statement expansion properties when preceded by @code{command}.
+
@item
The default history file is @file{~/.sh_history} (this is the
default value of @env{$HISTFILE}).
--- /dev/null
+\input texinfo.tex @c -*- texinfo -*-
+@c %**start of header
+@setfilename bashref.info
+@settitle Bash Reference Manual
+@c %**end of header
+
+@setchapternewpage odd
+
+@include version.texi
+
+@copying
+This text is a brief description of the features that are present in
+the Bash shell (version @value{VERSION}, @value{UPDATED}).
+
+This is Edition @value{EDITION}, last updated @value{UPDATED},
+of @cite{The GNU Bash Reference Manual},
+for @code{Bash}, Version @value{VERSION}.
+
+Copyright @copyright{} 1988--2011 Free Software Foundation, Inc.
+
+Permission is granted to make and distribute verbatim copies of
+this manual provided the copyright notice and this permission notice
+are preserved on all copies.
+
+@quotation
+Permission is granted to copy, distribute and/or modify this document
+under the terms of the GNU Free Documentation License, Version 1.3 or
+any later version published by the Free Software Foundation; with no
+Invariant Sections, with the Front-Cover texts being ``A GNU Manual'',
+and with the Back-Cover Texts as in (a) below. A copy of the license is
+included in the section entitled ``GNU Free Documentation License''.
+
+(a) The FSF's Back-Cover Text is: You are free to copy and modify
+this GNU manual. Buying copies from GNU Press supports the FSF in
+developing GNU and promoting software freedom.''
+
+@end quotation
+@end copying
+
+@defcodeindex bt
+@defcodeindex rw
+@set BashFeatures
+
+@dircategory Basics
+@direntry
+* Bash: (bash). The GNU Bourne-Again SHell.
+@end direntry
+
+@finalout
+
+@titlepage
+@title Bash Reference Manual
+@subtitle Reference Documentation for Bash
+@subtitle Edition @value{EDITION}, for @code{Bash} Version @value{VERSION}.
+@subtitle @value{UPDATED-MONTH}
+@author Chet Ramey, Case Western Reserve University
+@author Brian Fox, Free Software Foundation
+
+@page
+@vskip 0pt plus 1filll
+@insertcopying
+
+@sp 1
+Published by the Free Software Foundation @*
+59 Temple Place, Suite 330, @*
+Boston, MA 02111-1307 @*
+USA @*
+
+@end titlepage
+
+@contents
+
+@ifnottex
+@node Top, Introduction, (dir), (dir)
+@top Bash Features
+
+This text is a brief description of the features that are present in
+the Bash shell (version @value{VERSION}, @value{UPDATED}).
+
+This is Edition @value{EDITION}, last updated @value{UPDATED},
+of @cite{The GNU Bash Reference Manual},
+for @code{Bash}, Version @value{VERSION}.
+
+Bash contains features that appear in other popular shells, and some
+features that only appear in Bash. Some of the shells that Bash has
+borrowed concepts from are the Bourne Shell (@file{sh}), the Korn Shell
+(@file{ksh}), and the C-shell (@file{csh} and its successor,
+@file{tcsh}). The following menu breaks the features up into
+categories based upon which one of these other shells inspired the
+feature.
+
+This manual is meant as a brief introduction to features found in
+Bash. The Bash manual page should be used as the definitive
+reference on shell behavior.
+
+@menu
+* Introduction:: An introduction to the shell.
+* Definitions:: Some definitions used in the rest of this
+ manual.
+* Basic Shell Features:: The shell "building blocks".
+* Shell Builtin Commands:: Commands that are a part of the shell.
+* Shell Variables:: Variables used or set by Bash.
+* Bash Features:: Features found only in Bash.
+* Job Control:: What job control is and how Bash allows you
+ to use it.
+* Command Line Editing:: Chapter describing the command line
+ editing features.
+* Using History Interactively:: Command History Expansion
+* Installing Bash:: How to build and install Bash on your system.
+* Reporting Bugs:: How to report bugs in Bash.
+* Major Differences From The Bourne Shell:: A terse list of the differences
+ between Bash and historical
+ versions of /bin/sh.
+* GNU Free Documentation License:: Copying and sharing this documentation.
+* Indexes:: Various indexes for this manual.
+@end menu
+@end ifnottex
+
+@node Introduction
+@chapter Introduction
+@menu
+* What is Bash?:: A short description of Bash.
+* What is a shell?:: A brief introduction to shells.
+@end menu
+
+@node What is Bash?
+@section What is Bash?
+
+Bash is the shell, or command language interpreter,
+for the @sc{gnu} operating system.
+The name is an acronym for the @samp{Bourne-Again SHell},
+a pun on Stephen Bourne, the author of the direct ancestor of
+the current Unix shell @code{sh},
+which appeared in the Seventh Edition Bell Labs Research version
+of Unix.
+
+Bash is largely compatible with @code{sh} and incorporates useful
+features from the Korn shell @code{ksh} and the C shell @code{csh}.
+It is intended to be a conformant implementation of the @sc{ieee}
+@sc{posix} Shell and Tools portion of the @sc{ieee} @sc{posix}
+specification (@sc{ieee} Standard 1003.1).
+It offers functional improvements over @code{sh} for both interactive and
+programming use.
+
+While the @sc{gnu} operating system provides other shells, including
+a version of @code{csh}, Bash is the default shell.
+Like other @sc{gnu} software, Bash is quite portable. It currently runs
+on nearly every version of Unix and a few other operating systems @minus{}
+independently-supported ports exist for @sc{ms-dos}, @sc{os/2},
+and Windows platforms.
+
+@node What is a shell?
+@section What is a shell?
+
+At its base, a shell is simply a macro processor that executes
+commands. The term macro processor means functionality where text
+and symbols are expanded to create larger expressions.
+
+A Unix shell is both a command interpreter and a programming
+language. As a command interpreter, the shell provides the user
+interface to the rich set of @sc{gnu} utilities. The programming
+language features allow these utilities to be combined.
+Files containing commands can be created, and become
+commands themselves. These new commands have the same status as
+system commands in directories such as @file{/bin}, allowing users
+or groups to establish custom environments to automate their common
+tasks.
+
+Shells may be used interactively or non-interactively. In
+interactive mode, they accept input typed from the keyboard.
+When executing non-interactively, shells execute commands read
+from a file.
+
+A shell allows execution of @sc{gnu} commands, both synchronously and
+asynchronously.
+The shell waits for synchronous commands to complete before accepting
+more input; asynchronous commands continue to execute in parallel
+with the shell while it reads and executes additional commands.
+The @dfn{redirection} constructs permit
+fine-grained control of the input and output of those commands.
+Moreover, the shell allows control over the contents of commands'
+environments.
+
+Shells also provide a small set of built-in
+commands (@dfn{builtins}) implementing functionality impossible
+or inconvenient to obtain via separate utilities.
+For example, @code{cd}, @code{break}, @code{continue}, and
+@code{exec} cannot be implemented outside of the shell because
+they directly manipulate the shell itself.
+The @code{history}, @code{getopts}, @code{kill}, or @code{pwd}
+builtins, among others, could be implemented in separate utilities,
+but they are more convenient to use as builtin commands.
+All of the shell builtins are described in
+subsequent sections.
+
+While executing commands is essential, most of the power (and
+complexity) of shells is due to their embedded programming
+languages. Like any high-level language, the shell provides
+variables, flow control constructs, quoting, and functions.
+
+Shells offer features geared specifically for
+interactive use rather than to augment the programming language.
+These interactive features include job control, command line
+editing, command history and aliases. Each of these features is
+described in this manual.
+
+@node Definitions
+@chapter Definitions
+These definitions are used throughout the remainder of this manual.
+
+@table @code
+
+@item POSIX
+@cindex POSIX
+A family of open system standards based on Unix. Bash
+is primarily concerned with the Shell and Utilities portion of the
+@sc{posix} 1003.1 standard.
+
+@item blank
+A space or tab character.
+
+@item builtin
+@cindex builtin
+A command that is implemented internally by the shell itself, rather
+than by an executable program somewhere in the file system.
+
+@item control operator
+@cindex control operator
+A @code{token} that performs a control function. It is a @code{newline}
+or one of the following:
+@samp{||}, @samp{&&}, @samp{&}, @samp{;}, @samp{;;},
+@samp{|}, @samp{|&}, @samp{(}, or @samp{)}.
+
+@item exit status
+@cindex exit status
+The value returned by a command to its caller. The value is restricted
+to eight bits, so the maximum value is 255.
+
+@item field
+@cindex field
+A unit of text that is the result of one of the shell expansions. After
+expansion, when executing a command, the resulting fields are used as
+the command name and arguments.
+
+@item filename
+@cindex filename
+A string of characters used to identify a file.
+
+@item job
+@cindex job
+A set of processes comprising a pipeline, and any processes descended
+from it, that are all in the same process group.
+
+@item job control
+@cindex job control
+A mechanism by which users can selectively stop (suspend) and restart
+(resume) execution of processes.
+
+@item metacharacter
+@cindex metacharacter
+A character that, when unquoted, separates words. A metacharacter is
+a @code{blank} or one of the following characters:
+@samp{|}, @samp{&}, @samp{;}, @samp{(}, @samp{)}, @samp{<}, or
+@samp{>}.
+
+@item name
+@cindex name
+@cindex identifier
+A @code{word} consisting solely of letters, numbers, and underscores,
+and beginning with a letter or underscore. @code{Name}s are used as
+shell variable and function names.
+Also referred to as an @code{identifier}.
+
+@item operator
+@cindex operator, shell
+A @code{control operator} or a @code{redirection operator}.
+@xref{Redirections}, for a list of redirection operators.
+Operators contain at least one unquoted @code{metacharacter}.
+
+@item process group
+@cindex process group
+A collection of related processes each having the same process
+group @sc{id}.
+
+@item process group ID
+@cindex process group ID
+A unique identifier that represents a @code{process group}
+during its lifetime.
+
+@item reserved word
+@cindex reserved word
+A @code{word} that has a special meaning to the shell. Most reserved
+words introduce shell flow control constructs, such as @code{for} and
+@code{while}.
+
+@item return status
+@cindex return status
+A synonym for @code{exit status}.
+
+@item signal
+@cindex signal
+A mechanism by which a process may be notified by the kernel
+of an event occurring in the system.
+
+@item special builtin
+@cindex special builtin
+A shell builtin command that has been classified as special by the
+@sc{posix} standard.
+
+@item token
+@cindex token
+A sequence of characters considered a single unit by the shell.
+It is either a @code{word} or an @code{operator}.
+
+@item word
+@cindex word
+A sequence of characters treated as a unit by the shell.
+Words may not include unquoted @code{metacharacters}.
+@end table
+
+@node Basic Shell Features
+@chapter Basic Shell Features
+@cindex Bourne shell
+
+Bash is an acronym for @samp{Bourne-Again SHell}.
+The Bourne shell is
+the traditional Unix shell originally written by Stephen Bourne.
+All of the Bourne shell builtin commands are available in Bash,
+The rules for evaluation and quoting are taken from the @sc{posix}
+specification for the `standard' Unix shell.
+
+This chapter briefly summarizes the shell's `building blocks':
+commands, control structures, shell functions, shell @i{parameters},
+shell expansions,
+@i{redirections}, which are a way to direct input and output from
+and to named files, and how the shell executes commands.
+
+@menu
+* Shell Syntax:: What your input means to the shell.
+* Shell Commands:: The types of commands you can use.
+* Shell Functions:: Grouping commands by name.
+* Shell Parameters:: How the shell stores values.
+* Shell Expansions:: How Bash expands parameters and the various
+ expansions available.
+* Redirections:: A way to control where input and output go.
+* Executing Commands:: What happens when you run a command.
+* Shell Scripts:: Executing files of shell commands.
+@end menu
+
+@node Shell Syntax
+@section Shell Syntax
+@menu
+* Shell Operation:: The basic operation of the shell.
+* Quoting:: How to remove the special meaning from characters.
+* Comments:: How to specify comments.
+@end menu
+
+When the shell reads input, it proceeds through a
+sequence of operations. If the input indicates the beginning of a
+comment, the shell ignores the comment symbol (@samp{#}), and the rest
+of that line.
+
+Otherwise, roughly speaking, the shell reads its input and
+divides the input into words and operators, employing the quoting rules
+to select which meanings to assign various words and characters.
+
+The shell then parses these tokens into commands and other constructs,
+removes the special meaning of certain words or characters, expands
+others, redirects input and output as needed, executes the specified
+command, waits for the command's exit status, and makes that exit status
+available for further inspection or processing.
+
+@node Shell Operation
+@subsection Shell Operation
+
+The following is a brief description of the shell's operation when it
+reads and executes a command. Basically, the shell does the
+following:
+
+@enumerate
+@item
+Reads its input from a file (@pxref{Shell Scripts}), from a string
+supplied as an argument to the @option{-c} invocation option
+(@pxref{Invoking Bash}), or from the user's terminal.
+
+@item
+Breaks the input into words and operators, obeying the quoting rules
+described in @ref{Quoting}. These tokens are separated by
+@code{metacharacters}. Alias expansion is performed by this step
+(@pxref{Aliases}).
+
+@item
+Parses the tokens into simple and compound commands
+(@pxref{Shell Commands}).
+
+@item
+Performs the various shell expansions (@pxref{Shell Expansions}), breaking
+the expanded tokens into lists of filenames (@pxref{Filename Expansion})
+and commands and arguments.
+
+@item
+Performs any necessary redirections (@pxref{Redirections}) and removes
+the redirection operators and their operands from the argument list.
+
+@item
+Executes the command (@pxref{Executing Commands}).
+
+@item
+Optionally waits for the command to complete and collects its exit
+status (@pxref{Exit Status}).
+
+@end enumerate
+
+@node Quoting
+@subsection Quoting
+@cindex quoting
+@menu
+* Escape Character:: How to remove the special meaning from a single
+ character.
+* Single Quotes:: How to inhibit all interpretation of a sequence
+ of characters.
+* Double Quotes:: How to suppress most of the interpretation of a
+ sequence of characters.
+* ANSI-C Quoting:: How to expand ANSI-C sequences in quoted strings.
+* Locale Translation:: How to translate strings into different languages.
+@end menu
+
+Quoting is used to remove the special meaning of certain
+characters or words to the shell. Quoting can be used to
+disable special treatment for special characters, to prevent
+reserved words from being recognized as such, and to prevent
+parameter expansion.
+
+Each of the shell metacharacters (@pxref{Definitions})
+has special meaning to the shell and must be quoted if it is to
+represent itself.
+When the command history expansion facilities are being used
+(@pxref{History Interaction}), the
+@var{history expansion} character, usually @samp{!}, must be quoted
+to prevent history expansion. @xref{Bash History Facilities}, for
+more details concerning history expansion.
+
+There are three quoting mechanisms: the
+@var{escape character}, single quotes, and double quotes.
+
+@node Escape Character
+@subsubsection Escape Character
+A non-quoted backslash @samp{\} is the Bash escape character.
+It preserves the literal value of the next character that follows,
+with the exception of @code{newline}. If a @code{\newline} pair
+appears, and the backslash itself is not quoted, the @code{\newline}
+is treated as a line continuation (that is, it is removed from
+the input stream and effectively ignored).
+
+@node Single Quotes
+@subsubsection Single Quotes
+
+Enclosing characters in single quotes (@samp{'}) preserves the literal value
+of each character within the quotes. A single quote may not occur
+between single quotes, even when preceded by a backslash.
+
+@node Double Quotes
+@subsubsection Double Quotes
+
+Enclosing characters in double quotes (@samp{"}) preserves the literal value
+of all characters within the quotes, with the exception of
+@samp{$}, @samp{`}, @samp{\},
+and, when history expansion is enabled, @samp{!}.
+The characters @samp{$} and @samp{`}
+retain their special meaning within double quotes (@pxref{Shell Expansions}).
+The backslash retains its special meaning only when followed by one of
+the following characters:
+@samp{$}, @samp{`}, @samp{"}, @samp{\}, or @code{newline}.
+Within double quotes, backslashes that are followed by one of these
+characters are removed. Backslashes preceding characters without a
+special meaning are left unmodified.
+A double quote may be quoted within double quotes by preceding it with
+a backslash.
+If enabled, history expansion will be performed unless an @samp{!}
+appearing in double quotes is escaped using a backslash.
+The backslash preceding the @samp{!} is not removed.
+
+The special parameters @samp{*} and @samp{@@} have special meaning
+when in double quotes (@pxref{Shell Parameter Expansion}).
+
+@node ANSI-C Quoting
+@subsubsection ANSI-C Quoting
+@cindex quoting, ANSI
+
+Words of the form @code{$'@var{string}'} are treated specially. The
+word expands to @var{string}, with backslash-escaped characters replaced
+as specified by the ANSI C standard. Backslash escape sequences, if
+present, are decoded as follows:
+
+@table @code
+@item \a
+alert (bell)
+@item \b
+backspace
+@item \e
+@itemx \E
+an escape character (not ANSI C)
+@item \f
+form feed
+@item \n
+newline
+@item \r
+carriage return
+@item \t
+horizontal tab
+@item \v
+vertical tab
+@item \\
+backslash
+@item \'
+single quote
+@item \"
+double quote
+@item \@var{nnn}
+the eight-bit character whose value is the octal value @var{nnn}
+(one to three digits)
+@item \x@var{HH}
+the eight-bit character whose value is the hexadecimal value @var{HH}
+(one or two hex digits)
+@item \u@var{HHHH}
+the Unicode (ISO/IEC 10646) character whose value is the hexadecimal value
+@var{HHHH} (one to four hex digits)
+@item \U@var{HHHHHHHH}
+the Unicode (ISO/IEC 10646) character whose value is the hexadecimal value
+@var{HHHHHHHH} (one to eight hex digits)
+@item \c@var{x}
+a control-@var{x} character
+@end table
+
+@noindent
+The expanded result is single-quoted, as if the dollar sign had not
+been present.
+
+@node Locale Translation
+@subsubsection Locale-Specific Translation
+@cindex localization
+@cindex internationalization
+@cindex native languages
+@cindex translation, native languages
+
+A double-quoted string preceded by a dollar sign (@samp{$}) will cause
+the string to be translated according to the current locale.
+If the current locale is @code{C} or @code{POSIX}, the dollar sign
+is ignored.
+If the string is translated and replaced, the replacement is
+double-quoted.
+
+@vindex LC_MESSAGES
+@vindex TEXTDOMAIN
+@vindex TEXTDOMAINDIR
+Some systems use the message catalog selected by the @env{LC_MESSAGES}
+shell variable. Others create the name of the message catalog from the
+value of the @env{TEXTDOMAIN} shell variable, possibly adding a
+suffix of @samp{.mo}. If you use the @env{TEXTDOMAIN} variable, you
+may need to set the @env{TEXTDOMAINDIR} variable to the location of
+the message catalog files. Still others use both variables in this
+fashion:
+@env{TEXTDOMAINDIR}/@env{LC_MESSAGES}/LC_MESSAGES/@env{TEXTDOMAIN}.mo.
+
+@node Comments
+@subsection Comments
+@cindex comments, shell
+
+In a non-interactive shell, or an interactive shell in which the
+@code{interactive_comments} option to the @code{shopt}
+builtin is enabled (@pxref{The Shopt Builtin}),
+a word beginning with @samp{#}
+causes that word and all remaining characters on that line to
+be ignored. An interactive shell without the @code{interactive_comments}
+option enabled does not allow comments. The @code{interactive_comments}
+option is on by default in interactive shells.
+@xref{Interactive Shells}, for a description of what makes
+a shell interactive.
+
+@node Shell Commands
+@section Shell Commands
+@cindex commands, shell
+
+A simple shell command such as @code{echo a b c} consists of the command
+itself followed by arguments, separated by spaces.
+
+More complex shell commands are composed of simple commands arranged together
+in a variety of ways: in a pipeline in which the output of one command
+becomes the input of a second, in a loop or conditional construct, or in
+some other grouping.
+
+@menu
+* Simple Commands:: The most common type of command.
+* Pipelines:: Connecting the input and output of several
+ commands.
+* Lists:: How to execute commands sequentially.
+* Compound Commands:: Shell commands for control flow.
+* Coprocesses:: Two-way communication between commands.
+* GNU Parallel:: Running commands in parallel.
+@end menu
+
+@node Simple Commands
+@subsection Simple Commands
+@cindex commands, simple
+
+A simple command is the kind of command encountered most often.
+It's just a sequence of words separated by @code{blank}s, terminated
+by one of the shell's control operators (@pxref{Definitions}). The
+first word generally specifies a command to be executed, with the
+rest of the words being that command's arguments.
+
+The return status (@pxref{Exit Status}) of a simple command is
+its exit status as provided
+by the @sc{posix} 1003.1 @code{waitpid} function, or 128+@var{n} if
+the command was terminated by signal @var{n}.
+
+@node Pipelines
+@subsection Pipelines
+@cindex pipeline
+@cindex commands, pipelines
+
+A @code{pipeline} is a sequence of simple commands separated by one of
+the control operators @samp{|} or @samp{|&}.
+
+@rwindex time
+@rwindex !
+@cindex command timing
+The format for a pipeline is
+@example
+[@code{time} [@code{-p}]] [@code{!}] @var{command1} [ [@code{|} or @code{|&}] @var{command2} @dots{}]
+@end example
+
+@noindent
+The output of each command in the pipeline is connected via a pipe
+to the input of the next command.
+That is, each command reads the previous command's output. This
+connection is performed before any redirections specified by the
+command.
+
+If @samp{|&} is used, the standard error of @var{command1} is connected to
+@var{command2}'s standard input through the pipe; it is shorthand for
+@code{2>&1 |}. This implicit redirection of the standard error is
+performed after any redirections specified by the command.
+
+The reserved word @code{time} causes timing statistics
+to be printed for the pipeline once it finishes.
+The statistics currently consist of elapsed (wall-clock) time and
+user and system time consumed by the command's execution.
+The @option{-p} option changes the output format to that specified
+by @sc{posix}.
+When the shell is in @sc{posix} mode (@pxref{Bash POSIX Mode}),
+it does not recognize @code{time} as a reserved word if the next
+token begins with a @samp{-}.
+The @env{TIMEFORMAT} variable may be set to a format string that
+specifies how the timing information should be displayed.
+@xref{Bash Variables}, for a description of the available formats.
+The use of @code{time} as a reserved word permits the timing of
+shell builtins, shell functions, and pipelines. An external
+@code{time} command cannot time these easily.
+
+When the shell is in @sc{posix} mode (@pxref{Bash POSIX Mode}), @code{time}
+may be followed by a newline. In this case, the shell displays the
+total user and system time consumed by the shell and its children.
+The @env{TIMEFORMAT} variable may be used to specify the format of
+the time information.
+
+If the pipeline is not executed asynchronously (@pxref{Lists}), the
+shell waits for all commands in the pipeline to complete.
+
+Each command in a pipeline is executed in its own subshell
+(@pxref{Command Execution Environment}). The exit
+status of a pipeline is the exit status of the last command in the
+pipeline, unless the @code{pipefail} option is enabled
+(@pxref{The Set Builtin}).
+If @code{pipefail} is enabled, the pipeline's return status is the
+value of the last (rightmost) command to exit with a non-zero status,
+or zero if all commands exit successfully.
+If the reserved word @samp{!} precedes the pipeline, the
+exit status is the logical negation of the exit status as described
+above.
+The shell waits for all commands in the pipeline to terminate before
+returning a value.
+
+@node Lists
+@subsection Lists of Commands
+@cindex commands, lists
+
+A @code{list} is a sequence of one or more pipelines separated by one
+of the operators @samp{;}, @samp{&}, @samp{&&}, or @samp{||},
+and optionally terminated by one of @samp{;}, @samp{&}, or a
+@code{newline}.
+
+Of these list operators, @samp{&&} and @samp{||}
+have equal precedence, followed by @samp{;} and @samp{&},
+which have equal precedence.
+
+A sequence of one or more newlines may appear in a @code{list}
+to delimit commands, equivalent to a semicolon.
+
+If a command is terminated by the control operator @samp{&},
+the shell executes the command asynchronously in a subshell.
+This is known as executing the command in the @var{background}.
+The shell does not wait for the command to finish, and the return
+status is 0 (true).
+When job control is not active (@pxref{Job Control}),
+the standard input for asynchronous commands, in the absence of any
+explicit redirections, is redirected from @code{/dev/null}.
+
+Commands separated by a @samp{;} are executed sequentially; the shell
+waits for each command to terminate in turn. The return status is the
+exit status of the last command executed.
+
+@sc{and} and @sc{or} lists are sequences of one or more pipelines
+separated by the control operators @samp{&&} and @samp{||},
+respectively. @sc{and} and @sc{or} lists are executed with left
+associativity.
+
+An @sc{and} list has the form
+@example
+@var{command1} && @var{command2}
+@end example
+
+@noindent
+@var{command2} is executed if, and only if, @var{command1}
+returns an exit status of zero.
+
+An @sc{or} list has the form
+@example
+@var{command1} || @var{command2}
+@end example
+
+@noindent
+@var{command2} is executed if, and only if, @var{command1}
+returns a non-zero exit status.
+
+The return status of
+@sc{and} and @sc{or} lists is the exit status of the last command
+executed in the list.
+
+@node Compound Commands
+@subsection Compound Commands
+@cindex commands, compound
+
+@menu
+* Looping Constructs:: Shell commands for iterative action.
+* Conditional Constructs:: Shell commands for conditional execution.
+* Command Grouping:: Ways to group commands.
+@end menu
+
+Compound commands are the shell programming constructs.
+Each construct begins with a reserved word or control operator and is
+terminated by a corresponding reserved word or operator.
+Any redirections (@pxref{Redirections}) associated with a compound command
+apply to all commands within that compound command unless explicitly overridden.
+
+In most cases a list of commands in a compound command's description may be
+separated from the rest of the command by one or more newlines, and may be
+followed by a newline in place of a semicolon.
+
+Bash provides looping constructs, conditional commands, and mechanisms
+to group commands and execute them as a unit.
+
+@node Looping Constructs
+@subsubsection Looping Constructs
+@cindex commands, looping
+
+Bash supports the following looping constructs.
+
+Note that wherever a @samp{;} appears in the description of a
+command's syntax, it may be replaced with one or more newlines.
+
+@table @code
+@item until
+@rwindex until
+@rwindex do
+@rwindex done
+The syntax of the @code{until} command is:
+@example
+until @var{test-commands}; do @var{consequent-commands}; done
+@end example
+Execute @var{consequent-commands} as long as
+@var{test-commands} has an exit status which is not zero.
+The return status is the exit status of the last command executed
+in @var{consequent-commands}, or zero if none was executed.
+
+@item while
+@rwindex while
+The syntax of the @code{while} command is:
+@example
+while @var{test-commands}; do @var{consequent-commands}; done
+@end example
+
+Execute @var{consequent-commands} as long as
+@var{test-commands} has an exit status of zero.
+The return status is the exit status of the last command executed
+in @var{consequent-commands}, or zero if none was executed.
+
+@item for
+@rwindex for
+The syntax of the @code{for} command is:
+
+@example
+for @var{name} [ [in [@var{words} @dots{}] ] ; ] do @var{commands}; done
+@end example
+Expand @var{words}, and execute @var{commands} once for each member
+in the resultant list, with @var{name} bound to the current member.
+If @samp{in @var{words}} is not present, the @code{for} command
+executes the @var{commands} once for each positional parameter that is
+set, as if @samp{in "$@@"} had been specified
+(@pxref{Special Parameters}).
+The return status is the exit status of the last command that executes.
+If there are no items in the expansion of @var{words}, no commands are
+executed, and the return status is zero.
+
+An alternate form of the @code{for} command is also supported:
+
+@example
+for (( @var{expr1} ; @var{expr2} ; @var{expr3} )) ; do @var{commands} ; done
+@end example
+First, the arithmetic expression @var{expr1} is evaluated according
+to the rules described below (@pxref{Shell Arithmetic}).
+The arithmetic expression @var{expr2} is then evaluated repeatedly
+until it evaluates to zero.
+Each time @var{expr2} evaluates to a non-zero value, @var{commands} are
+executed and the arithmetic expression @var{expr3} is evaluated.
+If any expression is omitted, it behaves as if it evaluates to 1.
+The return value is the exit status of the last command in @var{commands}
+that is executed, or false if any of the expressions is invalid.
+
+@end table
+
+The @code{break} and @code{continue} builtins (@pxref{Bourne Shell Builtins})
+may be used to control loop execution.
+
+@node Conditional Constructs
+@subsubsection Conditional Constructs
+@cindex commands, conditional
+
+@table @code
+@item if
+@rwindex if
+@rwindex then
+@rwindex else
+@rwindex elif
+@rwindex fi
+The syntax of the @code{if} command is:
+
+@example
+if @var{test-commands}; then
+ @var{consequent-commands};
+[elif @var{more-test-commands}; then
+ @var{more-consequents};]
+[else @var{alternate-consequents};]
+fi
+@end example
+
+The @var{test-commands} list is executed, and if its return status is zero,
+the @var{consequent-commands} list is executed.
+If @var{test-commands} returns a non-zero status, each @code{elif} list
+is executed in turn, and if its exit status is zero,
+the corresponding @var{more-consequents} is executed and the
+command completes.
+If @samp{else @var{alternate-consequents}} is present, and
+the final command in the final @code{if} or @code{elif} clause
+has a non-zero exit status, then @var{alternate-consequents} is executed.
+The return status is the exit status of the last command executed, or
+zero if no condition tested true.
+
+@item case
+@rwindex case
+@rwindex in
+@rwindex esac
+The syntax of the @code{case} command is:
+
+@example
+@code{case @var{word} in [ [(] @var{pattern} [| @var{pattern}]@dots{}) @var{command-list} ;;]@dots{} esac}
+@end example
+
+@code{case} will selectively execute the @var{command-list} corresponding to
+the first @var{pattern} that matches @var{word}.
+If the shell option @code{nocasematch}
+(see the description of @code{shopt} in @ref{The Shopt Builtin})
+is enabled, the match is performed without regard to the case
+of alphabetic characters.
+The @samp{|} is used to separate multiple patterns, and the @samp{)}
+operator terminates a pattern list.
+A list of patterns and an associated command-list is known
+as a @var{clause}.
+
+Each clause must be terminated with @samp{;;}, @samp{;&}, or @samp{;;&}.
+The @var{word} undergoes tilde expansion, parameter expansion, command
+substitution, arithmetic expansion, and quote removal before matching is
+attempted. Each @var{pattern} undergoes tilde expansion, parameter
+expansion, command substitution, and arithmetic expansion.
+
+There may be an arbitrary number of @code{case} clauses, each terminated
+by a @samp{;;}, @samp{;&}, or @samp{;;&}.
+The first pattern that matches determines the
+command-list that is executed.
+
+Here is an example using @code{case} in a script that could be used to
+describe one interesting feature of an animal:
+
+@example
+echo -n "Enter the name of an animal: "
+read ANIMAL
+echo -n "The $ANIMAL has "
+case $ANIMAL in
+ horse | dog | cat) echo -n "four";;
+ man | kangaroo ) echo -n "two";;
+ *) echo -n "an unknown number of";;
+esac
+echo " legs."
+@end example
+
+@noindent
+
+If the @samp{;;} operator is used, no subsequent matches are attempted after
+the first pattern match.
+Using @samp{;&} in place of @samp{;;} causes execution to continue with
+the @var{command-list} associated with the next clause, if any.
+Using @samp{;;&} in place of @samp{;;} causes the shell to test the patterns
+in the next clause, if any, and execute any associated @var{command-list}
+on a successful match.
+
+The return status is zero if no @var{pattern} is matched. Otherwise, the
+return status is the exit status of the @var{command-list} executed.
+
+@item select
+@rwindex select
+
+The @code{select} construct allows the easy generation of menus.
+It has almost the same syntax as the @code{for} command:
+
+@example
+select @var{name} [in @var{words} @dots{}]; do @var{commands}; done
+@end example
+
+The list of words following @code{in} is expanded, generating a list
+of items. The set of expanded words is printed on the standard
+error output stream, each preceded by a number. If the
+@samp{in @var{words}} is omitted, the positional parameters are printed,
+as if @samp{in "$@@"} had been specified.
+The @env{PS3} prompt is then displayed and a line is read from the
+standard input.
+If the line consists of a number corresponding to one of the displayed
+words, then the value of @var{name} is set to that word.
+If the line is empty, the words and prompt are displayed again.
+If @code{EOF} is read, the @code{select} command completes.
+Any other value read causes @var{name} to be set to null.
+The line read is saved in the variable @env{REPLY}.
+
+The @var{commands} are executed after each selection until a
+@code{break} command is executed, at which
+point the @code{select} command completes.
+
+Here is an example that allows the user to pick a filename from the
+current directory, and displays the name and index of the file
+selected.
+
+@example
+select fname in *;
+do
+ echo you picked $fname \($REPLY\)
+ break;
+done
+@end example
+
+@item ((@dots{}))
+@example
+(( @var{expression} ))
+@end example
+
+The arithmetic @var{expression} is evaluated according to the rules
+described below (@pxref{Shell Arithmetic}).
+If the value of the expression is non-zero, the return status is 0;
+otherwise the return status is 1. This is exactly equivalent to
+@example
+let "@var{expression}"
+@end example
+@noindent
+@xref{Bash Builtins}, for a full description of the @code{let} builtin.
+
+@item [[@dots{}]]
+@rwindex [[
+@rwindex ]]
+@example
+[[ @var{expression} ]]
+@end example
+
+Return a status of 0 or 1 depending on the evaluation of
+the conditional expression @var{expression}.
+Expressions are composed of the primaries described below in
+@ref{Bash Conditional Expressions}.
+Word splitting and filename expansion are not performed on the words
+between the @samp{[[} and @samp{]]}; tilde expansion, parameter and
+variable expansion, arithmetic expansion, command substitution, process
+substitution, and quote removal are performed.
+Conditional operators such as @samp{-f} must be unquoted to be recognized
+as primaries.
+
+When used with @samp{[[}, the @samp{<} and @samp{>} operators sort
+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}.
+If the shell option @code{nocasematch}
+(see the description of @code{shopt} in @ref{The Shopt Builtin})
+is enabled, the match is performed without regard to the case
+of alphabetic characters.
+The return value is 0 if the string matches (@samp{==}) or does not
+match (@samp{!=})the pattern, and 1 otherwise.
+Any part of the pattern may be quoted to force the quoted portion
+to be matched as a string.
+
+An additional binary operator, @samp{=~}, is available, with the same
+precedence as @samp{==} and @samp{!=}.
+When it is used, the string to the right of the operator is considered
+an extended regular expression and matched accordingly (as in @i{regex}3)).
+The return value is 0 if the string matches
+the pattern, and 1 otherwise.
+If the regular expression is syntactically incorrect, the conditional
+expression's return value is 2.
+If the shell option @code{nocasematch}
+(see the description of @code{shopt} in @ref{The Shopt Builtin})
+is enabled, the match is performed without regard to the case
+of alphabetic characters.
+Any part of the pattern may be quoted to force the quoted portion
+to be matched as a string.
+Substrings matched by parenthesized subexpressions within the regular
+expression are saved in the array variable @code{BASH_REMATCH}.
+The element of @code{BASH_REMATCH} with index 0 is the portion of the string
+matching the entire regular expression.
+The element of @code{BASH_REMATCH} with index @var{n} is the portion of the
+string matching the @var{n}th parenthesized subexpression.
+
+Expressions may be combined using the following operators, listed
+in decreasing order of precedence:
+
+@table @code
+@item ( @var{expression} )
+Returns the value of @var{expression}.
+This may be used to override the normal precedence of operators.
+
+@item ! @var{expression}
+True if @var{expression} is false.
+
+@item @var{expression1} && @var{expression2}
+True if both @var{expression1} and @var{expression2} are true.
+
+@item @var{expression1} || @var{expression2}
+True if either @var{expression1} or @var{expression2} is true.
+@end table
+@noindent
+The @code{&&} and @code{||} operators do not evaluate @var{expression2} if the
+value of @var{expression1} is sufficient to determine the return
+value of the entire conditional expression.
+
+@end table
+
+@node Command Grouping
+@subsubsection Grouping Commands
+@cindex commands, grouping
+
+Bash provides two ways to group a list of commands to be executed
+as a unit. When commands are grouped, redirections may be applied
+to the entire command list. For example, the output of all the
+commands in the list may be redirected to a single stream.
+
+@table @code
+@item ()
+@example
+( @var{list} )
+@end example
+
+Placing a list of commands between parentheses causes a subshell
+environment to be created (@pxref{Command Execution Environment}), and each
+of the commands in @var{list} to be executed in that subshell. Since the
+@var{list} is executed in a subshell, variable assignments do not remain in
+effect after the subshell completes.
+
+@item @{@}
+@rwindex @{
+@rwindex @}
+@example
+@{ @var{list}; @}
+@end example
+
+Placing a list of commands between curly braces causes the list to
+be executed in the current shell context. No subshell is created.
+The semicolon (or newline) following @var{list} is required.
+@end table
+
+In addition to the creation of a subshell, there is a subtle difference
+between these two constructs due to historical reasons. The braces
+are @code{reserved words}, so they must be separated from the @var{list}
+by @code{blank}s or other shell metacharacters.
+The parentheses are @code{operators}, and are
+recognized as separate tokens by the shell even if they are not separated
+from the @var{list} by whitespace.
+
+The exit status of both of these constructs is the exit status of
+@var{list}.
+
+@node Coprocesses
+@subsection Coprocesses
+@cindex coprocess
+
+A @code{coprocess} is a shell command preceded by the @code{coproc}
+reserved word.
+A coprocess is executed asynchronously in a subshell, as if the command
+had been terminated with the @samp{&} control operator, with a two-way pipe
+established between the executing shell and the coprocess.
+
+The format for a coprocess is:
+@example
+@code{coproc} [@var{NAME}] @var{command} [@var{redirections}]
+@end example
+
+@noindent
+This creates a coprocess named @var{NAME}.
+If @var{NAME} is not supplied, the default name is @var{COPROC}.
+@var{NAME} must not be supplied if @var{command} is a simple
+command (@pxref{Simple Commands}); otherwise, it is interpreted as
+the first word of the simple command.
+
+When the coproc is executed, the shell creates an array variable
+(@pxref{Arrays})
+named @var{NAME} in the context of the executing shell.
+The standard output of @var{command}
+is connected via a pipe to a file descriptor in the executing shell,
+and that file descriptor is assigned to @var{NAME}[0].
+The standard input of @var{command}
+is connected via a pipe to a file descriptor in the executing shell,
+and that file descriptor is assigned to @var{NAME}[1].
+This pipe is established before any redirections specified by the
+command (@pxref{Redirections}).
+The file descriptors can be utilized as arguments to shell commands
+and redirections using standard word expansions.
+
+The process ID of the shell spawned to execute the coprocess is
+available as the value of the variable @var{NAME}_PID.
+The @code{wait}
+builtin command may be used to wait for the coprocess to terminate.
+
+The return status of a coprocess is the exit status of @var{command}.
+
+@node GNU Parallel
+@subsection GNU Parallel
+
+GNU Parallel, as its name suggests, can be used to build and run commands
+in parallel. You may run the same command with different arguments, whether
+they are filenames, usernames, hostnames, or lines read from files.
+
+For a complete description, refer to the GNU Parallel documentation. A few
+examples should provide a brief introduction to its use.
+
+For example, it is easy to prefix each line in a text file with a specified
+string:
+@example
+cat file | parallel -k echo prefix_string
+@end example
+@noindent
+The @option{-k} option is required to preserve the lines' order.
+
+Similarly, you can append a specified string to each line in a text file:
+@example
+cat file | parallel -k echo @{@} append_string
+@end example
+
+You can use Parallel to move files from the current directory when the
+number of files is too large to process with one @code{mv} invocation:
+@example
+ls | parallel mv @{@} destdir
+@end example
+
+As you can see, the @{@} is replaced with each line read from standard input.
+This will run as many @code{mv} commands as there are files in the current
+directory. You can emulate a parallel @code{xargs} by adding the @option{-X}
+option:
+@example
+ls | parallel -X mv @{@} destdir
+@end example
+
+GNU Parallel can replace certain common idioms that operate on lines read
+from a file (in this case, filenames):
+@example
+ for x in $(cat list); do
+ do-something1 $x config-$x
+ do-something2 < $x
+ done | process-output
+@end example
+
+@noindent
+with a more compact syntax reminiscent of lambdas:
+@example
+cat list | parallel "do-something1 @{@} config-@{@} ; do-something2 < @{@}" | process-output
+@end example
+
+Parallel provides a built-in mechanism to remove filename extensions, which
+lends itself to batch file transformations or renaming:
+@example
+ls *.gz | parallel -j+0 "zcat @{@} | bzip2 >@{.@}.bz2 && rm @{@}"
+@end example
+@noindent
+This will recompress all files in the current directory with names ending
+in .gz using bzip2, running one job per CPU (-j+0) in parallel.
+
+If a command generates output, you may want to preserve the input order in
+the output. For instance, the following command
+@example
+@{ echo foss.org.my ; echo debian.org; echo freenetproject.org; @} | parallel traceroute
+@end example
+@noindent
+will display as output the traceroute invocation that finishes first. Using
+the @option{-k} option, as we saw above
+@example
+@{ echo foss.org.my ; echo debian.org; echo freenetproject.org; @} | parallel -k traceroute
+@end example
+@noindent
+will ensure that the output of @code{traceroute foss.org.my} is displayed first.
+
+@node Shell Functions
+@section Shell Functions
+@cindex shell function
+@cindex functions, shell
+
+Shell functions are a way to group commands for later execution
+using a single name for the group. They are executed just like
+a "regular" command.
+When the name of a shell function is used as a simple command name,
+the list of commands associated with that function name is executed.
+Shell functions are executed in the current
+shell context; no new process is created to interpret them.
+
+Functions are declared using this syntax:
+@rwindex function
+@example
+@var{name} () @var{compound-command} [ @var{redirections} ]@*or@*
+@code{function} @var{name} [()] @var{compound-command} [ @var{redirections} ]
+@end example
+
+This defines a shell function named @var{name}. The reserved
+word @code{function} is optional.
+If the @code{function} reserved
+word is supplied, the parentheses are optional.
+The @var{body} of the function is the compound command
+@var{compound-command} (@pxref{Compound Commands}).
+That command is usually a @var{list} enclosed between @{ and @}, but
+may be any compound command listed above.
+@var{compound-command} is executed whenever @var{name} is specified as the
+name of a command.
+Any redirections (@pxref{Redirections}) associated with the shell function
+are performed when the function is executed.
+
+A function definition may be deleted using the @option{-f} option to the
+@code{unset} builtin (@pxref{Bourne Shell Builtins}).
+
+The exit status of a function definition is zero unless a syntax error
+occurs or a readonly function with the same name already exists.
+When executed, the exit status of a function is the exit status of the
+last command executed in the body.
+
+Note that for historical reasons, in the most common usage the curly braces
+that surround the body of the function must be separated from the body by
+@code{blank}s or newlines.
+This is because the braces are reserved words and are only recognized
+as such when they are separated from the command list
+by whitespace or another shell metacharacter.
+Also, when using the braces, the @var{list} must be terminated by a semicolon,
+a @samp{&}, or a newline.
+
+When a function is executed, the arguments to the
+function become the positional parameters
+during its execution (@pxref{Positional Parameters}).
+The special parameter @samp{#} that expands to the number of
+positional parameters is updated to reflect the change.
+Special parameter @code{0} is unchanged.
+The first element of the @env{FUNCNAME} variable is set to the
+name of the function while the function is executing.
+
+All other aspects of the shell execution
+environment are identical between a function and its caller
+with these exceptions:
+the @env{DEBUG} and @env{RETURN} traps
+are not inherited unless the function has been given the
+@code{trace} attribute using the @code{declare} builtin or
+the @code{-o functrace} option has been enabled with
+the @code{set} builtin,
+(in which case all functions inherit the @env{DEBUG} and @env{RETURN} traps),
+and the @env{ERR} trap is not inherited unless the @code{-o errtrace}
+shell option has been enabled.
+@xref{Bourne Shell Builtins}, for the description of the
+@code{trap} builtin.
+
+The @env{FUNCNEST} variable, if set to a numeric value greater
+than 0, defines a maximum function nesting level. Function
+invocations that exceed the limit cause the entire command to
+abort.
+
+If the builtin command @code{return}
+is executed in a function, the function completes and
+execution resumes with the next command after the function
+call.
+Any command associated with the @code{RETURN} trap is executed
+before execution resumes.
+When a function completes, the values of the
+positional parameters and the special parameter @samp{#}
+are restored to the values they had prior to the function's
+execution. If a numeric argument is given to @code{return},
+that is the function's return status; otherwise the function's
+return status is the exit status of the last command executed
+before the @code{return}.
+
+Variables local to the function may be declared with the
+@code{local} builtin. These variables are visible only to
+the function and the commands it invokes.
+
+Function names and definitions may be listed with the
+@option{-f} option to the @code{declare} or @code{typeset}
+builtin commands (@pxref{Bash Builtins}).
+The @option{-F} option to @code{declare} or @code{typeset}
+will list the function names only
+(and optionally the source file and line number, if the @code{extdebug}
+shell option is enabled).
+Functions may be exported so that subshells
+automatically have them defined with the
+@option{-f} option to the @code{export} builtin
+(@pxref{Bourne Shell Builtins}).
+Note that shell functions and variables with the same name may result
+in multiple identically-named entries in the environment passed to the
+shell's children.
+Care should be taken in cases where this may cause a problem.
+
+Functions may be recursive.
+The @code{FUNCNEST} variable may be used to limit the depth of the
+function call stack and restrict the number of function invocations.
+By default, no limit is placed on the number of recursive calls.
+
+@node Shell Parameters
+@section Shell Parameters
+@cindex parameters
+@cindex variable, shell
+@cindex shell variable
+
+@menu
+* Positional Parameters:: The shell's command-line arguments.
+* Special Parameters:: Parameters denoted by special characters.
+@end menu
+
+A @var{parameter} is an entity that stores values.
+It can be a @code{name}, a number, or one of the special characters
+listed below.
+A @var{variable} is a parameter denoted by a @code{name}.
+A variable has a @var{value} and zero or more @var{attributes}.
+Attributes are assigned using the @code{declare} builtin command
+(see the description of the @code{declare} builtin in @ref{Bash Builtins}).
+
+A parameter is set if it has been assigned a value. The null string is
+a valid value. Once a variable is set, it may be unset only by using
+the @code{unset} builtin command.
+
+A variable may be assigned to by a statement of the form
+@example
+@var{name}=[@var{value}]
+@end example
+@noindent
+If @var{value}
+is not given, the variable is assigned the null string. All
+@var{value}s undergo tilde expansion, parameter and variable expansion,
+command substitution, arithmetic expansion, and quote
+removal (detailed below). If the variable has its @code{integer}
+attribute set, then @var{value}
+is evaluated as an arithmetic expression even if the @code{$((@dots{}))}
+expansion is not used (@pxref{Arithmetic Expansion}).
+Word splitting is not performed, with the exception
+of @code{"$@@"} as explained below.
+Filename expansion is not performed.
+Assignment statements may also appear as arguments to the
+@code{alias},
+@code{declare}, @code{typeset}, @code{export}, @code{readonly},
+and @code{local} builtin commands.
+When in @sc{posix} mode (@pxref{Bash POSIX Mode}), these builtins may appear
+in a command after one or more instances of the @code{command} builtin
+and retain these assignment statement properties.
+
+In the context where an assignment statement is assigning a value
+to a shell variable or array index (@pxref{Arrays}), the @samp{+=}
+operator can be used to
+append to or add to the variable's previous value.
+When @samp{+=} is applied to a variable for which the @var{integer} attribute
+has been set, @var{value} is evaluated as an arithmetic expression and
+added to the variable's current value, which is also evaluated.
+When @samp{+=} is applied to an array variable using compound assignment
+(@pxref{Arrays}), the
+variable's value is not unset (as it is when using @samp{=}), and new
+values are appended to the array beginning at one greater than the array's
+maximum index (for indexed arrays), or added as additional key-value pairs
+in an associative array.
+When applied to a string-valued variable, @var{value} is expanded and
+appended to the variable's value.
+
+@node Positional Parameters
+@subsection Positional Parameters
+@cindex parameters, positional
+
+A @var{positional parameter} is a parameter denoted by one or more
+digits, other than the single digit @code{0}. Positional parameters are
+assigned from the shell's arguments when it is invoked,
+and may be reassigned using the @code{set} builtin command.
+Positional parameter @code{N} may be referenced as @code{$@{N@}}, or
+as @code{$N} when @code{N} consists of a single digit.
+Positional parameters may not be assigned to with assignment statements.
+The @code{set} and @code{shift} builtins are used to set and
+unset them (@pxref{Shell Builtin Commands}).
+The positional parameters are
+temporarily replaced when a shell function is executed
+(@pxref{Shell Functions}).
+
+When a positional parameter consisting of more than a single
+digit is expanded, it must be enclosed in braces.
+
+@node Special Parameters
+@subsection Special Parameters
+@cindex parameters, special
+
+The shell treats several parameters specially. These parameters may
+only be referenced; assignment to them is not allowed.
+
+@vtable @code
+
+@item *
+Expands to the positional parameters, starting from one. When the
+expansion occurs within double quotes, it expands to a single word
+with the value of each parameter separated by the first character
+of the @env{IFS}
+special variable. That is, @code{"$*"} is equivalent
+to @code{"$1@var{c}$2@var{c}@dots{}"}, where @var{c}
+is the first character of the value of the @code{IFS}
+variable.
+If @env{IFS} is unset, the parameters are separated by spaces.
+If @env{IFS} is null, the parameters are joined without intervening
+separators.
+
+
+@item @@
+Expands to the positional parameters, starting from one. When the
+expansion occurs within double quotes, each parameter expands to a
+separate word. That is, @code{"$@@"} is equivalent to
+@code{"$1" "$2" @dots{}}.
+If the double-quoted expansion occurs within a word, the expansion of
+the first parameter is joined with the beginning part of the original
+word, and the expansion of the last parameter is joined with the last
+part of the original word.
+When there are no positional parameters, @code{"$@@"} and
+@code{$@@}
+expand to nothing (i.e., they are removed).
+
+@item #
+Expands to the number of positional parameters in decimal.
+
+@item ?
+Expands to the exit status of the most recently executed foreground
+pipeline.
+
+@item -
+(A hyphen.) Expands to the current option flags as specified upon
+invocation, by the @code{set}
+builtin command, or those set by the shell itself
+(such as the @option{-i} option).
+
+@item $
+Expands to the process @sc{id} of the shell. In a @code{()} subshell, it
+expands to the process @sc{id} of the invoking shell, not the subshell.
+
+@item !
+Expands to the process @sc{id} of the most recently executed background
+(asynchronous) command.
+
+@item 0
+Expands to the name of the shell or shell script. This is set at
+shell initialization. If Bash is invoked with a file of commands
+(@pxref{Shell Scripts}), @code{$0} is set to the name of that file.
+If Bash is started with the @option{-c} option (@pxref{Invoking Bash}),
+then @code{$0} is set to the first argument after the string to be
+executed, if one is present. Otherwise, it is set
+to the filename used to invoke Bash, as given by argument zero.
+
+@item _
+(An underscore.)
+At shell startup, set to the absolute pathname used to invoke the
+shell or shell script being executed as passed in the environment
+or argument list.
+Subsequently, expands to the last argument to the previous command,
+after expansion.
+Also set to the full pathname used to invoke each command executed
+and placed in the environment exported to that command.
+When checking mail, this parameter holds the name of the mail file.
+@end vtable
+
+@node Shell Expansions
+@section Shell Expansions
+@cindex expansion
+
+Expansion is performed on the command line after it has been split into
+@code{token}s. There are seven kinds of expansion performed:
+@itemize @bullet
+@item brace expansion
+@item tilde expansion
+@item parameter and variable expansion
+@item command substitution
+@item arithmetic expansion
+@item word splitting
+@item filename expansion
+@end itemize
+
+@menu
+* Brace Expansion:: Expansion of expressions within braces.
+* Tilde Expansion:: Expansion of the ~ character.
+* Shell Parameter Expansion:: How Bash expands variables to their values.
+* Command Substitution:: Using the output of a command as an argument.
+* Arithmetic Expansion:: How to use arithmetic in shell expansions.
+* Process Substitution:: A way to write and read to and from a
+ command.
+* Word Splitting:: How the results of expansion are split into separate
+ arguments.
+* Filename Expansion:: A shorthand for specifying filenames matching patterns.
+* Quote Removal:: How and when quote characters are removed from
+ words.
+@end menu
+
+The order of expansions is: brace expansion, tilde expansion,
+parameter, variable, and arithmetic expansion and
+command substitution
+(done in a left-to-right fashion), word splitting, and filename
+expansion.
+
+On systems that can support it, there is an additional expansion
+available: @var{process substitution}. This is performed at the
+same time as parameter, variable, and arithmetic expansion and
+command substitution.
+
+Only brace expansion, word splitting, and filename expansion
+can change the number of words of the expansion; other expansions
+expand a single word to a single word.
+The only exceptions to this are the expansions of
+@code{"$@@"} (@pxref{Special Parameters}) and @code{"$@{@var{name}[@@]@}"}
+(@pxref{Arrays}).
+
+After all expansions, @code{quote removal} (@pxref{Quote Removal})
+is performed.
+
+@node Brace Expansion
+@subsection Brace Expansion
+@cindex brace expansion
+@cindex expansion, brace
+
+Brace expansion is a mechanism by which arbitrary strings may be generated.
+This mechanism is similar to
+@var{filename expansion} (@pxref{Filename Expansion}),
+but the file names generated need not exist.
+Patterns to be brace expanded take the form of an optional @var{preamble},
+followed by either a series of comma-separated strings or a sequence expression
+between a pair of braces,
+followed by an optional @var{postscript}.
+The preamble is prefixed to each string contained within the braces, and
+the postscript is then appended to each resulting string, expanding left
+to right.
+
+Brace expansions may be nested.
+The results of each expanded string are not sorted; left to right order
+is preserved.
+For example,
+@example
+bash$ echo a@{d,c,b@}e
+ade ace abe
+@end example
+
+A sequence expression takes the form @code{@{@var{x}..@var{y}[..@var{incr}]@}},
+where @var{x} and @var{y} are either integers or single characters,
+and @var{incr}, an optional increment, is an integer.
+When integers are supplied, the expression expands to each number between
+@var{x} and @var{y}, inclusive.
+Supplied integers may be prefixed with @samp{0} to force each term to have the
+same width. When either @var{x} or @var{y} begins with a zero, the shell
+attempts to force all generated terms to contain the same number of digits,
+zero-padding where necessary.
+When characters are supplied, the expression expands to each character
+lexicographically between @var{x} and @var{y}, inclusive. Note that
+both @var{x} and @var{y} must be of the same type.
+When the increment is supplied, it is used as the difference between
+each term. The default increment is 1 or -1 as appropriate.
+
+Brace expansion is performed before any other expansions,
+and any characters special to other expansions are preserved
+in the result. It is strictly textual. Bash
+does not apply any syntactic interpretation to the context of the
+expansion or the text between the braces.
+To avoid conflicts with parameter expansion, the string @samp{$@{}
+is not considered eligible for brace expansion.
+
+A correctly-formed brace expansion must contain unquoted opening
+and closing braces, and at least one unquoted comma or a valid
+sequence expression.
+Any incorrectly formed brace expansion is left unchanged.
+
+A @{ or @samp{,} may be quoted with a backslash to prevent its
+being considered part of a brace expression.
+To avoid conflicts with parameter expansion, the string @samp{$@{}
+is not considered eligible for brace expansion.
+
+This construct is typically used as shorthand when the common
+prefix of the strings to be generated is longer than in the
+above example:
+@example
+mkdir /usr/local/src/bash/@{old,new,dist,bugs@}
+@end example
+or
+@example
+chown root /usr/@{ucb/@{ex,edit@},lib/@{ex?.?*,how_ex@}@}
+@end example
+
+@node Tilde Expansion
+@subsection Tilde Expansion
+@cindex tilde expansion
+@cindex expansion, tilde
+
+If a word begins with an unquoted tilde character (@samp{~}), all of the
+characters up to the first unquoted slash (or all characters,
+if there is no unquoted slash) are considered a @var{tilde-prefix}.
+If none of the characters in the tilde-prefix are quoted, the
+characters in the tilde-prefix following the tilde are treated as a
+possible @var{login name}.
+If this login name is the null string, the tilde is replaced with the
+value of the @env{HOME} shell variable.
+If @env{HOME} is unset, the home directory of the user executing the
+shell is substituted instead.
+Otherwise, the tilde-prefix is replaced with the home directory
+associated with the specified login name.
+
+If the tilde-prefix is @samp{~+}, the value of
+the shell variable @env{PWD} replaces the tilde-prefix.
+If the tilde-prefix is @samp{~-}, the value of the shell variable
+@env{OLDPWD}, if it is set, is substituted.
+
+If the characters following the tilde in the tilde-prefix consist of a
+number @var{N}, optionally prefixed by a @samp{+} or a @samp{-},
+the tilde-prefix is replaced with the
+corresponding element from the directory stack, as it would be displayed
+by the @code{dirs} builtin invoked with the characters following tilde
+in the tilde-prefix as an argument (@pxref{The Directory Stack}).
+If the tilde-prefix, sans the tilde, consists of a number without a
+leading @samp{+} or @samp{-}, @samp{+} is assumed.
+
+If the login name is invalid, or the tilde expansion fails, the word is
+left unchanged.
+
+Each variable assignment is checked for unquoted tilde-prefixes immediately
+following a @samp{:} or the first @samp{=}.
+In these cases, tilde expansion is also performed.
+Consequently, one may use file names with tildes in assignments to
+@env{PATH}, @env{MAILPATH}, and @env{CDPATH},
+and the shell assigns the expanded value.
+
+The following table shows how Bash treats unquoted tilde-prefixes:
+
+@table @code
+@item ~
+The value of @code{$HOME}
+@item ~/foo
+@file{$HOME/foo}
+
+@item ~fred/foo
+The subdirectory @code{foo} of the home directory of the user
+@code{fred}
+
+@item ~+/foo
+@file{$PWD/foo}
+
+@item ~-/foo
+@file{$@{OLDPWD-'~-'@}/foo}
+
+@item ~@var{N}
+The string that would be displayed by @samp{dirs +@var{N}}
+
+@item ~+@var{N}
+The string that would be displayed by @samp{dirs +@var{N}}
+
+@item ~-@var{N}
+The string that would be displayed by @samp{dirs -@var{N}}
+
+@end table
+
+@node Shell Parameter Expansion
+@subsection Shell Parameter Expansion
+@cindex parameter expansion
+@cindex expansion, parameter
+
+The @samp{$} character introduces parameter expansion,
+command substitution, or arithmetic expansion. The parameter name
+or symbol to be expanded may be enclosed in braces, which
+are optional but serve to protect the variable to be expanded from
+characters immediately following it which could be
+interpreted as part of the name.
+
+When braces are used, the matching ending brace is the first @samp{@}}
+not escaped by a backslash or within a quoted string, and not within an
+embedded arithmetic expansion, command substitution, or parameter
+expansion.
+
+The basic form of parameter expansion is $@{@var{parameter}@}.
+The value of @var{parameter} is substituted. The braces are required
+when @var{parameter}
+is a positional parameter with more than one digit,
+or when @var{parameter}
+is followed by a character that is not to be
+interpreted as part of its name.
+
+If the first character of @var{parameter} is an exclamation point (!),
+a level of variable indirection is introduced.
+Bash uses the value of the variable formed from the rest of
+@var{parameter} as the name of the variable; this variable is then
+expanded and that value is used in the rest of the substitution, rather
+than the value of @var{parameter} itself.
+This is known as @code{indirect expansion}.
+The exceptions to this are the expansions of $@{!@var{prefix}@*@}
+and $@{!@var{name}[@@]@}
+described below.
+The exclamation point must immediately follow the left brace in order to
+introduce indirection.
+
+In each of the cases below, @var{word} is subject to tilde expansion,
+parameter expansion, command substitution, and arithmetic expansion.
+
+When not performing substring expansion, using the form described
+below, Bash tests for a parameter that is unset or null.
+Omitting the colon results in a test only for a parameter that is unset.
+Put another way, if the colon is included,
+the operator tests for both @var{parameter}'s existence and that its value
+is not null; if the colon is omitted, the operator tests only for existence.
+
+@table @code
+
+@item $@{@var{parameter}:@minus{}@var{word}@}
+If @var{parameter} is unset or null, the expansion of
+@var{word} is substituted. Otherwise, the value of
+@var{parameter} is substituted.
+
+@item $@{@var{parameter}:=@var{word}@}
+If @var{parameter}
+is unset or null, the expansion of @var{word}
+is assigned to @var{parameter}.
+The value of @var{parameter} is then substituted.
+Positional parameters and special parameters may not be assigned to
+in this way.
+
+@item $@{@var{parameter}:?@var{word}@}
+If @var{parameter}
+is null or unset, the expansion of @var{word} (or a message
+to that effect if @var{word}
+is not present) is written to the standard error and the shell, if it
+is not interactive, exits. Otherwise, the value of @var{parameter} is
+substituted.
+
+@item $@{@var{parameter}:+@var{word}@}
+If @var{parameter}
+is null or unset, nothing is substituted, otherwise the expansion of
+@var{word} is substituted.
+
+@item $@{@var{parameter}:@var{offset}@}
+@itemx $@{@var{parameter}:@var{offset}:@var{length}@}
+Expands to up to @var{length} characters of @var{parameter}
+starting at the character specified by @var{offset}.
+If @var{length} is omitted, expands to the substring of
+@var{parameter} starting at the character specified by @var{offset}.
+@var{length} and @var{offset} are arithmetic expressions
+(@pxref{Shell Arithmetic}).
+This is referred to as Substring Expansion.
+
+If @var{offset} evaluates to a number less than zero, the value
+is used as an offset from the end of the value of @var{parameter}.
+If @var{length} evaluates to a number less than zero, and @var{parameter}
+is not @samp{@@} and not an indexed or associative array, it is interpreted
+as an offset from the end of the value of @var{parameter} rather than
+a number of characters, and the expansion is the characters between the
+two offsets.
+If @var{parameter} is @samp{@@}, the result is @var{length} positional
+parameters beginning at @var{offset}.
+If @var{parameter} is an indexed array name subscripted
+by @samp{@@} or @samp{*}, the result is the @var{length}
+members of the array beginning with @code{$@{@var{parameter}[@var{offset}]@}}.
+A negative @var{offset} is taken relative to one greater than the maximum
+index of the specified array.
+Substring expansion applied to an associative array produces undefined
+results.
+
+Note that a negative offset must be separated from the colon by at least
+one space to avoid being confused with the @samp{:-} expansion.
+Substring indexing is zero-based unless the positional parameters
+are used, in which case the indexing starts at 1 by default.
+If @var{offset} is 0, and the positional parameters are used, @code{$@@} is
+prefixed to the list.
+
+@item $@{!@var{prefix}*@}
+@itemx $@{!@var{prefix}@@@}
+Expands to the names of variables whose names begin with @var{prefix},
+separated by the first character of the @env{IFS} special variable.
+When @samp{@@} is used and the expansion appears within double quotes, each
+variable name expands to a separate word.
+
+@item $@{!@var{name}[@@]@}
+@itemx $@{!@var{name}[*]@}
+If @var{name} is an array variable, expands to the list of array indices
+(keys) assigned in @var{name}.
+If @var{name} is not an array, expands to 0 if @var{name} is set and null
+otherwise.
+When @samp{@@} is used and the expansion appears within double quotes, each
+key expands to a separate word.
+
+@item $@{#@var{parameter}@}
+The length in characters of the expanded value of @var{parameter} is
+substituted.
+If @var{parameter} is @samp{*} or @samp{@@}, the value substituted
+is the number of positional parameters.
+If @var{parameter} is an array name subscripted by @samp{*} or @samp{@@},
+the value substituted is the number of elements in the array.
+
+@item $@{@var{parameter}#@var{word}@}
+@itemx $@{@var{parameter}##@var{word}@}
+The @var{word}
+is expanded to produce a pattern just as in filename
+expansion (@pxref{Filename Expansion}). If the pattern matches
+the beginning of the expanded value of @var{parameter},
+then the result of the expansion is the expanded value of @var{parameter}
+with the shortest matching pattern (the @samp{#} case) or the
+longest matching pattern (the @samp{##} case) deleted.
+If @var{parameter} is @samp{@@} or @samp{*},
+the pattern removal operation is applied to each positional
+parameter in turn, and the expansion is the resultant list.
+If @var{parameter} is an array variable subscripted with
+@samp{@@} or @samp{*},
+the pattern removal operation is applied to each member of the
+array in turn, and the expansion is the resultant list.
+
+@item $@{@var{parameter}%@var{word}@}
+@itemx $@{@var{parameter}%%@var{word}@}
+The @var{word} is expanded to produce a pattern just as in
+filename expansion.
+If the pattern matches a trailing portion of the expanded value of
+@var{parameter}, then the result of the expansion is the value of
+@var{parameter} with the shortest matching pattern (the @samp{%} case)
+or the longest matching pattern (the @samp{%%} case) deleted.
+If @var{parameter} is @samp{@@} or @samp{*},
+the pattern removal operation is applied to each positional
+parameter in turn, and the expansion is the resultant list.
+If @var{parameter}
+is an array variable subscripted with @samp{@@} or @samp{*},
+the pattern removal operation is applied to each member of the
+array in turn, and the expansion is the resultant list.
+
+@item $@{@var{parameter}/@var{pattern}/@var{string}@}
+
+The @var{pattern} is expanded to produce a pattern just as in
+filename expansion.
+@var{Parameter} is expanded and the longest match of @var{pattern}
+against its value is replaced with @var{string}.
+If @var{pattern} begins with @samp{/}, all matches of @var{pattern} are
+replaced with @var{string}. Normally only the first match is replaced.
+If @var{pattern} begins with @samp{#}, it must match at the beginning
+of the expanded value of @var{parameter}.
+If @var{pattern} begins with @samp{%}, it must match at the end
+of the expanded value of @var{parameter}.
+If @var{string} is null, matches of @var{pattern} are deleted
+and the @code{/} following @var{pattern} may be omitted.
+If @var{parameter} is @samp{@@} or @samp{*},
+the substitution operation is applied to each positional
+parameter in turn, and the expansion is the resultant list.
+If @var{parameter}
+is an array variable subscripted with @samp{@@} or @samp{*},
+the substitution operation is applied to each member of the
+array in turn, and the expansion is the resultant list.
+
+@item $@{@var{parameter}^@var{pattern}@}
+@itemx $@{@var{parameter}^^@var{pattern}@}
+@itemx $@{@var{parameter},@var{pattern}@}
+@itemx $@{@var{parameter},,@var{pattern}@}
+This expansion modifies the case of alphabetic characters in @var{parameter}.
+The @var{pattern} is expanded to produce a pattern just as in
+filename expansion.
+The @samp{^} operator converts lowercase letters matching @var{pattern}
+to uppercase; the @samp{,} operator converts matching uppercase letters
+to lowercase.
+The @samp{^^} and @samp{,,} expansions convert each matched character in the
+expanded value; the @samp{^} and @samp{,} expansions match and convert only
+the first character in the expanded value.
+If @var{pattern} is omitted, it is treated like a @samp{?}, which matches
+every character.
+If @var{parameter} is @samp{@@} or @samp{*},
+the case modification operation is applied to each positional
+parameter in turn, and the expansion is the resultant list.
+If @var{parameter}
+is an array variable subscripted with @samp{@@} or @samp{*},
+the case modification operation is applied to each member of the
+array in turn, and the expansion is the resultant list.
+
+@end table
+
+@node Command Substitution
+@subsection Command Substitution
+@cindex command substitution
+
+Command substitution allows the output of a command to replace
+the command itself.
+Command substitution occurs when a command is enclosed as follows:
+@example
+$(@var{command})
+@end example
+@noindent
+or
+@example
+`@var{command}`
+@end example
+
+@noindent
+Bash performs the expansion by executing @var{command} and
+replacing the command substitution with the standard output of the
+command, with any trailing newlines deleted.
+Embedded newlines are not deleted, but they may be removed during
+word splitting.
+The command substitution @code{$(cat @var{file})} can be
+replaced by the equivalent but faster @code{$(< @var{file})}.
+
+When the old-style backquote form of substitution is used,
+backslash retains its literal meaning except when followed by
+@samp{$}, @samp{`}, or @samp{\}.
+The first backquote not preceded by a backslash terminates the
+command substitution.
+When using the @code{$(@var{command})} form, all characters between
+the parentheses make up the command; none are treated specially.
+
+Command substitutions may be nested. To nest when using the backquoted
+form, escape the inner backquotes with backslashes.
+
+If the substitution appears within double quotes, word splitting and
+filename expansion are not performed on the results.
+
+@node Arithmetic Expansion
+@subsection Arithmetic Expansion
+@cindex expansion, arithmetic
+@cindex arithmetic expansion
+
+Arithmetic expansion allows the evaluation of an arithmetic expression
+and the substitution of the result. The format for arithmetic expansion is:
+
+@example
+$(( @var{expression} ))
+@end example
+
+The expression is treated as if it were within double quotes, but
+a double quote inside the parentheses is not treated specially.
+All tokens in the expression undergo parameter expansion, command
+substitution, and quote removal.
+Arithmetic expansions may be nested.
+
+The evaluation is performed according to the rules listed below
+(@pxref{Shell Arithmetic}).
+If the expression is invalid, Bash prints a message indicating
+failure to the standard error and no substitution occurs.
+
+@node Process Substitution
+@subsection Process Substitution
+@cindex process substitution
+
+Process substitution is supported on systems that support named
+pipes (@sc{fifo}s) or the @file{/dev/fd} method of naming open files.
+It takes the form of
+@example
+<(@var{list})
+@end example
+@noindent
+or
+@example
+>(@var{list})
+@end example
+@noindent
+The process @var{list} is run with its input or output connected to a
+@sc{fifo} or some file in @file{/dev/fd}. The name of this file is
+passed as an argument to the current command as the result of the
+expansion. If the @code{>(@var{list})} form is used, writing to
+the file will provide input for @var{list}. If the
+@code{<(@var{list})} form is used, the file passed as an
+argument should be read to obtain the output of @var{list}.
+Note that no space may appear between the @code{<} or @code{>}
+and the left parenthesis, otherwise the construct would be interpreted
+as a redirection.
+
+When available, process substitution is performed simultaneously with
+parameter and variable expansion, command substitution, and arithmetic
+expansion.
+
+@node Word Splitting
+@subsection Word Splitting
+@cindex word splitting
+
+The shell scans the results of parameter expansion, command substitution,
+and arithmetic expansion that did not occur within double quotes for
+word splitting.
+
+The shell treats each character of @env{$IFS} as a delimiter, and splits
+the results of the other expansions into words on these characters.
+If @env{IFS} is unset, or its value is exactly @code{<space><tab><newline>},
+the default, then sequences of
+@code{ <space>}, @code{<tab>}, and @code{<newline>}
+at the beginning and end of the results of the previous
+expansions are ignored, and any sequence of @env{IFS}
+characters not at the beginning or end serves to delimit words.
+If @env{IFS} has a value other than the default, then sequences of
+the whitespace characters @code{space} and @code{tab}
+are ignored at the beginning and end of the
+word, as long as the whitespace character is in the
+value of @env{IFS} (an @env{IFS} whitespace character).
+Any character in @env{IFS} that is not @env{IFS}
+whitespace, along with any adjacent @env{IFS}
+whitespace characters, delimits a field. A sequence of @env{IFS}
+whitespace characters is also treated as a delimiter.
+If the value of @env{IFS} is null, no word splitting occurs.
+
+Explicit null arguments (@code{""} or @code{''}) are retained.
+Unquoted implicit null arguments, resulting from the expansion of
+parameters that have no values, are removed.
+If a parameter with no value is expanded within double quotes, a
+null argument results and is retained.
+
+Note that if no expansion occurs, no splitting
+is performed.
+
+@node Filename Expansion
+@subsection Filename Expansion
+@menu
+* Pattern Matching:: How the shell matches patterns.
+@end menu
+@cindex expansion, filename
+@cindex expansion, pathname
+@cindex filename expansion
+@cindex pathname expansion
+
+After word splitting, unless the @option{-f} option has been set
+(@pxref{The Set Builtin}), Bash scans each word for the characters
+@samp{*}, @samp{?}, and @samp{[}.
+If one of these characters appears, then the word is
+regarded as a @var{pattern},
+and replaced with an alphabetically sorted list of
+file names matching the pattern (@pxref{Pattern Matching}).
+If no matching file names are found,
+and the shell option @code{nullglob} is disabled, the word is left
+unchanged.
+If the @code{nullglob} option is set, and no matches are found, the word
+is removed.
+If the @code{failglob} shell option is set, and no matches are found,
+an error message is printed and the command is not executed.
+If the shell option @code{nocaseglob} is enabled, the match is performed
+without regard to the case of alphabetic characters.
+
+When a pattern is used for filename expansion, the character @samp{.}
+at the start of a filename or immediately following a slash
+must be matched explicitly, unless the shell option @code{dotglob} is set.
+When matching a file name, the slash character must always be
+matched explicitly.
+In other cases, the @samp{.} character is not treated specially.
+
+See the description of @code{shopt} in @ref{The Shopt Builtin},
+for a description of the @code{nocaseglob}, @code{nullglob},
+@code{failglob}, and @code{dotglob} options.
+
+The @env{GLOBIGNORE}
+shell variable may be used to restrict the set of filenames matching a
+pattern. If @env{GLOBIGNORE}
+is set, each matching filename that also matches one of the patterns in
+@env{GLOBIGNORE} is removed from the list of matches. The filenames
+@file{.} and @file{..}
+are always ignored when @env{GLOBIGNORE}
+is set and not null.
+However, setting @env{GLOBIGNORE} to a non-null value has the effect of
+enabling the @code{dotglob}
+shell option, so all other filenames beginning with a
+@samp{.} will match.
+To get the old behavior of ignoring filenames beginning with a
+@samp{.}, make @samp{.*} one of the patterns in @env{GLOBIGNORE}.
+The @code{dotglob} option is disabled when @env{GLOBIGNORE}
+is unset.
+
+@node Pattern Matching
+@subsubsection Pattern Matching
+@cindex pattern matching
+@cindex matching, pattern
+
+Any character that appears in a pattern, other than the special pattern
+characters described below, matches itself.
+The @sc{nul} character may not occur in a pattern.
+A backslash escapes the following character; the
+escaping backslash is discarded when matching.
+The special pattern characters must be quoted if they are to be matched
+literally.
+
+The special pattern characters have the following meanings:
+@table @code
+@item *
+Matches any string, including the null string.
+When the @code{globstar} shell option is enabled, and @samp{*} is used in
+a filename expansion context, two adjacent @samp{*}s used as a single
+pattern will match all files and zero or more directories and
+subdirectories.
+If followed by a @samp{/}, two adjacent @samp{*}s will match only
+directories and subdirectories.
+@item ?
+Matches any single character.
+@item [@dots{}]
+Matches any one of the enclosed characters. A pair of characters
+separated by a hyphen denotes a @var{range expression};
+any character that sorts between those two characters, inclusive,
+using the current locale's collating sequence and character set,
+is matched. If the first character following the
+@samp{[} is a @samp{!} or a @samp{^}
+then any character not enclosed is matched. A @samp{@minus{}}
+may be matched by including it as the first or last character
+in the set. A @samp{]} may be matched by including it as the first
+character in the set.
+The sorting order of characters in range expressions is determined by
+the current locale and the values of the
+@env{LC_COLLATE} and @env{LC_ALL} shell variables, if set.
+
+For example, in the default C locale, @samp{[a-dx-z]} is equivalent to
+@samp{[abcdxyz]}. Many locales sort characters in dictionary order, and in
+these locales @samp{[a-dx-z]} is typically not equivalent to @samp{[abcdxyz]};
+it might be equivalent to @samp{[aBbCcDdxXyYz]}, for example. To obtain
+the traditional interpretation of ranges in bracket expressions, you can
+force the use of the C locale by setting the @env{LC_COLLATE} or
+@env{LC_ALL} environment variable to the value @samp{C}, or enable the
+@code{globasciiranges} shell option.
+
+Within @samp{[} and @samp{]}, @var{character classes} can be specified
+using the syntax
+@code{[:}@var{class}@code{:]}, where @var{class} is one of the
+following classes defined in the @sc{posix} standard:
+@example
+alnum alpha ascii blank cntrl digit graph lower
+print punct space upper word xdigit
+@end example
+@noindent
+A character class matches any character belonging to that class.
+The @code{word} character class matches letters, digits, and the character
+@samp{_}.
+
+Within @samp{[} and @samp{]}, an @var{equivalence class} can be
+specified using the syntax @code{[=}@var{c}@code{=]}, which
+matches all characters with the same collation weight (as defined
+by the current locale) as the character @var{c}.
+
+Within @samp{[} and @samp{]}, the syntax @code{[.}@var{symbol}@code{.]}
+matches the collating symbol @var{symbol}.
+@end table
+
+If the @code{extglob} shell option is enabled using the @code{shopt}
+builtin, several extended pattern matching operators are recognized.
+In the following description, a @var{pattern-list} is a list of one
+or more patterns separated by a @samp{|}.
+Composite patterns may be formed using one or more of the following
+sub-patterns:
+
+@table @code
+@item ?(@var{pattern-list})
+Matches zero or one occurrence of the given patterns.
+
+@item *(@var{pattern-list})
+Matches zero or more occurrences of the given patterns.
+
+@item +(@var{pattern-list})
+Matches one or more occurrences of the given patterns.
+
+@item @@(@var{pattern-list})
+Matches one of the given patterns.
+
+@item !(@var{pattern-list})
+Matches anything except one of the given patterns.
+@end table
+
+@node Quote Removal
+@subsection Quote Removal
+
+After the preceding expansions, all unquoted occurrences of the
+characters @samp{\}, @samp{'}, and @samp{"} that did not
+result from one of the above expansions are removed.
+
+@node Redirections
+@section Redirections
+@cindex redirection
+
+Before a command is executed, its input and output
+may be @var{redirected}
+using a special notation interpreted by the shell.
+Redirection may also be used to open and close files for the
+current shell execution 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 @{@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
+descriptor 0). If the first character of the redirection operator
+is @samp{>}, the redirection refers to the standard output (file
+descriptor 1).
+
+The word following the redirection operator in the following
+descriptions, unless otherwise noted, is subjected to brace expansion,
+tilde expansion, parameter expansion, command substitution, arithmetic
+expansion, quote removal, filename expansion, and word splitting.
+If it expands to more than one word, Bash reports an error.
+
+Note that the order of redirections is significant. For example,
+the command
+@example
+ls > @var{dirlist} 2>&1
+@end example
+@noindent
+directs both standard output (file descriptor 1) and standard error
+(file descriptor 2) to the file @var{dirlist}, while the command
+@example
+ls 2>&1 > @var{dirlist}
+@end example
+@noindent
+directs only the standard output to file @var{dirlist},
+because the standard error was made a copy of the standard output
+before the standard output was redirected to @var{dirlist}.
+
+Bash handles several filenames specially when they are used in
+redirections, as described in the following table:
+
+@table @code
+@item /dev/fd/@var{fd}
+If @var{fd} is a valid integer, file descriptor @var{fd} is duplicated.
+
+@item /dev/stdin
+File descriptor 0 is duplicated.
+
+@item /dev/stdout
+File descriptor 1 is duplicated.
+
+@item /dev/stderr
+File descriptor 2 is duplicated.
+
+@item /dev/tcp/@var{host}/@var{port}
+If @var{host} is a valid hostname or Internet address, and @var{port}
+is an integer port number or service name, Bash attempts to open a TCP
+connection to the corresponding socket.
+
+@item /dev/udp/@var{host}/@var{port}
+If @var{host} is a valid hostname or Internet address, and @var{port}
+is an integer port number or service name, Bash attempts to open a UDP
+connection to the corresponding socket.
+
+@end table
+
+A failure to open or create a file causes the redirection to fail.
+
+Redirections using file descriptors greater than 9 should be used with
+care, as they may conflict with file descriptors the shell uses
+internally.
+
+@subsection Redirecting Input
+Redirection of input causes the file whose name results from
+the expansion of @var{word}
+to be opened for reading on file descriptor @code{n},
+or the standard input (file descriptor 0) if @code{n}
+is not specified.
+
+The general format for redirecting input is:
+@example
+[@var{n}]<@var{word}
+@end example
+
+@subsection Redirecting Output
+Redirection of output causes the file whose name results from
+the expansion of @var{word}
+to be opened for writing on file descriptor @var{n},
+or the standard output (file descriptor 1) if @var{n}
+is not specified. If the file does not exist it is created;
+if it does exist it is truncated to zero size.
+
+The general format for redirecting output is:
+@example
+[@var{n}]>[|]@var{word}
+@end example
+
+If the redirection operator is @samp{>}, and the @code{noclobber}
+option to the @code{set} builtin has been enabled, the redirection
+will fail if the file whose name results from the expansion of
+@var{word} exists and is a regular file.
+If the redirection operator is @samp{>|}, or the redirection operator is
+@samp{>} and the @code{noclobber} option is not enabled, the redirection
+is attempted even if the file named by @var{word} exists.
+
+@subsection Appending Redirected Output
+Redirection of output in this fashion
+causes the file whose name results from
+the expansion of @var{word}
+to be opened for appending on file descriptor @var{n},
+or the standard output (file descriptor 1) if @var{n}
+is not specified. If the file does not exist it is created.
+
+The general format for appending output is:
+@example
+[@var{n}]>>@var{word}
+@end example
+
+@subsection Redirecting Standard Output and Standard Error
+This construct allows both the
+standard output (file descriptor 1) and
+the standard error output (file descriptor 2)
+to be redirected to the file whose name is the
+expansion of @var{word}.
+
+There are two formats for redirecting standard output and
+standard error:
+@example
+&>@var{word}
+@end example
+@noindent
+and
+@example
+>&@var{word}
+@end example
+@noindent
+Of the two forms, the first is preferred.
+This is semantically equivalent to
+@example
+>@var{word} 2>&1
+@end example
+(see Duplicating File Descriptors below).
+
+@subsection Appending Standard Output and Standard Error
+This construct allows both the
+standard output (file descriptor 1) and
+the standard error output (file descriptor 2)
+to be appended to the file whose name is the
+expansion of @var{word}.
+
+The format for appending standard output and standard error is:
+@example
+&>>@var{word}
+@end example
+@noindent
+This is semantically equivalent to
+@example
+>>@var{word} 2>&1
+@end example
+(see Duplicating File Descriptors below).
+
+@subsection Here Documents
+This type of redirection instructs the shell to read input from the
+current source until a line containing only @var{word}
+(with no trailing blanks) is seen. All of
+the lines read up to that point are then used as the standard
+input for a command.
+
+The format of here-documents is:
+@example
+<<[@minus{}]@var{word}
+ @var{here-document}
+@var{delimiter}
+@end example
+
+No parameter expansion, command substitution, arithmetic expansion,
+or filename expansion is performed on
+@var{word}. If any characters in @var{word} are quoted, the
+@var{delimiter} is the result of quote removal on @var{word},
+and the lines in the here-document are not expanded.
+If @var{word} is unquoted,
+all lines of the here-document are subjected to parameter expansion,
+command substitution, and arithmetic expansion. In the latter
+case, the character sequence @code{\newline} is ignored, and @samp{\}
+must be used to quote the characters
+@samp{\}, @samp{$}, and @samp{`}.
+
+If the redirection operator is @samp{<<-},
+then all leading tab characters are stripped from input lines and the
+line containing @var{delimiter}.
+This allows here-documents within shell scripts to be indented in a
+natural fashion.
+
+@subsection Here Strings
+A variant of here documents, the format is:
+@example
+<<< @var{word}
+@end example
+
+The @var{word}
+is expanded as described above, with the exception that
+pathname expansion is not applied, and supplied as a single string
+to the command on its standard input.
+
+@subsection Duplicating File Descriptors
+The redirection operator
+@example
+[@var{n}]<&@var{word}
+@end example
+@noindent
+is used to duplicate input file descriptors.
+If @var{word}
+expands to one or more digits, the file descriptor denoted by @var{n}
+is made to be a copy of that file descriptor.
+If the digits in @var{word} do not specify a file descriptor open for
+input, a redirection error occurs.
+If @var{word}
+evaluates to @samp{-}, file descriptor @var{n} is closed. If
+@var{n} is not specified, the standard input (file descriptor 0) is used.
+
+The operator
+@example
+[@var{n}]>&@var{word}
+@end example
+@noindent
+is used similarly to duplicate output file descriptors. If
+@var{n} is not specified, the standard output (file descriptor 1) is used.
+If the digits in @var{word} do not specify a file descriptor open for
+output, a redirection error occurs.
+As a special case, if @var{n} is omitted, and @var{word} does not
+expand to one or more digits, the standard output and standard
+error are redirected as described previously.
+
+@subsection Moving File Descriptors
+The redirection operator
+@example
+[@var{n}]<&@var{digit}-
+@end example
+@noindent
+moves the file descriptor @var{digit} to file descriptor @var{n},
+or the standard input (file descriptor 0) if @var{n} is not specified.
+@var{digit} is closed after being duplicated to @var{n}.
+
+Similarly, the redirection operator
+@example
+[@var{n}]>&@var{digit}-
+@end example
+@noindent
+moves the file descriptor @var{digit} to file descriptor @var{n},
+or the standard output (file descriptor 1) if @var{n} is not specified.
+
+@subsection Opening File Descriptors for Reading and Writing
+The redirection operator
+@example
+[@var{n}]<>@var{word}
+@end example
+@noindent
+causes the file whose name is the expansion of @var{word}
+to be opened for both reading and writing on file descriptor
+@var{n}, or on file descriptor 0 if @var{n}
+is not specified. If the file does not exist, it is created.
+
+@node Executing Commands
+@section Executing Commands
+
+@menu
+* Simple Command Expansion:: How Bash expands simple commands before
+ executing them.
+* Command Search and Execution:: How Bash finds commands and runs them.
+* Command Execution Environment:: The environment in which Bash
+ executes commands that are not
+ shell builtins.
+* Environment:: The environment given to a command.
+* Exit Status:: The status returned by commands and how Bash
+ interprets it.
+* Signals:: What happens when Bash or a command it runs
+ receives a signal.
+@end menu
+
+@node Simple Command Expansion
+@subsection Simple Command Expansion
+@cindex command expansion
+
+When a simple command is executed, the shell performs the following
+expansions, assignments, and redirections, from left to right.
+
+@enumerate
+@item
+The words that the parser has marked as variable assignments (those
+preceding the command name) and redirections are saved for later
+processing.
+
+@item
+The words that are not variable assignments or redirections are
+expanded (@pxref{Shell Expansions}).
+If any words remain after expansion, the first word
+is taken to be the name of the command and the remaining words are
+the arguments.
+
+@item
+Redirections are performed as described above (@pxref{Redirections}).
+
+@item
+The text after the @samp{=} in each variable assignment undergoes tilde
+expansion, parameter expansion, command substitution, arithmetic expansion,
+and quote removal before being assigned to the variable.
+@end enumerate
+
+If no command name results, the variable assignments affect the current
+shell environment. Otherwise, the variables are added to the environment
+of the executed command and do not affect the current shell environment.
+If any of the assignments attempts to assign a value to a readonly variable,
+an error occurs, and the command exits with a non-zero status.
+
+If no command name results, redirections are performed, but do not
+affect the current shell environment. A redirection error causes the
+command to exit with a non-zero status.
+
+If there is a command name left after expansion, execution proceeds as
+described below. Otherwise, the command exits. If one of the expansions
+contained a command substitution, the exit status of the command is
+the exit status of the last command substitution performed. If there
+were no command substitutions, the command exits with a status of zero.
+
+@node Command Search and Execution
+@subsection Command Search and Execution
+@cindex command execution
+@cindex command search
+
+After a command has been split into words, if it results in a
+simple command and an optional list of arguments, the following
+actions are taken.
+
+@enumerate
+@item
+If the command name contains no slashes, the shell attempts to
+locate it. If there exists a shell function by that name, that
+function is invoked as described in @ref{Shell Functions}.
+
+@item
+If the name does not match a function, the shell searches for
+it in the list of shell builtins. If a match is found, that
+builtin is invoked.
+
+@item
+If the name is neither a shell function nor a builtin,
+and contains no slashes, Bash searches each element of
+@env{$PATH} for a directory containing an executable file
+by that name. Bash uses a hash table to remember the full
+pathnames of executable files to avoid multiple @env{PATH} searches
+(see the description of @code{hash} in @ref{Bourne Shell Builtins}).
+A full search of the directories in @env{$PATH}
+is performed only if the command is not found in the hash table.
+If the search is unsuccessful, the shell searches for a defined shell
+function named @code{command_not_found_handle}.
+If that function exists, it is invoked with the original command and
+the original command's arguments as its arguments, and the function's
+exit status becomes the exit status of the shell.
+If that function is not defined, the shell prints an error
+message and returns an exit status of 127.
+
+@item
+If the search is successful, or if the command name contains
+one or more slashes, the shell executes the named program in
+a separate execution environment.
+Argument 0 is set to the name given, and the remaining arguments
+to the command are set to the arguments supplied, if any.
+
+@item
+If this execution fails because the file is not in executable
+format, and the file is not a directory, it is assumed to be a
+@var{shell script} and the shell executes it as described in
+@ref{Shell Scripts}.
+
+@item
+If the command was not begun asynchronously, the shell waits for
+the command to complete and collects its exit status.
+
+@end enumerate
+
+@node Command Execution Environment
+@subsection Command Execution Environment
+@cindex execution environment
+
+The shell has an @var{execution environment}, which consists of the
+following:
+
+@itemize @bullet
+@item
+open files inherited by the shell at invocation, as modified by
+redirections supplied to the @code{exec} builtin
+
+@item
+the current working directory as set by @code{cd}, @code{pushd}, or
+@code{popd}, or inherited by the shell at invocation
+
+@item
+the file creation mode mask as set by @code{umask} or inherited from
+the shell's parent
+
+@item
+current traps set by @code{trap}
+
+@item
+shell parameters that are set by variable assignment or with @code{set}
+or inherited from the shell's parent in the environment
+
+@item
+shell functions defined during execution or inherited from the shell's
+parent in the environment
+
+@item
+options enabled at invocation (either by default or with command-line
+arguments) or by @code{set}
+
+@item
+options enabled by @code{shopt} (@pxref{The Shopt Builtin})
+
+@item
+shell aliases defined with @code{alias} (@pxref{Aliases})
+
+@item
+various process @sc{id}s, including those of background jobs
+(@pxref{Lists}), the value of @code{$$}, and the value of
+@env{$PPID}
+
+@end itemize
+
+When a simple command other than a builtin or shell function
+is to be executed, it
+is invoked in a separate execution environment that consists of
+the following. Unless otherwise noted, the values are inherited
+from the shell.
+
+@itemize @bullet
+@item
+the shell's open files, plus any modifications and additions specified
+by redirections to the command
+
+@item
+the current working directory
+
+@item
+the file creation mode mask
+
+@item
+shell variables and functions marked for export, along with variables
+exported for the command, passed in the environment (@pxref{Environment})
+
+@item
+traps caught by the shell are reset to the values inherited from the
+shell's parent, and traps ignored by the shell are ignored
+
+@end itemize
+
+A command invoked in this separate environment cannot affect the
+shell's execution environment.
+
+Command substitution, commands grouped with parentheses,
+and asynchronous commands are invoked in a
+subshell environment that is a duplicate of the shell environment,
+except that traps caught by the shell are reset to the values
+that the shell inherited from its parent at invocation. Builtin
+commands that are invoked as part of a pipeline are also executed
+in a subshell environment. Changes made to the subshell environment
+cannot affect the shell's execution environment.
+
+Subshells spawned to execute command substitutions inherit the value of
+the @option{-e} option from the parent shell. When not in @sc{posix} mode,
+Bash clears the @option{-e} option in such subshells.
+
+If a command is followed by a @samp{&} and job control is not active, the
+default standard input for the command is the empty file @file{/dev/null}.
+Otherwise, the invoked command inherits the file descriptors of the calling
+shell as modified by redirections.
+
+@node Environment
+@subsection Environment
+@cindex environment
+
+When a program is invoked it is given an array of strings
+called the @var{environment}.
+This is a list of name-value pairs, of the form @code{name=value}.
+
+Bash provides several ways to manipulate the environment.
+On invocation, the shell scans its own environment and
+creates a parameter for each name found, automatically marking
+it for @var{export}
+to child processes. Executed commands inherit the environment.
+The @code{export} and @samp{declare -x}
+commands allow parameters and functions to be added to and
+deleted from the environment. If the value of a parameter
+in the environment is modified, the new value becomes part
+of the environment, replacing the old. The environment
+inherited by any executed command consists of the shell's
+initial environment, whose values may be modified in the shell,
+less any pairs removed by the @code{unset} and @samp{export -n}
+commands, plus any additions via the @code{export} and
+@samp{declare -x} commands.
+
+The environment for any simple command
+or function may be augmented temporarily by prefixing it with
+parameter assignments, as described in @ref{Shell Parameters}.
+These assignment statements affect only the environment seen
+by that command.
+
+If the @option{-k} option is set (@pxref{The Set Builtin}), then all
+parameter assignments are placed in the environment for a command,
+not just those that precede the command name.
+
+When Bash invokes an external command, the variable @samp{$_}
+is set to the full path name of the command and passed to that
+command in its environment.
+
+@node Exit Status
+@subsection Exit Status
+@cindex exit status
+
+The exit status of an executed command is the value returned by the
+@var{waitpid} system call or equivalent function. Exit statuses
+fall between 0 and 255, though, as explained below, the shell may
+use values above 125 specially. Exit statuses from shell builtins and
+compound commands are also limited to this range. Under certain
+circumstances, the shell will use special values to indicate specific
+failure modes.
+
+For the shell's purposes, a command which exits with a
+zero exit status has succeeded.
+A non-zero exit status indicates failure.
+This seemingly counter-intuitive scheme is used so there
+is one well-defined way to indicate success and a variety of
+ways to indicate various failure modes.
+When a command terminates on a fatal signal whose number is @var{N},
+Bash uses the value 128+@var{N} as the exit status.
+
+If a command is not found, the child process created to
+execute it returns a status of 127. If a command is found
+but is not executable, the return status is 126.
+
+If a command fails because of an error during expansion or redirection,
+the exit status is greater than zero.
+
+The exit status is used by the Bash conditional commands
+(@pxref{Conditional Constructs}) and some of the list
+constructs (@pxref{Lists}).
+
+All of the Bash builtins return an exit status of zero if they succeed
+and a non-zero status on failure, so they may be used by the
+conditional and list constructs.
+All builtins return an exit status of 2 to indicate incorrect usage.
+
+@node Signals
+@subsection Signals
+@cindex signal handling
+
+When Bash is interactive, in the absence of any traps, it ignores
+@code{SIGTERM} (so that @samp{kill 0} does not kill an interactive shell),
+and @code{SIGINT}
+is caught and handled (so that the @code{wait} builtin is interruptible).
+When Bash receives a @code{SIGINT}, it breaks out of any executing loops.
+In all cases, Bash ignores @code{SIGQUIT}.
+If job control is in effect (@pxref{Job Control}), Bash
+ignores @code{SIGTTIN}, @code{SIGTTOU}, and @code{SIGTSTP}.
+
+Non-builtin commands started by Bash have signal handlers set to the
+values inherited by the shell from its parent.
+When job control is not in effect, asynchronous commands
+ignore @code{SIGINT} and @code{SIGQUIT} in addition to these inherited
+handlers.
+Commands run as a result of
+command substitution ignore the keyboard-generated job control signals
+@code{SIGTTIN}, @code{SIGTTOU}, and @code{SIGTSTP}.
+
+The shell exits by default upon receipt of a @code{SIGHUP}.
+Before exiting, an interactive shell resends the @code{SIGHUP} to
+all jobs, running or stopped.
+Stopped jobs are sent @code{SIGCONT} to ensure that they receive
+the @code{SIGHUP}.
+To prevent the shell from sending the @code{SIGHUP} signal to a
+particular job, it should be removed
+from the jobs table with the @code{disown}
+builtin (@pxref{Job Control Builtins}) or marked
+to not receive @code{SIGHUP} using @code{disown -h}.
+
+If the @code{huponexit} shell option has been set with @code{shopt}
+(@pxref{The Shopt Builtin}), Bash sends a @code{SIGHUP} to all jobs when
+an interactive login shell exits.
+
+If Bash is waiting for a command to complete and receives a signal
+for which a trap has been set, the trap will not be executed until
+the command completes.
+When Bash is waiting for an asynchronous
+command via the @code{wait} builtin, the reception of a signal for
+which a trap has been set will cause the @code{wait} builtin to return
+immediately with an exit status greater than 128, immediately after
+which the trap is executed.
+
+@node Shell Scripts
+@section Shell Scripts
+@cindex shell script
+
+A shell script is a text file containing shell commands. When such
+a file is used as the first non-option argument when invoking Bash,
+and neither the @option{-c} nor @option{-s} option is supplied
+(@pxref{Invoking Bash}),
+Bash reads and executes commands from the file, then exits. This
+mode of operation creates a non-interactive shell. The shell first
+searches for the file in the current directory, and looks in the
+directories in @env{$PATH} if not found there.
+
+When Bash runs
+a shell script, it sets the special parameter @code{0} to the name
+of the file, rather than the name of the shell, and the positional
+parameters are set to the remaining arguments, if any are given.
+If no additional arguments are supplied, the positional parameters
+are unset.
+
+A shell script may be made executable by using the @code{chmod} command
+to turn on the execute bit. When Bash finds such a file while
+searching the @env{$PATH} for a command, it spawns a subshell to
+execute it. In other words, executing
+@example
+filename @var{arguments}
+@end example
+@noindent
+is equivalent to executing
+@example
+bash filename @var{arguments}
+@end example
+
+@noindent
+if @code{filename} is an executable shell script.
+This subshell reinitializes itself, so that the effect is as if a
+new shell had been invoked to interpret the script, with the
+exception that the locations of commands remembered by the parent
+(see the description of @code{hash} in @ref{Bourne Shell Builtins})
+are retained by the child.
+
+Most versions of Unix make this a part of the operating system's command
+execution mechanism. If the first line of a script begins with
+the two characters @samp{#!}, the remainder of the line specifies
+an interpreter for the program.
+Thus, you can specify Bash, @code{awk}, Perl, or some other
+interpreter and write the rest of the script file in that language.
+
+The arguments to the interpreter
+consist of a single optional argument following the interpreter
+name on the first line of the script file, followed by the name of
+the script file, followed by the rest of the arguments. Bash
+will perform this action on operating systems that do not handle it
+themselves. Note that some older versions of Unix limit the interpreter
+name and argument to a maximum of 32 characters.
+
+Bash scripts often begin with @code{#! /bin/bash} (assuming that
+Bash has been installed in @file{/bin}), since this ensures that
+Bash will be used to interpret the script, even if it is executed
+under another shell.
+
+@node Shell Builtin Commands
+@chapter Shell Builtin Commands
+
+@menu
+* Bourne Shell Builtins:: Builtin commands inherited from the Bourne
+ Shell.
+* Bash Builtins:: Table of builtins specific to Bash.
+* Modifying Shell Behavior:: Builtins to modify shell attributes and
+ optional behavior.
+* Special Builtins:: Builtin commands classified specially by
+ POSIX.
+@end menu
+
+Builtin commands are contained within the shell itself.
+When the name of a builtin command is used as the first word of
+a simple command (@pxref{Simple Commands}), the shell executes
+the command directly, without invoking another program.
+Builtin commands are necessary to implement functionality impossible
+or inconvenient to obtain with separate utilities.
+
+This section briefly describes the builtins which Bash inherits from
+the Bourne Shell, as well as the builtin commands which are unique
+to or have been extended in Bash.
+
+Several builtin commands are described in other chapters: builtin
+commands which provide the Bash interface to the job control
+facilities (@pxref{Job Control Builtins}), the directory stack
+(@pxref{Directory Stack Builtins}), the command history
+(@pxref{Bash History Builtins}), and the programmable completion
+facilities (@pxref{Programmable Completion Builtins}).
+
+Many of the builtins have been extended by @sc{posix} or Bash.
+
+Unless otherwise noted, each builtin command documented as accepting
+options preceded by @samp{-} accepts @samp{--}
+to signify the end of the options.
+The @code{:}, @code{true}, @code{false}, and @code{test}
+builtins do not accept options and do not treat @samp{--} specially.
+The @code{exit}, @code{logout}, @code{break}, @code{continue}, @code{let},
+and @code{shift} builtins accept and process arguments beginning
+with @samp{-} without requiring @samp{--}.
+Other builtins that accept arguments but are not specified as accepting
+options interpret arguments beginning with @samp{-} as invalid options and
+require @samp{--} to prevent this interpretation.
+
+@node Bourne Shell Builtins
+@section Bourne Shell Builtins
+
+The following shell builtin commands are inherited from the Bourne Shell.
+These commands are implemented as specified by the @sc{posix} standard.
+
+@table @code
+@item : @r{(a colon)}
+@btindex :
+@example
+: [@var{arguments}]
+@end example
+Do nothing beyond expanding @var{arguments} and performing redirections.
+The return status is zero.
+
+@item . @r{(a period)}
+@btindex .
+@example
+. @var{filename} [@var{arguments}]
+@end example
+Read and execute commands from the @var{filename} argument in the
+current shell context. If @var{filename} does not contain a slash,
+the @env{PATH} variable is used to find @var{filename}.
+When Bash is not in @sc{posix} mode, the current directory is searched
+if @var{filename} is not found in @env{$PATH}.
+If any @var{arguments} are supplied, they become the positional
+parameters when @var{filename} is executed. Otherwise the positional
+parameters are unchanged.
+The return status is the exit status of the last command executed, or
+zero if no commands are executed. If @var{filename} is not found, or
+cannot be read, the return status is non-zero.
+This builtin is equivalent to @code{source}.
+
+@item break
+@btindex break
+@example
+break [@var{n}]
+@end example
+Exit from a @code{for}, @code{while}, @code{until}, or @code{select} loop.
+If @var{n} is supplied, the @var{n}th enclosing loop is exited.
+@var{n} must be greater than or equal to 1.
+The return status is zero unless @var{n} is not greater than or equal to 1.
+
+@item cd
+@btindex cd
+@example
+cd [-L|[-P [-e]]] [@var{directory}]
+@end example
+Change the current working directory to @var{directory}.
+If @var{directory} is not given, the value of the @env{HOME} shell
+variable is used.
+If the shell variable @env{CDPATH} exists, it is used as a search path.
+If @var{directory} begins with a slash, @env{CDPATH} is not used.
+
+The @option{-P} option means to not follow symbolic links; symbolic
+links are followed by default or with the @option{-L} option.
+If the @option{-e} option is supplied with @option{-P}
+and the current working directory cannot be successfully determined
+after a successful directory change, @code{cd} will return an unsuccessful
+status.
+If @var{directory} is @samp{-}, it is equivalent to @env{$OLDPWD}.
+
+If a non-empty directory name from @env{CDPATH} is used, or if
+@samp{-} is the first argument, and the directory change is
+successful, the absolute pathname of the new working directory is
+written to the standard output.
+
+The return status is zero if the directory is successfully changed,
+non-zero otherwise.
+
+@item continue
+@btindex continue
+@example
+continue [@var{n}]
+@end example
+Resume the next iteration of an enclosing @code{for}, @code{while},
+@code{until}, or @code{select} loop.
+If @var{n} is supplied, the execution of the @var{n}th enclosing loop
+is resumed.
+@var{n} must be greater than or equal to 1.
+The return status is zero unless @var{n} is not greater than or equal to 1.
+
+@item eval
+@btindex eval
+@example
+eval [@var{arguments}]
+@end example
+The arguments are concatenated together into a single command, which is
+then read and executed, and its exit status returned as the exit status
+of @code{eval}.
+If there are no arguments or only empty arguments, the return status is
+zero.
+
+@item exec
+@btindex exec
+@example
+exec [-cl] [-a @var{name}] [@var{command} [@var{arguments}]]
+@end example
+If @var{command}
+is supplied, it replaces the shell without creating a new process.
+If the @option{-l} option is supplied, the shell places a dash at the
+beginning of the zeroth argument passed to @var{command}.
+This is what the @code{login} program does.
+The @option{-c} option causes @var{command} to be executed with an empty
+environment.
+If @option{-a} is supplied, the shell passes @var{name} as the zeroth
+argument to @var{command}.
+If no @var{command} is specified, redirections may be used to affect
+the current shell environment. If there are no redirection errors, the
+return status is zero; otherwise the return status is non-zero.
+
+@item exit
+@btindex exit
+@example
+exit [@var{n}]
+@end example
+Exit the shell, returning a status of @var{n} to the shell's parent.
+If @var{n} is omitted, the exit status is that of the last command executed.
+Any trap on @code{EXIT} is executed before the shell terminates.
+
+@item export
+@btindex export
+@example
+export [-fn] [-p] [@var{name}[=@var{value}]]
+@end example
+Mark each @var{name} to be passed to child processes
+in the environment. If the @option{-f} option is supplied, the @var{name}s
+refer to shell functions; otherwise the names refer to shell variables.
+The @option{-n} option means to no longer mark each @var{name} for export.
+If no @var{names} are supplied, or if the @option{-p} option is given, a
+list of exported names is displayed.
+The @option{-p} option displays output in a form that may be reused as input.
+If a variable name is followed by =@var{value}, the value of
+the variable is set to @var{value}.
+
+The return status is zero unless an invalid option is supplied, one of
+the names is not a valid shell variable name, or @option{-f} is supplied
+with a name that is not a shell function.
+
+@item getopts
+@btindex getopts
+@example
+getopts @var{optstring} @var{name} [@var{args}]
+@end example
+@code{getopts} is used by shell scripts to parse positional parameters.
+@var{optstring} contains the option characters to be recognized; if a
+character is followed by a colon, the option is expected to have an
+argument, which should be separated from it by white space.
+The colon (@samp{:}) and question mark (@samp{?}) may not be
+used as option characters.
+Each time it is invoked, @code{getopts}
+places the next option in the shell variable @var{name}, initializing
+@var{name} if it does not exist,
+and the index of the next argument to be processed into the
+variable @env{OPTIND}.
+@env{OPTIND} is initialized to 1 each time the shell or a shell script
+is invoked.
+When an option requires an argument,
+@code{getopts} places that argument into the variable @env{OPTARG}.
+The shell does not reset @env{OPTIND} automatically; it must be manually
+reset between multiple calls to @code{getopts} within the same shell
+invocation if a new set of parameters is to be used.
+
+When the end of options is encountered, @code{getopts} exits with a
+return value greater than zero.
+@env{OPTIND} is set to the index of the first non-option argument,
+and @var{name} is set to @samp{?}.
+
+@code{getopts}
+normally parses the positional parameters, but if more arguments are
+given in @var{args}, @code{getopts} parses those instead.
+
+@code{getopts} can report errors in two ways. If the first character of
+@var{optstring} is a colon, @var{silent}
+error reporting is used. In normal operation diagnostic messages
+are printed when invalid options or missing option arguments are
+encountered.
+If the variable @env{OPTERR}
+is set to 0, no error messages will be displayed, even if the first
+character of @code{optstring} is not a colon.
+
+If an invalid option is seen,
+@code{getopts} places @samp{?} into @var{name} and, if not silent,
+prints an error message and unsets @env{OPTARG}.
+If @code{getopts} is silent, the option character found is placed in
+@env{OPTARG} and no diagnostic message is printed.
+
+If a required argument is not found, and @code{getopts}
+is not silent, a question mark (@samp{?}) is placed in @var{name},
+@code{OPTARG} is unset, and a diagnostic message is printed.
+If @code{getopts} is silent, then a colon (@samp{:}) is placed in
+@var{name} and @env{OPTARG} is set to the option character found.
+
+@item hash
+@btindex hash
+@example
+hash [-r] [-p @var{filename}] [-dt] [@var{name}]
+@end example
+Each time @code{hash} is invoked, it remembers the full pathnames of the
+commands specified as @var{name} arguments,
+so they need not be searched for on subsequent invocations.
+The commands are found by searching through the directories listed in
+@env{$PATH}.
+Any previously-remembered pathname is discarded.
+The @option{-p} option inhibits the path search, and @var{filename} is
+used as the location of @var{name}.
+The @option{-r} option causes the shell to forget all remembered locations.
+The @option{-d} option causes the shell to forget the remembered location
+of each @var{name}.
+If the @option{-t} option is supplied, the full pathname to which each
+@var{name} corresponds is printed. If multiple @var{name} arguments are
+supplied with @option{-t} the @var{name} is printed before the hashed
+full pathname.
+The @option{-l} option causes output to be displayed in a format
+that may be reused as input.
+If no arguments are given, or if only @option{-l} is supplied,
+information about remembered commands is printed.
+The return status is zero unless a @var{name} is not found or an invalid
+option is supplied.
+
+@item pwd
+@btindex pwd
+@example
+pwd [-LP]
+@end example
+Print the absolute pathname of the current working directory.
+If the @option{-P} option is supplied, the pathname printed will not
+contain symbolic links.
+If the @option{-L} option is supplied, the pathname printed may contain
+symbolic links.
+The return status is zero unless an error is encountered while
+determining the name of the current directory or an invalid option
+is supplied.
+
+@item readonly
+@btindex readonly
+@example
+readonly [-aAf] [-p] [@var{name}[=@var{value}]] @dots{}
+@end example
+Mark each @var{name} as readonly.
+The values of these names may not be changed by subsequent assignment.
+If the @option{-f} option is supplied, each @var{name} refers to a shell
+function.
+The @option{-a} option means each @var{name} refers to an indexed
+array variable; the @option{-A} option means each @var{name} refers
+to an associative array variable.
+If both options are supplied, @option{-A} takes precedence.
+If no @var{name} arguments are given, or if the @option{-p}
+option is supplied, a list of all readonly names is printed.
+The other options may be used to restrict the output to a subset of
+the set of readonly names.
+The @option{-p} option causes output to be displayed in a format that
+may be reused as input.
+If a variable name is followed by =@var{value}, the value of
+the variable is set to @var{value}.
+The return status is zero unless an invalid option is supplied, one of
+the @var{name} arguments is not a valid shell variable or function name,
+or the @option{-f} option is supplied with a name that is not a shell function.
+
+@item return
+@btindex return
+@example
+return [@var{n}]
+@end example
+Cause a shell function to exit with the return value @var{n}.
+If @var{n} is not supplied, the return value is the exit status of the
+last command executed in the function.
+This may also be used to terminate execution of a script being executed
+with the @code{.} (or @code{source}) builtin, returning either @var{n} or
+the exit status of the last command executed within the script as the exit
+status of the script.
+Any command associated with the @code{RETURN} trap is executed
+before execution resumes after the function or script.
+The return status is non-zero if @code{return} is used outside a function
+and not during the execution of a script by @code{.} or @code{source}.
+
+@item shift
+@btindex shift
+@example
+shift [@var{n}]
+@end example
+Shift the positional parameters to the left by @var{n}.
+The positional parameters from @var{n}+1 @dots{} @code{$#} are
+renamed to @code{$1} @dots{} @code{$#}-@var{n}.
+Parameters represented by the numbers @code{$#} to @code{$#}-@var{n}+1
+are unset.
+@var{n} must be a non-negative number less than or equal to @code{$#}.
+If @var{n} is zero or greater than @code{$#}, the positional parameters
+are not changed.
+If @var{n} is not supplied, it is assumed to be 1.
+The return status is zero unless @var{n} is greater than @code{$#} or
+less than zero, non-zero otherwise.
+
+@item test
+@itemx [
+@btindex test
+@btindex [
+Evaluate a conditional expression @var{expr}.
+Each operator and operand must be a separate argument.
+Expressions are composed of the primaries described below in
+@ref{Bash Conditional Expressions}.
+@code{test} does not accept any options, nor does it accept and ignore
+an argument of @option{--} as signifying the end of options.
+
+When the @code{[} form is used, the last argument to the command must
+be a @code{]}.
+
+Expressions may be combined using the following operators, listed in
+decreasing order of precedence.
+The evaluation depends on the number of arguments; see below.
+Operator precedence is used when there are five or more arguments.
+
+@table @code
+@item ! @var{expr}
+True if @var{expr} is false.
+
+@item ( @var{expr} )
+Returns the value of @var{expr}.
+This may be used to override the normal precedence of operators.
+
+@item @var{expr1} -a @var{expr2}
+True if both @var{expr1} and @var{expr2} are true.
+
+@item @var{expr1} -o @var{expr2}
+True if either @var{expr1} or @var{expr2} is true.
+@end table
+
+The @code{test} and @code{[} builtins evaluate conditional
+expressions using a set of rules based on the number of arguments.
+
+@table @asis
+@item 0 arguments
+The expression is false.
+
+@item 1 argument
+The expression is true if and only if the argument is not null.
+
+@item 2 arguments
+If the first argument is @samp{!}, the expression is true if and
+only if the second argument is null.
+If the first argument is one of the unary conditional operators
+(@pxref{Bash Conditional Expressions}), the expression
+is true if the unary test is true.
+If the first argument is not a valid unary operator, the expression is
+false.
+
+@item 3 arguments
+The following conditions are applied in the order listed.
+If the second argument is one of the binary conditional
+operators (@pxref{Bash Conditional Expressions}), the
+result of the expression is the result of the binary test using the
+first and third arguments as operands.
+The @samp{-a} and @samp{-o} operators are considered binary operators
+when there are three arguments.
+If the first argument is @samp{!}, the value is the negation of
+the two-argument test using the second and third arguments.
+If the first argument is exactly @samp{(} and the third argument is
+exactly @samp{)}, the result is the one-argument test of the second
+argument.
+Otherwise, the expression is false.
+
+@item 4 arguments
+If the first argument is @samp{!}, the result is the negation of
+the three-argument expression composed of the remaining arguments.
+Otherwise, the expression is parsed and evaluated according to
+precedence using the rules listed above.
+
+@item 5 or more arguments
+The expression is parsed and evaluated according to precedence
+using the rules listed above.
+@end table
+
+When used with @code{test} or @samp{[}, the @samp{<} and @samp{>}
+operators sort lexicographically using ASCII ordering.
+
+@item times
+@btindex times
+@example
+times
+@end example
+Print out the user and system times used by the shell and its children.
+The return status is zero.
+
+@item trap
+@btindex trap
+@example
+trap [-lp] [@var{arg}] [@var{sigspec} @dots{}]
+@end example
+The commands in @var{arg} are to be read and executed when the
+shell receives signal @var{sigspec}. If @var{arg} is absent (and
+there is a single @var{sigspec}) or
+equal to @samp{-}, each specified signal's disposition is reset
+to the value it had when the shell was started.
+If @var{arg} is the null string, then the signal specified by
+each @var{sigspec} is ignored by the shell and commands it invokes.
+If @var{arg} is not present and @option{-p} has been supplied,
+the shell displays the trap commands associated with each @var{sigspec}.
+If no arguments are supplied, or
+only @option{-p} is given, @code{trap} prints the list of commands
+associated with each signal number in a form that may be reused as
+shell input.
+The @option{-l} option causes the shell to print a list of signal names
+and their corresponding numbers.
+Each @var{sigspec} is either a signal name or a signal number.
+Signal names are case insensitive and the @code{SIG} prefix is optional.
+
+If a @var{sigspec}
+is @code{0} or @code{EXIT}, @var{arg} is executed when the shell exits.
+If a @var{sigspec} is @code{DEBUG}, the command @var{arg} is executed
+before every simple command, @code{for} command, @code{case} command,
+@code{select} command, every arithmetic @code{for} command, and before
+the first command executes in a shell function.
+Refer to the description of the @code{extdebug} option to the
+@code{shopt} builtin (@pxref{The Shopt Builtin}) for details of its
+effect on the @code{DEBUG} trap.
+If a @var{sigspec} is @code{RETURN}, the command @var{arg} is executed
+each time a shell function or a script executed with the @code{.} or
+@code{source} builtins finishes executing.
+
+If a @var{sigspec} is @code{ERR}, the command @var{arg}
+is executed whenever a simple command has a non-zero exit status,
+subject to the following conditions.
+The @code{ERR} trap is not executed if the failed command is part of the
+command list immediately following an @code{until} or @code{while} keyword,
+part of the test following the @code{if} or @code{elif} reserved words,
+part of a command executed in a @code{&&} or @code{||} list,
+or if the command's return
+status is being inverted using @code{!}.
+These are the same conditions obeyed by the @code{errexit} option.
+
+Signals ignored upon entry to the shell cannot be trapped or reset.
+Trapped signals that are not being ignored are reset to their original
+values in a subshell or subshell environment when one is created.
+
+The return status is zero unless a @var{sigspec} does not specify a
+valid signal.
+
+@item umask
+@btindex umask
+@example
+umask [-p] [-S] [@var{mode}]
+@end example
+Set the shell process's file creation mask to @var{mode}. If
+@var{mode} begins with a digit, it is interpreted as an octal number;
+if not, it is interpreted as a symbolic mode mask similar
+to that accepted by the @code{chmod} command. If @var{mode} is
+omitted, the current value of the mask is printed. If the @option{-S}
+option is supplied without a @var{mode} argument, the mask is printed
+in a symbolic format.
+If the @option{-p} option is supplied, and @var{mode}
+is omitted, the output is in a form that may be reused as input.
+The return status is zero if the mode is successfully changed or if
+no @var{mode} argument is supplied, and non-zero otherwise.
+
+Note that when the mode is interpreted as an octal number, each number
+of the umask is subtracted from @code{7}. Thus, a umask of @code{022}
+results in permissions of @code{755}.
+
+@item unset
+@btindex unset
+@example
+unset [-fv] [@var{name}]
+@end example
+Each variable or function @var{name} is removed.
+If the @option{-v} option is given, each
+@var{name} refers to a shell variable and that variable is remvoved.
+If the @option{-f} option is given, the @var{name}s refer to shell
+functions, and the function definition is removed.
+If no options are supplied, each @var{name} refers to a variable; if
+there is no variable by that name, any function with that name is
+unset.
+Readonly variables and functions may not be unset.
+The return status is zero unless a @var{name} is readonly.
+@end table
+
+@node Bash Builtins
+@section Bash Builtin Commands
+
+This section describes builtin commands which are unique to
+or have been extended in Bash.
+Some of these commands are specified in the @sc{posix} standard.
+
+@table @code
+
+@item alias
+@btindex alias
+@example
+alias [@code{-p}] [@var{name}[=@var{value}] @dots{}]
+@end example
+
+Without arguments or with the @option{-p} option, @code{alias} prints
+the list of aliases on the standard output in a form that allows
+them to be reused as input.
+If arguments are supplied, an alias is defined for each @var{name}
+whose @var{value} is given. If no @var{value} is given, the name
+and value of the alias is printed.
+Aliases are described in @ref{Aliases}.
+
+@item bind
+@btindex bind
+@example
+bind [-m @var{keymap}] [-lpsvPSV]
+bind [-m @var{keymap}] [-q @var{function}] [-u @var{function}] [-r @var{keyseq}]
+bind [-m @var{keymap}] -f @var{filename}
+bind [-m @var{keymap}] -x @var{keyseq:shell-command}
+bind [-m @var{keymap}] @var{keyseq:function-name}
+bind @var{readline-command}
+@end example
+
+Display current Readline (@pxref{Command Line Editing})
+key and function bindings,
+bind a key sequence to a Readline function or macro,
+or set a Readline variable.
+Each non-option argument is a command as it would appear in a
+Readline initialization file (@pxref{Readline Init File}),
+but each binding or command must be passed as a separate argument; e.g.,
+@samp{"\C-x\C-r":re-read-init-file}.
+
+Options, if supplied, have the following meanings:
+
+@table @code
+@item -m @var{keymap}
+Use @var{keymap} as the keymap to be affected by
+the subsequent bindings. Acceptable @var{keymap}
+names are
+@code{emacs},
+@code{emacs-standard},
+@code{emacs-meta},
+@code{emacs-ctlx},
+@code{vi},
+@code{vi-move},
+@code{vi-command}, and
+@code{vi-insert}.
+@code{vi} is equivalent to @code{vi-command};
+@code{emacs} is equivalent to @code{emacs-standard}.
+
+@item -l
+List the names of all Readline functions.
+
+@item -p
+Display Readline function names and bindings in such a way that they
+can be used as input or in a Readline initialization file.
+
+@item -P
+List current Readline function names and bindings.
+
+@item -v
+Display Readline variable names and values in such a way that they
+can be used as input or in a Readline initialization file.
+
+@item -V
+List current Readline variable names and values.
+
+@item -s
+Display Readline key sequences bound to macros and the strings they output
+in such a way that they can be used as input or in a Readline
+initialization file.
+
+@item -S
+Display Readline key sequences bound to macros and the strings they output.
+
+@item -f @var{filename}
+Read key bindings from @var{filename}.
+
+@item -q @var{function}
+Query about which keys invoke the named @var{function}.
+
+@item -u @var{function}
+Unbind all keys bound to the named @var{function}.
+
+@item -r @var{keyseq}
+Remove any current binding for @var{keyseq}.
+
+@item -x @var{keyseq:shell-command}
+Cause @var{shell-command} to be executed whenever @var{keyseq} is
+entered.
+When @var{shell-command} is executed, the shell sets the
+@code{READLINE_LINE} variable to the contents of the Readline line
+buffer and the @code{READLINE_POINT} variable to the current location
+of the insertion point.
+If the executed command changes the value of @code{READLINE_LINE} or
+@code{READLINE_POINT}, those new values will be reflected in the
+editing state.
+@end table
+
+@noindent
+The return status is zero unless an invalid option is supplied or an
+error occurs.
+
+@item builtin
+@btindex builtin
+@example
+builtin [@var{shell-builtin} [@var{args}]]
+@end example
+Run a shell builtin, passing it @var{args}, and return its exit status.
+This is useful when defining a shell function with the same
+name as a shell builtin, retaining the functionality of the builtin within
+the function.
+The return status is non-zero if @var{shell-builtin} is not a shell
+builtin command.
+
+@item caller
+@btindex caller
+@example
+caller [@var{expr}]
+@end example
+Returns the context of any active subroutine call (a shell function or
+a script executed with the @code{.} or @code{source} builtins).
+
+Without @var{expr}, @code{caller} displays the line number and source
+filename of the current subroutine call.
+If a non-negative integer is supplied as @var{expr}, @code{caller}
+displays the line number, subroutine name, and source file corresponding
+to that position in the current execution call stack. This extra
+information may be used, for example, to print a stack trace. The
+current frame is frame 0.
+
+The return value is 0 unless the shell is not executing a subroutine
+call or @var{expr} does not correspond to a valid position in the
+call stack.
+
+@item command
+@btindex command
+@example
+command [-pVv] @var{command} [@var{arguments} @dots{}]
+@end example
+Runs @var{command} with @var{arguments} ignoring any shell function
+named @var{command}.
+Only shell builtin commands or commands found by searching the
+@env{PATH} are executed.
+If there is a shell function named @code{ls}, running @samp{command ls}
+within the function will execute the external command @code{ls}
+instead of calling the function recursively.
+The @option{-p} option means to use a default value for @env{PATH}
+that is guaranteed to find all of the standard utilities.
+The return status in this case is 127 if @var{command} cannot be
+found or an error occurred, and the exit status of @var{command}
+otherwise.
+
+If either the @option{-V} or @option{-v} option is supplied, a
+description of @var{command} is printed. The @option{-v} option
+causes a single word indicating the command or file name used to
+invoke @var{command} to be displayed; the @option{-V} option produces
+a more verbose description. In this case, the return status is
+zero if @var{command} is found, and non-zero if not.
+
+@item declare
+@btindex declare
+@example
+declare [-aAfFilrtux] [-p] [@var{name}[=@var{value}] @dots{}]
+@end example
+
+Declare variables and give them attributes. If no @var{name}s
+are given, then display the values of variables instead.
+
+The @option{-p} option will display the attributes and values of each
+@var{name}.
+When @option{-p} is used with @var{name} arguments, additional options
+are ignored.
+
+When @option{-p} is supplied without @var{name} arguments, @code{declare}
+will display the attributes and values of all variables having the
+attributes specified by the additional options.
+If no other options are supplied with @option{-p}, @code{declare} will
+display the attributes and values of all shell variables. The @option{-f}
+option will restrict the display to shell functions.
+
+The @option{-F} option inhibits the display of function definitions;
+only the function name and attributes are printed.
+If the @code{extdebug} shell option is enabled using @code{shopt}
+(@pxref{The Shopt Builtin}), the source file name and line number where
+the function is defined are displayed as well.
+@option{-F} implies @option{-f}.
+
+The @option{-g} option forces variables to be created or modified at
+the global scope, even when @code{declare} is executed in a shell function.
+It is ignored in all other cases.
+
+The following options can be used to restrict output to variables with
+the specified attributes or to give variables attributes:
+
+@table @code
+@item -a
+Each @var{name} is an indexed array variable (@pxref{Arrays}).
+
+@item -A
+Each @var{name} is an associative array variable (@pxref{Arrays}).
+
+@item -f
+Use function names only.
+
+@item -i
+The variable is to be treated as
+an integer; arithmetic evaluation (@pxref{Shell Arithmetic}) is
+performed when the variable is assigned a value.
+
+@item -l
+When the variable is assigned a value, all upper-case characters are
+converted to lower-case.
+The upper-case attribute is disabled.
+
+@item -r
+Make @var{name}s readonly. These names cannot then be assigned values
+by subsequent assignment statements or unset.
+
+@item -t
+Give each @var{name} the @code{trace} attribute.
+Traced functions inherit the @code{DEBUG} and @code{RETURN} traps from
+the calling shell.
+The trace attribute has no special meaning for variables.
+
+@item -u
+When the variable is assigned a value, all lower-case characters are
+converted to upper-case.
+The lower-case attribute is disabled.
+
+@item -x
+Mark each @var{name} for export to subsequent commands via
+the environment.
+@end table
+
+Using @samp{+} instead of @samp{-} turns off the attribute instead,
+with the exceptions that @samp{+a}
+may not be used to destroy an array variable and @samp{+r} will not
+remove the readonly attribute.
+When used in a function, @code{declare} makes each @var{name} local,
+as with the @code{local} command, unless the @samp{-g} option is used.
+If a variable name is followed by =@var{value}, the value of the variable
+is set to @var{value}.
+
+The return status is zero unless an invalid option is encountered,
+an attempt is made to define a function using @samp{-f foo=bar},
+an attempt is made to assign a value to a readonly variable,
+an attempt is made to assign a value to an array variable without
+using the compound assignment syntax (@pxref{Arrays}),
+one of the @var{names} is not a valid shell variable name,
+an attempt is made to turn off readonly status for a readonly variable,
+an attempt is made to turn off array status for an array variable,
+or an attempt is made to display a non-existent function with @option{-f}.
+
+@item echo
+@btindex echo
+@example
+echo [-neE] [@var{arg} @dots{}]
+@end example
+Output the @var{arg}s, separated by spaces, terminated with a
+newline.
+The return status is 0 unless a write error occurs.
+If @option{-n} is specified, the trailing newline is suppressed.
+If the @option{-e} option is given, interpretation of the following
+backslash-escaped characters is enabled.
+The @option{-E} option disables the interpretation of these escape characters,
+even on systems where they are interpreted by default.
+The @code{xpg_echo} shell option may be used to
+dynamically determine whether or not @code{echo} expands these
+escape characters by default.
+@code{echo} does not interpret @option{--} to mean the end of options.
+
+@code{echo} interprets the following escape sequences:
+@table @code
+@item \a
+alert (bell)
+@item \b
+backspace
+@item \c
+suppress further output
+@item \e
+@itemx \E
+escape
+@item \f
+form feed
+@item \n
+new line
+@item \r
+carriage return
+@item \t
+horizontal tab
+@item \v
+vertical tab
+@item \\
+backslash
+@item \0@var{nnn}
+the eight-bit character whose value is the octal value @var{nnn}
+(zero to three octal digits)
+@item \x@var{HH}
+the eight-bit character whose value is the hexadecimal value @var{HH}
+(one or two hex digits)
+@item \u@var{HHHH}
+the Unicode (ISO/IEC 10646) character whose value is the hexadecimal value
+@var{HHHH} (one to four hex digits)
+@item \U@var{HHHHHHHH}
+the Unicode (ISO/IEC 10646) character whose value is the hexadecimal value
+@var{HHHHHHHH} (one to eight hex digits)
+@end table
+
+@item enable
+@btindex enable
+@example
+enable [-a] [-dnps] [-f @var{filename}] [@var{name} @dots{}]
+@end example
+Enable and disable builtin shell commands.
+Disabling a builtin allows a disk command which has the same name
+as a shell builtin to be executed without specifying a full pathname,
+even though the shell normally searches for builtins before disk commands.
+If @option{-n} is used, the @var{name}s become disabled. Otherwise
+@var{name}s are enabled. For example, to use the @code{test} binary
+found via @env{$PATH} instead of the shell builtin version, type
+@samp{enable -n test}.
+
+If the @option{-p} option is supplied, or no @var{name} arguments appear,
+a list of shell builtins is printed. With no other arguments, the list
+consists of all enabled shell builtins.
+The @option{-a} option means to list
+each builtin with an indication of whether or not it is enabled.
+
+The @option{-f} option means to load the new builtin command @var{name}
+from shared object @var{filename}, on systems that support dynamic loading.
+The @option{-d} option will delete a builtin loaded with @option{-f}.
+
+If there are no options, a list of the shell builtins is displayed.
+The @option{-s} option restricts @code{enable} to the @sc{posix} special
+builtins. If @option{-s} is used with @option{-f}, the new builtin becomes
+a special builtin (@pxref{Special Builtins}).
+
+The return status is zero unless a @var{name} is not a shell builtin
+or there is an error loading a new builtin from a shared object.
+
+@item help
+@btindex help
+@example
+help [-dms] [@var{pattern}]
+@end example
+Display helpful information about builtin commands.
+If @var{pattern} is specified, @code{help} gives detailed help
+on all commands matching @var{pattern}, otherwise a list of
+the builtins is printed.
+
+Options, if supplied, have the following meanings:
+
+@table @code
+@item -d
+Display a short description of each @var{pattern}
+@item -m
+Display the description of each @var{pattern} in a manpage-like format
+@item -s
+Display only a short usage synopsis for each @var{pattern}
+@end table
+
+The return status is zero unless no command matches @var{pattern}.
+
+@item let
+@btindex let
+@example
+let @var{expression} [@var{expression}]
+@end example
+The @code{let} builtin allows arithmetic to be performed on shell
+variables. Each @var{expression} is evaluated according to the
+rules given below in @ref{Shell Arithmetic}. If the
+last @var{expression} evaluates to 0, @code{let} returns 1;
+otherwise 0 is returned.
+
+@item local
+@btindex local
+@example
+local [@var{option}] @var{name}[=@var{value}] @dots{}
+@end example
+For each argument, a local variable named @var{name} is created,
+and assigned @var{value}.
+The @var{option} can be any of the options accepted by @code{declare}.
+@code{local} can only be used within a function; it makes the variable
+@var{name} have a visible scope restricted to that function and its
+children. The return status is zero unless @code{local} is used outside
+a function, an invalid @var{name} is supplied, or @var{name} is a
+readonly variable.
+
+@item logout
+@btindex logout
+@example
+logout [@var{n}]
+@end example
+Exit a login shell, returning a status of @var{n} to the shell's
+parent.
+
+@item mapfile
+@btindex mapfile
+@example
+mapfile [-n @var{count}] [-O @var{origin}] [-s @var{count}] [-t] [-u @var{fd}] [
+-C @var{callback}] [-c @var{quantum}] [@var{array}]
+@end example
+Read lines from the standard input into the indexed array variable @var{array},
+or from file descriptor @var{fd}
+if the @option{-u} option is supplied.
+The variable @code{MAPFILE} is the default @var{array}.
+Options, if supplied, have the following meanings:
+@table @code
+
+@item -n
+Copy at most @var{count} lines. If @var{count} is 0, all lines are copied.
+@item -O
+Begin assigning to @var{array} at index @var{origin}.
+The default index is 0.
+@item -s
+Discard the first @var{count} lines read.
+@item -t
+Remove a trailing newline from each line read.
+@item -u
+Read lines from file descriptor @var{fd} instead of the standard input.
+@item -C
+Evaluate @var{callback} each time @var{quantum}P lines are read.
+The @option{-c} option specifies @var{quantum}.
+@item -c
+Specify the number of lines read between each call to @var{callback}.
+@end table
+
+If @option{-C} is specified without @option{-c},
+the default quantum is 5000.
+When @var{callback} is evaluated, it is supplied the index of the next
+array element to be assigned and the line to be assigned to that element
+as additional arguments.
+@var{callback} is evaluated after the line is read but before the
+array element is assigned.
+
+If not supplied with an explicit origin, @code{mapfile} will clear @var{array}
+before assigning to it.
+
+@code{mapfile} returns successfully unless an invalid option or option
+argument is supplied, @var{array} is invalid or unassignable, or @var{array}
+is not an indexed array.
+
+@item printf
+@btindex printf
+@example
+printf [-v @var{var}] @var{format} [@var{arguments}]
+@end example
+Write the formatted @var{arguments} to the standard output under the
+control of the @var{format}.
+The @option{-v} option causes the output to be assigned to the variable
+@var{var} rather than being printed to the standard output.
+
+The @var{format} is a character string which contains three types of objects:
+plain characters, which are simply copied to standard output, character
+escape sequences, which are converted and copied to the standard output, and
+format specifications, each of which causes printing of the next successive
+@var{argument}.
+In addition to the standard @code{printf(1)} formats, @code{printf}
+interprets the following extensions:
+
+@table @code
+@item %b
+causes @code{printf} to expand backslash escape sequences in the
+corresponding @var{argument},
+(except that @samp{\c} terminates output, backslashes in
+@samp{\'}, @samp{\"}, and @samp{\?} are not removed, and octal escapes
+beginning with @samp{\0} may contain up to four digits).
+@item %q
+causes @code{printf} to output the
+corresponding @var{argument} in a format that can be reused as shell input.
+@item %(@var{datefmt})T
+causes @code{printf} to output the date-time string resulting from using
+@var{datefmt} as a format string for @code{strftime}(3). The corresponding
+@var{argument} is an integer representing the number of seconds since the
+epoch. Two special argument values may be used: -1 represents the current
+time, and -2 represents the time the shell was invoked.
+@end table
+
+@noindent
+Arguments to non-string format specifiers are treated as C language constants,
+except that a leading plus or minus sign is allowed, and if the leading
+character is a single or double quote, the value is the ASCII value of
+the following character.
+
+The @var{format} is reused as necessary to consume all of the @var{arguments}.
+If the @var{format} requires more @var{arguments} than are supplied, the
+extra format specifications behave as if a zero value or null string, as
+appropriate, had been supplied. The return value is zero on success,
+non-zero on failure.
+
+@item read
+@btindex read
+@example
+read [-ers] [-a @var{aname}] [-d @var{delim}] [-i @var{text}] [-n @var{nchars}] [-N @var{nchars}] [-p @var{prompt}] [-t @var{timeout}] [-u @var{fd}] [@var{name} @dots{}]
+@end example
+One line is read from the standard input, or from the file descriptor
+@var{fd} supplied as an argument to the @option{-u} option, and the first word
+is assigned to the first @var{name}, the second word to the second @var{name},
+and so on, with leftover words and their intervening separators assigned
+to the last @var{name}.
+If there are fewer words read from the input stream than names,
+the remaining names are assigned empty values.
+The characters in the value of the @env{IFS} variable
+are used to split the line into words.
+The backslash character @samp{\} may be used to remove any special
+meaning for the next character read and for line continuation.
+If no names are supplied, the line read is assigned to the
+variable @env{REPLY}.
+The return code is zero, unless end-of-file is encountered, @code{read}
+times out (in which case the return code is greater than 128), or an
+invalid file descriptor is supplied as the argument to @option{-u}.
+
+Options, if supplied, have the following meanings:
+
+@table @code
+@item -a @var{aname}
+The words are assigned to sequential indices of the array variable
+@var{aname}, starting at 0.
+All elements are removed from @var{aname} before the assignment.
+Other @var{name} arguments are ignored.
+
+@item -d @var{delim}
+The first character of @var{delim} is used to terminate the input line,
+rather than newline.
+
+@item -e
+Readline (@pxref{Command Line Editing}) is used to obtain the line.
+Readline uses the current (or default, if line editing was not previously
+active) editing settings.
+
+@item -i @var{text}
+If Readline is being used to read the line, @var{text} is placed into
+the editing buffer before editing begins.
+
+@item -n @var{nchars}
+@code{read} returns after reading @var{nchars} characters rather than
+waiting for a complete line of input, but honor a delimiter if fewer
+than @var{nchars} characters are read before the delimiter.
+
+@item -N @var{nchars}
+@code{read} returns after reading exactly @var{nchars} characters rather
+than waiting for a complete line of input, unless EOF is encountered or
+@code{read} times out.
+Delimiter characters encountered in the input are
+not treated specially and do not cause @code{read} to return until
+@var{nchars} characters are read.
+
+@item -p @var{prompt}
+Display @var{prompt}, without a trailing newline, before attempting
+to read any input.
+The prompt is displayed only if input is coming from a terminal.
+
+@item -r
+If this option is given, backslash does not act as an escape character.
+The backslash is considered to be part of the line.
+In particular, a backslash-newline pair may not be used as a line
+continuation.
+
+@item -s
+Silent mode. If input is coming from a terminal, characters are
+not echoed.
+
+@item -t @var{timeout}
+Cause @code{read} to time out and return failure if a complete line of
+input is not read within @var{timeout} seconds.
+@var{timeout} may be a decimal number with a fractional portion following
+the decimal point.
+This option is only effective if @code{read} is reading input from a
+terminal, pipe, or other special file; it has no effect when reading
+from regular files.
+If @var{timeout} is 0, @code{read} returns success if input is available on
+the specified file descriptor, failure otherwise.
+The exit status is greater than 128 if the timeout is exceeded.
+
+@item -u @var{fd}
+Read input from file descriptor @var{fd}.
+
+@end table
+
+@item readarray
+@btindex readarray
+@example
+readarray [-n @var{count}] [-O @var{origin}] [-s @var{count}] [-t] [-u @var{fd}] [
+-C @var{callback}] [-c @var{quantum}] [@var{array}]
+@end example
+Read lines from the standard input into the indexed array variable @var{array},
+or from file descriptor @var{fd}
+if the @option{-u} option is supplied.
+
+A synonym for @code{mapfile}.
+
+@item source
+@btindex source
+@example
+source @var{filename}
+@end example
+A synonym for @code{.} (@pxref{Bourne Shell Builtins}).
+
+@item type
+@btindex type
+@example
+type [-afptP] [@var{name} @dots{}]
+@end example
+For each @var{name}, indicate how it would be interpreted if used as a
+command name.
+
+If the @option{-t} option is used, @code{type} prints a single word
+which is one of @samp{alias}, @samp{function}, @samp{builtin},
+@samp{file} or @samp{keyword},
+if @var{name} is an alias, shell function, shell builtin,
+disk file, or shell reserved word, respectively.
+If the @var{name} is not found, then nothing is printed, and
+@code{type} returns a failure status.
+
+If the @option{-p} option is used, @code{type} either returns the name
+of the disk file that would be executed, or nothing if @option{-t}
+would not return @samp{file}.
+
+The @option{-P} option forces a path search for each @var{name}, even if
+@option{-t} would not return @samp{file}.
+
+If a command is hashed, @option{-p} and @option{-P} print the hashed value,
+not necessarily the file that appears first in @code{$PATH}.
+
+If the @option{-a} option is used, @code{type} returns all of the places
+that contain an executable named @var{file}.
+This includes aliases and functions, if and only if the @option{-p} option
+is not also used.
+
+If the @option{-f} option is used, @code{type} does not attempt to find
+shell functions, as with the @code{command} builtin.
+
+The return status is zero if all of the @var{names} are found, non-zero
+if any are not found.
+
+@item typeset
+@btindex typeset
+@example
+typeset [-afFrxi] [-p] [@var{name}[=@var{value}] @dots{}]
+@end example
+The @code{typeset} command is supplied for compatibility with the Korn
+shell; however, it has been deprecated in favor of the @code{declare}
+builtin command.
+
+@item ulimit
+@btindex ulimit
+@example
+ulimit [-abcdefilmnpqrstuvxHST] [@var{limit}]
+@end example
+@code{ulimit} provides control over the resources available to processes
+started by the shell, on systems that allow such control. If an
+option is given, it is interpreted as follows:
+@table @code
+@item -S
+Change and report the soft limit associated with a resource.
+
+@item -H
+Change and report the hard limit associated with a resource.
+
+@item -a
+All current limits are reported.
+
+@item -b
+The maximum socket buffer size.
+
+@item -c
+The maximum size of core files created.
+
+@item -d
+The maximum size of a process's data segment.
+
+@item -e
+The maximum scheduling priority ("nice").
+
+@item -f
+The maximum size of files written by the shell and its children.
+
+@item -i
+The maximum number of pending signals.
+
+@item -l
+The maximum size that may be locked into memory.
+
+@item -m
+The maximum resident set size (many systems do not honor this limit).
+
+@item -n
+The maximum number of open file descriptors (most systems do not
+allow this value to be set).
+
+@item -p
+The pipe buffer size.
+
+@item -q
+The maximum number of bytes in POSIX message queues.
+
+@item -r
+The maximum real-time scheduling priority.
+
+@item -s
+The maximum stack size.
+
+@item -t
+The maximum amount of cpu time in seconds.
+
+@item -u
+The maximum number of processes available to a single user.
+
+@item -v
+The maximum amount of virtual memory available to the shell, and, on
+some systems, to its children.
+
+@item -x
+The maximum number of file locks.
+
+@item -T
+The maximum number of threads.
+
+@end table
+
+If @var{limit} is given, it is the new value of the specified resource;
+the special @var{limit} values @code{hard}, @code{soft}, and
+@code{unlimited} stand for the current hard limit, the current soft limit,
+and no limit, respectively.
+A hard limit cannot be increased by a non-root user once it is set;
+a soft limit may be increased up to the value of the hard limit.
+Otherwise, the current value of the soft limit for the specified resource
+is printed, unless the @option{-H} option is supplied.
+When setting new limits, if neither @option{-H} nor @option{-S} is supplied,
+both the hard and soft limits are set.
+If no option is given, then @option{-f} is assumed. Values are in 1024-byte
+increments, except for @option{-t}, which is in seconds, @option{-p},
+which is in units of 512-byte blocks, and @option{-n} and @option{-u}, which
+are unscaled values.
+
+The return status is zero unless an invalid option or argument is supplied,
+or an error occurs while setting a new limit.
+
+@item unalias
+@btindex unalias
+@example
+unalias [-a] [@var{name} @dots{} ]
+@end example
+
+Remove each @var{name} from the list of aliases. If @option{-a} is
+supplied, all aliases are removed.
+Aliases are described in @ref{Aliases}.
+
+@end table
+
+@node Modifying Shell Behavior
+@section Modifying Shell Behavior
+
+@menu
+* The Set Builtin:: Change the values of shell attributes and
+ positional parameters.
+* The Shopt Builtin:: Modify shell optional behavior.
+@end menu
+
+@node The Set Builtin
+@subsection The Set Builtin
+
+This builtin is so complicated that it deserves its own section. @code{set}
+allows you to change the values of shell options and set the positional
+parameters, or to display the names and values of shell variables.
+
+@table @code
+@item set
+@btindex set
+@example
+set [--abefhkmnptuvxBCEHPT] [-o @var{option-name}] [@var{argument} @dots{}]
+set [+abefhkmnptuvxBCEHPT] [+o @var{option-name}] [@var{argument} @dots{}]
+@end example
+
+If no options or arguments are supplied, @code{set} displays the names
+and values of all shell variables and functions, sorted according to the
+current locale, in a format that may be reused as input
+for setting or resetting the currently-set variables.
+Read-only variables cannot be reset.
+In @sc{posix} mode, only shell variables are listed.
+
+When options are supplied, they set or unset shell attributes.
+Options, if specified, have the following meanings:
+
+@table @code
+@item -a
+Mark variables and function which are modified or created for export
+to the environment of subsequent commands.
+
+@item -b
+Cause the status of terminated background jobs to be reported
+immediately, rather than before printing the next primary prompt.
+
+@item -e
+Exit immediately if a pipeline (@pxref{Pipelines}), which may consist
+of a single simple command (@pxref{Simple Commands}),
+a subshell command enclosed in parentheses (@pxref{Command Grouping}),
+or one of the commands executed as part of a command list enclosed
+by braces (@pxref{Command Grouping})
+returns a non-zero status.
+The shell does not exit if the command that fails is part of the
+command list immediately following a @code{while} or @code{until} keyword,
+part of the test in an @code{if} statement,
+part of any command executed in a @code{&&} or @code{||} list except
+the command following the final @code{&&} or @code{||},
+any command in a pipeline but the last,
+or if the command's return status is being inverted with @code{!}.
+A trap on @code{ERR}, if set, is executed before the shell exits.
+
+This option applies to the shell environment and each subshell environment
+separately (@pxref{Command Execution Environment}), and may cause
+subshells to exit before executing all the commands in the subshell.
+
+@item -f
+Disable filename expansion (globbing).
+
+@item -h
+Locate and remember (hash) commands as they are looked up for execution.
+This option is enabled by default.
+
+@item -k
+All arguments in the form of assignment statements are placed
+in the environment for a command, not just those that precede
+the command name.
+
+@item -m
+Job control is enabled (@pxref{Job Control}).
+All processes run in a separate process group.
+When a background job completes, the shell prints a line
+containing its exit status.
+
+@item -n
+Read commands but do not execute them; this may be used to check a
+script for syntax errors.
+This option is ignored by interactive shells.
+
+@item -o @var{option-name}
+
+Set the option corresponding to @var{option-name}:
+
+@table @code
+@item allexport
+Same as @code{-a}.
+
+@item braceexpand
+Same as @code{-B}.
+
+@item emacs
+Use an @code{emacs}-style line editing interface (@pxref{Command Line Editing}).
+This also affects the editing interface used for @code{read -e}.
+
+@item errexit
+Same as @code{-e}.
+
+@item errtrace
+Same as @code{-E}.
+
+@item functrace
+Same as @code{-T}.
+
+@item hashall
+Same as @code{-h}.
+
+@item histexpand
+Same as @code{-H}.
+
+@item history
+Enable command history, as described in @ref{Bash History Facilities}.
+This option is on by default in interactive shells.
+
+@item ignoreeof
+An interactive shell will not exit upon reading EOF.
+
+@item keyword
+Same as @code{-k}.
+
+@item monitor
+Same as @code{-m}.
+
+@item noclobber
+Same as @code{-C}.
+
+@item noexec
+Same as @code{-n}.
+
+@item noglob
+Same as @code{-f}.
+
+@item nolog
+Currently ignored.
+
+@item notify
+Same as @code{-b}.
+
+@item nounset
+Same as @code{-u}.
+
+@item onecmd
+Same as @code{-t}.
+
+@item physical
+Same as @code{-P}.
+
+@item pipefail
+If set, the return value of a pipeline is the value of the last
+(rightmost) command to exit with a non-zero status, or zero if all
+commands in the pipeline exit successfully.
+This option is disabled by default.
+
+@item posix
+Change the behavior of Bash where the default operation differs
+from the @sc{posix} standard to match the standard
+(@pxref{Bash POSIX Mode}).
+This is intended to make Bash behave as a strict superset of that
+standard.
+
+@item privileged
+Same as @code{-p}.
+
+@item verbose
+Same as @code{-v}.
+
+@item vi
+Use a @code{vi}-style line editing interface.
+This also affects the editing interface used for @code{read -e}.
+
+@item xtrace
+Same as @code{-x}.
+@end table
+
+@item -p
+Turn on privileged mode.
+In this mode, the @env{$BASH_ENV} and @env{$ENV} files are not
+processed, shell functions are not inherited from the environment,
+and the @env{SHELLOPTS}, @env{BASHOPTS}, @env{CDPATH} and @env{GLOBIGNORE}
+variables, if they appear in the environment, are ignored.
+If the shell is started with the effective user (group) id not equal to the
+real user (group) id, and the @code{-p} option is not supplied, these actions
+are taken and the effective user id is set to the real user id.
+If the @code{-p} option is supplied at startup, the effective user id is
+not reset.
+Turning this option off causes the effective user
+and group ids to be set to the real user and group ids.
+
+@item -t
+Exit after reading and executing one command.
+
+@item -u
+Treat unset variables and parameters other than the special parameters
+@samp{@@} or @samp{*} as an error when performing parameter expansion.
+An error message will be written to the standard error, and a non-interactive
+shell will exit.
+
+@item -v
+Print shell input lines as they are read.
+
+@item -x
+Print a trace of simple commands, @code{for} commands, @code{case}
+commands, @code{select} commands, and arithmetic @code{for} commands
+and their arguments or associated word lists after they are
+expanded and before they are executed. The value of the @env{PS4}
+variable is expanded and the resultant value is printed before
+the command and its expanded arguments.
+
+@item -B
+The shell will perform brace expansion (@pxref{Brace Expansion}).
+This option is on by default.
+
+@item -C
+Prevent output redirection using @samp{>}, @samp{>&}, and @samp{<>}
+from overwriting existing files.
+
+@item -E
+If set, any trap on @code{ERR} is inherited by shell functions, command
+substitutions, and commands executed in a subshell environment.
+The @code{ERR} trap is normally not inherited in such cases.
+
+@item -H
+Enable @samp{!} style history substitution (@pxref{History Interaction}).
+This option is on by default for interactive shells.
+
+@item -P
+If set, do not follow symbolic links when performing commands such as
+@code{cd} which change the current directory. The physical directory
+is used instead. By default, Bash follows
+the logical chain of directories when performing commands
+which change the current directory.
+
+For example, if @file{/usr/sys} is a symbolic link to @file{/usr/local/sys}
+then:
+@example
+$ cd /usr/sys; echo $PWD
+/usr/sys
+$ cd ..; pwd
+/usr
+@end example
+
+@noindent
+If @code{set -P} is on, then:
+@example
+$ cd /usr/sys; echo $PWD
+/usr/local/sys
+$ cd ..; pwd
+/usr/local
+@end example
+
+@item -T
+If set, any trap on @code{DEBUG} and @code{RETURN} are inherited by
+shell functions, command substitutions, and commands executed
+in a subshell environment.
+The @code{DEBUG} and @code{RETURN} traps are normally not inherited
+in such cases.
+
+@item --
+If no arguments follow this option, then the positional parameters are
+unset. Otherwise, the positional parameters are set to the
+@var{arguments}, even if some of them begin with a @samp{-}.
+
+@item -
+Signal the end of options, cause all remaining @var{arguments}
+to be assigned to the positional parameters. The @option{-x}
+and @option{-v} options are turned off.
+If there are no arguments, the positional parameters remain unchanged.
+@end table
+
+Using @samp{+} rather than @samp{-} causes these options to be
+turned off. The options can also be used upon invocation of the
+shell. The current set of options may be found in @code{$-}.
+
+The remaining N @var{arguments} are positional parameters and are
+assigned, in order, to @code{$1}, @code{$2}, @dots{} @code{$N}.
+The special parameter @code{#} is set to N.
+
+The return status is always zero unless an invalid option is supplied.
+@end table
+
+@node The Shopt Builtin
+@subsection The Shopt Builtin
+
+This builtin allows you to change additional shell optional behavior.
+
+@table @code
+
+@item shopt
+@btindex shopt
+@example
+shopt [-pqsu] [-o] [@var{optname} @dots{}]
+@end example
+Toggle the values of variables controlling optional shell behavior.
+With no options, or with the @option{-p} option, a list of all settable
+options is displayed, with an indication of whether or not each is set.
+The @option{-p} option causes output to be displayed in a form that
+may be reused as input.
+Other options have the following meanings:
+
+@table @code
+@item -s
+Enable (set) each @var{optname}.
+
+@item -u
+Disable (unset) each @var{optname}.
+
+@item -q
+Suppresses normal output; the return status
+indicates whether the @var{optname} is set or unset.
+If multiple @var{optname} arguments are given with @option{-q},
+the return status is zero if all @var{optnames} are enabled;
+non-zero otherwise.
+
+@item -o
+Restricts the values of
+@var{optname} to be those defined for the @option{-o} option to the
+@code{set} builtin (@pxref{The Set Builtin}).
+@end table
+
+If either @option{-s} or @option{-u}
+is used with no @var{optname} arguments, the display is limited to
+those options which are set or unset, respectively.
+
+Unless otherwise noted, the @code{shopt} options are disabled (off)
+by default.
+
+The return status when listing options is zero if all @var{optnames}
+are enabled, non-zero otherwise. When setting or unsetting options,
+the return status is zero unless an @var{optname} is not a valid shell
+option.
+
+The list of @code{shopt} options is:
+@table @code
+
+@item autocd
+If set, a command name that is the name of a directory is executed as if
+it were the argument to the @code{cd} command.
+This option is only used by interactive shells.
+
+@item cdable_vars
+If this is set, an argument to the @code{cd} builtin command that
+is not a directory is assumed to be the name of a variable whose
+value is the directory to change to.
+
+@item cdspell
+If set, minor errors in the spelling of a directory component in a
+@code{cd} command will be corrected.
+The errors checked for are transposed characters,
+a missing character, and a character too many.
+If a correction is found, the corrected path is printed,
+and the command proceeds.
+This option is only used by interactive shells.
+
+@item checkhash
+If this is set, Bash checks that a command found in the hash
+table exists before trying to execute it. If a hashed command no
+longer exists, a normal path search is performed.
+
+@item checkjobs
+If set, Bash lists the status of any stopped and running jobs before
+exiting an interactive shell. If any jobs are running, this causes
+the exit to be deferred until a second exit is attempted without an
+intervening command (@pxref{Job Control}).
+The shell always postpones exiting if any jobs are stopped.
+
+@item checkwinsize
+If set, Bash checks the window size after each command
+ and, if necessary, updates the values of
+@env{LINES} and @env{COLUMNS}.
+
+@item cmdhist
+If set, Bash
+attempts to save all lines of a multiple-line
+command in the same history entry. This allows
+easy re-editing of multi-line commands.
+
+@item compat31
+If set, Bash
+changes its behavior to that of version 3.1 with respect to quoted
+arguments to the conditional command's @samp{=~} operator.
+
+@item compat32
+If set, Bash
+changes its behavior to that of version 3.2 with respect to locale-specific
+string comparison when using the @samp{[[}
+conditional command's @samp{<} and @samp{>} operators.
+Bash versions prior to bash-4.0 use ASCII collation and strcmp(3);
+bash-4.1 and later use the current locale's collation sequence and strcoll(3).
+
+@item compat40
+If set, Bash
+changes its behavior to that of version 4.0 with respect to locale-specific
+string comparison when using the @samp{[[}
+conditional command's @samp{<} and @samp{>} operators (see previous item)
+and the effect of interrupting a command list.
+
+@item compat41
+If set, Bash, when in posix mode, treats a single quote in a double-quoted
+parameter expansion as a special character. The single quotes must match
+(an even number) and the characters between the single quotes are considered
+quoted. This is the behavior of @sc{posix} mode through version 4.1.
+The default Bash behavior remains as in previous versions.
+
+@item direxpand
+If set, Bash
+replaces directory names with the results of word expansion when performing
+filename completion. This changes the contents of the readline editing
+buffer.
+If not set, Bash attempts to preserve what the user typed.
+
+@item dirspell
+If set, Bash
+attempts spelling correction on directory names during word completion
+if the directory name initially supplied does not exist.
+
+@item dotglob
+If set, Bash includes filenames beginning with a `.' in
+the results of filename expansion.
+
+@item execfail
+If this is set, a non-interactive shell will not exit if
+it cannot execute the file specified as an argument to the @code{exec}
+builtin command. An interactive shell does not exit if @code{exec}
+fails.
+
+@item expand_aliases
+If set, aliases are expanded as described below under Aliases,
+@ref{Aliases}.
+This option is enabled by default for interactive shells.
+
+@item extdebug
+If set, behavior intended for use by debuggers is enabled:
+
+@enumerate
+@item
+The @option{-F} option to the @code{declare} builtin (@pxref{Bash Builtins})
+displays the source file name and line number corresponding to each function
+name supplied as an argument.
+
+@item
+If the command run by the @code{DEBUG} trap returns a non-zero value, the
+next command is skipped and not executed.
+
+@item
+If the command run by the @code{DEBUG} trap returns a value of 2, and the
+shell is executing in a subroutine (a shell function or a shell script
+executed by the @code{.} or @code{source} builtins), a call to
+@code{return} is simulated.
+
+@item
+@code{BASH_ARGC} and @code{BASH_ARGV} are updated as described in their
+descriptions (@pxref{Bash Variables}).
+
+@item
+Function tracing is enabled: command substitution, shell functions, and
+subshells invoked with @code{( @var{command} )} inherit the
+@code{DEBUG} and @code{RETURN} traps.
+
+@item
+Error tracing is enabled: command substitution, shell functions, and
+subshells invoked with @code{( @var{command} )} inherit the
+@code{ERR} trap.
+@end enumerate
+
+@item extglob
+If set, the extended pattern matching features described above
+(@pxref{Pattern Matching}) are enabled.
+
+@item extquote
+If set, @code{$'@var{string}'} and @code{$"@var{string}"} quoting is
+performed within @code{$@{@var{parameter}@}} expansions
+enclosed in double quotes. This option is enabled by default.
+
+@item failglob
+If set, patterns which fail to match filenames during filename expansion
+result in an expansion error.
+
+@item force_fignore
+If set, the suffixes specified by the @env{FIGNORE} shell variable
+cause words to be ignored when performing word completion even if
+the ignored words are the only possible completions.
+@xref{Bash Variables}, for a description of @env{FIGNORE}.
+This option is enabled by default.
+
+@item globasciiranges
+If set, range expressions used in pattern matching (@pxref{Pattern Matching})
+behave as if in the traditional C locale when performing
+comparisons. That is, the current locale's collating sequence
+is not taken into account, so
+@samp{b} will not collate between @samp{A} and @samp{B},
+and upper-case and lower-case ASCII characters will collate together.
+
+@item globstar
+If set, the pattern @samp{**} used in a filename expansion context will
+match all files and zero or more directories and subdirectories.
+If the pattern is followed by a @samp{/}, only directories and
+subdirectories match.
+
+@item gnu_errfmt
+If set, shell error messages are written in the standard @sc{gnu} error
+message format.
+
+@item histappend
+If set, the history list is appended to the file named by the value
+of the @env{HISTFILE}
+variable when the shell exits, rather than overwriting the file.
+
+@item histreedit
+If set, and Readline
+is being used, a user is given the opportunity to re-edit a
+failed history substitution.
+
+@item histverify
+If set, and Readline
+is being used, the results of history substitution are not immediately
+passed to the shell parser. Instead, the resulting line is loaded into
+the Readline editing buffer, allowing further modification.
+
+@item hostcomplete
+If set, and Readline is being used, Bash will attempt to perform
+hostname completion when a word containing a @samp{@@} is being
+completed (@pxref{Commands For Completion}). This option is enabled
+by default.
+
+@item huponexit
+If set, Bash will send @code{SIGHUP} to all jobs when an interactive
+login shell exits (@pxref{Signals}).
+
+@item interactive_comments
+Allow a word beginning with @samp{#}
+to cause that word and all remaining characters on that
+line to be ignored in an interactive shell.
+This option is enabled by default.
+
+@item lastpipe
+If set, and job control is not active, the shell runs the last command of
+a pipeline not executed in the background in the current shell environment.
+
+@item lithist
+If enabled, and the @code{cmdhist}
+option is enabled, multi-line commands are saved to the history with
+embedded newlines rather than using semicolon separators where possible.
+
+@item login_shell
+The shell sets this option if it is started as a login shell
+(@pxref{Invoking Bash}).
+The value may not be changed.
+
+@item mailwarn
+If set, and a file that Bash is checking for mail has been
+accessed since the last time it was checked, the message
+@code{"The mail in @var{mailfile} has been read"} is displayed.
+
+@item no_empty_cmd_completion
+If set, and Readline is being used, Bash will not attempt to search
+the @env{PATH} for possible completions when completion is attempted
+on an empty line.
+
+@item nocaseglob
+If set, Bash matches filenames in a case-insensitive fashion when
+performing filename expansion.
+
+@item nocasematch
+If set, Bash matches patterns in a case-insensitive fashion when
+performing matching while executing @code{case} or @code{[[}
+conditional commands.
+
+@item nullglob
+If set, Bash allows filename patterns which match no
+files to expand to a null string, rather than themselves.
+
+@item progcomp
+If set, the programmable completion facilities
+(@pxref{Programmable Completion}) are enabled.
+This option is enabled by default.
+
+@item promptvars
+If set, prompt strings undergo
+parameter expansion, command substitution, arithmetic
+expansion, and quote removal after being expanded
+as described below (@pxref{Printing a Prompt}).
+This option is enabled by default.
+
+@item restricted_shell
+The shell sets this option if it is started in restricted mode
+(@pxref{The Restricted Shell}).
+The value may not be changed.
+This is not reset when the startup files are executed, allowing
+the startup files to discover whether or not a shell is restricted.
+
+@item shift_verbose
+If this is set, the @code{shift}
+builtin prints an error message when the shift count exceeds the
+number of positional parameters.
+
+@item sourcepath
+If set, the @code{source} builtin uses the value of @env{PATH}
+to find the directory containing the file supplied as an argument.
+This option is enabled by default.
+
+@item xpg_echo
+If set, the @code{echo} builtin expands backslash-escape sequences
+by default.
+
+@end table
+
+@noindent
+The return status when listing options is zero if all @var{optnames}
+are enabled, non-zero otherwise.
+When setting or unsetting options, the return status is zero unless an
+@var{optname} is not a valid shell option.
+
+@end table
+
+@node Special Builtins
+@section Special Builtins
+@cindex special builtin
+
+For historical reasons, the @sc{posix} standard has classified
+several builtin commands as @emph{special}.
+When Bash is executing in @sc{posix} mode, the special builtins
+differ from other builtin commands in three respects:
+
+@enumerate
+@item
+Special builtins are found before shell functions during command lookup.
+
+@item
+If a special builtin returns an error status, a non-interactive shell exits.
+
+@item
+Assignment statements preceding the command stay in effect in the shell
+environment after the command completes.
+@end enumerate
+
+When Bash is not executing in @sc{posix} mode, these builtins behave no
+differently than the rest of the Bash builtin commands.
+The Bash @sc{posix} mode is described in @ref{Bash POSIX Mode}.
+
+These are the @sc{posix} special builtins:
+@example
+@w{break : . continue eval exec exit export readonly return set}
+@w{shift trap unset}
+@end example
+
+@node Shell Variables
+@chapter Shell Variables
+
+@menu
+* Bourne Shell Variables:: Variables which Bash uses in the same way
+ as the Bourne Shell.
+* Bash Variables:: List of variables that exist in Bash.
+@end menu
+
+This chapter describes the shell variables that Bash uses.
+Bash automatically assigns default values to a number of variables.
+
+@node Bourne Shell Variables
+@section Bourne Shell Variables
+
+Bash uses certain shell variables in the same way as the Bourne shell.
+In some cases, Bash assigns a default value to the variable.
+
+@vtable @code
+
+@item CDPATH
+A colon-separated list of directories used as a search path for
+the @code{cd} builtin command.
+
+@item HOME
+The current user's home directory; the default for the @code{cd} builtin
+command.
+The value of this variable is also used by tilde expansion
+(@pxref{Tilde Expansion}).
+
+@item IFS
+A list of characters that separate fields; used when the shell splits
+words as part of expansion.
+
+@item MAIL
+If this parameter is set to a filename or directory name
+and the @env{MAILPATH} variable
+is not set, Bash informs the user of the arrival of mail in
+the specified file or Maildir-format directory.
+
+@item MAILPATH
+A colon-separated list of filenames which the shell periodically checks
+for new mail.
+Each list entry can specify the message that is printed when new mail
+arrives in the mail file by separating the file name from the message with
+a @samp{?}.
+When used in the text of the message, @code{$_} expands to the name of
+the current mail file.
+
+@item OPTARG
+The value of the last option argument processed by the @code{getopts} builtin.
+
+@item OPTIND
+The index of the last option argument processed by the @code{getopts} builtin.
+
+@item PATH
+A colon-separated list of directories in which the shell looks for
+commands.
+A zero-length (null) directory name in the value of @code{PATH} indicates the
+current directory.
+A null directory name may appear as two adjacent colons, or as an initial
+or trailing colon.
+
+
+@item PS1
+The primary prompt string. The default value is @samp{\s-\v\$ }.
+@xref{Printing a Prompt}, for the complete list of escape
+sequences that are expanded before @env{PS1} is displayed.
+
+@item PS2
+The secondary prompt string. The default value is @samp{> }.
+
+@end vtable
+
+@node Bash Variables
+@section Bash Variables
+
+These variables are set or used by Bash, but other shells
+do not normally treat them specially.
+
+A few variables used by Bash are described in different chapters:
+variables for controlling the job control facilities
+(@pxref{Job Control Variables}).
+
+@vtable @code
+
+@item BASH
+The full pathname used to execute the current instance of Bash.
+
+@item BASHOPTS
+A colon-separated list of enabled shell options. Each word in
+the list is a valid argument for the @option{-s} option to the
+@code{shopt} builtin command (@pxref{The Shopt Builtin}).
+The options appearing in @env{BASHOPTS} are those reported
+as @samp{on} by @samp{shopt}.
+If this variable is in the environment when Bash
+starts up, each shell option in the list will be enabled before
+reading any startup files. This variable is readonly.
+
+@item BASHPID
+Expands to the process ID of the current Bash process.
+This differs from @code{$$} under certain circumstances, such as subshells
+that do not require Bash to be re-initialized.
+
+@item BASH_ALIASES
+An associative array variable whose members correspond to the internal
+list of aliases as maintained by the @code{alias} builtin.
+(@pxref{Bourne Shell Builtins}).
+Elements added to this array appear in the alias list; unsetting array
+elements cause aliases to be removed from the alias list.
+
+@item BASH_ARGC
+An array variable whose values are the number of parameters in each
+frame of the current bash execution call stack. The number of
+parameters to the current subroutine (shell function or script executed
+with @code{.} or @code{source}) is at the top of the stack. When a
+subroutine is executed, the number of parameters passed is pushed onto
+@code{BASH_ARGC}.
+The shell sets @code{BASH_ARGC} only when in extended debugging mode
+(see @ref{The Shopt Builtin}
+for a description of the @code{extdebug} option to the @code{shopt}
+builtin).
+
+@item BASH_ARGV
+An array variable containing all of the parameters in the current bash
+execution call stack. The final parameter of the last subroutine call
+is at the top of the stack; the first parameter of the initial call is
+at the bottom. When a subroutine is executed, the parameters supplied
+are pushed onto @code{BASH_ARGV}.
+The shell sets @code{BASH_ARGV} only when in extended debugging mode
+(see @ref{The Shopt Builtin}
+for a description of the @code{extdebug} option to the @code{shopt}
+builtin).
+
+@item BASH_CMDS
+An associative array variable whose members correspond to the internal
+hash table of commands as maintained by the @code{hash} builtin
+(@pxref{Bourne Shell Builtins}).
+Elements added to this array appear in the hash table; unsetting array
+elements cause commands to be removed from the hash table.
+
+@item BASH_COMMAND
+The command currently being executed or about to be executed, unless the
+shell is executing a command as the result of a trap,
+in which case it is the command executing at the time of the trap.
+
+@item BASH_ENV
+If this variable is set when Bash is invoked to execute a shell
+script, its value is expanded and used as the name of a startup file
+to read before executing the script. @xref{Bash Startup Files}.
+
+@item BASH_EXECUTION_STRING
+The command argument to the @option{-c} invocation option.
+
+@item BASH_LINENO
+An array variable whose members are the line numbers in source files
+where each corresponding member of @var{FUNCNAME} was invoked.
+@code{$@{BASH_LINENO[$i]@}} is the line number in the source file
+(@code{$@{BASH_SOURCE[$i+1]@}}) where
+@code{$@{FUNCNAME[$i]@}} was called (or @code{$@{BASH_LINENO[$i-1]@}} if
+referenced within another shell function).
+Use @code{LINENO} to obtain the current line number.
+
+@item BASH_REMATCH
+An array variable whose members are assigned by the @samp{=~} binary
+operator to the @code{[[} conditional command
+(@pxref{Conditional Constructs}).
+The element with index 0 is the portion of the string
+matching the entire regular expression.
+The element with index @var{n} is the portion of the
+string matching the @var{n}th parenthesized subexpression.
+This variable is read-only.
+
+@item BASH_SOURCE
+An array variable whose members are the source filenames where the
+corresponding shell function names in the @code{FUNCNAME} array
+variable are defined.
+The shell function @code{$@{FUNCNAME[$i]@}} is defined in the file
+@code{$@{BASH_SOURCE[$i]@}} and called from @code{$@{BASH_SOURCE[$i+1]@}}
+
+@item BASH_SUBSHELL
+Incremented by one within each subshell or subshell environment when
+the shell begins executing in that environment.
+The initial value is 0.
+
+@item BASH_VERSINFO
+A readonly array variable (@pxref{Arrays})
+whose members hold version information for this instance of Bash.
+The values assigned to the array members are as follows:
+
+@table @code
+
+@item BASH_VERSINFO[0]
+The major version number (the @var{release}).
+
+@item BASH_VERSINFO[1]
+The minor version number (the @var{version}).
+
+@item BASH_VERSINFO[2]
+The patch level.
+
+@item BASH_VERSINFO[3]
+The build version.
+
+@item BASH_VERSINFO[4]
+The release status (e.g., @var{beta1}).
+
+@item BASH_VERSINFO[5]
+The value of @env{MACHTYPE}.
+
+@end table
+
+@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} command to determine the terminal width
+when printing selection lists. Automatically set by an interactive shell
+upon receipt of a
+@code{SIGWINCH}.
+
+@item COMP_CWORD
+An index into @env{$@{COMP_WORDS@}} of the word containing the current
+cursor position.
+This variable is available only in shell functions invoked by the
+programmable completion facilities (@pxref{Programmable Completion}).
+
+@item COMP_LINE
+The current command line.
+This variable is available only in shell functions and external
+commands invoked by the
+programmable completion facilities (@pxref{Programmable Completion}).
+
+@item COMP_POINT
+The index of the current cursor position relative to the beginning of
+the current command.
+If the current cursor position is at the end of the current command,
+the value of this variable is equal to @code{$@{#COMP_LINE@}}.
+This variable is available only in shell functions and external
+commands invoked by the
+programmable completion facilities (@pxref{Programmable Completion}).
+
+@item COMP_TYPE
+Set to an integer value corresponding to the type of completion attempted
+that caused a completion function to be called:
+@var{TAB}, for normal completion,
+@samp{?}, for listing completions after successive tabs,
+@samp{!}, for listing alternatives on partial word completion,
+@samp{@@}, to list completions if the word is not unmodified,
+or
+@samp{%}, for menu completion.
+This variable is available only in shell functions and external
+commands invoked by the
+programmable completion facilities (@pxref{Programmable Completion}).
+
+@item COMP_KEY
+The key (or final key of a key sequence) used to invoke the current
+completion function.
+
+@item COMP_WORDBREAKS
+The set of characters that the Readline library treats as word
+separators when performing word completion.
+If @code{COMP_WORDBREAKS} is unset, it loses its special properties,
+even if it is subsequently reset.
+
+@item COMP_WORDS
+An array variable consisting of the individual
+words in the current command line.
+The line is split into words as Readline would split it, using
+@code{COMP_WORDBREAKS} as described above.
+This variable is available only in shell functions invoked by the
+programmable completion facilities (@pxref{Programmable Completion}).
+
+@item COMPREPLY
+An array variable from which Bash reads the possible completions
+generated by a shell function invoked by the programmable completion
+facility (@pxref{Programmable Completion}).
+
+@item COPROC
+An array variable created to hold the file descriptors
+for output from and input to an unnamed coprocess (@pxref{Coprocesses}).
+
+@item DIRSTACK
+An array variable containing the current contents of the directory stack.
+Directories appear in the stack in the order they are displayed by the
+@code{dirs} builtin.
+Assigning to members of this array variable may be used to modify
+directories already in the stack, but the @code{pushd} and @code{popd}
+builtins must be used to add and remove directories.
+Assignment to this variable will not change the current directory.
+If @env{DIRSTACK} is unset, it loses its special properties, even if
+it is subsequently reset.
+
+@item EMACS
+If Bash finds this variable in the environment when the shell
+starts with value @samp{t}, it assumes that the shell is running in an
+Emacs shell buffer and disables line editing.
+
+@item ENV
+Similar to @code{BASH_ENV}; used when the shell is invoked in
+@sc{posix} Mode (@pxref{Bash POSIX Mode}).
+
+@item EUID
+The numeric effective user id of the current user. This variable
+is readonly.
+
+@item FCEDIT
+The editor used as a default by the @option{-e} option to the @code{fc}
+builtin command.
+
+@item FIGNORE
+A colon-separated list of suffixes to ignore when performing
+filename completion.
+A file name whose suffix matches one of the entries in
+@env{FIGNORE}
+is excluded from the list of matched file names. A sample
+value is @samp{.o:~}
+
+@item FUNCNAME
+An array variable containing the names of all shell functions
+currently in the execution call stack.
+The element with index 0 is the name of any currently-executing
+shell function.
+The bottom-most element (the one with the highest index)
+is @code{"main"}.
+This variable exists only when a shell function is executing.
+Assignments to @env{FUNCNAME} have no effect and return an error status.
+If @env{FUNCNAME} is unset, it loses its special properties, even if
+it is subsequently reset.
+
+This variable can be used with @code{BASH_LINENO} and @code{BASH_SOURCE}.
+Each element of @code{FUNCNAME} has corresponding elements in
+@code{BASH_LINENO} and @code{BASH_SOURCE} to describe the call stack.
+For instance, @code{$@{FUNCNAME[$i]@}} was called from the file
+@code{$@{BASH_SOURCE[$i+1]@}} at line number @code{$@{BASH_LINENO[$i]@}}.
+The @code{caller} builtin displays the current call stack using this
+information.
+
+@item FUNCNEST
+If set to a numeric value greater than 0, defines a maximum function
+nesting level. Function invocations that exceed this nesting level
+will cause the current command to abort.
+
+@item GLOBIGNORE
+A colon-separated list of patterns defining the set of filenames to
+be ignored by filename expansion.
+If a filename matched by a filename expansion pattern also matches one
+of the patterns in @env{GLOBIGNORE}, it is removed from the list
+of matches.
+
+@item GROUPS
+An array variable containing the list of groups of which the current
+user is a member.
+Assignments to @env{GROUPS} have no effect and return an error status.
+If @env{GROUPS} is unset, it loses its special properties, even if it is
+subsequently reset.
+
+@item histchars
+Up to three characters which control history expansion, quick
+substitution, and tokenization (@pxref{History Interaction}).
+The first character is the
+@var{history expansion} character, that is, the character which signifies the
+start of a history expansion, normally @samp{!}. The second character is the
+character which signifies `quick substitution' when seen as the first
+character on a line, normally @samp{^}. The optional third character is the
+character which indicates that the remainder of the line is a comment when
+found as the first character of a word, usually @samp{#}. The history
+comment character causes history substitution to be skipped for the
+remaining words on the line. It does not necessarily cause the shell
+parser to treat the rest of the line as a comment.
+
+@item HISTCMD
+The history number, or index in the history list, of the current
+command. If @env{HISTCMD} is unset, it loses its special properties,
+even if it is subsequently reset.
+
+@item HISTCONTROL
+A colon-separated list of values controlling how commands are saved on
+the history list.
+If the list of values includes @samp{ignorespace}, lines which begin
+with a space character are not saved in the history list.
+A value of @samp{ignoredups} causes lines which match the previous
+history entry to not be saved.
+A value of @samp{ignoreboth} is shorthand for
+@samp{ignorespace} and @samp{ignoredups}.
+A value of @samp{erasedups} causes all previous lines matching the
+current line to be removed from the history list before that line
+is saved.
+Any value not in the above list is ignored.
+If @env{HISTCONTROL} is unset, or does not include a valid value,
+all lines read by the shell parser are saved on the history list,
+subject to the value of @env{HISTIGNORE}.
+The second and subsequent lines of a multi-line compound command are
+not tested, and are added to the history regardless of the value of
+@env{HISTCONTROL}.
+
+@item HISTFILE
+The name of the file to which the command history is saved. The
+default value is @file{~/.bash_history}.
+
+@item HISTFILESIZE
+The maximum number of lines contained in the history file. When this
+variable is assigned a value, the history file is truncated, if
+necessary, by removing the oldest entries,
+to contain no more than that number of lines.
+The history file is also truncated to this size after
+writing it when an interactive shell exits.
+The default value is 500.
+
+@item HISTIGNORE
+A colon-separated list of patterns used to decide which command
+lines should be saved on the history list. Each pattern is
+anchored at the beginning of the line and must match the complete
+line (no implicit @samp{*} is appended). Each pattern is tested
+against the line after the checks specified by @env{HISTCONTROL}
+are applied. In addition to the normal shell pattern matching
+characters, @samp{&} matches the previous history line. @samp{&}
+may be escaped using a backslash; the backslash is removed
+before attempting a match.
+The second and subsequent lines of a multi-line compound command are
+not tested, and are added to the history regardless of the value of
+@env{HISTIGNORE}.
+
+@env{HISTIGNORE} subsumes the function of @env{HISTCONTROL}. A
+pattern of @samp{&} is identical to @code{ignoredups}, and a
+pattern of @samp{[ ]*} is identical to @code{ignorespace}.
+Combining these two patterns, separating them with a colon,
+provides the functionality of @code{ignoreboth}.
+
+@item HISTSIZE
+The maximum number of commands to remember on the history list.
+The default value is 500.
+
+@item HISTTIMEFORMAT
+If this variable is set and not null, its value is used as a format string
+for @var{strftime} to print the time stamp associated with each history
+entry displayed by the @code{history} builtin.
+If this variable is set, time stamps are written to the history file so
+they may be preserved across shell sessions.
+This uses the history comment character to distinguish timestamps from
+other history lines.
+
+@item HOSTFILE
+Contains the name of a file in the same format as @file{/etc/hosts} that
+should be read when the shell needs to complete a hostname.
+The list of possible hostname completions may be changed while the shell
+is running;
+the next time hostname completion is attempted after the
+value is changed, Bash adds the contents of the new file to the
+existing list.
+If @env{HOSTFILE} is set, but has no value, or does not name a readable file,
+Bash attempts to read
+@file{/etc/hosts} to obtain the list of possible hostname completions.
+When @env{HOSTFILE} is unset, the hostname list is cleared.
+
+@item HOSTNAME
+The name of the current host.
+
+@item HOSTTYPE
+A string describing the machine Bash is running on.
+
+@item IGNOREEOF
+Controls the action of the shell on receipt of an @code{EOF} character
+as the sole input. If set, the value denotes the number
+of consecutive @code{EOF} characters that can be read as the
+first character on an input line
+before the shell will exit. If the variable exists but does not
+have a numeric value (or has no value) then the default is 10.
+If the variable does not exist, then @code{EOF} signifies the end of
+input to the shell. This is only in effect for interactive shells.
+
+@item INPUTRC
+The name of the Readline initialization file, overriding the default
+of @file{~/.inputrc}.
+
+@item LANG
+Used to determine the locale category for any category not specifically
+selected with a variable starting with @code{LC_}.
+
+@item LC_ALL
+This variable overrides the value of @env{LANG} and any other
+@code{LC_} variable specifying a locale category.
+
+@item LC_COLLATE
+This variable determines the collation order used when sorting the
+results of filename expansion, and
+determines the behavior of range expressions, equivalence classes,
+and collating sequences within filename expansion and pattern matching
+(@pxref{Filename Expansion}).
+
+@item LC_CTYPE
+This variable determines the interpretation of characters and the
+behavior of character classes within filename expansion and pattern
+matching (@pxref{Filename Expansion}).
+
+@item LC_MESSAGES
+This variable determines the locale used to translate double-quoted
+strings preceded by a @samp{$} (@pxref{Locale Translation}).
+
+@item LC_NUMERIC
+This variable determines the locale category used for number formatting.
+
+@item LINENO
+The line number in the script or shell function currently executing.
+
+@item LINES
+Used by the @code{select} command to determine the column length
+for printing selection lists. Automatically set by an interactive shell
+upon receipt of a
+@code{SIGWINCH}.
+
+@item MACHTYPE
+A string that fully describes the system type on which Bash
+is executing, in the standard @sc{gnu} @var{cpu-company-system} format.
+
+@item MAILCHECK
+How often (in seconds) that the shell should check for mail in the
+files specified in the @env{MAILPATH} or @env{MAIL} variables.
+The default is 60 seconds. When it is time to check
+for mail, the shell does so before displaying the primary prompt.
+If this variable is unset, or set to a value that is not a number
+greater than or equal to zero, the shell disables mail checking.
+
+@item MAPFILE
+An array variable created to hold the text read by the
+@code{mapfile} builtin when no variable name is supplied.
+
+@item OLDPWD
+The previous working directory as set by the @code{cd} builtin.
+
+@item OPTERR
+If set to the value 1, Bash displays error messages
+generated by the @code{getopts} builtin command.
+
+@item OSTYPE
+A string describing the operating system Bash is running on.
+
+@item PIPESTATUS
+An array variable (@pxref{Arrays})
+containing a list of exit status values from the processes
+in the most-recently-executed foreground pipeline (which may
+contain only a single command).
+
+@item POSIXLY_CORRECT
+If this variable is in the environment when @code{bash} starts, the shell
+enters @sc{posix} mode (@pxref{Bash POSIX Mode}) before reading the
+startup files, as if the @option{--posix} invocation option had been supplied.
+If it is set while the shell is running, @code{bash} enables @sc{posix} mode,
+as if the command
+@example
+@code{set -o posix}
+@end example
+@noindent
+had been executed.
+
+@item PPID
+The process @sc{id} of the shell's parent process. This variable
+is readonly.
+
+@item PROMPT_COMMAND
+If set, the value is interpreted as a command to execute
+before the printing of each primary prompt (@env{$PS1}).
+
+@item PROMPT_DIRTRIM
+If set to a number greater than zero, the value is used as the number of
+trailing directory components to retain when expanding the @code{\w} and
+@code{\W} prompt string escapes (@pxref{Printing a Prompt}).
+Characters removed are replaced with an ellipsis.
+
+@item PS3
+The value of this variable is used as the prompt for the
+@code{select} command. If this variable is not set, the
+@code{select} command prompts with @samp{#? }
+
+@item PS4
+The value is the prompt printed before the command line is echoed
+when the @option{-x} option is set (@pxref{The Set Builtin}).
+The first character of @env{PS4} is replicated multiple times, as
+necessary, to indicate multiple levels of indirection.
+The default is @samp{+ }.
+
+@item PWD
+The current working directory as set by the @code{cd} builtin.
+
+@item RANDOM
+Each time this parameter is referenced, a random integer
+between 0 and 32767 is generated. Assigning a value to this
+variable seeds the random number generator.
+
+@item READLINE_LINE
+The contents of the Readline line buffer, for use
+with @samp{bind -x} (@pxref{Bash Builtins}).
+
+@item READLINE_POINT
+The position of the insertion point in the Readline line buffer, for use
+with @samp{bind -x} (@pxref{Bash Builtins}).
+
+@item REPLY
+The default variable for the @code{read} builtin.
+
+@item SECONDS
+This variable expands to the number of seconds since the
+shell was started. Assignment to this variable resets
+the count to the value assigned, and the expanded value
+becomes the value assigned plus the number of seconds
+since the assignment.
+
+@item SHELL
+The full pathname to the shell is kept in this environment variable.
+If it is not set when the shell starts,
+Bash assigns to it the full pathname of the current user's login shell.
+
+@item SHELLOPTS
+A colon-separated list of enabled shell options. Each word in
+the list is a valid argument for the @option{-o} option to the
+@code{set} builtin command (@pxref{The Set Builtin}).
+The options appearing in @env{SHELLOPTS} are those reported
+as @samp{on} by @samp{set -o}.
+If this variable is in the environment when Bash
+starts up, each shell option in the list will be enabled before
+reading any startup files. This variable is readonly.
+
+@item SHLVL
+Incremented by one each time a new instance of Bash is started. This is
+intended to be a count of how deeply your Bash shells are nested.
+
+@item TIMEFORMAT
+The value of this parameter is used as a format string specifying
+how the timing information for pipelines prefixed with the @code{time}
+reserved word should be displayed.
+The @samp{%} character introduces an
+escape sequence that is expanded to a time value or other
+information.
+The escape sequences and their meanings are as
+follows; the braces denote optional portions.
+
+@table @code
+
+@item %%
+A literal @samp{%}.
+
+@item %[@var{p}][l]R
+The elapsed time in seconds.
+
+@item %[@var{p}][l]U
+The number of CPU seconds spent in user mode.
+
+@item %[@var{p}][l]S
+The number of CPU seconds spent in system mode.
+
+@item %P
+The CPU percentage, computed as (%U + %S) / %R.
+@end table
+
+The optional @var{p} is a digit specifying the precision, the number of
+fractional digits after a decimal point.
+A value of 0 causes no decimal point or fraction to be output.
+At most three places after the decimal point may be specified; values
+of @var{p} greater than 3 are changed to 3.
+If @var{p} is not specified, the value 3 is used.
+
+The optional @code{l} specifies a longer format, including minutes, of
+the form @var{MM}m@var{SS}.@var{FF}s.
+The value of @var{p} determines whether or not the fraction is included.
+
+If this variable is not set, Bash acts as if it had the value
+@example
+@code{$'\nreal\t%3lR\nuser\t%3lU\nsys\t%3lS'}
+@end example
+If the value is null, no timing information is displayed.
+A trailing newline is added when the format string is displayed.
+
+@item TMOUT
+If set to a value greater than zero, @code{TMOUT} is treated as the
+default timeout for the @code{read} builtin (@pxref{Bash Builtins}).
+The @code{select} command (@pxref{Conditional Constructs}) terminates
+if input does not arrive after @code{TMOUT} seconds when input is coming
+from a terminal.
+
+In an interactive shell, the value is interpreted as
+the number of seconds to wait for input after issuing the primary
+prompt when the shell is interactive.
+Bash terminates after that number of seconds if input does
+not arrive.
+
+@item TMPDIR
+If set, Bash uses its value as the name of a directory in which
+Bash creates temporary files for the shell's use.
+
+@item UID
+The numeric real user id of the current user. This variable is readonly.
+
+@end vtable
+
+@node Bash Features
+@chapter Bash Features
+
+This section describes features unique to Bash.
+
+@menu
+* Invoking Bash:: Command line options that you can give
+ to Bash.
+* Bash Startup Files:: When and how Bash executes scripts.
+* Interactive Shells:: What an interactive shell is.
+* Bash Conditional Expressions:: Primitives used in composing expressions for
+ the @code{test} builtin.
+* Shell Arithmetic:: Arithmetic on shell variables.
+* Aliases:: Substituting one command for another.
+* Arrays:: Array Variables.
+* The Directory Stack:: History of visited directories.
+* Printing a Prompt:: Controlling the PS1 string.
+* The Restricted Shell:: A more controlled mode of shell execution.
+* Bash POSIX Mode:: Making Bash behave more closely to what
+ the POSIX standard specifies.
+@end menu
+
+@node Invoking Bash
+@section Invoking Bash
+
+@example
+bash [long-opt] [-ir] [-abefhkmnptuvxdBCDHP] [-o @var{option}] [-O @var{shopt_option}] [@var{argument} @dots{}]
+bash [long-opt] [-abefhkmnptuvxdBCDHP] [-o @var{option}] [-O @var{shopt_option}] -c @var{string} [@var{argument} @dots{}]
+bash [long-opt] -s [-abefhkmnptuvxdBCDHP] [-o @var{option}] [-O @var{shopt_option}] [@var{argument} @dots{}]
+@end example
+
+All of the single-character options used with the @code{set} builtin
+(@pxref{The Set Builtin}) can be used as options when the shell is invoked.
+In addition, there are several multi-character
+options that you can use. These options must appear on the command
+line before the single-character options to be recognized.
+
+@table @code
+@item --debugger
+Arrange for the debugger profile to be executed before the shell
+starts. Turns on extended debugging mode (see @ref{The Shopt Builtin}
+for a description of the @code{extdebug} option to the @code{shopt}
+builtin).
+
+@item --dump-po-strings
+A list of all double-quoted strings preceded by @samp{$}
+is printed on the standard output
+in the @sc{gnu} @code{gettext} PO (portable object) file format.
+Equivalent to @option{-D} except for the output format.
+
+@item --dump-strings
+Equivalent to @option{-D}.
+
+@item --help
+Display a usage message on standard output and exit successfully.
+
+@item --init-file @var{filename}
+@itemx --rcfile @var{filename}
+Execute commands from @var{filename} (instead of @file{~/.bashrc})
+in an interactive shell.
+
+@item --login
+Equivalent to @option{-l}.
+
+@item --noediting
+Do not use the @sc{gnu} Readline library (@pxref{Command Line Editing})
+to read command lines when the shell is interactive.
+
+@item --noprofile
+Don't load the system-wide startup file @file{/etc/profile}
+or any of the personal initialization files
+@file{~/.bash_profile}, @file{~/.bash_login}, or @file{~/.profile}
+when Bash is invoked as a login shell.
+
+@item --norc
+Don't read the @file{~/.bashrc} initialization file in an
+interactive shell. This is on by default if the shell is
+invoked as @code{sh}.
+
+@item --posix
+Change the behavior of Bash where the default operation differs
+from the @sc{posix} standard to match the standard. This
+is intended to make Bash behave as a strict superset of that
+standard. @xref{Bash POSIX Mode}, for a description of the Bash
+@sc{posix} mode.
+
+@item --restricted
+Make the shell a restricted shell (@pxref{The Restricted Shell}).
+
+@item --verbose
+Equivalent to @option{-v}. Print shell input lines as they're read.
+
+@item --version
+Show version information for this instance of
+Bash on the standard output and exit successfully.
+
+@end table
+
+There are several single-character options that may be supplied at
+invocation which are not available with the @code{set} builtin.
+
+@table @code
+@item -c @var{string}
+Read and execute commands from @var{string} after processing the
+options, then exit. Any remaining arguments are assigned to the
+positional parameters, starting with @code{$0}.
+
+@item -i
+Force the shell to run interactively. Interactive shells are
+described in @ref{Interactive Shells}.
+
+@item -l
+Make this shell act as if it had been directly invoked by login.
+When the shell is interactive, this is equivalent to starting a
+login shell with @samp{exec -l bash}.
+When the shell is not interactive, the login shell startup files will
+be executed.
+@samp{exec bash -l} or @samp{exec bash --login}
+will replace the current shell with a Bash login shell.
+@xref{Bash Startup Files}, for a description of the special behavior
+of a login shell.
+
+@item -r
+Make the shell a restricted shell (@pxref{The Restricted Shell}).
+
+@item -s
+If this option is present, or if no arguments remain after option
+processing, then commands are read from the standard input.
+This option allows the positional parameters to be set
+when invoking an interactive shell.
+
+@item -D
+A list of all double-quoted strings preceded by @samp{$}
+is printed on the standard output.
+These are the strings that
+are subject to language translation when the current locale
+is not @code{C} or @code{POSIX} (@pxref{Locale Translation}).
+This implies the @option{-n} option; no commands will be executed.
+
+@item [-+]O [@var{shopt_option}]
+@var{shopt_option} is one of the shell options accepted by the
+@code{shopt} builtin (@pxref{The Shopt Builtin}).
+If @var{shopt_option} is present, @option{-O} sets the value of that option;
+@option{+O} unsets it.
+If @var{shopt_option} is not supplied, the names and values of the shell
+options accepted by @code{shopt} are printed on the standard output.
+If the invocation option is @option{+O}, the output is displayed in a format
+that may be reused as input.
+
+@item --
+A @code{--} signals the end of options and disables further option
+processing.
+Any arguments after the @code{--} are treated as filenames and arguments.
+
+@end table
+
+@cindex login shell
+A @emph{login} shell is one whose first character of argument zero is
+@samp{-}, or one invoked with the @option{--login} option.
+
+@cindex interactive shell
+An @emph{interactive} shell is one started without non-option arguments,
+unless @option{-s} is specified,
+without specifying the @option{-c} option, and whose input and output are both
+connected to terminals (as determined by @code{isatty(3)}), or one
+started with the @option{-i} option. @xref{Interactive Shells}, for more
+information.
+
+If arguments remain after option processing, and neither the
+@option{-c} nor the @option{-s}
+option has been supplied, the first argument is assumed to
+be the name of a file containing shell commands (@pxref{Shell Scripts}).
+When Bash is invoked in this fashion, @code{$0}
+is set to the name of the file, and the positional parameters
+are set to the remaining arguments.
+Bash reads and executes commands from this file, then exits.
+Bash's exit status is the exit status of the last command executed
+in the script. If no commands are executed, the exit status is 0.
+
+@node Bash Startup Files
+@section Bash Startup Files
+@cindex startup files
+
+This section describes how Bash executes its startup files.
+If any of the files exist but cannot be read, Bash reports an error.
+Tildes are expanded in file names as described above under
+Tilde Expansion (@pxref{Tilde Expansion}).
+
+Interactive shells are described in @ref{Interactive Shells}.
+
+@subsubheading Invoked as an interactive login shell, or with @option{--login}
+
+When Bash is invoked as an interactive login shell, or as a
+non-interactive shell with the @option{--login} option, it first reads and
+executes commands from the file @file{/etc/profile}, if that file exists.
+After reading that file, it looks for @file{~/.bash_profile},
+@file{~/.bash_login}, and @file{~/.profile}, in that order, and reads
+and executes commands from the first one that exists and is readable.
+The @option{--noprofile} option may be used when the shell is started to
+inhibit this behavior.
+
+When a login shell exits, Bash reads and executes commands from
+the file @file{~/.bash_logout}, if it exists.
+
+@subsubheading Invoked as an interactive non-login shell
+
+When an interactive shell that is not a login shell is started, Bash
+reads and executes commands from @file{~/.bashrc}, if that file exists.
+This may be inhibited by using the @option{--norc} option.
+The @option{--rcfile @var{file}} option will force Bash to read and
+execute commands from @var{file} instead of @file{~/.bashrc}.
+
+So, typically, your @file{~/.bash_profile} contains the line
+@example
+@code{if [ -f ~/.bashrc ]; then . ~/.bashrc; fi}
+@end example
+@noindent
+after (or before) any login-specific initializations.
+
+@subsubheading Invoked non-interactively
+
+When Bash is started non-interactively, to run a shell script,
+for example, it looks for the variable @env{BASH_ENV} in the environment,
+expands its value if it appears there, and uses the expanded value as
+the name of a file to read and execute. Bash behaves as if the
+following command were executed:
+@example
+@code{if [ -n "$BASH_ENV" ]; then . "$BASH_ENV"; fi}
+@end example
+@noindent
+but the value of the @env{PATH} variable is not used to search for the
+file name.
+
+As noted above, if a non-interactive shell is invoked with the
+@option{--login} option, Bash attempts to read and execute commands from the
+login shell startup files.
+
+@subsubheading Invoked with name @code{sh}
+
+If Bash is invoked with the name @code{sh}, it tries to mimic the
+startup behavior of historical versions of @code{sh} as closely as
+possible, while conforming to the @sc{posix} standard as well.
+
+When invoked as an interactive login shell, or as a non-interactive
+shell with the @option{--login} option, it first attempts to read
+and execute commands from @file{/etc/profile} and @file{~/.profile}, in
+that order.
+The @option{--noprofile} option may be used to inhibit this behavior.
+When invoked as an interactive shell with the name @code{sh}, Bash
+looks for the variable @env{ENV}, expands its value if it is defined,
+and uses the expanded value as the name of a file to read and execute.
+Since a shell invoked as @code{sh} does not attempt to read and execute
+commands from any other startup files, the @option{--rcfile} option has
+no effect.
+A non-interactive shell invoked with the name @code{sh} does not attempt
+to read any other startup files.
+
+When invoked as @code{sh}, Bash enters @sc{posix} mode after
+the startup files are read.
+
+@subsubheading Invoked in @sc{posix} mode
+
+When Bash is started in @sc{posix} mode, as with the
+@option{--posix} command line option, it follows the @sc{posix} standard
+for startup files.
+In this mode, interactive shells expand the @env{ENV} variable
+and commands are read and executed from the file whose name is the
+expanded value.
+No other startup files are read.
+
+@subsubheading Invoked by remote shell daemon
+
+Bash attempts to determine when it is being run with its standard input
+connected to a network connection, as when executed by the remote shell
+daemon, usually @code{rshd}, or the secure shell daemon @code{sshd}.
+If Bash determines it is being run in
+this fashion, it reads and executes commands from @file{~/.bashrc}, if that
+file exists and is readable.
+It will not do this if invoked as @code{sh}.
+The @option{--norc} option may be used to inhibit this behavior, and the
+@option{--rcfile} option may be used to force another file to be read, but
+@code{rshd} does not generally invoke the shell with those options or
+allow them to be specified.
+
+@subsubheading Invoked with unequal effective and real @sc{uid/gid}s
+
+If Bash is started with the effective user (group) id not equal to the
+real user (group) id, and the @code{-p} option is not supplied, no startup
+files are read, shell functions are not inherited from the environment,
+the @env{SHELLOPTS}, @env{BASHOPTS}, @env{CDPATH}, and @env{GLOBIGNORE}
+variables, if they appear in the environment, are ignored, and the effective
+user id is set to the real user id.
+If the @code{-p} option is supplied at invocation, the startup behavior is
+the same, but the effective user id is not reset.
+
+@node Interactive Shells
+@section Interactive Shells
+@cindex interactive shell
+@cindex shell, interactive
+
+@menu
+* What is an Interactive Shell?:: What determines whether a shell is Interactive.
+* Is this Shell Interactive?:: How to tell if a shell is interactive.
+* Interactive Shell Behavior:: What changes in a interactive shell?
+@end menu
+
+@node What is an Interactive Shell?
+@subsection What is an Interactive Shell?
+
+An interactive shell
+is one started without non-option arguments, unless @option{-s} is
+specified, without specifying the @option{-c} option, and
+whose input and error output are both
+connected to terminals (as determined by @code{isatty(3)}),
+or one started with the @option{-i} option.
+
+An interactive shell generally reads from and writes to a user's
+terminal.
+
+The @option{-s} invocation option may be used to set the positional parameters
+when an interactive shell is started.
+
+@node Is this Shell Interactive?
+@subsection Is this Shell Interactive?
+
+To determine within a startup script whether or not Bash is
+running interactively,
+test the value of the @samp{-} special parameter.
+It contains @code{i} when the shell is interactive. For example:
+
+@example
+case "$-" in
+*i*) echo This shell is interactive ;;
+*) echo This shell is not interactive ;;
+esac
+@end example
+
+Alternatively, startup scripts may examine the variable
+@env{PS1}; it is unset in non-interactive shells, and set in
+interactive shells. Thus:
+
+@example
+if [ -z "$PS1" ]; then
+ echo This shell is not interactive
+else
+ echo This shell is interactive
+fi
+@end example
+
+@node Interactive Shell Behavior
+@subsection Interactive Shell Behavior
+
+When the shell is running interactively, it changes its behavior in
+several ways.
+
+@enumerate
+@item
+Startup files are read and executed as described in @ref{Bash Startup Files}.
+
+@item
+Job Control (@pxref{Job Control}) is enabled by default. When job
+control is in effect, Bash ignores the keyboard-generated job control
+signals @code{SIGTTIN}, @code{SIGTTOU}, and @code{SIGTSTP}.
+
+@item
+Bash expands and displays @env{PS1} before reading the first line
+of a command, and expands and displays @env{PS2} before reading the
+second and subsequent lines of a multi-line command.
+
+@item
+Bash executes the value of the @env{PROMPT_COMMAND} variable as a command
+before printing the primary prompt, @env{$PS1}
+(@pxref{Bash Variables}).
+
+@item
+Readline (@pxref{Command Line Editing}) is used to read commands from
+the user's terminal.
+
+@item
+Bash inspects the value of the @code{ignoreeof} option to @code{set -o}
+instead of exiting immediately when it receives an @code{EOF} on its
+standard input when reading a command (@pxref{The Set Builtin}).
+
+@item
+Command history (@pxref{Bash History Facilities})
+and history expansion (@pxref{History Interaction})
+are enabled by default.
+Bash will save the command history to the file named by @env{$HISTFILE}
+when an interactive shell exits.
+
+@item
+Alias expansion (@pxref{Aliases}) is performed by default.
+
+@item
+In the absence of any traps, Bash ignores @code{SIGTERM}
+(@pxref{Signals}).
+
+@item
+In the absence of any traps, @code{SIGINT} is caught and handled
+((@pxref{Signals}).
+@code{SIGINT} will interrupt some shell builtins.
+
+@item
+An interactive login shell sends a @code{SIGHUP} to all jobs on exit
+if the @code{huponexit} shell option has been enabled (@pxref{Signals}).
+
+@item
+The @option{-n} invocation option is ignored, and @samp{set -n} has
+no effect (@pxref{The Set Builtin}).
+
+@item
+Bash will check for mail periodically, depending on the values of the
+@env{MAIL}, @env{MAILPATH}, and @env{MAILCHECK} shell variables
+(@pxref{Bash Variables}).
+
+@item
+Expansion errors due to references to unbound shell variables after
+@samp{set -u} has been enabled will not cause the shell to exit
+(@pxref{The Set Builtin}).
+
+@item
+The shell will not exit on expansion errors caused by @var{var} being unset
+or null in @code{$@{@var{var}:?@var{word}@}} expansions
+(@pxref{Shell Parameter Expansion}).
+
+@item
+Redirection errors encountered by shell builtins will not cause the
+shell to exit.
+
+@item
+When running in @sc{posix} mode, a special builtin returning an error
+status will not cause the shell to exit (@pxref{Bash POSIX Mode}).
+
+@item
+A failed @code{exec} will not cause the shell to exit
+(@pxref{Bourne Shell Builtins}).
+
+@item
+Parser syntax errors will not cause the shell to exit.
+
+@item
+Simple spelling correction for directory arguments to the @code{cd}
+builtin is enabled by default (see the description of the @code{cdspell}
+option to the @code{shopt} builtin in @ref{The Shopt Builtin}).
+
+@item
+The shell will check the value of the @env{TMOUT} variable and exit
+if a command is not read within the specified number of seconds after
+printing @env{$PS1} (@pxref{Bash Variables}).
+
+@end enumerate
+
+@node Bash Conditional Expressions
+@section Bash Conditional Expressions
+@cindex expressions, conditional
+
+Conditional expressions are used by the @code{[[} compound command
+and the @code{test} and @code{[} builtin commands.
+
+Expressions may be unary or binary.
+Unary expressions are often used to examine the status of a file.
+There are string operators and numeric comparison operators as well.
+If the @var{file} argument to one of the primaries is of the form
+@file{/dev/fd/@var{N}}, then file descriptor @var{N} is checked.
+If the @var{file} argument to one of the primaries is one of
+@file{/dev/stdin}, @file{/dev/stdout}, or @file{/dev/stderr}, file
+descriptor 0, 1, or 2, respectively, is checked.
+
+When used with @samp{[[}, the @samp{<} and @samp{>} operators sort
+lexicographically using the current locale.
+The @code{test} command uses ASCII ordering.
+
+Unless otherwise specified, primaries that operate on files follow symbolic
+links and operate on the target of the link, rather than the link itself.
+
+@table @code
+@item -a @var{file}
+True if @var{file} exists.
+
+@item -b @var{file}
+True if @var{file} exists and is a block special file.
+
+@item -c @var{file}
+True if @var{file} exists and is a character special file.
+
+@item -d @var{file}
+True if @var{file} exists and is a directory.
+
+@item -e @var{file}
+True if @var{file} exists.
+
+@item -f @var{file}
+True if @var{file} exists and is a regular file.
+
+@item -g @var{file}
+True if @var{file} exists and its set-group-id bit is set.
+
+@item -h @var{file}
+True if @var{file} exists and is a symbolic link.
+
+@item -k @var{file}
+True if @var{file} exists and its "sticky" bit is set.
+
+@item -p @var{file}
+True if @var{file} exists and is a named pipe (FIFO).
+
+@item -r @var{file}
+True if @var{file} exists and is readable.
+
+@item -s @var{file}
+True if @var{file} exists and has a size greater than zero.
+
+@item -t @var{fd}
+True if file descriptor @var{fd} is open and refers to a terminal.
+
+@item -u @var{file}
+True if @var{file} exists and its set-user-id bit is set.
+
+@item -w @var{file}
+True if @var{file} exists and is writable.
+
+@item -x @var{file}
+True if @var{file} exists and is executable.
+
+@item -G @var{file}
+True if @var{file} exists and is owned by the effective group id.
+
+@item -L @var{file}
+True if @var{file} exists and is a symbolic link.
+
+@item -N @var{file}
+True if @var{file} exists and has been modified since it was last read.
+
+@item -O @var{file}
+True if @var{file} exists and is owned by the effective user id.
+
+@item -S @var{file}
+True if @var{file} exists and is a socket.
+
+@item @var{file1} -ef @var{file2}
+True if @var{file1} and @var{file2} refer to the same device and
+inode numbers.
+
+@item @var{file1} -nt @var{file2}
+True if @var{file1} is newer (according to modification date)
+than @var{file2}, or if @var{file1} exists and @var{file2} does not.
+
+@item @var{file1} -ot @var{file2}
+True if @var{file1} is older than @var{file2},
+or if @var{file2} exists and @var{file1} does not.
+
+@item -o @var{optname}
+True if the shell option @var{optname} is enabled.
+The list of options appears in the description of the @option{-o}
+option to the @code{set} builtin (@pxref{The Set Builtin}).
+
+@item -v @var{varname}
+True if the shell variable @var{varname} is set (has been assigned a value).
+
+@item -z @var{string}
+True if the length of @var{string} is zero.
+
+@item -n @var{string}
+@itemx @var{string}
+True if the length of @var{string} is non-zero.
+
+@item @var{string1} == @var{string2}
+@itemx @var{string1} = @var{string2}
+True if the strings are equal.
+@samp{=} should be used with the @code{test} command for @sc{posix} conformance.
+
+@item @var{string1} != @var{string2}
+True if the strings are not equal.
+
+@item @var{string1} < @var{string2}
+True if @var{string1} sorts before @var{string2} lexicographically.
+
+@item @var{string1} > @var{string2}
+True if @var{string1} sorts after @var{string2} lexicographically.
+
+@item @var{arg1} OP @var{arg2}
+@code{OP} is one of
+@samp{-eq}, @samp{-ne}, @samp{-lt}, @samp{-le}, @samp{-gt}, or @samp{-ge}.
+These arithmetic binary operators return true if @var{arg1}
+is equal to, not equal to, less than, less than or equal to,
+greater than, or greater than or equal to @var{arg2},
+respectively. @var{Arg1} and @var{arg2}
+may be positive or negative integers.
+
+@end table
+
+@node Shell Arithmetic
+@section Shell Arithmetic
+@cindex arithmetic, shell
+@cindex shell arithmetic
+@cindex expressions, arithmetic
+@cindex evaluation, arithmetic
+@cindex arithmetic evaluation
+
+The shell allows arithmetic expressions to be evaluated, as one of
+the shell expansions or by the @code{let} and the @option{-i} option
+to the @code{declare} builtins.
+
+Evaluation is done in fixed-width integers with no check for overflow,
+though division by 0 is trapped and flagged as an error.
+The operators and their precedence, associativity, and values
+are the same as in the C language.
+The following list of operators is grouped into levels of
+equal-precedence operators.
+The levels are listed in order of decreasing precedence.
+
+@table @code
+
+@item @var{id}++ @var{id}--
+variable post-increment and post-decrement
+
+@item ++@var{id} --@var{id}
+variable pre-increment and pre-decrement
+
+@item - +
+unary minus and plus
+
+@item ! ~
+logical and bitwise negation
+
+@item **
+exponentiation
+
+@item * / %
+multiplication, division, remainder
+
+@item + -
+addition, subtraction
+
+@item << >>
+left and right bitwise shifts
+
+@item <= >= < >
+comparison
+
+@item == !=
+equality and inequality
+
+@item &
+bitwise AND
+
+@item ^
+bitwise exclusive OR
+
+@item |
+bitwise OR
+
+@item &&
+logical AND
+
+@item ||
+logical OR
+
+@item expr ? expr : expr
+conditional operator
+
+@item = *= /= %= += -= <<= >>= &= ^= |=
+assignment
+
+@item expr1 , expr2
+comma
+@end table
+
+Shell variables are allowed as operands; parameter expansion is
+performed before the expression is evaluated.
+Within an expression, shell variables may also be referenced by name
+without using the parameter expansion syntax.
+A shell variable that is null or unset evaluates to 0 when referenced
+by name without using the parameter expansion syntax.
+The value of a variable is evaluated as an arithmetic expression
+when it is referenced, or when a variable which has been given the
+@var{integer} attribute using @samp{declare -i} is assigned a value.
+A null value evaluates to 0.
+A shell variable need not have its @var{integer} attribute turned on
+to be used in an expression.
+
+Constants with a leading 0 are interpreted as octal numbers.
+A leading @samp{0x} or @samp{0X} denotes hexadecimal. Otherwise,
+numbers take the form [@var{base}@code{#}]@var{n}, where the optional @var{base}
+is a decimal number between 2 and 64 representing the arithmetic
+base, and @var{n} is a number in that base. If @var{base}@code{#} is
+omitted, then base 10 is used.
+The digits greater than 9 are represented by the lowercase letters,
+the uppercase letters, @samp{@@}, and @samp{_}, in that order.
+If @var{base} is less than or equal to 36, lowercase and uppercase
+letters may be used interchangeably to represent numbers between 10
+and 35.
+
+Operators are evaluated in order of precedence. Sub-expressions in
+parentheses are evaluated first and may override the precedence
+rules above.
+
+@node Aliases
+@section Aliases
+@cindex alias expansion
+
+@var{Aliases} allow a string to be substituted for a word when it is used
+as the first word of a simple command.
+The shell maintains a list of aliases that may be set and unset with
+the @code{alias} and @code{unalias} builtin commands.
+
+The first word of each simple command, if unquoted, is checked to see
+if it has an alias.
+If so, that word is replaced by the text of the alias.
+The characters @samp{/}, @samp{$}, @samp{`}, @samp{=} and any of the
+shell metacharacters or quoting characters listed above may not appear
+in an alias name.
+The replacement text may contain any valid
+shell input, including shell metacharacters.
+The first word of the replacement text is tested for
+aliases, but a word that is identical to an alias being expanded
+is not expanded a second time.
+This means that one may alias @code{ls} to @code{"ls -F"},
+for instance, and Bash does not try to recursively expand the
+replacement text. If the last character of the alias value is a
+space or tab character, then the next command word following the
+alias is also checked for alias expansion.
+
+Aliases are created and listed with the @code{alias}
+command, and removed with the @code{unalias} command.
+
+There is no mechanism for using arguments in the replacement text,
+as in @code{csh}.
+If arguments are needed, a shell function should be used
+(@pxref{Shell Functions}).
+
+Aliases are not expanded when the shell is not interactive,
+unless the @code{expand_aliases} shell option is set using
+@code{shopt} (@pxref{The Shopt Builtin}).
+
+The rules concerning the definition and use of aliases are
+somewhat confusing. Bash
+always reads at least one complete line
+of input before executing any
+of the commands on that line. Aliases are expanded when a
+command is read, not when it is executed. Therefore, an
+alias definition appearing on the same line as another
+command does not take effect until the next line of input is read.
+The commands following the alias definition
+on that line are not affected by the new alias.
+This behavior is also an issue when functions are executed.
+Aliases are expanded when a function definition is read,
+not when the function is executed, because a function definition
+is itself a compound command. As a consequence, aliases
+defined in a function are not available until after that
+function is executed. To be safe, always put
+alias definitions on a separate line, and do not use @code{alias}
+in compound commands.
+
+For almost every purpose, shell functions are preferred over aliases.
+
+@node Arrays
+@section Arrays
+@cindex arrays
+
+Bash provides one-dimensional indexed and associative array variables.
+Any variable may be used as an indexed array;
+the @code{declare} builtin will explicitly declare an array.
+There is no maximum
+limit on the size of an array, nor any requirement that members
+be indexed or assigned contiguously.
+Indexed arrays are referenced using integers (including arithmetic
+expressions (@pxref{Shell Arithmetic})) and are zero-based;
+associative arrays use arbitrary strings.
+
+An indexed array is created automatically if any variable is assigned to
+using the syntax
+@example
+name[@var{subscript}]=@var{value}
+@end example
+
+@noindent
+The @var{subscript}
+is treated as an arithmetic expression that must evaluate to a number.
+To explicitly declare an array, use
+@example
+declare -a @var{name}
+@end example
+@noindent
+The syntax
+@example
+declare -a @var{name}[@var{subscript}]
+@end example
+@noindent
+is also accepted; the @var{subscript} is ignored.
+
+Associative arrays are created using
+@example
+declare -A @var{name}.
+@end example
+
+Attributes may be
+specified for an array variable using the @code{declare} and
+@code{readonly} builtins. Each attribute applies to all members of
+an array.
+
+Arrays are assigned to using compound assignments of the form
+@example
+name=(value@var{1} @dots{} value@var{n})
+@end example
+@noindent
+where each
+@var{value} is of the form @code{[@var{subscript}]=}@var{string}.
+Indexed array assignments do not require the bracket and subscript.
+When assigning to indexed arrays, if
+the optional subscript is supplied, that index is assigned to;
+otherwise the index of the element assigned is the last index assigned
+to by the statement plus one. Indexing starts at zero.
+
+When assigning to an associative array, the subscript is required.
+
+This syntax is also accepted by the @code{declare}
+builtin. Individual array elements may be assigned to using the
+@code{name[}@var{subscript}@code{]=}@var{value} syntax introduced above.
+
+Any element of an array may be referenced using
+@code{$@{name[}@var{subscript}@code{]@}}.
+The braces are required to avoid
+conflicts with the shell's filename expansion operators. If the
+@var{subscript} is @samp{@@} or @samp{*}, the word expands to all members
+of the array @var{name}. These subscripts differ only when the word
+appears within double quotes.
+If the word is double-quoted,
+@code{$@{name[*]@}} expands to a single word with
+the value of each array member separated by the first character of the
+@env{IFS} variable, and @code{$@{name[@@]@}} expands each element of
+@var{name} to a separate word. When there are no array members,
+@code{$@{name[@@]@}} expands to nothing.
+If the double-quoted expansion occurs within a word, the expansion of
+the first parameter is joined with the beginning part of the original
+word, and the expansion of the last parameter is joined with the last
+part of the original word.
+This is analogous to the
+expansion of the special parameters @samp{@@} and @samp{*}.
+@code{$@{#name[}@var{subscript}@code{]@}} expands to the length of
+@code{$@{name[}@var{subscript}@code{]@}}.
+If @var{subscript} is @samp{@@} or
+@samp{*}, the expansion is the number of elements in the array.
+Referencing an array variable without a subscript is equivalent to
+referencing with a subscript of 0.
+If the @var{subscript}
+used to reference an element of an indexed array
+evaluates to a number less than zero, it is used as
+an offset from one greater than the array's maximum index (so a subcript
+of -1 refers to the last element of the array).
+
+An array variable is considered set if a subscript has been assigned a
+value. The null string is a valid value.
+
+The @code{unset} builtin is used to destroy arrays.
+@code{unset} @var{name}[@var{subscript}]
+destroys the array element at index @var{subscript}.
+Care must be taken to avoid unwanted side effects caused by filename
+expansion.
+@code{unset} @var{name}, where @var{name} is an array, removes the
+entire array. A subscript of @samp{*} or @samp{@@} also removes the
+entire array.
+
+The @code{declare}, @code{local}, and @code{readonly}
+builtins each accept a @option{-a} option to specify an indexed
+array and a @option{-A} option to specify an associative array.
+If both options are supplied, @option{-A} takes precedence.
+The @code{read} builtin accepts a @option{-a}
+option to assign a list of words read from the standard input
+to an array, and can read values from the standard input into
+individual array elements. The @code{set} and @code{declare}
+builtins display array values in a way that allows them to be
+reused as input.
+
+@node The Directory Stack
+@section The Directory Stack
+@cindex directory stack
+
+@menu
+* Directory Stack Builtins:: Bash builtin commands to manipulate
+ the directory stack.
+@end menu
+
+The directory stack is a list of recently-visited directories. The
+@code{pushd} builtin adds directories to the stack as it changes
+the current directory, and the @code{popd} builtin removes specified
+directories from the stack and changes the current directory to
+the directory removed. The @code{dirs} builtin displays the contents
+of the directory stack.
+
+The contents of the directory stack are also visible
+as the value of the @env{DIRSTACK} shell variable.
+
+@node Directory Stack Builtins
+@subsection Directory Stack Builtins
+
+@table @code
+
+@item dirs
+@btindex dirs
+@example
+dirs [+@var{N} | -@var{N}] [-clpv]
+@end example
+Display the list of currently remembered directories. Directories
+are added to the list with the @code{pushd} command; the
+@code{popd} command removes directories from the list.
+@table @code
+@item +@var{N}
+Displays the @var{N}th directory (counting from the left of the
+list printed by @code{dirs} when invoked without options), starting
+with zero.
+@item -@var{N}
+Displays the @var{N}th directory (counting from the right of the
+list printed by @code{dirs} when invoked without options), starting
+with zero.
+@item -c
+Clears the directory stack by deleting all of the elements.
+@item -l
+Produces a longer listing; the default listing format uses a
+tilde to denote the home directory.
+@item -p
+Causes @code{dirs} to print the directory stack with one entry per
+line.
+@item -v
+Causes @code{dirs} to print the directory stack with one entry per
+line, prefixing each entry with its index in the stack.
+@end table
+
+@item popd
+@btindex popd
+@example
+popd [+@var{N} | -@var{N}] [-n]
+@end example
+
+Remove the top entry from the directory stack, and @code{cd}
+to the new top directory.
+When no arguments are given, @code{popd}
+removes the top directory from the stack and
+performs a @code{cd} to the new top directory. The
+elements are numbered from 0 starting at the first directory listed with
+@code{dirs}; i.e., @code{popd} is equivalent to @code{popd +0}.
+@table @code
+@item +@var{N}
+Removes the @var{N}th directory (counting from the left of the
+list printed by @code{dirs}), starting with zero.
+@item -@var{N}
+Removes the @var{N}th directory (counting from the right of the
+list printed by @code{dirs}), starting with zero.
+@item -n
+Suppresses the normal change of directory when removing directories
+from the stack, so that only the stack is manipulated.
+@end table
+
+@btindex pushd
+@item pushd
+@example
+pushd [-n] [@var{+N} | @var{-N} | @var{dir} ]
+@end example
+
+Save the current directory on the top of the directory stack
+and then @code{cd} to @var{dir}.
+With no arguments, @code{pushd} exchanges the top two directories.
+
+@table @code
+@item -n
+Suppresses the normal change of directory when adding directories
+to the stack, so that only the stack is manipulated.
+@item +@var{N}
+Brings the @var{N}th directory (counting from the left of the
+list printed by @code{dirs}, starting with zero) to the top of
+the list by rotating the stack.
+@item -@var{N}
+Brings the @var{N}th directory (counting from the right of the
+list printed by @code{dirs}, starting with zero) to the top of
+the list by rotating the stack.
+@item @var{dir}
+Makes the current working directory be the top of the stack, and then
+executes the equivalent of `@code{cd} @var{dir}'.
+@code{cd}s to @var{dir}.
+@end table
+
+@end table
+
+@node Printing a Prompt
+@section Controlling the Prompt
+@cindex prompting
+
+The value of the variable @env{PROMPT_COMMAND} is examined just before
+Bash prints each primary prompt. If @env{PROMPT_COMMAND} is set and
+has a non-null value, then the
+value is executed just as if it had been typed on the command line.
+
+In addition, the following table describes the special characters which
+can appear in the prompt variables:
+
+@table @code
+@item \a
+A bell character.
+@item \d
+The date, in "Weekday Month Date" format (e.g., "Tue May 26").
+@item \D@{@var{format}@}
+The @var{format} is passed to @code{strftime}(3) and the result is inserted
+into the prompt string; an empty @var{format} results in a locale-specific
+time representation. The braces are required.
+@item \e
+An escape character.
+@item \h
+The hostname, up to the first `.'.
+@item \H
+The hostname.
+@item \j
+The number of jobs currently managed by the shell.
+@item \l
+The basename of the shell's terminal device name.
+@item \n
+A newline.
+@item \r
+A carriage return.
+@item \s
+The name of the shell, the basename of @code{$0} (the portion
+following the final slash).
+@item \t
+The time, in 24-hour HH:MM:SS format.
+@item \T
+The time, in 12-hour HH:MM:SS format.
+@item \@@
+The time, in 12-hour am/pm format.
+@item \A
+The time, in 24-hour HH:MM format.
+@item \u
+The username of the current user.
+@item \v
+The version of Bash (e.g., 2.00)
+@item \V
+The release of Bash, version + patchlevel (e.g., 2.00.0)
+@item \w
+The current working directory, with @env{$HOME} abbreviated with a tilde
+(uses the @env{$PROMPT_DIRTRIM} variable).
+@item \W
+The basename of @env{$PWD}, with @env{$HOME} abbreviated with a tilde.
+@item \!
+The history number of this command.
+@item \#
+The command number of this command.
+@item \$
+If the effective uid is 0, @code{#}, otherwise @code{$}.
+@item \@var{nnn}
+The character whose ASCII code is the octal value @var{nnn}.
+@item \\
+A backslash.
+@item \[
+Begin a sequence of non-printing characters. This could be used to
+embed a terminal control sequence into the prompt.
+@item \]
+End a sequence of non-printing characters.
+@end table
+
+The command number and the history number are usually different:
+the history number of a command is its position in the history
+list, which may include commands restored from the history file
+(@pxref{Bash History Facilities}), while the command number is
+the position in the sequence of commands executed during the current
+shell session.
+
+After the string is decoded, it is expanded via
+parameter expansion, command substitution, arithmetic
+expansion, and quote removal, subject to the value of the
+@code{promptvars} shell option (@pxref{Bash Builtins}).
+
+@node The Restricted Shell
+@section The Restricted Shell
+@cindex restricted shell
+
+If Bash is started with the name @code{rbash}, or the
+@option{--restricted}
+or
+@option{-r}
+option is supplied at invocation, the shell becomes restricted.
+A restricted shell is used to
+set up an environment more controlled than the standard shell.
+A restricted shell behaves identically to @code{bash}
+with the exception that the following are disallowed or not performed:
+
+@itemize @bullet
+@item
+Changing directories with the @code{cd} builtin.
+@item
+Setting or unsetting the values of the @env{SHELL}, @env{PATH},
+@env{ENV}, or @env{BASH_ENV} variables.
+@item
+Specifying command names containing slashes.
+@item
+Specifying a filename containing a slash as an argument to the @code{.}
+builtin command.
+@item
+Specifying a filename containing a slash as an argument to the @option{-p}
+option to the @code{hash} builtin command.
+@item
+Importing function definitions from the shell environment at startup.
+@item
+Parsing the value of @env{SHELLOPTS} from the shell environment at startup.
+@item
+Redirecting output using the @samp{>}, @samp{>|}, @samp{<>}, @samp{>&},
+@samp{&>}, and @samp{>>} redirection operators.
+@item
+Using the @code{exec} builtin to replace the shell with another command.
+@item
+Adding or deleting builtin commands with the
+@option{-f} and @option{-d} options to the @code{enable} builtin.
+@item
+Using the @code{enable} builtin command to enable disabled shell builtins.
+@item
+Specifying the @option{-p} option to the @code{command} builtin.
+@item
+Turning off restricted mode with @samp{set +r} or @samp{set +o restricted}.
+@end itemize
+
+These restrictions are enforced after any startup files are read.
+
+When a command that is found to be a shell script is executed
+(@pxref{Shell Scripts}), @code{rbash} turns off any restrictions in
+the shell spawned to execute the script.
+
+@node Bash POSIX Mode
+@section Bash POSIX Mode
+@cindex POSIX Mode
+
+Starting Bash with the @option{--posix} command-line option or executing
+@samp{set -o posix} while Bash is running will cause Bash to conform more
+closely to the @sc{posix} standard by changing the behavior to
+match that specified by @sc{posix} in areas where the Bash default differs.
+
+When invoked as @code{sh}, Bash enters @sc{posix} mode after reading the
+startup files.
+
+The following list is what's changed when `@sc{posix} mode' is in effect:
+
+@enumerate
+@item
+When a command in the hash table no longer exists, Bash will re-search
+@env{$PATH} to find the new location. This is also available with
+@samp{shopt -s checkhash}.
+
+@item
+The message printed by the job control code and builtins when a job
+exits with a non-zero status is `Done(status)'.
+
+@item
+The message printed by the job control code and builtins when a job
+is stopped is `Stopped(@var{signame})', where @var{signame} is, for
+example, @code{SIGTSTP}.
+
+@item
+The @code{bg} builtin uses the required format to describe each job placed
+in the background, which does not include an indication of whether the job
+is the current or previous job.
+
+@item
+Reserved words appearing in a context where reserved words are recognized
+do not undergo alias expansion.
+
+@item
+The @sc{posix} @env{PS1} and @env{PS2} expansions of @samp{!} to
+the history number and @samp{!!} to @samp{!} are enabled,
+and parameter expansion is performed on the values of @env{PS1} and
+@env{PS2} regardless of the setting of the @code{promptvars} option.
+
+@item
+The @sc{posix} startup files are executed (@env{$ENV}) rather than
+the normal Bash files.
+
+@item
+Tilde expansion is only performed on assignments preceding a command
+name, rather than on all assignment statements on the line.
+
+@item
+The @code{command} builtin does not prevent builtins that take assignment
+statements as arguments from expanding them as assignment statements;
+when not in POSIX mode, assignment builtins lose their assignment
+statement expansion properties when preceded by @code{command}.
+
+@item
+The default history file is @file{~/.sh_history} (this is the
+default value of @env{$HISTFILE}).
+
+@item
+The output of @samp{kill -l} prints all the signal names on a single line,
+separated by spaces, without the @samp{SIG} prefix.
+
+@item
+The @code{kill} builtin does not accept signal names with a @samp{SIG}
+prefix.
+
+@item
+Non-interactive shells exit if @var{filename} in @code{.} @var{filename}
+is not found.
+
+@item
+Non-interactive shells exit if a syntax error in an arithmetic expansion
+results in an invalid expression.
+
+@item
+Non-interactive shells exit if there is a syntax error in a script read
+with the @code{.} or @code{source} builtins, or in a string processed by
+the @code{eval} builtin.
+
+@item
+Redirection operators do not perform filename expansion on the word
+in the redirection unless the shell is interactive.
+
+@item
+Redirection operators do not perform word splitting on the word in the
+redirection.
+
+@item
+Function names must be valid shell @code{name}s. That is, they may not
+contain characters other than letters, digits, and underscores, and
+may not start with a digit. Declaring a function with an invalid name
+causes a fatal syntax error in non-interactive shells.
+
+@item
+@sc{posix} special builtins are found before shell functions
+during command lookup.
+
+@item
+The @code{time} reserved word may be used by itself as a command. When
+used in this way, it displays timing statistics for the shell and its
+completed children. The @env{TIMEFORMAT} variable controls the format
+of the timing information.
+
+@item
+When parsing and expanding a $@{@dots{}@} expansion that appears within
+double quotes, single quotes are no longer special and cannot be used to
+quote a closing brace or other special character, unless the operator is
+one of those defined to perform pattern removal. In this case, they do
+not have to appear as matched pairs.
+
+@item
+The parser does not recognize @code{time} as a reserved word if the next
+token begins with a @samp{-}.
+
+@item
+If a @sc{posix} special builtin returns an error status, a
+non-interactive shell exits. The fatal errors are those listed in
+the @sc{posix} standard, and include things like passing incorrect options,
+redirection errors, variable assignment errors for assignments preceding
+the command name, and so on.
+
+@item
+A non-interactive shell exits with an error status if a variable
+assignment error occurs when no command name follows the assignment
+statements.
+A variable assignment error occurs, for example, when trying to assign
+a value to a readonly variable.
+
+@item
+A non-interactive shell exists with an error status if a variable
+assignment error occurs in an assignment statement preceding a special
+builtin, but not with any other simple command.
+
+@item
+A non-interactive shell exits with an error status if the iteration
+variable in a @code{for} statement or the selection variable in a
+@code{select} statement is a readonly variable.
+
+@item
+Process substitution is not available.
+
+@item
+While variable indirection is available, it may not be applied to the
+@samp{#} and @samp{?} special parameters.
+
+@item
+Assignment statements preceding @sc{posix} special builtins
+persist in the shell environment after the builtin completes.
+
+@item
+Assignment statements preceding shell function calls persist in the
+shell environment after the function returns, as if a @sc{posix}
+special builtin command had been executed.
+
+@item
+The @code{export} and @code{readonly} builtin commands display their
+output in the format required by @sc{posix}.
+
+@item
+The @code{trap} builtin displays signal names without the leading
+@code{SIG}.
+
+@item
+The @code{trap} builtin doesn't check the first argument for a possible
+signal specification and revert the signal handling to the original
+disposition if it is, unless that argument consists solely of digits and
+is a valid signal number. If users want to reset the handler for a given
+signal to the original disposition, they should use @samp{-} as the
+first argument.
+
+@item
+The @code{.} and @code{source} builtins do not search the current directory
+for the filename argument if it is not found by searching @env{PATH}.
+
+@item
+Subshells spawned to execute command substitutions inherit the value of
+the @option{-e} option from the parent shell. When not in @sc{posix} mode,
+Bash clears the @option{-e} option in such subshells.
+
+@item
+Alias expansion is always enabled, even in non-interactive shells.
+
+@item
+When the @code{alias} builtin displays alias definitions, it does not
+display them with a leading @samp{alias } unless the @option{-p} option
+is supplied.
+
+@item
+When the @code{set} builtin is invoked without options, it does not display
+shell function names and definitions.
+
+@item
+When the @code{set} builtin is invoked without options, it displays
+variable values without quotes, unless they contain shell metacharacters,
+even if the result contains nonprinting characters.
+
+@item
+When the @code{cd} builtin is invoked in @var{logical} mode, and the pathname
+constructed from @code{$PWD} and the directory name supplied as an argument
+does not refer to an existing directory, @code{cd} will fail instead of
+falling back to @var{physical} mode.
+
+@item
+The @code{pwd} builtin verifies that the value it prints is the same as the
+current directory, even if it is not asked to check the file system with the
+@option{-P} option.
+
+@item
+When listing the history, the @code{fc} builtin does not include an
+indication of whether or not a history entry has been modified.
+
+@item
+The default editor used by @code{fc} is @code{ed}.
+
+@item
+The @code{type} and @code{command} builtins will not report a non-executable
+file as having been found, though the shell will attempt to execute such a
+file if it is the only so-named file found in @code{$PATH}.
+
+@item
+The @code{vi} editing mode will invoke the @code{vi} editor directly when
+the @samp{v} command is run, instead of checking @code{$VISUAL} and
+@code{$EDITOR}.
+
+@item
+When the @code{xpg_echo} option is enabled, Bash does not attempt to interpret
+any arguments to @code{echo} as options. Each argument is displayed, after
+escape characters are converted.
+
+@item
+The @code{ulimit} builtin uses a block size of 512 bytes for the @option{-c}
+and @option{-f} options.
+
+@item
+The arrival of @code{SIGCHLD} when a trap is set on @code{SIGCHLD} does
+not interrupt the @code{wait} builtin and cause it to return immediately.
+The trap command is run once for each child that exits.
+
+@end enumerate
+
+There is other @sc{posix} behavior that Bash does not implement by
+default even when in @sc{posix} mode.
+Specifically:
+
+@enumerate
+
+@item
+The @code{fc} builtin checks @code{$EDITOR} as a program to edit history
+entries if @code{FCEDIT} is unset, rather than defaulting directly to
+@code{ed}. @code{fc} uses @code{ed} if @code{EDITOR} is unset.
+
+@item
+As noted above, Bash requires the @code{xpg_echo} option to be enabled for
+the @code{echo} builtin to be fully conformant.
+
+@end enumerate
+
+Bash can be configured to be @sc{posix}-conformant by default, by specifying
+the @option{--enable-strict-posix-default} to @code{configure} when building
+(@pxref{Optional Features}).
+
+@node Job Control
+@chapter Job Control
+
+This chapter discusses what job control is, how it works, and how
+Bash allows you to access its facilities.
+
+@menu
+* Job Control Basics:: How job control works.
+* Job Control Builtins:: Bash builtin commands used to interact
+ with job control.
+* Job Control Variables:: Variables Bash uses to customize job
+ control.
+@end menu
+
+@node Job Control Basics
+@section Job Control Basics
+@cindex job control
+@cindex foreground
+@cindex background
+@cindex suspending jobs
+
+Job control
+refers to the ability to selectively stop (suspend)
+the execution of processes and continue (resume)
+their execution at a later point. A user typically employs
+this facility via an interactive interface supplied jointly
+by the operating system kernel's terminal driver and Bash.
+
+The shell associates a @var{job} with each pipeline. It keeps a
+table of currently executing jobs, which may be listed with the
+@code{jobs} command. When Bash starts a job
+asynchronously, it prints a line that looks
+like:
+@example
+[1] 25647
+@end example
+@noindent
+indicating that this job is job number 1 and that the process @sc{id}
+of the last process in the pipeline associated with this job is
+25647. All of the processes in a single pipeline are members of
+the same job. Bash uses the @var{job} abstraction as the
+basis for job control.
+
+To facilitate the implementation of the user interface to job
+control, the operating system maintains the notion of a current terminal
+process group @sc{id}. Members of this process group (processes whose
+process group @sc{id} is equal to the current terminal process group
+@sc{id}) receive keyboard-generated signals such as @code{SIGINT}.
+These processes are said to be in the foreground. Background
+processes are those whose process group @sc{id} differs from the
+terminal's; such processes are immune to keyboard-generated
+signals. Only foreground processes are allowed to read from or, if
+the user so specifies with @code{stty tostop}, write to the terminal.
+Background processes which attempt to
+read from (write to when @code{stty tostop} is in effect) the
+terminal are sent a @code{SIGTTIN} (@code{SIGTTOU})
+signal by the kernel's terminal driver,
+which, unless caught, suspends the process.
+
+If the operating system on which Bash is running supports
+job control, Bash contains facilities to use it. Typing the
+@var{suspend} character (typically @samp{^Z}, Control-Z) while a
+process is running causes that process to be stopped and returns
+control to Bash. Typing the @var{delayed suspend} character
+(typically @samp{^Y}, Control-Y) causes the process to be stopped
+when it attempts to read input from the terminal, and control to
+be returned to Bash. The user then manipulates the state of
+this job, using the @code{bg} command to continue it in the
+background, the @code{fg} command to continue it in the
+foreground, or the @code{kill} command to kill it. A @samp{^Z}
+takes effect immediately, and has the additional side effect of
+causing pending output and typeahead to be discarded.
+
+There are a number of ways to refer to a job in the shell. The
+character @samp{%} introduces a job specification (@var{jobspec}).
+
+Job number @code{n} may be referred to as @samp{%n}.
+The symbols @samp{%%} and @samp{%+} refer to the shell's notion of the
+current job, which is the last job stopped while it was in the foreground
+or started in the background.
+A single @samp{%} (with no accompanying job specification) also refers
+to the current job.
+The previous job may be referenced using @samp{%-}.
+If there is only a single job, @samp{%+} and @samp{%-} can both be used
+to refer to that job.
+In output pertaining to jobs (e.g., the output of the @code{jobs}
+command), the current job is always flagged with a @samp{+}, and the
+previous job with a @samp{-}.
+
+A job may also be referred to
+using a prefix of the name used to start it, or using a substring
+that appears in its command line. For example, @samp{%ce} refers
+to a stopped @code{ce} job. Using @samp{%?ce}, on the
+other hand, refers to any job containing the string @samp{ce} in
+its command line. If the prefix or substring matches more than one job,
+Bash reports an error.
+
+Simply naming a job can be used to bring it into the foreground:
+@samp{%1} is a synonym for @samp{fg %1}, bringing job 1 from the
+background into the foreground. Similarly, @samp{%1 &} resumes
+job 1 in the background, equivalent to @samp{bg %1}
+
+The shell learns immediately whenever a job changes state.
+Normally, Bash waits until it is about to print a prompt
+before reporting changes in a job's status so as to not interrupt
+any other output.
+If the @option{-b} option to the @code{set} builtin is enabled,
+Bash reports such changes immediately (@pxref{The Set Builtin}).
+Any trap on @code{SIGCHLD} is executed for each child process
+that exits.
+
+If an attempt to exit Bash is made while jobs are stopped, (or running, if
+the @code{checkjobs} option is enabled -- see @ref{The Shopt Builtin}), the
+shell prints a warning message, and if the @code{checkjobs} option is
+enabled, lists the jobs and their statuses.
+The @code{jobs} command may then be used to inspect their status.
+If a second attempt to exit is made without an intervening command,
+Bash does not print another warning, and any stopped jobs are terminated.
+
+@node Job Control Builtins
+@section Job Control Builtins
+
+@table @code
+
+@item bg
+@btindex bg
+@example
+bg [@var{jobspec} @dots{}]
+@end example
+Resume each suspended job @var{jobspec} in the background, as if it
+had been started with @samp{&}.
+If @var{jobspec} is not supplied, the current job is used.
+The return status is zero unless it is run when job control is not
+enabled, or, when run with job control enabled, any
+@var{jobspec} was not found or specifies a job
+that was started without job control.
+
+@item fg
+@btindex fg
+@example
+fg [@var{jobspec}]
+@end example
+Resume the job @var{jobspec} in the foreground and make it the current job.
+If @var{jobspec} is not supplied, the current job is used.
+The return status is that of the command placed into the foreground,
+or non-zero if run when job control is disabled or, when run with
+job control enabled, @var{jobspec} does not specify a valid job or
+@var{jobspec} specifies a job that was started without job control.
+
+@item jobs
+@btindex jobs
+@example
+jobs [-lnprs] [@var{jobspec}]
+jobs -x @var{command} [@var{arguments}]
+@end example
+
+The first form lists the active jobs. The options have the
+following meanings:
+
+@table @code
+@item -l
+List process @sc{id}s in addition to the normal information.
+
+@item -n
+Display information only about jobs that have changed status since
+the user was last notified of their status.
+
+@item -p
+List only the process @sc{id} of the job's process group leader.
+
+@item -r
+Restrict output to running jobs.
+
+@item -s
+Restrict output to stopped jobs.
+@end table
+
+If @var{jobspec} is given,
+output is restricted to information about that job.
+If @var{jobspec} is not supplied, the status of all jobs is
+listed.
+
+If the @option{-x} option is supplied, @code{jobs} replaces any
+@var{jobspec} found in @var{command} or @var{arguments} with the
+corresponding process group @sc{id}, and executes @var{command},
+passing it @var{argument}s, returning its exit status.
+
+@item kill
+@btindex kill
+@example
+kill [-s @var{sigspec}] [-n @var{signum}] [-@var{sigspec}] @var{jobspec} or @var{pid}
+kill -l [@var{exit_status}]
+@end example
+Send a signal specified by @var{sigspec} or @var{signum} to the process
+named by job specification @var{jobspec} or process @sc{id} @var{pid}.
+@var{sigspec} is either a case-insensitive signal name such as
+@code{SIGINT} (with or without the @code{SIG} prefix)
+or a signal number; @var{signum} is a signal number.
+If @var{sigspec} and @var{signum} are not present, @code{SIGTERM} is used.
+The @option{-l} option lists the signal names.
+If any arguments are supplied when @option{-l} is given, the names of the
+signals corresponding to the arguments are listed, and the return status
+is zero.
+@var{exit_status} is a number specifying a signal number or the exit
+status of a process terminated by a signal.
+The return status is zero if at least one signal was successfully sent,
+or non-zero if an error occurs or an invalid option is encountered.
+
+@item wait
+@btindex wait
+@example
+wait [@var{jobspec} or @var{pid} ...]
+@end example
+Wait until the child process specified by each process @sc{id} @var{pid}
+or job specification @var{jobspec} exits and return the exit status of the
+last command waited for.
+If a job spec is given, all processes in the job are waited for.
+If no arguments are given, all currently active child processes are
+waited for, and the return status is zero.
+If neither @var{jobspec} nor @var{pid} specifies an active child process
+of the shell, the return status is 127.
+
+@item disown
+@btindex disown
+@example
+disown [-ar] [-h] [@var{jobspec} @dots{}]
+@end example
+Without options, each @var{jobspec} is removed from the table of
+active jobs.
+If the @option{-h} option is given, the job is not removed from the table,
+but is marked so that @code{SIGHUP} is not sent to the job if the shell
+receives a @code{SIGHUP}.
+If @var{jobspec} is not present, and neither the @option{-a} nor @option{-r}
+option is supplied, the current job is used.
+If no @var{jobspec} is supplied, the @option{-a} option means to remove or
+mark all jobs; the @option{-r} option without a @var{jobspec}
+argument restricts operation to running jobs.
+
+@item suspend
+@btindex suspend
+@example
+suspend [-f]
+@end example
+Suspend the execution of this shell until it receives a
+@code{SIGCONT} signal.
+A login shell cannot be suspended; the @option{-f}
+option can be used to override this and force the suspension.
+
+@end table
+
+When job control is not active, the @code{kill} and @code{wait}
+builtins do not accept @var{jobspec} arguments. They must be
+supplied process @sc{id}s.
+
+@node Job Control Variables
+@section Job Control Variables
+
+@vtable @code
+
+@item auto_resume
+This variable controls how the shell interacts with the user and
+job control. If this variable exists then single word simple
+commands without redirections are treated as candidates for resumption
+of an existing job. There is no ambiguity allowed; if there is
+more than one job beginning with the string typed, then
+the most recently accessed job will be selected.
+The name of a stopped job, in this context, is the command line
+used to start it. If this variable is set to the value @samp{exact},
+the string supplied must match the name of a stopped job exactly;
+if set to @samp{substring},
+the string supplied needs to match a substring of the name of a
+stopped job. The @samp{substring} value provides functionality
+analogous to the @samp{%?} job @sc{id} (@pxref{Job Control Basics}).
+If set to any other value, the supplied string must
+be a prefix of a stopped job's name; this provides functionality
+analogous to the @samp{%} job @sc{id}.
+
+@end vtable
+
+@set readline-appendix
+@set history-appendix
+@cindex Readline, how to use
+@include rluser.texi
+@cindex History, how to use
+@include hsuser.texi
+@clear readline-appendix
+@clear history-appendix
+
+@node Installing Bash
+@chapter Installing Bash
+
+This chapter provides basic instructions for installing Bash on
+the various supported platforms. The distribution supports the
+@sc{gnu} operating systems, nearly every version of Unix, and several
+non-Unix systems such as BeOS and Interix.
+Other independent ports exist for
+@sc{ms-dos}, @sc{os/2}, and Windows platforms.
+
+@menu
+* Basic Installation:: Installation instructions.
+* Compilers and Options:: How to set special options for various
+ systems.
+* Compiling For Multiple Architectures:: How to compile Bash for more
+ than one kind of system from
+ the same source tree.
+* Installation Names:: How to set the various paths used by the installation.
+* Specifying the System Type:: How to configure Bash for a particular system.
+* Sharing Defaults:: How to share default configuration values among GNU
+ programs.
+* Operation Controls:: Options recognized by the configuration program.
+* Optional Features:: How to enable and disable optional features when
+ building Bash.
+@end menu
+
+@node Basic Installation
+@section Basic Installation
+@cindex installation
+@cindex configuration
+@cindex Bash installation
+@cindex Bash configuration
+
+These are installation instructions for Bash.
+
+The simplest way to compile Bash is:
+
+@enumerate
+@item
+@code{cd} to the directory containing the source code and type
+@samp{./configure} to configure Bash for your system. If you're
+using @code{csh} on an old version of System V, you might need to
+type @samp{sh ./configure} instead to prevent @code{csh} from trying
+to execute @code{configure} itself.
+
+Running @code{configure} takes some time.
+While running, it prints messages telling which features it is
+checking for.
+
+@item
+Type @samp{make} to compile Bash and build the @code{bashbug} bug
+reporting script.
+
+@item
+Optionally, type @samp{make tests} to run the Bash test suite.
+
+@item
+Type @samp{make install} to install @code{bash} and @code{bashbug}.
+This will also install the manual pages and Info file.
+
+@end enumerate
+
+The @code{configure} shell script attempts to guess correct
+values for various system-dependent variables used during
+compilation. It uses those values to create a @file{Makefile} in
+each directory of the package (the top directory, the
+@file{builtins}, @file{doc}, and @file{support} directories,
+each directory under @file{lib}, and several others). It also creates a
+@file{config.h} file containing system-dependent definitions.
+Finally, it creates a shell script named @code{config.status} that you
+can run in the future to recreate the current configuration, a
+file @file{config.cache} that saves the results of its tests to
+speed up reconfiguring, and a file @file{config.log} containing
+compiler output (useful mainly for debugging @code{configure}).
+If at some point
+@file{config.cache} contains results you don't want to keep, you
+may remove or edit it.
+
+To find out more about the options and arguments that the
+@code{configure} script understands, type
+
+@example
+bash-2.04$ ./configure --help
+@end example
+
+@noindent
+at the Bash prompt in your Bash source directory.
+
+If you need to do unusual things to compile Bash, please
+try to figure out how @code{configure} could check whether or not
+to do them, and mail diffs or instructions to
+@email{bash-maintainers@@gnu.org} so they can be
+considered for the next release.
+
+The file @file{configure.in} is used to create @code{configure}
+by a program called Autoconf. You only need
+@file{configure.in} if you want to change it or regenerate
+@code{configure} using a newer version of Autoconf. If
+you do this, make sure you are using Autoconf version 2.50 or
+newer.
+
+You can remove the program binaries and object files from the
+source code directory by typing @samp{make clean}. To also remove the
+files that @code{configure} created (so you can compile Bash for
+a different kind of computer), type @samp{make distclean}.
+
+@node Compilers and Options
+@section Compilers and Options
+
+Some systems require unusual options for compilation or linking
+that the @code{configure} script does not know about. You can
+give @code{configure} initial values for variables by setting
+them in the environment. Using a Bourne-compatible shell, you
+can do that on the command line like this:
+
+@example
+CC=c89 CFLAGS=-O2 LIBS=-lposix ./configure
+@end example
+
+On systems that have the @code{env} program, you can do it like this:
+
+@example
+env CPPFLAGS=-I/usr/local/include LDFLAGS=-s ./configure
+@end example
+
+The configuration process uses GCC to build Bash if it
+is available.
+
+@node Compiling For Multiple Architectures
+@section Compiling For Multiple Architectures
+
+You can compile Bash for more than one kind of computer at the
+same time, by placing the object files for each architecture in their
+own directory. To do this, you must use a version of @code{make} that
+supports the @code{VPATH} variable, such as GNU @code{make}.
+@code{cd} to the
+directory where you want the object files and executables to go and run
+the @code{configure} script from the source directory. You may need to
+supply the @option{--srcdir=PATH} argument to tell @code{configure} where the
+source files are. @code{configure} automatically checks for the
+source code in the directory that @code{configure} is in and in `..'.
+
+If you have to use a @code{make} that does not supports the @code{VPATH}
+variable, you can compile Bash for one architecture at a
+time in the source code directory. After you have installed
+Bash for one architecture, use @samp{make distclean} before
+reconfiguring for another architecture.
+
+Alternatively, if your system supports symbolic links, you can use the
+@file{support/mkclone} script to create a build tree which has
+symbolic links back to each file in the source directory. Here's an
+example that creates a build directory in the current directory from a
+source directory @file{/usr/gnu/src/bash-2.0}:
+
+@example
+bash /usr/gnu/src/bash-2.0/support/mkclone -s /usr/gnu/src/bash-2.0 .
+@end example
+
+@noindent
+The @code{mkclone} script requires Bash, so you must have already built
+Bash for at least one architecture before you can create build
+directories for other architectures.
+
+@node Installation Names
+@section Installation Names
+
+By default, @samp{make install} will install into
+@file{/usr/local/bin}, @file{/usr/local/man}, etc. You can
+specify an installation prefix other than @file{/usr/local} by
+giving @code{configure} the option @option{--prefix=@var{PATH}},
+or by specifying a value for the @code{DESTDIR} @samp{make}
+variable when running @samp{make install}.
+
+You can specify separate installation prefixes for
+architecture-specific files and architecture-independent files.
+If you give @code{configure} the option
+@option{--exec-prefix=@var{PATH}}, @samp{make install} will use
+@var{PATH} as the prefix for installing programs and libraries.
+Documentation and other data files will still use the regular prefix.
+
+@node Specifying the System Type
+@section Specifying the System Type
+
+There may be some features @code{configure} can not figure out
+automatically, but need to determine by the type of host Bash
+will run on. Usually @code{configure} can figure that
+out, but if it prints a message saying it can not guess the host
+type, give it the @option{--host=TYPE} option. @samp{TYPE} can
+either be a short name for the system type, such as @samp{sun4},
+or a canonical name with three fields: @samp{CPU-COMPANY-SYSTEM}
+(e.g., @samp{i386-unknown-freebsd4.2}).
+
+See the file @file{support/config.sub} for the possible
+values of each field.
+
+@node Sharing Defaults
+@section Sharing Defaults
+
+If you want to set default values for @code{configure} scripts to
+share, you can create a site shell script called
+@code{config.site} that gives default values for variables like
+@code{CC}, @code{cache_file}, and @code{prefix}. @code{configure}
+looks for @file{PREFIX/share/config.site} if it exists, then
+@file{PREFIX/etc/config.site} if it exists. Or, you can set the
+@code{CONFIG_SITE} environment variable to the location of the site
+script. A warning: the Bash @code{configure} looks for a site script,
+but not all @code{configure} scripts do.
+
+@node Operation Controls
+@section Operation Controls
+
+@code{configure} recognizes the following options to control how it
+operates.
+
+@table @code
+
+@item --cache-file=@var{file}
+Use and save the results of the tests in
+@var{file} instead of @file{./config.cache}. Set @var{file} to
+@file{/dev/null} to disable caching, for debugging
+@code{configure}.
+
+@item --help
+Print a summary of the options to @code{configure}, and exit.
+
+@item --quiet
+@itemx --silent
+@itemx -q
+Do not print messages saying which checks are being made.
+
+@item --srcdir=@var{dir}
+Look for the Bash source code in directory @var{dir}. Usually
+@code{configure} can determine that directory automatically.
+
+@item --version
+Print the version of Autoconf used to generate the @code{configure}
+script, and exit.
+@end table
+
+@code{configure} also accepts some other, not widely used, boilerplate
+options. @samp{configure --help} prints the complete list.
+
+@node Optional Features
+@section Optional Features
+
+The Bash @code{configure} has a number of @option{--enable-@var{feature}}
+options, where @var{feature} indicates an optional part of Bash.
+There are also several @option{--with-@var{package}} options,
+where @var{package} is something like @samp{bash-malloc} or @samp{purify}.
+To turn off the default use of a package, use
+@option{--without-@var{package}}. To configure Bash without a feature
+that is enabled by default, use @option{--disable-@var{feature}}.
+
+Here is a complete list of the @option{--enable-} and
+@option{--with-} options that the Bash @code{configure} recognizes.
+
+@table @code
+@item --with-afs
+Define if you are using the Andrew File System from Transarc.
+
+@item --with-bash-malloc
+Use the Bash version of
+@code{malloc} in the directory @file{lib/malloc}. This is not the same
+@code{malloc} that appears in @sc{gnu} libc, but an older version
+originally derived from the 4.2 @sc{bsd} @code{malloc}. This @code{malloc}
+is very fast, but wastes some space on each allocation.
+This option is enabled by default.
+The @file{NOTES} file contains a list of systems for
+which this should be turned off, and @code{configure} disables this
+option automatically for a number of systems.
+
+@item --with-curses
+Use the curses library instead of the termcap library. This should
+be supplied if your system has an inadequate or incomplete termcap
+database.
+
+@item --with-gnu-malloc
+A synonym for @code{--with-bash-malloc}.
+
+@item --with-installed-readline[=@var{PREFIX}]
+Define this to make Bash link with a locally-installed version of Readline
+rather than the version in @file{lib/readline}. This works only with
+Readline 5.0 and later versions. If @var{PREFIX} is @code{yes} or not
+supplied, @code{configure} uses the values of the make variables
+@code{includedir} and @code{libdir}, which are subdirectories of @code{prefix}
+by default, to find the installed version of Readline if it is not in
+the standard system include and library directories.
+If @var{PREFIX} is @code{no}, Bash links with the version in
+@file{lib/readline}.
+If @var{PREFIX} is set to any other value, @code{configure} treats it as
+a directory pathname and looks for
+the installed version of Readline in subdirectories of that directory
+(include files in @var{PREFIX}/@code{include} and the library in
+@var{PREFIX}/@code{lib}).
+
+@item --with-purify
+Define this to use the Purify memory allocation checker from Rational
+Software.
+
+@item --enable-minimal-config
+This produces a shell with minimal features, close to the historical
+Bourne shell.
+@end table
+
+There are several @option{--enable-} options that alter how Bash is
+compiled and linked, rather than changing run-time features.
+
+@table @code
+@item --enable-largefile
+Enable support for @uref{http://www.sas.com/standards/large_file/x_open.20Mar96.html,
+large files} if the operating system requires special compiler options
+to build programs which can access large files. This is enabled by
+default, if the operating system provides large file support.
+
+@item --enable-profiling
+This builds a Bash binary that produces profiling information to be
+processed by @code{gprof} each time it is executed.
+
+@item --enable-static-link
+This causes Bash to be linked statically, if @code{gcc} is being used.
+This could be used to build a version to use as root's shell.
+@end table
+
+The @samp{minimal-config} option can be used to disable all of
+the following options, but it is processed first, so individual
+options may be enabled using @samp{enable-@var{feature}}.
+
+All of the following options except for @samp{disabled-builtins} and
+@samp{xpg-echo-default} are
+enabled by default, unless the operating system does not provide the
+necessary support.
+
+@table @code
+@item --enable-alias
+Allow alias expansion and include the @code{alias} and @code{unalias}
+builtins (@pxref{Aliases}).
+
+@item --enable-arith-for-command
+Include support for the alternate form of the @code{for} command
+that behaves like the C language @code{for} statement
+(@pxref{Looping Constructs}).
+
+@item --enable-array-variables
+Include support for one-dimensional array shell variables
+(@pxref{Arrays}).
+
+@item --enable-bang-history
+Include support for @code{csh}-like history substitution
+(@pxref{History Interaction}).
+
+@item --enable-brace-expansion
+Include @code{csh}-like brace expansion
+( @code{b@{a,b@}c} @expansion{} @code{bac bbc} ).
+See @ref{Brace Expansion}, for a complete description.
+
+@item --enable-casemod-attributes
+Include support for case-modifying attributes in the @code{declare} builtin
+and assignment statements. Variables with the @var{uppercase} attribute,
+for example, will have their values converted to uppercase upon assignment.
+
+@item --enable-casemod-expansion
+Include support for case-modifying word expansions.
+
+@item --enable-command-timing
+Include support for recognizing @code{time} as a reserved word and for
+displaying timing statistics for the pipeline following @code{time}
+(@pxref{Pipelines}).
+This allows pipelines as well as shell builtins and functions to be timed.
+
+@item --enable-cond-command
+Include support for the @code{[[} conditional command.
+(@pxref{Conditional Constructs}).
+
+@item --enable-cond-regexp
+Include support for matching @sc{posix} regular expressions using the
+@samp{=~} binary operator in the @code{[[} conditional command.
+(@pxref{Conditional Constructs}).
+
+@item --enable-coprocesses
+Include support for coprocesses and the @code{coproc} reserved word
+(@pxref{Pipelines}).
+
+@item --enable-debugger
+Include support for the bash debugger (distributed separately).
+
+@item --enable-directory-stack
+Include support for a @code{csh}-like directory stack and the
+@code{pushd}, @code{popd}, and @code{dirs} builtins
+(@pxref{The Directory Stack}).
+
+@item --enable-disabled-builtins
+Allow builtin commands to be invoked via @samp{builtin xxx}
+even after @code{xxx} has been disabled using @samp{enable -n xxx}.
+See @ref{Bash Builtins}, for details of the @code{builtin} and
+@code{enable} builtin commands.
+
+@item --enable-dparen-arithmetic
+Include support for the @code{((@dots{}))} command
+(@pxref{Conditional Constructs}).
+
+@item --enable-extended-glob
+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}).
+
+@item --enable-history
+Include command history and the @code{fc} and @code{history}
+builtin commands (@pxref{Bash History Facilities}).
+
+@item --enable-job-control
+This enables the job control features (@pxref{Job Control}),
+if the operating system supports them.
+
+@item --enable-multibyte
+This enables support for multibyte characters if the operating
+system provides the necessary support.
+
+@item --enable-net-redirections
+This enables the special handling of filenames of the form
+@code{/dev/tcp/@var{host}/@var{port}} and
+@code{/dev/udp/@var{host}/@var{port}}
+when used in redirections (@pxref{Redirections}).
+
+@item --enable-process-substitution
+This enables process substitution (@pxref{Process Substitution}) if
+the operating system provides the necessary support.
+
+@item --enable-progcomp
+Enable the programmable completion facilities
+(@pxref{Programmable Completion}).
+If Readline is not enabled, this option has no effect.
+
+@item --enable-prompt-string-decoding
+Turn on the interpretation of a number of backslash-escaped characters
+in the @env{$PS1}, @env{$PS2}, @env{$PS3}, and @env{$PS4} prompt
+strings. See @ref{Printing a Prompt}, for a complete list of prompt
+string escape sequences.
+
+@item --enable-readline
+Include support for command-line editing and history with the Bash
+version of the Readline library (@pxref{Command Line Editing}).
+
+@item --enable-restricted
+Include support for a @dfn{restricted shell}. If this is enabled, Bash,
+when called as @code{rbash}, enters a restricted mode. See
+@ref{The Restricted Shell}, for a description of restricted mode.
+
+@item --enable-select
+Include the @code{select} compound command, which allows the generation of
+simple menus (@pxref{Conditional Constructs}).
+
+@item --enable-separate-helpfiles
+Use external files for the documentation displayed by the @code{help} builtin
+instead of storing the text internally.
+
+@item --enable-single-help-strings
+Store the text displayed by the @code{help} builtin as a single string for
+each help topic. This aids in translating the text to different languages.
+You may need to disable this if your compiler cannot handle very long string
+literals.
+
+@item --enable-strict-posix-default
+Make Bash @sc{posix}-conformant by default (@pxref{Bash POSIX Mode}).
+
+@item --enable-usg-echo-default
+A synonym for @code{--enable-xpg-echo-default}.
+
+@item --enable-xpg-echo-default
+Make the @code{echo} builtin expand backslash-escaped characters by default,
+without requiring the @option{-e} option.
+This sets the default value of the @code{xpg_echo} shell option to @code{on},
+which makes the Bash @code{echo} behave more like the version specified in
+the Single Unix Specification, version 3.
+@xref{Bash Builtins}, for a description of the escape sequences that
+@code{echo} recognizes.
+
+@end table
+
+The file @file{config-top.h} contains C Preprocessor
+@samp{#define} statements for options which are not settable from
+@code{configure}.
+Some of these are not meant to be changed; beware of the consequences if
+you do.
+Read the comments associated with each definition for more
+information about its effect.
+
+@node Reporting Bugs
+@appendix Reporting Bugs
+
+Please report all bugs you find in Bash.
+But first, you should
+make sure that it really is a bug, and that it appears in the latest
+version of Bash.
+The latest version of Bash is always available for FTP from
+@uref{ftp://ftp.gnu.org/pub/gnu/bash/}.
+
+Once you have determined that a bug actually exists, use the
+@code{bashbug} command to submit a bug report.
+If you have a fix, you are encouraged to mail that as well!
+Suggestions and `philosophical' bug reports may be mailed
+to @email{bug-bash@@gnu.org} or posted to the Usenet
+newsgroup @code{gnu.bash.bug}.
+
+All bug reports should include:
+@itemize @bullet
+@item
+The version number of Bash.
+@item
+The hardware and operating system.
+@item
+The compiler used to compile Bash.
+@item
+A description of the bug behaviour.
+@item
+A short script or `recipe' which exercises the bug and may be used
+to reproduce it.
+@end itemize
+
+@noindent
+@code{bashbug} inserts the first three items automatically into
+the template it provides for filing a bug report.
+
+Please send all reports concerning this manual to
+@email{chet.ramey@@case.edu}.
+
+@node Major Differences From The Bourne Shell
+@appendix Major Differences From The Bourne Shell
+
+Bash implements essentially the same grammar, parameter and
+variable expansion, redirection, and quoting as the Bourne Shell.
+Bash uses the @sc{posix} standard as the specification of
+how these features are to be implemented. There are some
+differences between the traditional Bourne shell and Bash; this
+section quickly details the differences of significance. A
+number of these differences are explained in greater depth in
+previous sections.
+This section uses the version of @code{sh} included in SVR4.2 (the
+last version of the historical Bourne shell) as the baseline reference.
+
+@itemize @bullet
+
+@item
+Bash is @sc{posix}-conformant, even where the @sc{posix} specification
+differs from traditional @code{sh} behavior (@pxref{Bash POSIX Mode}).
+
+@item
+Bash has multi-character invocation options (@pxref{Invoking Bash}).
+
+@item
+Bash has command-line editing (@pxref{Command Line Editing}) and
+the @code{bind} builtin.
+
+@item
+Bash provides a programmable word completion mechanism
+(@pxref{Programmable Completion}), and builtin commands
+@code{complete}, @code{compgen}, and @code{compopt}, to
+manipulate it.
+
+@item
+Bash has command history (@pxref{Bash History Facilities}) and the
+@code{history} and @code{fc} builtins to manipulate it.
+The Bash history list maintains timestamp information and uses the
+value of the @code{HISTTIMEFORMAT} variable to display it.
+
+@item
+Bash implements @code{csh}-like history expansion
+(@pxref{History Interaction}).
+
+@item
+Bash has one-dimensional array variables (@pxref{Arrays}), and the
+appropriate variable expansions and assignment syntax to use them.
+Several of the Bash builtins take options to act on arrays.
+Bash provides a number of built-in array variables.
+
+@item
+The @code{$'@dots{}'} quoting syntax, which expands ANSI-C
+backslash-escaped characters in the text between the single quotes,
+is supported (@pxref{ANSI-C Quoting}).
+
+@item
+Bash supports the @code{$"@dots{}"} quoting syntax to do
+locale-specific translation of the characters between the double
+quotes. The @option{-D}, @option{--dump-strings}, and @option{--dump-po-strings}
+invocation options list the translatable strings found in a script
+(@pxref{Locale Translation}).
+
+@item
+Bash implements the @code{!} keyword to negate the return value of
+a pipeline (@pxref{Pipelines}).
+Very useful when an @code{if} statement needs to act only if a test fails.
+The Bash @samp{-o pipefail} option to @code{set} will cause a pipeline to
+return a failure status if any command fails.
+
+@item
+Bash has the @code{time} reserved word and command timing (@pxref{Pipelines}).
+The display of the timing statistics may be controlled with the
+@env{TIMEFORMAT} variable.
+
+@item
+Bash implements the @code{for (( @var{expr1} ; @var{expr2} ; @var{expr3} ))}
+arithmetic for command, similar to the C language (@pxref{Looping Constructs}).
+
+@item
+Bash includes the @code{select} compound command, which allows the
+generation of simple menus (@pxref{Conditional Constructs}).
+
+@item
+Bash includes the @code{[[} compound command, which makes conditional
+testing part of the shell grammar (@pxref{Conditional Constructs}), including
+optional regular expression matching.
+
+@item
+Bash provides optional case-insensitive matching for the @code{case} and
+@code{[[} constructs.
+
+@item
+Bash includes brace expansion (@pxref{Brace Expansion}) and tilde
+expansion (@pxref{Tilde Expansion}).
+
+@item
+Bash implements command aliases and the @code{alias} and @code{unalias}
+builtins (@pxref{Aliases}).
+
+@item
+Bash provides shell arithmetic, the @code{((} compound command
+(@pxref{Conditional Constructs}),
+and arithmetic expansion (@pxref{Shell Arithmetic}).
+
+@item
+Variables present in the shell's initial environment are automatically
+exported to child processes. The Bourne shell does not normally do
+this unless the variables are explicitly marked using the @code{export}
+command.
+
+@item
+Bash supports the @samp{+=} assignment operator, which appends to the value
+of the variable named on the left hand side.
+
+@item
+Bash includes the @sc{posix} pattern removal @samp{%}, @samp{#}, @samp{%%}
+and @samp{##} expansions to remove leading or trailing substrings from
+variable values (@pxref{Shell Parameter Expansion}).
+
+@item
+The expansion @code{$@{#xx@}}, which returns the length of @code{$@{xx@}},
+is supported (@pxref{Shell Parameter Expansion}).
+
+@item
+The expansion @code{$@{var:}@var{offset}@code{[:}@var{length}@code{]@}},
+which expands to the substring of @code{var}'s value of length
+@var{length}, beginning at @var{offset}, is present
+(@pxref{Shell Parameter Expansion}).
+
+@item
+The expansion
+@code{$@{var/[/]}@var{pattern}@code{[/}@var{replacement}@code{]@}},
+which matches @var{pattern} and replaces it with @var{replacement} in
+the value of @code{var}, is available (@pxref{Shell Parameter Expansion}).
+
+@item
+The expansion @code{$@{!@var{prefix@}*}} expansion, which expands to
+the names of all shell variables whose names begin with @var{prefix},
+is available (@pxref{Shell Parameter Expansion}).
+
+@item
+Bash has @var{indirect} variable expansion using @code{$@{!word@}}
+(@pxref{Shell Parameter Expansion}).
+
+@item
+Bash can expand positional parameters beyond @code{$9} using
+@code{$@{@var{num}@}}.
+
+@item
+The @sc{posix} @code{$()} form of command substitution
+is implemented (@pxref{Command Substitution}),
+and preferred to the Bourne shell's @code{``} (which
+is also implemented for backwards compatibility).
+
+@item
+Bash has process substitution (@pxref{Process Substitution}).
+
+@item
+Bash automatically assigns variables that provide information about the
+current user (@env{UID}, @env{EUID}, and @env{GROUPS}), the current host
+(@env{HOSTTYPE}, @env{OSTYPE}, @env{MACHTYPE}, and @env{HOSTNAME}),
+and the instance of Bash that is running (@env{BASH},
+@env{BASH_VERSION}, and @env{BASH_VERSINFO}). @xref{Bash Variables},
+for details.
+
+@item
+The @env{IFS} variable is used to split only the results of expansion,
+not all words (@pxref{Word Splitting}).
+This closes a longstanding shell security hole.
+
+@item
+Bash implements the full set of @sc{posix} filename expansion operators,
+including @var{character classes}, @var{equivalence classes}, and
+@var{collating symbols} (@pxref{Filename Expansion}).
+
+@item
+Bash implements extended pattern matching features when the @code{extglob}
+shell option is enabled (@pxref{Pattern Matching}).
+
+@item
+It is possible to have a variable and a function with the same name;
+@code{sh} does not separate the two name spaces.
+
+@item
+Bash functions are permitted to have local variables using the
+@code{local} builtin, and thus useful recursive functions may be written
+(@pxref{Bash Builtins}).
+
+@item
+Variable assignments preceding commands affect only that command, even
+builtins and functions (@pxref{Environment}).
+In @code{sh}, all variable assignments
+preceding commands are global unless the command is executed from the
+file system.
+
+@item
+Bash performs filename expansion on filenames specified as operands
+to input and output redirection operators (@pxref{Redirections}).
+
+@item
+Bash contains the @samp{<>} redirection operator, allowing a file to be
+opened for both reading and writing, and the @samp{&>} redirection
+operator, for directing standard output and standard error to the same
+file (@pxref{Redirections}).
+
+@item
+Bash includes the @samp{<<<} redirection operator, allowing a string to
+be used as the standard input to a command.
+
+@item
+Bash implements the @samp{[n]<&@var{word}} and @samp{[n]>&@var{word}}
+redirection operators, which move one file descriptor to another.
+
+@item
+Bash treats a number of filenames specially when they are
+used in redirection operators (@pxref{Redirections}).
+
+@item
+Bash can open network connections to arbitrary machines and services
+with the redirection operators (@pxref{Redirections}).
+
+@item
+The @code{noclobber} option is available to avoid overwriting existing
+files with output redirection (@pxref{The Set Builtin}).
+The @samp{>|} redirection operator may be used to override @code{noclobber}.
+
+@item
+The Bash @code{cd} and @code{pwd} builtins (@pxref{Bourne Shell Builtins})
+each take @option{-L} and @option{-P} options to switch between logical and
+physical modes.
+
+@item
+Bash allows a function to override a builtin with the same name, and provides
+access to that builtin's functionality within the function via the
+@code{builtin} and @code{command} builtins (@pxref{Bash Builtins}).
+
+@item
+The @code{command} builtin allows selective disabling of functions
+when command lookup is performed (@pxref{Bash Builtins}).
+
+@item
+Individual builtins may be enabled or disabled using the @code{enable}
+builtin (@pxref{Bash Builtins}).
+
+@item
+The Bash @code{exec} builtin takes additional options that allow users
+to control the contents of the environment passed to the executed
+command, and what the zeroth argument to the command is to be
+(@pxref{Bourne Shell Builtins}).
+
+@item
+Shell functions may be exported to children via the environment
+using @code{export -f} (@pxref{Shell Functions}).
+
+@item
+The Bash @code{export}, @code{readonly}, and @code{declare} builtins can
+take a @option{-f} option to act on shell functions, a @option{-p} option to
+display variables with various attributes set in a format that can be
+used as shell input, a @option{-n} option to remove various variable
+attributes, and @samp{name=value} arguments to set variable attributes
+and values simultaneously.
+
+@item
+The Bash @code{hash} builtin allows a name to be associated with
+an arbitrary filename, even when that filename cannot be found by
+searching the @env{$PATH}, using @samp{hash -p}
+(@pxref{Bourne Shell Builtins}).
+
+@item
+Bash includes a @code{help} builtin for quick reference to shell
+facilities (@pxref{Bash Builtins}).
+
+@item
+The @code{printf} builtin is available to display formatted output
+(@pxref{Bash Builtins}).
+
+@item
+The Bash @code{read} builtin (@pxref{Bash Builtins})
+will read a line ending in @samp{\} with
+the @option{-r} option, and will use the @env{REPLY} variable as a
+default if no non-option arguments are supplied.
+The Bash @code{read} builtin
+also accepts a prompt string with the @option{-p} option and will use
+Readline to obtain the line when given the @option{-e} option.
+The @code{read} builtin also has additional options to control input:
+the @option{-s} option will turn off echoing of input characters as
+they are read, the @option{-t} option will allow @code{read} to time out
+if input does not arrive within a specified number of seconds, the
+@option{-n} option will allow reading only a specified number of
+characters rather than a full line, and the @option{-d} option will read
+until a particular character rather than newline.
+
+@item
+The @code{return} builtin may be used to abort execution of scripts
+executed with the @code{.} or @code{source} builtins
+(@pxref{Bourne Shell Builtins}).
+
+@item
+Bash includes the @code{shopt} builtin, for finer control of shell
+optional capabilities (@pxref{The Shopt Builtin}), and allows these options
+to be set and unset at shell invocation (@pxref{Invoking Bash}).
+
+@item
+Bash has much more optional behavior controllable with the @code{set}
+builtin (@pxref{The Set Builtin}).
+
+@item
+The @samp{-x} (@code{xtrace}) option displays commands other than
+simple commands when performing an execution trace
+(@pxref{The Set Builtin}).
+
+@item
+The @code{test} builtin (@pxref{Bourne Shell Builtins})
+is slightly different, as it implements the @sc{posix} algorithm,
+which specifies the behavior based on the number of arguments.
+
+@item
+Bash includes the @code{caller} builtin, which displays the context of
+any active subroutine call (a shell function or a script executed with
+the @code{.} or @code{source} builtins). This supports the bash
+debugger.
+
+@item
+The @code{trap} builtin (@pxref{Bourne Shell Builtins}) allows a
+@code{DEBUG} pseudo-signal specification, similar to @code{EXIT}.
+Commands specified with a @code{DEBUG} trap are executed before every
+simple command, @code{for} command, @code{case} command,
+@code{select} command, every arithmetic @code{for} command, and before
+the first command executes in a shell function.
+The @code{DEBUG} trap is not inherited by shell functions unless the
+function has been given the @code{trace} attribute or the
+@code{functrace} option has been enabled using the @code{shopt} builtin.
+The @code{extdebug} shell option has additional effects on the
+@code{DEBUG} trap.
+
+The @code{trap} builtin (@pxref{Bourne Shell Builtins}) allows an
+@code{ERR} pseudo-signal specification, similar to @code{EXIT} and @code{DEBUG}.
+Commands specified with an @code{ERR} trap are executed after a simple
+command fails, with a few exceptions.
+The @code{ERR} trap is not inherited by shell functions unless the
+@code{-o errtrace} option to the @code{set} builtin is enabled.
+
+The @code{trap} builtin (@pxref{Bourne Shell Builtins}) allows a
+@code{RETURN} pseudo-signal specification, similar to
+@code{EXIT} and @code{DEBUG}.
+Commands specified with an @code{RETURN} trap are executed before
+execution resumes after a shell function or a shell script executed with
+@code{.} or @code{source} returns.
+The @code{RETURN} trap is not inherited by shell functions unless the
+function has been given the @code{trace} attribute or the
+@code{functrace} option has been enabled using the @code{shopt} builtin.
+
+@item
+The Bash @code{type} builtin is more extensive and gives more information
+about the names it finds (@pxref{Bash Builtins}).
+
+@item
+The Bash @code{umask} builtin permits a @option{-p} option to cause
+the output to be displayed in the form of a @code{umask} command
+that may be reused as input (@pxref{Bourne Shell Builtins}).
+
+@item
+Bash implements a @code{csh}-like directory stack, and provides the
+@code{pushd}, @code{popd}, and @code{dirs} builtins to manipulate it
+(@pxref{The Directory Stack}).
+Bash also makes the directory stack visible as the value of the
+@env{DIRSTACK} shell variable.
+
+@item
+Bash interprets special backslash-escaped characters in the prompt
+strings when interactive (@pxref{Printing a Prompt}).
+
+@item
+The Bash restricted mode is more useful (@pxref{The Restricted Shell});
+the SVR4.2 shell restricted mode is too limited.
+
+@item
+The @code{disown} builtin can remove a job from the internal shell
+job table (@pxref{Job Control Builtins}) or suppress the sending
+of @code{SIGHUP} to a job when the shell exits as the result of a
+@code{SIGHUP}.
+
+@item
+Bash includes a number of features to support a separate debugger for
+shell scripts.
+
+@item
+The SVR4.2 shell has two privilege-related builtins
+(@code{mldmode} and @code{priv}) not present in Bash.
+
+@item
+Bash does not have the @code{stop} or @code{newgrp} builtins.
+
+@item
+Bash does not use the @env{SHACCT} variable or perform shell accounting.
+
+@item
+The SVR4.2 @code{sh} uses a @env{TIMEOUT} variable like Bash uses
+@env{TMOUT}.
+
+@end itemize
+
+@noindent
+More features unique to Bash may be found in @ref{Bash Features}.
+
+
+@appendixsec Implementation Differences From The SVR4.2 Shell
+
+Since Bash is a completely new implementation, it does not suffer from
+many of the limitations of the SVR4.2 shell. For instance:
+
+@itemize @bullet
+
+@item
+Bash does not fork a subshell when redirecting into or out of
+a shell control structure such as an @code{if} or @code{while}
+statement.
+
+@item
+Bash does not allow unbalanced quotes. The SVR4.2 shell will silently
+insert a needed closing quote at @code{EOF} under certain circumstances.
+This can be the cause of some hard-to-find errors.
+
+@item
+The SVR4.2 shell uses a baroque memory management scheme based on
+trapping @code{SIGSEGV}. If the shell is started from a process with
+@code{SIGSEGV} blocked (e.g., by using the @code{system()} C library
+function call), it misbehaves badly.
+
+@item
+In a questionable attempt at security, the SVR4.2 shell,
+when invoked without the @option{-p} option, will alter its real
+and effective @sc{uid} and @sc{gid} if they are less than some
+magic threshold value, commonly 100.
+This can lead to unexpected results.
+
+@item
+The SVR4.2 shell does not allow users to trap @code{SIGSEGV},
+@code{SIGALRM}, or @code{SIGCHLD}.
+
+@item
+The SVR4.2 shell does not allow the @env{IFS}, @env{MAILCHECK},
+@env{PATH}, @env{PS1}, or @env{PS2} variables to be unset.
+
+@item
+The SVR4.2 shell treats @samp{^} as the undocumented equivalent of
+@samp{|}.
+
+@item
+Bash allows multiple option arguments when it is invoked (@code{-x -v});
+the SVR4.2 shell allows only one option argument (@code{-xv}). In
+fact, some versions of the shell dump core if the second argument begins
+with a @samp{-}.
+
+@item
+The SVR4.2 shell exits a script if any builtin fails; Bash exits
+a script only if one of the @sc{posix} special builtins fails, and
+only for certain failures, as enumerated in the @sc{posix} standard.
+
+@item
+The SVR4.2 shell behaves differently when invoked as @code{jsh}
+(it turns on job control).
+@end itemize
+
+@node GNU Free Documentation License
+@appendix GNU Free Documentation License
+
+@include fdl.texi
+
+@node Indexes
+@appendix Indexes
+
+@menu
+* Builtin Index:: Index of Bash builtin commands.
+* Reserved Word Index:: Index of Bash reserved words.
+* Variable Index:: Quick reference helps you find the
+ variable you want.
+* Function Index:: Index of bindable Readline functions.
+* Concept Index:: General index for concepts described in
+ this manual.
+@end menu
+
+@node Builtin Index
+@appendixsec Index of Shell Builtin Commands
+@printindex bt
+
+@node Reserved Word Index
+@appendixsec Index of Shell Reserved Words
+@printindex rw
+
+@node Variable Index
+@appendixsec Parameter and Variable Index
+@printindex vr
+
+@node Function Index
+@appendixsec Function Index
+@printindex fn
+
+@node Concept Index
+@appendixsec Concept Index
+@printindex cp
+
+@bye
Copyright (C) 1988-2011 Free Software Foundation, Inc.
@end ignore
-@set LASTCHANGE Thu Jul 7 07:34:57 EDT 2011
+@set LASTCHANGE Thu Jul 28 18:11:38 EDT 2011
@set EDITION 4.2
@set VERSION 4.2
-@set UPDATED 7 July 2011
+@set UPDATED 28 July 2011
@set UPDATED-MONTH July 2011
--- /dev/null
+@ignore
+Copyright (C) 1988-2011 Free Software Foundation, Inc.
+@end ignore
+
+@set LASTCHANGE Sun Jul 24 16:17:58 EDT 2011
+
+@set EDITION 4.2
+@set VERSION 4.2
+@set UPDATED 24 July 2011
+@set UPDATED-MONTH July 2011
fix_assignment_words (words)
WORD_LIST *words;
{
- WORD_LIST *w;
+ WORD_LIST *w, *wcmd;
struct builtin *b;
int assoc;
b = 0;
assoc = 0;
+ wcmd = words;
for (w = words; w; w = w->next)
if (w->word->flags & W_ASSIGNMENT)
{
if (b == 0)
{
- b = builtin_address_internal (words->word->word, 0);
+ /* Posix (post-2008) says that `command' doesn't change whether
+ or not the builtin it shadows is a `declaration command', even
+ though it removes other special builtin properties. In Posix
+ mode, we skip over one or more instances of `command' and
+ deal with the next word as the assignment builtin. */
+ while (posixly_correct && wcmd && wcmd->word && wcmd->word->word && STREQ (wcmd->word->word, "command"))
+ wcmd = wcmd->next;
+ b = builtin_address_internal (wcmd->word->word, 0);
if (b == 0 || (b->flags & ASSIGNMENT_BUILTIN) == 0)
return;
else if (b && (b->flags & ASSIGNMENT_BUILTIN))
- words->word->flags |= W_ASSNBLTIN;
+ wcmd->word->flags |= W_ASSNBLTIN;
}
w->word->flags |= (W_NOSPLIT|W_NOGLOB|W_TILDEEXP|W_ASSIGNARG);
#if defined (ARRAY_VARS)
{
if (b == 0)
{
- b = builtin_address_internal (words->word->word, 0);
+ while (posixly_correct && wcmd && wcmd->word && wcmd->word->word && STREQ (wcmd->word->word, "command"))
+ wcmd = wcmd->next;
+ b = builtin_address_internal (wcmd->word->word, 0);
if (b == 0 || (b->flags & ASSIGNMENT_BUILTIN) == 0)
return;
else if (b && (b->flags & ASSIGNMENT_BUILTIN))
- words->word->flags |= W_ASSNBLTIN;
+ wcmd->word->flags |= W_ASSNBLTIN;
}
- if (words->word->flags & W_ASSNBLTIN)
+ if (wcmd->word->flags & W_ASSNBLTIN)
assoc = 1;
}
#endif
--- /dev/null
+/* execute_cmd.c -- Execute a COMMAND structure. */
+
+/* Copyright (C) 1987-2010 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/>.
+*/
+
+#include "config.h"
+
+#if !defined (__GNUC__) && !defined (HAVE_ALLOCA_H) && defined (_AIX)
+ #pragma alloca
+#endif /* _AIX && RISC6000 && !__GNUC__ */
+
+#include <stdio.h>
+#include "chartypes.h"
+#include "bashtypes.h"
+#if !defined (_MINIX) && defined (HAVE_SYS_FILE_H)
+# include <sys/file.h>
+#endif
+#include "filecntl.h"
+#include "posixstat.h"
+#include <signal.h>
+#ifndef _MINIX
+# include <sys/param.h>
+#endif
+
+#if defined (HAVE_UNISTD_H)
+# include <unistd.h>
+#endif
+
+#include "posixtime.h"
+
+#if defined (HAVE_SYS_RESOURCE_H) && !defined (RLIMTYPE)
+# include <sys/resource.h>
+#endif
+
+#if defined (HAVE_SYS_TIMES_H) && defined (HAVE_TIMES)
+# include <sys/times.h>
+#endif
+
+#include <errno.h>
+
+#if !defined (errno)
+extern int errno;
+#endif
+
+#define NEED_FPURGE_DECL
+
+#include "bashansi.h"
+#include "bashintl.h"
+
+#include "memalloc.h"
+#include "shell.h"
+#include <y.tab.h> /* use <...> so we pick it up from the build directory */
+#include "flags.h"
+#include "builtins.h"
+#include "hashlib.h"
+#include "jobs.h"
+#include "execute_cmd.h"
+#include "findcmd.h"
+#include "redir.h"
+#include "trap.h"
+#include "pathexp.h"
+#include "hashcmd.h"
+
+#if defined (COND_COMMAND)
+# include "test.h"
+#endif
+
+#include "builtins/common.h"
+#include "builtins/builtext.h" /* list of builtins */
+
+#include <glob/strmatch.h>
+#include <tilde/tilde.h>
+
+#if defined (BUFFERED_INPUT)
+# include "input.h"
+#endif
+
+#if defined (ALIAS)
+# include "alias.h"
+#endif
+
+#if defined (HISTORY)
+# include "bashhist.h"
+#endif
+
+extern int dollar_dollar_pid;
+extern int posixly_correct;
+extern int expand_aliases;
+extern int autocd;
+extern int breaking, continuing, loop_level;
+extern int parse_and_execute_level, running_trap, sourcelevel;
+extern int command_string_index, line_number;
+extern int dot_found_in_search;
+extern int already_making_children;
+extern int tempenv_assign_error;
+extern char *the_printed_command, *shell_name;
+extern pid_t last_command_subst_pid;
+extern sh_builtin_func_t *last_shell_builtin, *this_shell_builtin;
+extern char **subshell_argv, **subshell_envp;
+extern int subshell_argc;
+extern time_t shell_start_time;
+#if 0
+extern char *glob_argv_flags;
+#endif
+
+extern int close __P((int));
+
+/* Static functions defined and used in this file. */
+static void close_pipes __P((int, int));
+static void do_piping __P((int, int));
+static void bind_lastarg __P((char *));
+static int shell_control_structure __P((enum command_type));
+static void cleanup_redirects __P((REDIRECT *));
+
+#if defined (JOB_CONTROL)
+static int restore_signal_mask __P((sigset_t *));
+#endif
+
+static void async_redirect_stdin __P((void));
+
+static int builtin_status __P((int));
+
+static int execute_for_command __P((FOR_COM *));
+#if defined (SELECT_COMMAND)
+static int displen __P((const char *));
+static int print_index_and_element __P((int, int, WORD_LIST *));
+static void indent __P((int, int));
+static void print_select_list __P((WORD_LIST *, int, int, int));
+static char *select_query __P((WORD_LIST *, int, char *, int));
+static int execute_select_command __P((SELECT_COM *));
+#endif
+#if defined (DPAREN_ARITHMETIC)
+static int execute_arith_command __P((ARITH_COM *));
+#endif
+#if defined (COND_COMMAND)
+static int execute_cond_node __P((COND_COM *));
+static int execute_cond_command __P((COND_COM *));
+#endif
+#if defined (COMMAND_TIMING)
+static int mkfmt __P((char *, int, int, time_t, int));
+static void print_formatted_time __P((FILE *, char *,
+ time_t, int, time_t, int,
+ time_t, int, int));
+static int time_command __P((COMMAND *, int, int, int, struct fd_bitmap *));
+#endif
+#if defined (ARITH_FOR_COMMAND)
+static intmax_t eval_arith_for_expr __P((WORD_LIST *, int *));
+static int execute_arith_for_command __P((ARITH_FOR_COM *));
+#endif
+static int execute_case_command __P((CASE_COM *));
+static int execute_while_command __P((WHILE_COM *));
+static int execute_until_command __P((WHILE_COM *));
+static int execute_while_or_until __P((WHILE_COM *, int));
+static int execute_if_command __P((IF_COM *));
+static int execute_null_command __P((REDIRECT *, int, int, int));
+static void fix_assignment_words __P((WORD_LIST *));
+static int execute_simple_command __P((SIMPLE_COM *, int, int, int, struct fd_bitmap *));
+static int execute_builtin __P((sh_builtin_func_t *, WORD_LIST *, int, int));
+static int execute_function __P((SHELL_VAR *, WORD_LIST *, int, struct fd_bitmap *, int, int));
+static int execute_builtin_or_function __P((WORD_LIST *, sh_builtin_func_t *,
+ SHELL_VAR *,
+ REDIRECT *, struct fd_bitmap *, int));
+static void execute_subshell_builtin_or_function __P((WORD_LIST *, REDIRECT *,
+ sh_builtin_func_t *,
+ SHELL_VAR *,
+ int, int, int,
+ struct fd_bitmap *,
+ int));
+static int execute_disk_command __P((WORD_LIST *, REDIRECT *, char *,
+ int, int, int, struct fd_bitmap *, int));
+
+static char *getinterp __P((char *, int, int *));
+static void initialize_subshell __P((void));
+static int execute_in_subshell __P((COMMAND *, int, int, int, struct fd_bitmap *));
+#if defined (COPROCESS_SUPPORT)
+static int execute_coproc __P((COMMAND *, int, int, struct fd_bitmap *));
+#endif
+
+static int execute_pipeline __P((COMMAND *, int, int, int, struct fd_bitmap *));
+
+static int execute_connection __P((COMMAND *, int, int, int, struct fd_bitmap *));
+
+static int execute_intern_function __P((WORD_DESC *, COMMAND *));
+
+/* Set to 1 if fd 0 was the subject of redirection to a subshell. Global
+ so that reader_loop can set it to zero before executing a command. */
+int stdin_redir;
+
+/* The name of the command that is currently being executed.
+ `test' needs this, for example. */
+char *this_command_name;
+
+/* The printed representation of the currently-executing command (same as
+ the_printed_command), except when a trap is being executed. Useful for
+ a debugger to know where exactly the program is currently executing. */
+char *the_printed_command_except_trap;
+
+/* For catching RETURN in a function. */
+int return_catch_flag;
+int return_catch_value;
+procenv_t return_catch;
+
+/* The value returned by the last synchronous command. */
+int last_command_exit_value;
+
+/* Whether or not the last command (corresponding to last_command_exit_value)
+ was terminated by a signal, and, if so, which one. */
+int last_command_exit_signal;
+
+/* The list of redirections to perform which will undo the redirections
+ that I made in the shell. */
+REDIRECT *redirection_undo_list = (REDIRECT *)NULL;
+
+/* The list of redirections to perform which will undo the internal
+ redirections performed by the `exec' builtin. These are redirections
+ that must be undone even when exec discards redirection_undo_list. */
+REDIRECT *exec_redirection_undo_list = (REDIRECT *)NULL;
+
+/* When greater than zero, value is the `level' of builtins we are
+ currently executing (e.g. `eval echo a' would have it set to 2). */
+int executing_builtin = 0;
+
+/* Non-zero if we are executing a command list (a;b;c, etc.) */
+int executing_list = 0;
+
+/* Non-zero if failing commands in a command substitution should not exit the
+ shell even if -e is set. Used to pass the CMD_IGNORE_RETURN flag down to
+ commands run in command substitutions by parse_and_execute. */
+int comsub_ignore_return = 0;
+
+/* Non-zero if we have just forked and are currently running in a subshell
+ environment. */
+int subshell_environment;
+
+/* Count of nested subshells, like SHLVL. Available via $BASH_SUBSHELL */
+int subshell_level = 0;
+
+/* Currently-executing shell function. */
+SHELL_VAR *this_shell_function;
+
+/* If non-zero, matches in case and [[ ... ]] are case-insensitive */
+int match_ignore_case = 0;
+
+int executing_command_builtin = 0;
+
+struct stat SB; /* used for debugging */
+
+static int special_builtin_failed;
+
+static COMMAND *currently_executing_command;
+
+/* The line number that the currently executing function starts on. */
+static int function_line_number;
+
+/* XXX - set to 1 if we're running the DEBUG trap and we want to show the line
+ number containing the function name. Used by executing_line_number to
+ report the correct line number. Kind of a hack. */
+static int showing_function_line;
+
+static int line_number_for_err_trap;
+
+/* A sort of function nesting level counter */
+int funcnest = 0;
+int funcnest_max = 0; /* XXX - bash-4.2 */
+
+int lastpipe_opt = 0;
+
+struct fd_bitmap *current_fds_to_close = (struct fd_bitmap *)NULL;
+
+#define FD_BITMAP_DEFAULT_SIZE 32
+
+/* Functions to allocate and deallocate the structures used to pass
+ information from the shell to its children about file descriptors
+ to close. */
+struct fd_bitmap *
+new_fd_bitmap (size)
+ int size;
+{
+ struct fd_bitmap *ret;
+
+ ret = (struct fd_bitmap *)xmalloc (sizeof (struct fd_bitmap));
+
+ ret->size = size;
+
+ if (size)
+ {
+ ret->bitmap = (char *)xmalloc (size);
+ memset (ret->bitmap, '\0', size);
+ }
+ else
+ ret->bitmap = (char *)NULL;
+ return (ret);
+}
+
+void
+dispose_fd_bitmap (fdbp)
+ struct fd_bitmap *fdbp;
+{
+ FREE (fdbp->bitmap);
+ free (fdbp);
+}
+
+void
+close_fd_bitmap (fdbp)
+ struct fd_bitmap *fdbp;
+{
+ register int i;
+
+ if (fdbp)
+ {
+ for (i = 0; i < fdbp->size; i++)
+ if (fdbp->bitmap[i])
+ {
+ close (i);
+ fdbp->bitmap[i] = 0;
+ }
+ }
+}
+
+/* Return the line number of the currently executing command. */
+int
+executing_line_number ()
+{
+ if (executing && showing_function_line == 0 &&
+ (variable_context == 0 || interactive_shell == 0) &&
+ currently_executing_command)
+ {
+#if defined (COND_COMMAND)
+ if (currently_executing_command->type == cm_cond)
+ return currently_executing_command->value.Cond->line;
+#endif
+#if defined (DPAREN_ARITHMETIC)
+ else if (currently_executing_command->type == cm_arith)
+ return currently_executing_command->value.Arith->line;
+#endif
+#if defined (ARITH_FOR_COMMAND)
+ else if (currently_executing_command->type == cm_arith_for)
+ return currently_executing_command->value.ArithFor->line;
+#endif
+
+ return line_number;
+ }
+ else
+ return line_number;
+}
+
+/* Execute the command passed in COMMAND. COMMAND is exactly what
+ read_command () places into GLOBAL_COMMAND. See "command.h" for the
+ details of the command structure.
+
+ EXECUTION_SUCCESS or EXECUTION_FAILURE are the only possible
+ return values. Executing a command with nothing in it returns
+ EXECUTION_SUCCESS. */
+int
+execute_command (command)
+ COMMAND *command;
+{
+ struct fd_bitmap *bitmap;
+ int result;
+
+ current_fds_to_close = (struct fd_bitmap *)NULL;
+ bitmap = new_fd_bitmap (FD_BITMAP_DEFAULT_SIZE);
+ begin_unwind_frame ("execute-command");
+ add_unwind_protect (dispose_fd_bitmap, (char *)bitmap);
+
+ /* Just do the command, but not asynchronously. */
+ result = execute_command_internal (command, 0, NO_PIPE, NO_PIPE, bitmap);
+
+ dispose_fd_bitmap (bitmap);
+ discard_unwind_frame ("execute-command");
+
+#if defined (PROCESS_SUBSTITUTION)
+ /* don't unlink fifos if we're in a shell function; wait until the function
+ returns. */
+ if (variable_context == 0)
+ unlink_fifo_list ();
+#endif /* PROCESS_SUBSTITUTION */
+
+ QUIT;
+ return (result);
+}
+
+/* Return 1 if TYPE is a shell control structure type. */
+static int
+shell_control_structure (type)
+ enum command_type type;
+{
+ switch (type)
+ {
+#if defined (ARITH_FOR_COMMAND)
+ case cm_arith_for:
+#endif
+#if defined (SELECT_COMMAND)
+ case cm_select:
+#endif
+#if defined (DPAREN_ARITHMETIC)
+ case cm_arith:
+#endif
+#if defined (COND_COMMAND)
+ case cm_cond:
+#endif
+ case cm_case:
+ case cm_while:
+ case cm_until:
+ case cm_if:
+ case cm_for:
+ case cm_group:
+ case cm_function_def:
+ return (1);
+
+ default:
+ return (0);
+ }
+}
+
+/* A function to use to unwind_protect the redirection undo list
+ for loops. */
+static void
+cleanup_redirects (list)
+ REDIRECT *list;
+{
+ do_redirections (list, RX_ACTIVE);
+ dispose_redirects (list);
+}
+
+#if 0
+/* Function to unwind_protect the redirections for functions and builtins. */
+static void
+cleanup_func_redirects (list)
+ REDIRECT *list;
+{
+ do_redirections (list, RX_ACTIVE);
+}
+#endif
+
+void
+dispose_exec_redirects ()
+{
+ if (exec_redirection_undo_list)
+ {
+ dispose_redirects (exec_redirection_undo_list);
+ exec_redirection_undo_list = (REDIRECT *)NULL;
+ }
+}
+
+#if defined (JOB_CONTROL)
+/* A function to restore the signal mask to its proper value when the shell
+ is interrupted or errors occur while creating a pipeline. */
+static int
+restore_signal_mask (set)
+ sigset_t *set;
+{
+ return (sigprocmask (SIG_SETMASK, set, (sigset_t *)NULL));
+}
+#endif /* JOB_CONTROL */
+
+#ifdef DEBUG
+/* A debugging function that can be called from gdb, for instance. */
+void
+open_files ()
+{
+ register int i;
+ int f, fd_table_size;
+
+ fd_table_size = getdtablesize ();
+
+ fprintf (stderr, "pid %ld open files:", (long)getpid ());
+ for (i = 3; i < fd_table_size; i++)
+ {
+ if ((f = fcntl (i, F_GETFD, 0)) != -1)
+ fprintf (stderr, " %d (%s)", i, f ? "close" : "open");
+ }
+ fprintf (stderr, "\n");
+}
+#endif
+
+static void
+async_redirect_stdin ()
+{
+ int fd;
+
+ fd = open ("/dev/null", O_RDONLY);
+ if (fd > 0)
+ {
+ dup2 (fd, 0);
+ close (fd);
+ }
+ else if (fd < 0)
+ internal_error (_("cannot redirect standard input from /dev/null: %s"), strerror (errno));
+}
+
+#define DESCRIBE_PID(pid) do { if (interactive) describe_pid (pid); } while (0)
+
+/* Execute the command passed in COMMAND, perhaps doing it asynchrounously.
+ COMMAND is exactly what read_command () places into GLOBAL_COMMAND.
+ ASYNCHROUNOUS, if non-zero, says to do this command in the background.
+ PIPE_IN and PIPE_OUT are file descriptors saying where input comes
+ from and where it goes. They can have the value of NO_PIPE, which means
+ I/O is stdin/stdout.
+ FDS_TO_CLOSE is a list of file descriptors to close once the child has
+ been forked. This list often contains the unusable sides of pipes, etc.
+
+ EXECUTION_SUCCESS or EXECUTION_FAILURE are the only possible
+ return values. Executing a command with nothing in it returns
+ EXECUTION_SUCCESS. */
+int
+execute_command_internal (command, asynchronous, pipe_in, pipe_out,
+ fds_to_close)
+ COMMAND *command;
+ int asynchronous;
+ int pipe_in, pipe_out;
+ struct fd_bitmap *fds_to_close;
+{
+ int exec_result, user_subshell, invert, ignore_return, was_error_trap;
+ REDIRECT *my_undo_list, *exec_undo_list;
+ volatile int last_pid;
+ volatile int save_line_number;
+
+#if 0
+ if (command == 0 || breaking || continuing || read_but_dont_execute)
+ return (EXECUTION_SUCCESS);
+#else
+ if (breaking || continuing)
+ return (last_command_exit_value);
+ if (command == 0 || read_but_dont_execute)
+ return (EXECUTION_SUCCESS);
+#endif
+
+ QUIT;
+ run_pending_traps ();
+
+#if 0
+ if (running_trap == 0)
+#endif
+ currently_executing_command = command;
+
+ invert = (command->flags & CMD_INVERT_RETURN) != 0;
+
+ /* If we're inverting the return value and `set -e' has been executed,
+ we don't want a failing command to inadvertently cause the shell
+ to exit. */
+ if (exit_immediately_on_error && invert) /* XXX */
+ command->flags |= CMD_IGNORE_RETURN; /* XXX */
+
+ exec_result = EXECUTION_SUCCESS;
+
+ /* If a command was being explicitly run in a subshell, or if it is
+ a shell control-structure, and it has a pipe, then we do the command
+ in a subshell. */
+ if (command->type == cm_subshell && (command->flags & CMD_NO_FORK))
+ return (execute_in_subshell (command, asynchronous, pipe_in, pipe_out, fds_to_close));
+
+#if defined (COPROCESS_SUPPORT)
+ if (command->type == cm_coproc)
+ return (execute_coproc (command, pipe_in, pipe_out, fds_to_close));
+#endif
+
+ user_subshell = command->type == cm_subshell || ((command->flags & CMD_WANT_SUBSHELL) != 0);
+
+ if (command->type == cm_subshell ||
+ (command->flags & (CMD_WANT_SUBSHELL|CMD_FORCE_SUBSHELL)) ||
+ (shell_control_structure (command->type) &&
+ (pipe_out != NO_PIPE || pipe_in != NO_PIPE || asynchronous)))
+ {
+ pid_t paren_pid;
+
+ /* Fork a subshell, turn off the subshell bit, turn off job
+ control and call execute_command () on the command again. */
+ line_number_for_err_trap = line_number;
+ paren_pid = make_child (savestring (make_command_string (command)),
+ asynchronous);
+ if (paren_pid == 0)
+ exit (execute_in_subshell (command, asynchronous, pipe_in, pipe_out, fds_to_close));
+ /* NOTREACHED */
+ else
+ {
+ close_pipes (pipe_in, pipe_out);
+
+#if defined (PROCESS_SUBSTITUTION) && defined (HAVE_DEV_FD)
+ unlink_fifo_list ();
+#endif
+ /* If we are part of a pipeline, and not the end of the pipeline,
+ then we should simply return and let the last command in the
+ pipe be waited for. If we are not in a pipeline, or are the
+ last command in the pipeline, then we wait for the subshell
+ and return its exit status as usual. */
+ if (pipe_out != NO_PIPE)
+ return (EXECUTION_SUCCESS);
+
+ stop_pipeline (asynchronous, (COMMAND *)NULL);
+
+ if (asynchronous == 0)
+ {
+ was_error_trap = signal_is_trapped (ERROR_TRAP) && signal_is_ignored (ERROR_TRAP) == 0;
+ invert = (command->flags & CMD_INVERT_RETURN) != 0;
+ ignore_return = (command->flags & CMD_IGNORE_RETURN) != 0;
+
+ exec_result = wait_for (paren_pid);
+
+ /* If we have to, invert the return value. */
+ if (invert)
+ exec_result = ((exec_result == EXECUTION_SUCCESS)
+ ? EXECUTION_FAILURE
+ : EXECUTION_SUCCESS);
+
+ last_command_exit_value = exec_result;
+ if (user_subshell && was_error_trap && ignore_return == 0 && invert == 0 && exec_result != EXECUTION_SUCCESS)
+ {
+ save_line_number = line_number;
+ line_number = line_number_for_err_trap;
+ run_error_trap ();
+ line_number = save_line_number;
+ }
+
+ if (user_subshell && ignore_return == 0 && invert == 0 && exit_immediately_on_error && exec_result != EXECUTION_SUCCESS)
+ {
+ run_pending_traps ();
+ jump_to_top_level (ERREXIT);
+ }
+
+ return (last_command_exit_value);
+ }
+ else
+ {
+ DESCRIBE_PID (paren_pid);
+
+ run_pending_traps ();
+
+ return (EXECUTION_SUCCESS);
+ }
+ }
+ }
+
+#if defined (COMMAND_TIMING)
+ if (command->flags & CMD_TIME_PIPELINE)
+ {
+ if (asynchronous)
+ {
+ command->flags |= CMD_FORCE_SUBSHELL;
+ exec_result = execute_command_internal (command, 1, pipe_in, pipe_out, fds_to_close);
+ }
+ else
+ {
+ exec_result = time_command (command, asynchronous, pipe_in, pipe_out, fds_to_close);
+#if 0
+ if (running_trap == 0)
+#endif
+ currently_executing_command = (COMMAND *)NULL;
+ }
+ return (exec_result);
+ }
+#endif /* COMMAND_TIMING */
+
+ if (shell_control_structure (command->type) && command->redirects)
+ stdin_redir = stdin_redirects (command->redirects);
+
+ /* Handle WHILE FOR CASE etc. with redirections. (Also '&' input
+ redirection.) */
+ if (do_redirections (command->redirects, RX_ACTIVE|RX_UNDOABLE) != 0)
+ {
+ cleanup_redirects (redirection_undo_list);
+ redirection_undo_list = (REDIRECT *)NULL;
+ dispose_exec_redirects ();
+ return (last_command_exit_value = EXECUTION_FAILURE);
+ }
+
+ if (redirection_undo_list)
+ {
+ /* XXX - why copy here? */
+ my_undo_list = (REDIRECT *)copy_redirects (redirection_undo_list);
+ dispose_redirects (redirection_undo_list);
+ redirection_undo_list = (REDIRECT *)NULL;
+ }
+ else
+ my_undo_list = (REDIRECT *)NULL;
+
+ if (exec_redirection_undo_list)
+ {
+ /* XXX - why copy here? */
+ exec_undo_list = (REDIRECT *)copy_redirects (exec_redirection_undo_list);
+ dispose_redirects (exec_redirection_undo_list);
+ exec_redirection_undo_list = (REDIRECT *)NULL;
+ }
+ else
+ exec_undo_list = (REDIRECT *)NULL;
+
+ if (my_undo_list || exec_undo_list)
+ begin_unwind_frame ("loop_redirections");
+
+ if (my_undo_list)
+ add_unwind_protect ((Function *)cleanup_redirects, my_undo_list);
+
+ if (exec_undo_list)
+ add_unwind_protect ((Function *)dispose_redirects, exec_undo_list);
+
+ ignore_return = (command->flags & CMD_IGNORE_RETURN) != 0;
+
+ QUIT;
+
+ switch (command->type)
+ {
+ case cm_simple:
+ {
+ save_line_number = line_number;
+ /* We can't rely on variables retaining their values across a
+ call to execute_simple_command if a longjmp occurs as the
+ result of a `return' builtin. This is true for sure with gcc. */
+#if defined (RECYCLES_PIDS)
+ last_made_pid = NO_PID;
+#endif
+ last_pid = last_made_pid;
+ was_error_trap = signal_is_trapped (ERROR_TRAP) && signal_is_ignored (ERROR_TRAP) == 0;
+
+ if (ignore_return && command->value.Simple)
+ command->value.Simple->flags |= CMD_IGNORE_RETURN;
+ if (command->flags & CMD_STDIN_REDIR)
+ command->value.Simple->flags |= CMD_STDIN_REDIR;
+
+ line_number_for_err_trap = line_number = command->value.Simple->line;
+ exec_result =
+ execute_simple_command (command->value.Simple, pipe_in, pipe_out,
+ asynchronous, fds_to_close);
+ line_number = save_line_number;
+
+ /* The temporary environment should be used for only the simple
+ command immediately following its definition. */
+ dispose_used_env_vars ();
+
+#if (defined (ultrix) && defined (mips)) || defined (C_ALLOCA)
+ /* Reclaim memory allocated with alloca () on machines which
+ may be using the alloca emulation code. */
+ (void) alloca (0);
+#endif /* (ultrix && mips) || C_ALLOCA */
+
+ /* If we forked to do the command, then we must wait_for ()
+ the child. */
+
+ /* XXX - this is something to watch out for if there are problems
+ when the shell is compiled without job control. */
+ if (already_making_children && pipe_out == NO_PIPE &&
+ last_made_pid != last_pid)
+ {
+ stop_pipeline (asynchronous, (COMMAND *)NULL);
+
+ if (asynchronous)
+ {
+ DESCRIBE_PID (last_made_pid);
+ }
+ else
+#if !defined (JOB_CONTROL)
+ /* Do not wait for asynchronous processes started from
+ startup files. */
+ if (last_made_pid != last_asynchronous_pid)
+#endif
+ /* When executing a shell function that executes other
+ commands, this causes the last simple command in
+ the function to be waited for twice. This also causes
+ subshells forked to execute builtin commands (e.g., in
+ pipelines) to be waited for twice. */
+ exec_result = wait_for (last_made_pid);
+ }
+ }
+
+ /* 2009/02/13 -- pipeline failure is processed elsewhere. This handles
+ only the failure of a simple command. */
+ if (was_error_trap && ignore_return == 0 && invert == 0 && pipe_in == NO_PIPE && pipe_out == NO_PIPE && exec_result != EXECUTION_SUCCESS)
+ {
+ last_command_exit_value = exec_result;
+ line_number = line_number_for_err_trap;
+ run_error_trap ();
+ line_number = save_line_number;
+ }
+
+ if (ignore_return == 0 && invert == 0 &&
+ ((posixly_correct && interactive == 0 && special_builtin_failed) ||
+ (exit_immediately_on_error && pipe_in == NO_PIPE && pipe_out == NO_PIPE && exec_result != EXECUTION_SUCCESS)))
+ {
+ last_command_exit_value = exec_result;
+ run_pending_traps ();
+ jump_to_top_level (ERREXIT);
+ }
+
+ break;
+
+ case cm_for:
+ if (ignore_return)
+ command->value.For->flags |= CMD_IGNORE_RETURN;
+ exec_result = execute_for_command (command->value.For);
+ break;
+
+#if defined (ARITH_FOR_COMMAND)
+ case cm_arith_for:
+ if (ignore_return)
+ command->value.ArithFor->flags |= CMD_IGNORE_RETURN;
+ exec_result = execute_arith_for_command (command->value.ArithFor);
+ break;
+#endif
+
+#if defined (SELECT_COMMAND)
+ case cm_select:
+ if (ignore_return)
+ command->value.Select->flags |= CMD_IGNORE_RETURN;
+ exec_result = execute_select_command (command->value.Select);
+ break;
+#endif
+
+ case cm_case:
+ if (ignore_return)
+ command->value.Case->flags |= CMD_IGNORE_RETURN;
+ exec_result = execute_case_command (command->value.Case);
+ break;
+
+ case cm_while:
+ if (ignore_return)
+ command->value.While->flags |= CMD_IGNORE_RETURN;
+ exec_result = execute_while_command (command->value.While);
+ break;
+
+ case cm_until:
+ if (ignore_return)
+ command->value.While->flags |= CMD_IGNORE_RETURN;
+ exec_result = execute_until_command (command->value.While);
+ break;
+
+ case cm_if:
+ if (ignore_return)
+ command->value.If->flags |= CMD_IGNORE_RETURN;
+ exec_result = execute_if_command (command->value.If);
+ break;
+
+ case cm_group:
+
+ /* This code can be executed from either of two paths: an explicit
+ '{}' command, or via a function call. If we are executed via a
+ function call, we have already taken care of the function being
+ executed in the background (down there in execute_simple_command ()),
+ and this command should *not* be marked as asynchronous. If we
+ are executing a regular '{}' group command, and asynchronous == 1,
+ we must want to execute the whole command in the background, so we
+ need a subshell, and we want the stuff executed in that subshell
+ (this group command) to be executed in the foreground of that
+ subshell (i.e. there will not be *another* subshell forked).
+
+ What we do is to force a subshell if asynchronous, and then call
+ execute_command_internal again with asynchronous still set to 1,
+ but with the original group command, so the printed command will
+ look right.
+
+ The code above that handles forking off subshells will note that
+ both subshell and async are on, and turn off async in the child
+ after forking the subshell (but leave async set in the parent, so
+ the normal call to describe_pid is made). This turning off
+ async is *crucial*; if it is not done, this will fall into an
+ infinite loop of executions through this spot in subshell after
+ subshell until the process limit is exhausted. */
+
+ if (asynchronous)
+ {
+ command->flags |= CMD_FORCE_SUBSHELL;
+ exec_result =
+ execute_command_internal (command, 1, pipe_in, pipe_out,
+ fds_to_close);
+ }
+ else
+ {
+ if (ignore_return && command->value.Group->command)
+ command->value.Group->command->flags |= CMD_IGNORE_RETURN;
+ exec_result =
+ execute_command_internal (command->value.Group->command,
+ asynchronous, pipe_in, pipe_out,
+ fds_to_close);
+ }
+ break;
+
+ case cm_connection:
+ exec_result = execute_connection (command, asynchronous,
+ pipe_in, pipe_out, fds_to_close);
+ break;
+
+#if defined (DPAREN_ARITHMETIC)
+ case cm_arith:
+ was_error_trap = signal_is_trapped (ERROR_TRAP) && signal_is_ignored (ERROR_TRAP) == 0;
+ if (ignore_return)
+ command->value.Arith->flags |= CMD_IGNORE_RETURN;
+ line_number_for_err_trap = save_line_number = line_number;
+ exec_result = execute_arith_command (command->value.Arith);
+ line_number = save_line_number;
+
+ if (was_error_trap && ignore_return == 0 && invert == 0 && exec_result != EXECUTION_SUCCESS)
+ {
+ last_command_exit_value = exec_result;
+ save_line_number = line_number;
+ line_number = line_number_for_err_trap;
+ run_error_trap ();
+ line_number = save_line_number;
+ }
+
+ if (ignore_return == 0 && invert == 0 && exit_immediately_on_error && exec_result != EXECUTION_SUCCESS)
+ {
+ last_command_exit_value = exec_result;
+ run_pending_traps ();
+ jump_to_top_level (ERREXIT);
+ }
+
+ break;
+#endif
+
+#if defined (COND_COMMAND)
+ case cm_cond:
+ was_error_trap = signal_is_trapped (ERROR_TRAP) && signal_is_ignored (ERROR_TRAP) == 0;
+ if (ignore_return)
+ command->value.Cond->flags |= CMD_IGNORE_RETURN;
+
+ line_number_for_err_trap = save_line_number = line_number;
+ exec_result = execute_cond_command (command->value.Cond);
+ line_number = save_line_number;
+
+ if (was_error_trap && ignore_return == 0 && invert == 0 && exec_result != EXECUTION_SUCCESS)
+ {
+ last_command_exit_value = exec_result;
+ save_line_number = line_number;
+ line_number = line_number_for_err_trap;
+ run_error_trap ();
+ line_number = save_line_number;
+ }
+
+ if (ignore_return == 0 && invert == 0 && exit_immediately_on_error && exec_result != EXECUTION_SUCCESS)
+ {
+ last_command_exit_value = exec_result;
+ run_pending_traps ();
+ jump_to_top_level (ERREXIT);
+ }
+
+ break;
+#endif
+
+ case cm_function_def:
+ exec_result = execute_intern_function (command->value.Function_def->name,
+ command->value.Function_def->command);
+ break;
+
+ default:
+ command_error ("execute_command", CMDERR_BADTYPE, command->type, 0);
+ }
+
+ if (my_undo_list)
+ {
+ do_redirections (my_undo_list, RX_ACTIVE);
+ dispose_redirects (my_undo_list);
+ }
+
+ if (exec_undo_list)
+ dispose_redirects (exec_undo_list);
+
+ if (my_undo_list || exec_undo_list)
+ discard_unwind_frame ("loop_redirections");
+
+ /* Invert the return value if we have to */
+ if (invert)
+ exec_result = (exec_result == EXECUTION_SUCCESS)
+ ? EXECUTION_FAILURE
+ : EXECUTION_SUCCESS;
+
+#if defined (DPAREN_ARITHMETIC) || defined (COND_COMMAND)
+ /* This is where we set PIPESTATUS from the exit status of the appropriate
+ compound commands (the ones that look enough like simple commands to
+ cause confusion). We might be able to optimize by not doing this if
+ subshell_environment != 0. */
+ switch (command->type)
+ {
+# if defined (DPAREN_ARITHMETIC)
+ case cm_arith:
+# endif
+# if defined (COND_COMMAND)
+ case cm_cond:
+# endif
+ set_pipestatus_from_exit (exec_result);
+ break;
+ }
+#endif
+
+ last_command_exit_value = exec_result;
+ run_pending_traps ();
+#if 0
+ if (running_trap == 0)
+#endif
+ currently_executing_command = (COMMAND *)NULL;
+ return (last_command_exit_value);
+}
+
+#if defined (COMMAND_TIMING)
+
+#if defined (HAVE_GETRUSAGE) && defined (HAVE_GETTIMEOFDAY)
+extern struct timeval *difftimeval __P((struct timeval *, struct timeval *, struct timeval *));
+extern struct timeval *addtimeval __P((struct timeval *, struct timeval *, struct timeval *));
+extern int timeval_to_cpu __P((struct timeval *, struct timeval *, struct timeval *));
+#endif
+
+#define POSIX_TIMEFORMAT "real %2R\nuser %2U\nsys %2S"
+#define BASH_TIMEFORMAT "\nreal\t%3lR\nuser\t%3lU\nsys\t%3lS"
+
+static const int precs[] = { 0, 100, 10, 1 };
+
+/* Expand one `%'-prefixed escape sequence from a time format string. */
+static int
+mkfmt (buf, prec, lng, sec, sec_fraction)
+ char *buf;
+ int prec, lng;
+ time_t sec;
+ int sec_fraction;
+{
+ time_t min;
+ char abuf[INT_STRLEN_BOUND(time_t) + 1];
+ int ind, aind;
+
+ ind = 0;
+ abuf[sizeof(abuf) - 1] = '\0';
+
+ /* If LNG is non-zero, we want to decompose SEC into minutes and seconds. */
+ if (lng)
+ {
+ min = sec / 60;
+ sec %= 60;
+ aind = sizeof(abuf) - 2;
+ do
+ abuf[aind--] = (min % 10) + '0';
+ while (min /= 10);
+ aind++;
+ while (abuf[aind])
+ buf[ind++] = abuf[aind++];
+ buf[ind++] = 'm';
+ }
+
+ /* Now add the seconds. */
+ aind = sizeof (abuf) - 2;
+ do
+ abuf[aind--] = (sec % 10) + '0';
+ while (sec /= 10);
+ aind++;
+ while (abuf[aind])
+ buf[ind++] = abuf[aind++];
+
+ /* We want to add a decimal point and PREC places after it if PREC is
+ nonzero. PREC is not greater than 3. SEC_FRACTION is between 0
+ and 999. */
+ if (prec != 0)
+ {
+ buf[ind++] = '.';
+ for (aind = 1; aind <= prec; aind++)
+ {
+ buf[ind++] = (sec_fraction / precs[aind]) + '0';
+ sec_fraction %= precs[aind];
+ }
+ }
+
+ if (lng)
+ buf[ind++] = 's';
+ buf[ind] = '\0';
+
+ return (ind);
+}
+
+/* Interpret the format string FORMAT, interpolating the following escape
+ sequences:
+ %[prec][l][RUS]
+
+ where the optional `prec' is a precision, meaning the number of
+ characters after the decimal point, the optional `l' means to format
+ using minutes and seconds (MMmNN[.FF]s), like the `times' builtin',
+ and the last character is one of
+
+ R number of seconds of `real' time
+ U number of seconds of `user' time
+ S number of seconds of `system' time
+
+ An occurrence of `%%' in the format string is translated to a `%'. The
+ result is printed to FP, a pointer to a FILE. The other variables are
+ the seconds and thousandths of a second of real, user, and system time,
+ resectively. */
+static void
+print_formatted_time (fp, format, rs, rsf, us, usf, ss, ssf, cpu)
+ FILE *fp;
+ char *format;
+ time_t rs;
+ int rsf;
+ time_t us;
+ int usf;
+ time_t ss;
+ int ssf, cpu;
+{
+ int prec, lng, len;
+ char *str, *s, ts[INT_STRLEN_BOUND (time_t) + sizeof ("mSS.FFFF")];
+ time_t sum;
+ int sum_frac;
+ int sindex, ssize;
+
+ len = strlen (format);
+ ssize = (len + 64) - (len % 64);
+ str = (char *)xmalloc (ssize);
+ sindex = 0;
+
+ for (s = format; *s; s++)
+ {
+ if (*s != '%' || s[1] == '\0')
+ {
+ RESIZE_MALLOCED_BUFFER (str, sindex, 1, ssize, 64);
+ str[sindex++] = *s;
+ }
+ else if (s[1] == '%')
+ {
+ s++;
+ RESIZE_MALLOCED_BUFFER (str, sindex, 1, ssize, 64);
+ str[sindex++] = *s;
+ }
+ else if (s[1] == 'P')
+ {
+ s++;
+#if 0
+ /* clamp CPU usage at 100% */
+ if (cpu > 10000)
+ cpu = 10000;
+#endif
+ sum = cpu / 100;
+ sum_frac = (cpu % 100) * 10;
+ len = mkfmt (ts, 2, 0, sum, sum_frac);
+ RESIZE_MALLOCED_BUFFER (str, sindex, len, ssize, 64);
+ strcpy (str + sindex, ts);
+ sindex += len;
+ }
+ else
+ {
+ prec = 3; /* default is three places past the decimal point. */
+ lng = 0; /* default is to not use minutes or append `s' */
+ s++;
+ if (DIGIT (*s)) /* `precision' */
+ {
+ prec = *s++ - '0';
+ if (prec > 3) prec = 3;
+ }
+ if (*s == 'l') /* `length extender' */
+ {
+ lng = 1;
+ s++;
+ }
+ if (*s == 'R' || *s == 'E')
+ len = mkfmt (ts, prec, lng, rs, rsf);
+ else if (*s == 'U')
+ len = mkfmt (ts, prec, lng, us, usf);
+ else if (*s == 'S')
+ len = mkfmt (ts, prec, lng, ss, ssf);
+ else
+ {
+ internal_error (_("TIMEFORMAT: `%c': invalid format character"), *s);
+ free (str);
+ return;
+ }
+ RESIZE_MALLOCED_BUFFER (str, sindex, len, ssize, 64);
+ strcpy (str + sindex, ts);
+ sindex += len;
+ }
+ }
+
+ str[sindex] = '\0';
+ fprintf (fp, "%s\n", str);
+ fflush (fp);
+
+ free (str);
+}
+
+static int
+time_command (command, asynchronous, pipe_in, pipe_out, fds_to_close)
+ COMMAND *command;
+ int asynchronous, pipe_in, pipe_out;
+ struct fd_bitmap *fds_to_close;
+{
+ int rv, posix_time, old_flags, nullcmd;
+ time_t rs, us, ss;
+ int rsf, usf, ssf;
+ int cpu;
+ char *time_format;
+
+#if defined (HAVE_GETRUSAGE) && defined (HAVE_GETTIMEOFDAY)
+ struct timeval real, user, sys;
+ struct timeval before, after;
+# if defined (HAVE_STRUCT_TIMEZONE)
+ struct timezone dtz; /* posix doesn't define this */
+# endif
+ struct rusage selfb, selfa, kidsb, kidsa; /* a = after, b = before */
+#else
+# if defined (HAVE_TIMES)
+ clock_t tbefore, tafter, real, user, sys;
+ struct tms before, after;
+# endif
+#endif
+
+#if defined (HAVE_GETRUSAGE) && defined (HAVE_GETTIMEOFDAY)
+# if defined (HAVE_STRUCT_TIMEZONE)
+ gettimeofday (&before, &dtz);
+# else
+ gettimeofday (&before, (void *)NULL);
+# endif /* !HAVE_STRUCT_TIMEZONE */
+ getrusage (RUSAGE_SELF, &selfb);
+ getrusage (RUSAGE_CHILDREN, &kidsb);
+#else
+# if defined (HAVE_TIMES)
+ tbefore = times (&before);
+# endif
+#endif
+
+ posix_time = (command->flags & CMD_TIME_POSIX);
+
+ nullcmd = (command == 0) || (command->type == cm_simple && command->value.Simple->words == 0 && command->value.Simple->redirects == 0);
+ if (posixly_correct && nullcmd)
+ {
+#if defined (HAVE_GETRUSAGE)
+ selfb.ru_utime.tv_sec = kidsb.ru_utime.tv_sec = selfb.ru_stime.tv_sec = kidsb.ru_stime.tv_sec = 0;
+ selfb.ru_utime.tv_usec = kidsb.ru_utime.tv_usec = selfb.ru_stime.tv_usec = kidsb.ru_stime.tv_usec = 0;
+ before.tv_sec = shell_start_time;
+ before.tv_usec = 0;
+#else
+ before.tms_utime = before.tms_stime = before.tms_cutime = before.tms_cstime = 0;
+ tbefore = shell_start_time;
+#endif
+ }
+
+ old_flags = command->flags;
+ command->flags &= ~(CMD_TIME_PIPELINE|CMD_TIME_POSIX);
+ rv = execute_command_internal (command, asynchronous, pipe_in, pipe_out, fds_to_close);
+ command->flags = old_flags;
+
+ rs = us = ss = 0;
+ rsf = usf = ssf = cpu = 0;
+
+#if defined (HAVE_GETRUSAGE) && defined (HAVE_GETTIMEOFDAY)
+# if defined (HAVE_STRUCT_TIMEZONE)
+ gettimeofday (&after, &dtz);
+# else
+ gettimeofday (&after, (void *)NULL);
+# endif /* !HAVE_STRUCT_TIMEZONE */
+ getrusage (RUSAGE_SELF, &selfa);
+ getrusage (RUSAGE_CHILDREN, &kidsa);
+
+ difftimeval (&real, &before, &after);
+ timeval_to_secs (&real, &rs, &rsf);
+
+ addtimeval (&user, difftimeval(&after, &selfb.ru_utime, &selfa.ru_utime),
+ difftimeval(&before, &kidsb.ru_utime, &kidsa.ru_utime));
+ timeval_to_secs (&user, &us, &usf);
+
+ addtimeval (&sys, difftimeval(&after, &selfb.ru_stime, &selfa.ru_stime),
+ difftimeval(&before, &kidsb.ru_stime, &kidsa.ru_stime));
+ timeval_to_secs (&sys, &ss, &ssf);
+
+ cpu = timeval_to_cpu (&real, &user, &sys);
+#else
+# if defined (HAVE_TIMES)
+ tafter = times (&after);
+
+ real = tafter - tbefore;
+ clock_t_to_secs (real, &rs, &rsf);
+
+ user = (after.tms_utime - before.tms_utime) + (after.tms_cutime - before.tms_cutime);
+ clock_t_to_secs (user, &us, &usf);
+
+ sys = (after.tms_stime - before.tms_stime) + (after.tms_cstime - before.tms_cstime);
+ clock_t_to_secs (sys, &ss, &ssf);
+
+ cpu = (real == 0) ? 0 : ((user + sys) * 10000) / real;
+
+# else
+ rs = us = ss = 0;
+ rsf = usf = ssf = cpu = 0;
+# endif
+#endif
+
+ if (posix_time)
+ time_format = POSIX_TIMEFORMAT;
+ else if ((time_format = get_string_value ("TIMEFORMAT")) == 0)
+ {
+ if (posixly_correct && nullcmd)
+ time_format = "user\t%2lU\nsys\t%2lS";
+ else
+ time_format = BASH_TIMEFORMAT;
+ }
+ if (time_format && *time_format)
+ print_formatted_time (stderr, time_format, rs, rsf, us, usf, ss, ssf, cpu);
+
+ return rv;
+}
+#endif /* COMMAND_TIMING */
+
+/* Execute a command that's supposed to be in a subshell. This must be
+ called after make_child and we must be running in the child process.
+ The caller will return or exit() immediately with the value this returns. */
+static int
+execute_in_subshell (command, asynchronous, pipe_in, pipe_out, fds_to_close)
+ COMMAND *command;
+ int asynchronous;
+ int pipe_in, pipe_out;
+ struct fd_bitmap *fds_to_close;
+{
+ int user_subshell, return_code, function_value, should_redir_stdin, invert;
+ int ois, user_coproc;
+ int result;
+ volatile COMMAND *tcom;
+
+ USE_VAR(user_subshell);
+ USE_VAR(user_coproc);
+ USE_VAR(invert);
+ USE_VAR(tcom);
+ USE_VAR(asynchronous);
+
+ subshell_level++;
+ should_redir_stdin = (asynchronous && (command->flags & CMD_STDIN_REDIR) &&
+ pipe_in == NO_PIPE &&
+ stdin_redirects (command->redirects) == 0);
+
+ invert = (command->flags & CMD_INVERT_RETURN) != 0;
+ user_subshell = command->type == cm_subshell || ((command->flags & CMD_WANT_SUBSHELL) != 0);
+ user_coproc = command->type == cm_coproc;
+
+ command->flags &= ~(CMD_FORCE_SUBSHELL | CMD_WANT_SUBSHELL | CMD_INVERT_RETURN);
+
+ /* If a command is asynchronous in a subshell (like ( foo ) & or
+ the special case of an asynchronous GROUP command where the
+ the subshell bit is turned on down in case cm_group: below),
+ turn off `asynchronous', so that two subshells aren't spawned.
+ XXX - asynchronous used to be set to 0 in this block, but that
+ means that setup_async_signals was never run. Now it's set to
+ 0 after subshell_environment is set appropriately and setup_async_signals
+ is run.
+
+ This seems semantically correct to me. For example,
+ ( foo ) & seems to say ``do the command `foo' in a subshell
+ environment, but don't wait for that subshell to finish'',
+ and "{ foo ; bar ; } &" seems to me to be like functions or
+ builtins in the background, which executed in a subshell
+ environment. I just don't see the need to fork two subshells. */
+
+ /* Don't fork again, we are already in a subshell. A `doubly
+ async' shell is not interactive, however. */
+ if (asynchronous)
+ {
+#if defined (JOB_CONTROL)
+ /* If a construct like ( exec xxx yyy ) & is given while job
+ control is active, we want to prevent exec from putting the
+ subshell back into the original process group, carefully
+ undoing all the work we just did in make_child. */
+ original_pgrp = -1;
+#endif /* JOB_CONTROL */
+ ois = interactive_shell;
+ interactive_shell = 0;
+ /* This test is to prevent alias expansion by interactive shells that
+ run `(command) &' but to allow scripts that have enabled alias
+ expansion with `shopt -s expand_alias' to continue to expand
+ aliases. */
+ if (ois != interactive_shell)
+ expand_aliases = 0;
+ }
+
+ /* Subshells are neither login nor interactive. */
+ login_shell = interactive = 0;
+
+ if (user_subshell)
+ subshell_environment = SUBSHELL_PAREN;
+ else
+ {
+ subshell_environment = 0; /* XXX */
+ if (asynchronous)
+ subshell_environment |= SUBSHELL_ASYNC;
+ if (pipe_in != NO_PIPE || pipe_out != NO_PIPE)
+ subshell_environment |= SUBSHELL_PIPE;
+ if (user_coproc)
+ subshell_environment |= SUBSHELL_COPROC;
+ }
+
+ reset_terminating_signals (); /* in sig.c */
+ /* Cancel traps, in trap.c. */
+ /* Reset the signal handlers in the child, but don't free the
+ trap strings. Set a flag noting that we have to free the
+ trap strings if we run trap to change a signal disposition. */
+ reset_signal_handlers ();
+ subshell_environment |= SUBSHELL_RESETTRAP;
+
+ /* Make sure restore_original_signals doesn't undo the work done by
+ make_child to ensure that asynchronous children are immune to SIGINT
+ and SIGQUIT. Turn off asynchronous to make sure more subshells are
+ not spawned. */
+ if (asynchronous)
+ {
+ setup_async_signals ();
+ asynchronous = 0;
+ }
+
+#if defined (JOB_CONTROL)
+ set_sigchld_handler ();
+#endif /* JOB_CONTROL */
+
+ set_sigint_handler ();
+
+#if defined (JOB_CONTROL)
+ /* Delete all traces that there were any jobs running. This is
+ only for subshells. */
+ without_job_control ();
+#endif /* JOB_CONTROL */
+
+ if (fds_to_close)
+ close_fd_bitmap (fds_to_close);
+
+ do_piping (pipe_in, pipe_out);
+
+#if defined (COPROCESS_SUPPORT)
+ coproc_closeall ();
+#endif
+
+ /* If this is a user subshell, set a flag if stdin was redirected.
+ This is used later to decide whether to redirect fd 0 to
+ /dev/null for async commands in the subshell. This adds more
+ sh compatibility, but I'm not sure it's the right thing to do. */
+ if (user_subshell)
+ {
+ stdin_redir = stdin_redirects (command->redirects);
+ restore_default_signal (0);
+ }
+
+ /* If this is an asynchronous command (command &), we want to
+ redirect the standard input from /dev/null in the absence of
+ any specific redirection involving stdin. */
+ if (should_redir_stdin && stdin_redir == 0)
+ async_redirect_stdin ();
+
+ /* Do redirections, then dispose of them before recursive call. */
+ if (command->redirects)
+ {
+ if (do_redirections (command->redirects, RX_ACTIVE) != 0)
+ exit (invert ? EXECUTION_SUCCESS : EXECUTION_FAILURE);
+
+ dispose_redirects (command->redirects);
+ command->redirects = (REDIRECT *)NULL;
+ }
+
+ if (command->type == cm_subshell)
+ tcom = command->value.Subshell->command;
+ else if (user_coproc)
+ tcom = command->value.Coproc->command;
+ else
+ tcom = command;
+
+ if (command->flags & CMD_TIME_PIPELINE)
+ tcom->flags |= CMD_TIME_PIPELINE;
+ if (command->flags & CMD_TIME_POSIX)
+ tcom->flags |= CMD_TIME_POSIX;
+
+ /* Make sure the subshell inherits any CMD_IGNORE_RETURN flag. */
+ if ((command->flags & CMD_IGNORE_RETURN) && tcom != command)
+ tcom->flags |= CMD_IGNORE_RETURN;
+
+ /* If this is a simple command, tell execute_disk_command that it
+ might be able to get away without forking and simply exec.
+ This means things like ( sleep 10 ) will only cause one fork.
+ If we're timing the command or inverting its return value, however,
+ we cannot do this optimization. */
+ if ((user_subshell || user_coproc) && (tcom->type == cm_simple || tcom->type == cm_subshell) &&
+ ((tcom->flags & CMD_TIME_PIPELINE) == 0) &&
+ ((tcom->flags & CMD_INVERT_RETURN) == 0))
+ {
+ tcom->flags |= CMD_NO_FORK;
+ if (tcom->type == cm_simple)
+ tcom->value.Simple->flags |= CMD_NO_FORK;
+ }
+
+ invert = (tcom->flags & CMD_INVERT_RETURN) != 0;
+ tcom->flags &= ~CMD_INVERT_RETURN;
+
+ result = setjmp (top_level);
+
+ /* If we're inside a function while executing this subshell, we
+ need to handle a possible `return'. */
+ function_value = 0;
+ if (return_catch_flag)
+ function_value = setjmp (return_catch);
+
+ /* If we're going to exit the shell, we don't want to invert the return
+ status. */
+ if (result == EXITPROG)
+ invert = 0, return_code = last_command_exit_value;
+ else if (result)
+ return_code = EXECUTION_FAILURE;
+ else if (function_value)
+ return_code = return_catch_value;
+ else
+ return_code = execute_command_internal ((COMMAND *)tcom, asynchronous, NO_PIPE, NO_PIPE, fds_to_close);
+
+ /* If we are asked to, invert the return value. */
+ if (invert)
+ return_code = (return_code == EXECUTION_SUCCESS) ? EXECUTION_FAILURE
+ : EXECUTION_SUCCESS;
+
+ /* If we were explicitly placed in a subshell with (), we need
+ to do the `shell cleanup' things, such as running traps[0]. */
+ if (user_subshell && signal_is_trapped (0))
+ {
+ last_command_exit_value = return_code;
+ return_code = run_exit_trap ();
+ }
+
+ subshell_level--;
+ return (return_code);
+ /* NOTREACHED */
+}
+
+#if defined (COPROCESS_SUPPORT)
+#define COPROC_MAX 16
+
+typedef struct cpelement
+ {
+ struct cpelement *next;
+ struct coproc *coproc;
+ }
+cpelement_t;
+
+typedef struct cplist
+ {
+ struct cpelement *head;
+ struct cpelement *tail;
+ int ncoproc;
+ }
+cplist_t;
+
+static struct cpelement *cpe_alloc __P((struct coproc *));
+static void cpe_dispose __P((struct cpelement *));
+static struct cpelement *cpl_add __P((struct coproc *));
+static struct cpelement *cpl_delete __P((pid_t));
+static void cpl_reap __P((void));
+static void cpl_flush __P((void));
+static void cpl_closeall __P((void));
+static struct cpelement *cpl_search __P((pid_t));
+static struct cpelement *cpl_searchbyname __P((const char *));
+static void cpl_prune __P((void));
+
+static void coproc_free __P((struct coproc *));
+
+/* Will go away when there is fully-implemented support for multiple coprocs. */
+Coproc sh_coproc = { 0, NO_PID, -1, -1, 0, 0, 0, 0 };
+
+cplist_t coproc_list = {0, 0, 0};
+
+/* Functions to manage the list of coprocs */
+
+static struct cpelement *
+cpe_alloc (cp)
+ Coproc *cp;
+{
+ struct cpelement *cpe;
+
+ cpe = (struct cpelement *)xmalloc (sizeof (struct cpelement));
+ cpe->coproc = cp;
+ cpe->next = (struct cpelement *)0;
+ return cpe;
+}
+
+static void
+cpe_dispose (cpe)
+ struct cpelement *cpe;
+{
+ free (cpe);
+}
+
+static struct cpelement *
+cpl_add (cp)
+ Coproc *cp;
+{
+ struct cpelement *cpe;
+
+ cpe = cpe_alloc (cp);
+
+ if (coproc_list.head == 0)
+ {
+ coproc_list.head = coproc_list.tail = cpe;
+ coproc_list.ncoproc = 0; /* just to make sure */
+ }
+ else
+ {
+ coproc_list.tail->next = cpe;
+ coproc_list.tail = cpe;
+ }
+ coproc_list.ncoproc++;
+
+ return cpe;
+}
+
+static struct cpelement *
+cpl_delete (pid)
+ pid_t pid;
+{
+ struct cpelement *prev, *p;
+
+ for (prev = p = coproc_list.head; p; prev = p, p = p->next)
+ if (p->coproc->c_pid == pid)
+ {
+ prev->next = p->next; /* remove from list */
+ break;
+ }
+
+ if (p == 0)
+ return 0; /* not found */
+
+#if defined (DEBUG)
+ itrace("cpl_delete: deleting %d", pid);
+#endif
+
+ /* Housekeeping in the border cases. */
+ if (p == coproc_list.head)
+ coproc_list.head = coproc_list.head->next;
+ else if (p == coproc_list.tail)
+ coproc_list.tail = prev;
+
+ coproc_list.ncoproc--;
+ if (coproc_list.ncoproc == 0)
+ coproc_list.head = coproc_list.tail = 0;
+ else if (coproc_list.ncoproc == 1)
+ coproc_list.tail = coproc_list.head; /* just to make sure */
+
+ return (p);
+}
+
+static void
+cpl_reap ()
+{
+ struct cpelement *prev, *p;
+
+ for (prev = p = coproc_list.head; p; prev = p, p = p->next)
+ if (p->coproc->c_flags & COPROC_DEAD)
+ {
+ prev->next = p->next; /* remove from list */
+
+ /* Housekeeping in the border cases. */
+ if (p == coproc_list.head)
+ coproc_list.head = coproc_list.head->next;
+ else if (p == coproc_list.tail)
+ coproc_list.tail = prev;
+
+ coproc_list.ncoproc--;
+ if (coproc_list.ncoproc == 0)
+ coproc_list.head = coproc_list.tail = 0;
+ else if (coproc_list.ncoproc == 1)
+ coproc_list.tail = coproc_list.head; /* just to make sure */
+
+#if defined (DEBUG)
+ itrace("cpl_reap: deleting %d", p->coproc->c_pid);
+#endif
+
+ coproc_dispose (p->coproc);
+ cpe_dispose (p);
+ }
+}
+
+/* Clear out the list of saved statuses */
+static void
+cpl_flush ()
+{
+ struct cpelement *cpe, *p;
+
+ for (cpe = coproc_list.head; cpe; )
+ {
+ p = cpe;
+ cpe = cpe->next;
+
+ coproc_dispose (p->coproc);
+ cpe_dispose (p);
+ }
+
+ coproc_list.head = coproc_list.tail = 0;
+ coproc_list.ncoproc = 0;
+}
+
+static void
+cpl_closeall ()
+{
+ struct cpelement *cpe;
+
+ for (cpe = coproc_list.head; cpe; cpe = cpe->next)
+ coproc_close (cpe->coproc);
+}
+
+static void
+cpl_fdchk (fd)
+ int fd;
+{
+ struct cpelement *cpe;
+
+ for (cpe = coproc_list.head; cpe; cpe = cpe->next)
+ coproc_checkfd (cpe->coproc, fd);
+}
+
+/* Search for PID in the list of coprocs; return the cpelement struct if
+ found. If not found, return NULL. */
+static struct cpelement *
+cpl_search (pid)
+ pid_t pid;
+{
+ struct cpelement *cpe;
+
+ for (cpe = coproc_list.head ; cpe; cpe = cpe->next)
+ if (cpe->coproc->c_pid == pid)
+ return cpe;
+ return (struct cpelement *)NULL;
+}
+
+/* Search for the coproc named NAME in the list of coprocs; return the
+ cpelement struct if found. If not found, return NULL. */
+static struct cpelement *
+cpl_searchbyname (name)
+ const char *name;
+{
+ struct cpelement *cp;
+
+ for (cp = coproc_list.head ; cp; cp = cp->next)
+ if (STREQ (cp->coproc->c_name, name))
+ return cp;
+ return (struct cpelement *)NULL;
+}
+
+#if 0
+static void
+cpl_prune ()
+{
+ struct cpelement *cp;
+
+ while (coproc_list.head && coproc_list.ncoproc > COPROC_MAX)
+ {
+ cp = coproc_list.head;
+ coproc_list.head = coproc_list.head->next;
+ coproc_dispose (cp->coproc);
+ cpe_dispose (cp);
+ coproc_list.ncoproc--;
+ }
+}
+#endif
+
+/* These currently use a single global "shell coproc" but are written in a
+ way to not preclude additional coprocs later (using the list management
+ package above). */
+
+struct coproc *
+getcoprocbypid (pid)
+ pid_t pid;
+{
+#if MULTIPLE_COPROCS
+ struct cpelement *p;
+
+ p = cpl_search (pid);
+ return (p ? p->coproc : 0);
+#else
+ return (pid == sh_coproc.c_pid ? &sh_coproc : 0);
+#endif
+}
+
+struct coproc *
+getcoprocbyname (name)
+ const char *name;
+{
+#if MULTIPLE_COPROCS
+ struct cpelement *p;
+
+ p = cpl_searchbyname (name);
+ return (p ? p->coproc : 0);
+#else
+ return ((sh_coproc.c_name && STREQ (sh_coproc.c_name, name)) ? &sh_coproc : 0);
+#endif
+}
+
+void
+coproc_init (cp)
+ struct coproc *cp;
+{
+ cp->c_name = 0;
+ cp->c_pid = NO_PID;
+ cp->c_rfd = cp->c_wfd = -1;
+ cp->c_rsave = cp->c_wsave = -1;
+ cp->c_flags = cp->c_status = 0;
+}
+
+struct coproc *
+coproc_alloc (name, pid)
+ char *name;
+ pid_t pid;
+{
+ struct coproc *cp;
+
+#if MULTIPLE_COPROCS
+ cp = (struct coproc *)xmalloc (sizeof (struct coproc));
+#else
+ cp = &sh_coproc;
+#endif
+ coproc_init (cp);
+
+ cp->c_name = savestring (name);
+ cp->c_pid = pid;
+
+#if MULTIPLE_COPROCS
+ cpl_add (cp);
+#endif
+
+ return (cp);
+}
+
+static void
+coproc_free (cp)
+ struct coproc *cp;
+{
+ free (cp);
+}
+
+void
+coproc_dispose (cp)
+ struct coproc *cp;
+{
+ if (cp == 0)
+ return;
+
+ coproc_unsetvars (cp);
+ FREE (cp->c_name);
+ coproc_close (cp);
+#if MULTIPLE_COPROCS
+ coproc_free (cp);
+#else
+ coproc_init (cp);
+#endif
+}
+
+/* Placeholder for now. Will require changes for multiple coprocs */
+void
+coproc_flush ()
+{
+#if MULTIPLE_COPROCS
+ cpl_flush ();
+#else
+ coproc_dispose (&sh_coproc);
+#endif
+}
+
+void
+coproc_close (cp)
+ struct coproc *cp;
+{
+ if (cp->c_rfd >= 0)
+ {
+ close (cp->c_rfd);
+ cp->c_rfd = -1;
+ }
+ if (cp->c_wfd >= 0)
+ {
+ close (cp->c_wfd);
+ cp->c_wfd = -1;
+ }
+ cp->c_rsave = cp->c_wsave = -1;
+}
+
+void
+coproc_closeall ()
+{
+#if MULTIPLE_COPROCS
+ cpl_closeall ();
+#else
+ coproc_close (&sh_coproc); /* XXX - will require changes for multiple coprocs */
+#endif
+}
+
+void
+coproc_reap ()
+{
+#if MULTIPLE_COPROCS
+ cpl_reap ();
+#else
+ struct coproc *cp;
+
+ cp = &sh_coproc; /* XXX - will require changes for multiple coprocs */
+ if (cp && (cp->c_flags & COPROC_DEAD))
+ coproc_dispose (cp);
+#endif
+}
+
+void
+coproc_rclose (cp, fd)
+ struct coproc *cp;
+ int fd;
+{
+ if (cp->c_rfd >= 0 && cp->c_rfd == fd)
+ {
+ close (cp->c_rfd);
+ cp->c_rfd = -1;
+ }
+}
+
+void
+coproc_wclose (cp, fd)
+ struct coproc *cp;
+ int fd;
+{
+ if (cp->c_wfd >= 0 && cp->c_wfd == fd)
+ {
+ close (cp->c_wfd);
+ cp->c_wfd = -1;
+ }
+}
+
+void
+coproc_checkfd (cp, fd)
+ struct coproc *cp;
+ int fd;
+{
+ int update;
+
+ update = 0;
+ if (cp->c_rfd >= 0 && cp->c_rfd == fd)
+ update = cp->c_rfd = -1;
+ if (cp->c_wfd >= 0 && cp->c_wfd == fd)
+ update = cp->c_wfd = -1;
+ if (update)
+ coproc_setvars (cp);
+}
+
+void
+coproc_fdchk (fd)
+ int fd;
+{
+#if MULTIPLE_COPROCS
+ cpl_fdchk (fd);
+#else
+ coproc_checkfd (&sh_coproc, fd);
+#endif
+}
+
+void
+coproc_fdclose (cp, fd)
+ struct coproc *cp;
+ int fd;
+{
+ coproc_rclose (cp, fd);
+ coproc_wclose (cp, fd);
+ coproc_setvars (cp);
+}
+
+void
+coproc_fdsave (cp)
+ struct coproc *cp;
+{
+ cp->c_rsave = cp->c_rfd;
+ cp->c_wsave = cp->c_wfd;
+}
+
+void
+coproc_fdrestore (cp)
+ struct coproc *cp;
+{
+ cp->c_rfd = cp->c_rsave;
+ cp->c_wfd = cp->c_wsave;
+}
+
+void
+coproc_pidchk (pid, status)
+ pid_t pid;
+{
+ struct coproc *cp;
+
+#if MULTIPLE_COPROCS
+ struct cpelement *cpe;
+
+ cpe = cpl_delete (pid);
+ cp = cpe ? cpe->coproc : 0;
+#else
+ cp = getcoprocbypid (pid);
+#endif
+ if (cp)
+ {
+#if 0
+ itrace("coproc_pidchk: pid %d has died", pid);
+#endif
+ cp->c_status = status;
+ cp->c_flags |= COPROC_DEAD;
+ cp->c_flags &= ~COPROC_RUNNING;
+#if MULTIPLE_COPROCS
+ coproc_dispose (cp);
+#else
+ coproc_unsetvars (cp);
+#endif
+ }
+}
+
+void
+coproc_setvars (cp)
+ struct coproc *cp;
+{
+ SHELL_VAR *v;
+ char *namevar, *t;
+ int l;
+#if defined (ARRAY_VARS)
+ arrayind_t ind;
+#endif
+
+ if (cp->c_name == 0)
+ return;
+
+ l = strlen (cp->c_name);
+ namevar = xmalloc (l + 16);
+
+#if defined (ARRAY_VARS)
+ v = find_variable (cp->c_name);
+ if (v == 0)
+ v = make_new_array_variable (cp->c_name);
+ if (array_p (v) == 0)
+ v = convert_var_to_array (v);
+
+ t = itos (cp->c_rfd);
+ ind = 0;
+ v = bind_array_variable (cp->c_name, ind, t, 0);
+ free (t);
+
+ t = itos (cp->c_wfd);
+ ind = 1;
+ bind_array_variable (cp->c_name, ind, t, 0);
+ free (t);
+#else
+ sprintf (namevar, "%s_READ", cp->c_name);
+ t = itos (cp->c_rfd);
+ bind_variable (namevar, t, 0);
+ free (t);
+ sprintf (namevar, "%s_WRITE", cp->c_name);
+ t = itos (cp->c_wfd);
+ bind_variable (namevar, t, 0);
+ free (t);
+#endif
+
+ sprintf (namevar, "%s_PID", cp->c_name);
+ t = itos (cp->c_pid);
+ bind_variable (namevar, t, 0);
+ free (t);
+
+ free (namevar);
+}
+
+void
+coproc_unsetvars (cp)
+ struct coproc *cp;
+{
+ int l;
+ char *namevar;
+
+ if (cp->c_name == 0)
+ return;
+
+ l = strlen (cp->c_name);
+ namevar = xmalloc (l + 16);
+
+ sprintf (namevar, "%s_PID", cp->c_name);
+ unbind_variable (namevar);
+
+#if defined (ARRAY_VARS)
+ unbind_variable (cp->c_name);
+#else
+ sprintf (namevar, "%s_READ", cp->c_name);
+ unbind_variable (namevar);
+ sprintf (namevar, "%s_WRITE", cp->c_name);
+ unbind_variable (namevar);
+#endif
+
+ free (namevar);
+}
+
+static int
+execute_coproc (command, pipe_in, pipe_out, fds_to_close)
+ COMMAND *command;
+ int pipe_in, pipe_out;
+ struct fd_bitmap *fds_to_close;
+{
+ int rpipe[2], wpipe[2], estat;
+ pid_t coproc_pid;
+ Coproc *cp;
+ char *tcmd;
+
+ /* XXX -- can be removed after changes to handle multiple coprocs */
+#if !MULTIPLE_COPROCS
+ if (sh_coproc.c_pid != NO_PID)
+ internal_warning ("execute_coproc: coproc [%d:%s] still exists", sh_coproc.c_pid, sh_coproc.c_name);
+ coproc_init (&sh_coproc);
+#endif
+
+ command_string_index = 0;
+ tcmd = make_command_string (command);
+
+ sh_openpipe ((int *)&rpipe); /* 0 = parent read, 1 = child write */
+ sh_openpipe ((int *)&wpipe); /* 0 = child read, 1 = parent write */
+
+ coproc_pid = make_child (savestring (tcmd), 1);
+ if (coproc_pid == 0)
+ {
+ close (rpipe[0]);
+ close (wpipe[1]);
+
+ estat = execute_in_subshell (command, 1, wpipe[0], rpipe[1], fds_to_close);
+
+ fflush (stdout);
+ fflush (stderr);
+
+ exit (estat);
+ }
+
+ close (rpipe[1]);
+ close (wpipe[0]);
+
+ cp = coproc_alloc (command->value.Coproc->name, coproc_pid);
+ cp->c_rfd = rpipe[0];
+ cp->c_wfd = wpipe[1];
+
+ SET_CLOSE_ON_EXEC (cp->c_rfd);
+ SET_CLOSE_ON_EXEC (cp->c_wfd);
+
+ coproc_setvars (cp);
+
+#if 0
+ itrace ("execute_coproc: [%d] %s", coproc_pid, the_printed_command);
+#endif
+
+ close_pipes (pipe_in, pipe_out);
+#if defined (PROCESS_SUBSTITUTION) && defined (HAVE_DEV_FD)
+ unlink_fifo_list ();
+#endif
+ stop_pipeline (1, (COMMAND *)NULL);
+ DESCRIBE_PID (coproc_pid);
+ run_pending_traps ();
+
+ return (EXECUTION_SUCCESS);
+}
+#endif
+
+static void
+restore_stdin (s)
+ int s;
+{
+ dup2 (s, 0);
+ close (s);
+}
+
+/* Catch-all cleanup function for lastpipe code for unwind-protects */
+static void
+lastpipe_cleanup (s)
+ int s;
+{
+ unfreeze_jobs_list ();
+}
+
+static int
+execute_pipeline (command, asynchronous, pipe_in, pipe_out, fds_to_close)
+ COMMAND *command;
+ int asynchronous, pipe_in, pipe_out;
+ struct fd_bitmap *fds_to_close;
+{
+ int prev, fildes[2], new_bitmap_size, dummyfd, ignore_return, exec_result;
+ int lstdin, lastpipe_flag, lastpipe_jid;
+ COMMAND *cmd;
+ struct fd_bitmap *fd_bitmap;
+ pid_t lastpid;
+
+#if defined (JOB_CONTROL)
+ sigset_t set, oset;
+ BLOCK_CHILD (set, oset);
+#endif /* JOB_CONTROL */
+
+ ignore_return = (command->flags & CMD_IGNORE_RETURN) != 0;
+
+ prev = pipe_in;
+ cmd = command;
+
+ while (cmd && cmd->type == cm_connection &&
+ cmd->value.Connection && cmd->value.Connection->connector == '|')
+ {
+ /* Make a pipeline between the two commands. */
+ if (pipe (fildes) < 0)
+ {
+ sys_error (_("pipe error"));
+#if defined (JOB_CONTROL)
+ terminate_current_pipeline ();
+ kill_current_pipeline ();
+ UNBLOCK_CHILD (oset);
+#endif /* JOB_CONTROL */
+ last_command_exit_value = EXECUTION_FAILURE;
+ /* The unwind-protects installed below will take care
+ of closing all of the open file descriptors. */
+ throw_to_top_level ();
+ return (EXECUTION_FAILURE); /* XXX */
+ }
+
+ /* Here is a problem: with the new file close-on-exec
+ code, the read end of the pipe (fildes[0]) stays open
+ in the first process, so that process will never get a
+ SIGPIPE. There is no way to signal the first process
+ that it should close fildes[0] after forking, so it
+ remains open. No SIGPIPE is ever sent because there
+ is still a file descriptor open for reading connected
+ to the pipe. We take care of that here. This passes
+ around a bitmap of file descriptors that must be
+ closed after making a child process in execute_simple_command. */
+
+ /* We need fd_bitmap to be at least as big as fildes[0].
+ If fildes[0] is less than fds_to_close->size, then
+ use fds_to_close->size. */
+ new_bitmap_size = (fildes[0] < fds_to_close->size)
+ ? fds_to_close->size
+ : fildes[0] + 8;
+
+ fd_bitmap = new_fd_bitmap (new_bitmap_size);
+
+ /* Now copy the old information into the new bitmap. */
+ xbcopy ((char *)fds_to_close->bitmap, (char *)fd_bitmap->bitmap, fds_to_close->size);
+
+ /* And mark the pipe file descriptors to be closed. */
+ fd_bitmap->bitmap[fildes[0]] = 1;
+
+ /* In case there are pipe or out-of-processes errors, we
+ want all these file descriptors to be closed when
+ unwind-protects are run, and the storage used for the
+ bitmaps freed up. */
+ begin_unwind_frame ("pipe-file-descriptors");
+ add_unwind_protect (dispose_fd_bitmap, fd_bitmap);
+ add_unwind_protect (close_fd_bitmap, fd_bitmap);
+ if (prev >= 0)
+ add_unwind_protect (close, prev);
+ dummyfd = fildes[1];
+ add_unwind_protect (close, dummyfd);
+
+#if defined (JOB_CONTROL)
+ add_unwind_protect (restore_signal_mask, &oset);
+#endif /* JOB_CONTROL */
+
+ if (ignore_return && cmd->value.Connection->first)
+ cmd->value.Connection->first->flags |= CMD_IGNORE_RETURN;
+ execute_command_internal (cmd->value.Connection->first, asynchronous,
+ prev, fildes[1], fd_bitmap);
+
+ if (prev >= 0)
+ close (prev);
+
+ prev = fildes[0];
+ close (fildes[1]);
+
+ dispose_fd_bitmap (fd_bitmap);
+ discard_unwind_frame ("pipe-file-descriptors");
+
+ cmd = cmd->value.Connection->second;
+ }
+
+ lastpid = last_made_pid;
+
+ /* Now execute the rightmost command in the pipeline. */
+ if (ignore_return && cmd)
+ cmd->flags |= CMD_IGNORE_RETURN;
+
+#if defined (JOB_CONTROL)
+ lastpipe_flag = 0;
+ begin_unwind_frame ("lastpipe-exec");
+ lstdin = -1;
+ /* If the `lastpipe' option is set with shopt, and job control is not
+ enabled, execute the last element of non-async pipelines in the
+ current shell environment. */
+ if (lastpipe_opt && job_control == 0 && asynchronous == 0 && pipe_out == NO_PIPE && prev > 0)
+ {
+ lstdin = move_to_high_fd (0, 0, 255);
+ if (lstdin > 0)
+ {
+ do_piping (prev, pipe_out);
+ prev = NO_PIPE;
+ add_unwind_protect (restore_stdin, lstdin);
+ lastpipe_flag = 1;
+ freeze_jobs_list ();
+ lastpipe_jid = stop_pipeline (0, (COMMAND *)NULL); /* XXX */
+ add_unwind_protect (lastpipe_cleanup, lastpipe_jid);
+ }
+ cmd->flags |= CMD_LASTPIPE;
+ }
+ if (prev >= 0)
+ add_unwind_protect (close, prev);
+#endif
+
+ exec_result = execute_command_internal (cmd, asynchronous, prev, pipe_out, fds_to_close);
+
+#if defined (JOB_CONTROL)
+ if (lstdin > 0)
+ restore_stdin (lstdin);
+#endif
+
+ if (prev >= 0)
+ close (prev);
+
+#if defined (JOB_CONTROL)
+ UNBLOCK_CHILD (oset);
+#endif
+
+ QUIT;
+
+ if (lastpipe_flag)
+ {
+#if defined (JOB_CONTROL)
+ append_process (savestring (the_printed_command), dollar_dollar_pid, exec_result, lastpipe_jid);
+#endif
+ lstdin = wait_for (lastpid);
+#if defined (JOB_CONTROL)
+ exec_result = job_exit_status (lastpipe_jid);
+#endif
+ unfreeze_jobs_list ();
+ }
+
+ discard_unwind_frame ("lastpipe-exec");
+
+ return (exec_result);
+}
+
+static int
+execute_connection (command, asynchronous, pipe_in, pipe_out, fds_to_close)
+ COMMAND *command;
+ int asynchronous, pipe_in, pipe_out;
+ struct fd_bitmap *fds_to_close;
+{
+ COMMAND *tc, *second;
+ int ignore_return, exec_result, was_error_trap, invert;
+ volatile int save_line_number;
+
+ ignore_return = (command->flags & CMD_IGNORE_RETURN) != 0;
+
+ switch (command->value.Connection->connector)
+ {
+ /* Do the first command asynchronously. */
+ case '&':
+ tc = command->value.Connection->first;
+ if (tc == 0)
+ return (EXECUTION_SUCCESS);
+
+ if (ignore_return)
+ tc->flags |= CMD_IGNORE_RETURN;
+ tc->flags |= CMD_AMPERSAND;
+
+ /* If this shell was compiled without job control support,
+ if we are currently in a subshell via `( xxx )', or if job
+ control is not active then the standard input for an
+ asynchronous command is forced to /dev/null. */
+#if defined (JOB_CONTROL)
+ if ((subshell_environment || !job_control) && !stdin_redir)
+#else
+ if (!stdin_redir)
+#endif /* JOB_CONTROL */
+ tc->flags |= CMD_STDIN_REDIR;
+
+ exec_result = execute_command_internal (tc, 1, pipe_in, pipe_out, fds_to_close);
+ QUIT;
+
+ if (tc->flags & CMD_STDIN_REDIR)
+ tc->flags &= ~CMD_STDIN_REDIR;
+
+ second = command->value.Connection->second;
+ if (second)
+ {
+ if (ignore_return)
+ second->flags |= CMD_IGNORE_RETURN;
+
+ exec_result = execute_command_internal (second, asynchronous, pipe_in, pipe_out, fds_to_close);
+ }
+
+ break;
+
+ /* Just call execute command on both sides. */
+ case ';':
+ if (ignore_return)
+ {
+ if (command->value.Connection->first)
+ command->value.Connection->first->flags |= CMD_IGNORE_RETURN;
+ if (command->value.Connection->second)
+ command->value.Connection->second->flags |= CMD_IGNORE_RETURN;
+ }
+ executing_list++;
+ QUIT;
+ execute_command (command->value.Connection->first);
+ QUIT;
+ exec_result = execute_command_internal (command->value.Connection->second,
+ asynchronous, pipe_in, pipe_out,
+ fds_to_close);
+ executing_list--;
+ break;
+
+ case '|':
+ was_error_trap = signal_is_trapped (ERROR_TRAP) && signal_is_ignored (ERROR_TRAP) == 0;
+ invert = (command->flags & CMD_INVERT_RETURN) != 0;
+ ignore_return = (command->flags & CMD_IGNORE_RETURN) != 0;
+
+ line_number_for_err_trap = line_number;
+ exec_result = execute_pipeline (command, asynchronous, pipe_in, pipe_out, fds_to_close);
+
+ if (was_error_trap && ignore_return == 0 && invert == 0 && exec_result != EXECUTION_SUCCESS)
+ {
+ last_command_exit_value = exec_result;
+ save_line_number = line_number;
+ line_number = line_number_for_err_trap;
+ run_error_trap ();
+ line_number = save_line_number;
+ }
+
+ if (ignore_return == 0 && invert == 0 && exit_immediately_on_error && exec_result != EXECUTION_SUCCESS)
+ {
+ last_command_exit_value = exec_result;
+ run_pending_traps ();
+ jump_to_top_level (ERREXIT);
+ }
+
+ break;
+
+ case AND_AND:
+ case OR_OR:
+ if (asynchronous)
+ {
+ /* If we have something like `a && b &' or `a || b &', run the
+ && or || stuff in a subshell. Force a subshell and just call
+ execute_command_internal again. Leave asynchronous on
+ so that we get a report from the parent shell about the
+ background job. */
+ command->flags |= CMD_FORCE_SUBSHELL;
+ exec_result = execute_command_internal (command, 1, pipe_in, pipe_out, fds_to_close);
+ break;
+ }
+
+ /* Execute the first command. If the result of that is successful
+ and the connector is AND_AND, or the result is not successful
+ and the connector is OR_OR, then execute the second command,
+ otherwise return. */
+
+ executing_list++;
+ if (command->value.Connection->first)
+ command->value.Connection->first->flags |= CMD_IGNORE_RETURN;
+
+ exec_result = execute_command (command->value.Connection->first);
+ QUIT;
+ if (((command->value.Connection->connector == AND_AND) &&
+ (exec_result == EXECUTION_SUCCESS)) ||
+ ((command->value.Connection->connector == OR_OR) &&
+ (exec_result != EXECUTION_SUCCESS)))
+ {
+ if (ignore_return && command->value.Connection->second)
+ command->value.Connection->second->flags |= CMD_IGNORE_RETURN;
+
+ exec_result = execute_command (command->value.Connection->second);
+ }
+ executing_list--;
+ break;
+
+ default:
+ command_error ("execute_connection", CMDERR_BADCONN, command->value.Connection->connector, 0);
+ jump_to_top_level (DISCARD);
+ exec_result = EXECUTION_FAILURE;
+ }
+
+ return exec_result;
+}
+
+#define REAP() \
+ do \
+ { \
+ if (!interactive_shell) \
+ reap_dead_jobs (); \
+ } \
+ while (0)
+
+/* Execute a FOR command. The syntax is: FOR word_desc IN word_list;
+ DO command; DONE */
+static int
+execute_for_command (for_command)
+ FOR_COM *for_command;
+{
+ register WORD_LIST *releaser, *list;
+ SHELL_VAR *v;
+ char *identifier;
+ int retval, save_line_number;
+#if 0
+ SHELL_VAR *old_value = (SHELL_VAR *)NULL; /* Remember the old value of x. */
+#endif
+
+ save_line_number = line_number;
+ if (check_identifier (for_command->name, 1) == 0)
+ {
+ if (posixly_correct && interactive_shell == 0)
+ {
+ last_command_exit_value = EX_BADUSAGE;
+ jump_to_top_level (ERREXIT);
+ }
+ return (EXECUTION_FAILURE);
+ }
+
+ loop_level++;
+ identifier = for_command->name->word;
+
+ list = releaser = expand_words_no_vars (for_command->map_list);
+
+ begin_unwind_frame ("for");
+ add_unwind_protect (dispose_words, releaser);
+
+#if 0
+ if (lexical_scoping)
+ {
+ old_value = copy_variable (find_variable (identifier));
+ if (old_value)
+ add_unwind_protect (dispose_variable, old_value);
+ }
+#endif
+
+ if (for_command->flags & CMD_IGNORE_RETURN)
+ for_command->action->flags |= CMD_IGNORE_RETURN;
+
+ for (retval = EXECUTION_SUCCESS; list; list = list->next)
+ {
+ QUIT;
+
+ line_number = for_command->line;
+
+ /* Remember what this command looks like, for debugger. */
+ command_string_index = 0;
+ print_for_command_head (for_command);
+
+ if (echo_command_at_execute)
+ xtrace_print_for_command_head (for_command);
+
+ /* Save this command unless it's a trap command and we're not running
+ a debug trap. */
+#if 0
+ if (signal_in_progress (DEBUG_TRAP) == 0 && (this_command_name == 0 || (STREQ (this_command_name, "trap") == 0)))
+#else
+ if (signal_in_progress (DEBUG_TRAP) == 0 && running_trap == 0)
+#endif
+ {
+ FREE (the_printed_command_except_trap);
+ the_printed_command_except_trap = savestring (the_printed_command);
+ }
+
+ retval = run_debug_trap ();
+#if defined (DEBUGGER)
+ /* In debugging mode, if the DEBUG trap returns a non-zero status, we
+ skip the command. */
+ if (debugging_mode && retval != EXECUTION_SUCCESS)
+ continue;
+#endif
+
+ this_command_name = (char *)NULL;
+ v = bind_variable (identifier, list->word->word, 0);
+ if (readonly_p (v) || noassign_p (v))
+ {
+ line_number = save_line_number;
+ if (readonly_p (v) && interactive_shell == 0 && posixly_correct)
+ {
+ last_command_exit_value = EXECUTION_FAILURE;
+ jump_to_top_level (FORCE_EOF);
+ }
+ else
+ {
+ dispose_words (releaser);
+ discard_unwind_frame ("for");
+ loop_level--;
+ return (EXECUTION_FAILURE);
+ }
+ }
+ retval = execute_command (for_command->action);
+ REAP ();
+ QUIT;
+
+ if (breaking)
+ {
+ breaking--;
+ break;
+ }
+
+ if (continuing)
+ {
+ continuing--;
+ if (continuing)
+ break;
+ }
+ }
+
+ loop_level--;
+ line_number = save_line_number;
+
+#if 0
+ if (lexical_scoping)
+ {
+ if (!old_value)
+ unbind_variable (identifier);
+ else
+ {
+ SHELL_VAR *new_value;
+
+ new_value = bind_variable (identifier, value_cell(old_value), 0);
+ new_value->attributes = old_value->attributes;
+ dispose_variable (old_value);
+ }
+ }
+#endif
+
+ dispose_words (releaser);
+ discard_unwind_frame ("for");
+ return (retval);
+}
+
+#if defined (ARITH_FOR_COMMAND)
+/* Execute an arithmetic for command. The syntax is
+
+ for (( init ; step ; test ))
+ do
+ body
+ done
+
+ The execution should be exactly equivalent to
+
+ eval \(\( init \)\)
+ while eval \(\( test \)\) ; do
+ body;
+ eval \(\( step \)\)
+ done
+*/
+static intmax_t
+eval_arith_for_expr (l, okp)
+ WORD_LIST *l;
+ int *okp;
+{
+ WORD_LIST *new;
+ intmax_t expresult;
+ int r;
+
+ new = expand_words_no_vars (l);
+ if (new)
+ {
+ if (echo_command_at_execute)
+ xtrace_print_arith_cmd (new);
+ this_command_name = "(("; /* )) for expression error messages */
+
+ command_string_index = 0;
+ print_arith_command (new);
+ if (signal_in_progress (DEBUG_TRAP) == 0)
+ {
+ FREE (the_printed_command_except_trap);
+ the_printed_command_except_trap = savestring (the_printed_command);
+ }
+
+ r = run_debug_trap ();
+ /* In debugging mode, if the DEBUG trap returns a non-zero status, we
+ skip the command. */
+#if defined (DEBUGGER)
+ if (debugging_mode == 0 || r == EXECUTION_SUCCESS)
+ expresult = evalexp (new->word->word, okp);
+ else
+ {
+ expresult = 0;
+ if (okp)
+ *okp = 1;
+ }
+#else
+ expresult = evalexp (new->word->word, okp);
+#endif
+ dispose_words (new);
+ }
+ else
+ {
+ expresult = 0;
+ if (okp)
+ *okp = 1;
+ }
+ return (expresult);
+}
+
+static int
+execute_arith_for_command (arith_for_command)
+ ARITH_FOR_COM *arith_for_command;
+{
+ intmax_t expresult;
+ int expok, body_status, arith_lineno, save_lineno;
+
+ body_status = EXECUTION_SUCCESS;
+ loop_level++;
+ save_lineno = line_number;
+
+ if (arith_for_command->flags & CMD_IGNORE_RETURN)
+ arith_for_command->action->flags |= CMD_IGNORE_RETURN;
+
+ this_command_name = "(("; /* )) for expression error messages */
+
+ /* save the starting line number of the command so we can reset
+ line_number before executing each expression -- for $LINENO
+ and the DEBUG trap. */
+ line_number = arith_lineno = arith_for_command->line;
+ if (variable_context && interactive_shell)
+ line_number -= function_line_number;
+
+ /* Evaluate the initialization expression. */
+ expresult = eval_arith_for_expr (arith_for_command->init, &expok);
+ if (expok == 0)
+ {
+ line_number = save_lineno;
+ return (EXECUTION_FAILURE);
+ }
+
+ while (1)
+ {
+ /* Evaluate the test expression. */
+ line_number = arith_lineno;
+ expresult = eval_arith_for_expr (arith_for_command->test, &expok);
+ line_number = save_lineno;
+
+ if (expok == 0)
+ {
+ body_status = EXECUTION_FAILURE;
+ break;
+ }
+ REAP ();
+ if (expresult == 0)
+ break;
+
+ /* Execute the body of the arithmetic for command. */
+ QUIT;
+ body_status = execute_command (arith_for_command->action);
+ QUIT;
+
+ /* Handle any `break' or `continue' commands executed by the body. */
+ if (breaking)
+ {
+ breaking--;
+ break;
+ }
+
+ if (continuing)
+ {
+ continuing--;
+ if (continuing)
+ break;
+ }
+
+ /* Evaluate the step expression. */
+ line_number = arith_lineno;
+ expresult = eval_arith_for_expr (arith_for_command->step, &expok);
+ line_number = save_lineno;
+
+ if (expok == 0)
+ {
+ body_status = EXECUTION_FAILURE;
+ break;
+ }
+ }
+
+ loop_level--;
+ line_number = save_lineno;
+
+ return (body_status);
+}
+#endif
+
+#if defined (SELECT_COMMAND)
+static int LINES, COLS, tabsize;
+
+#define RP_SPACE ") "
+#define RP_SPACE_LEN 2
+
+/* XXX - does not handle numbers > 1000000 at all. */
+#define NUMBER_LEN(s) \
+((s < 10) ? 1 \
+ : ((s < 100) ? 2 \
+ : ((s < 1000) ? 3 \
+ : ((s < 10000) ? 4 \
+ : ((s < 100000) ? 5 \
+ : 6)))))
+
+static int
+displen (s)
+ const char *s;
+{
+#if defined (HANDLE_MULTIBYTE)
+ wchar_t *wcstr;
+ size_t wclen, slen;
+
+ wcstr = 0;
+ slen = mbstowcs (wcstr, s, 0);
+ if (slen == -1)
+ slen = 0;
+ wcstr = (wchar_t *)xmalloc (sizeof (wchar_t) * (slen + 1));
+ mbstowcs (wcstr, s, slen + 1);
+ wclen = wcswidth (wcstr, slen);
+ free (wcstr);
+ return ((int)wclen);
+#else
+ return (STRLEN (s));
+#endif
+}
+
+static int
+print_index_and_element (len, ind, list)
+ int len, ind;
+ WORD_LIST *list;
+{
+ register WORD_LIST *l;
+ register int i;
+
+ if (list == 0)
+ return (0);
+ for (i = ind, l = list; l && --i; l = l->next)
+ ;
+ fprintf (stderr, "%*d%s%s", len, ind, RP_SPACE, l->word->word);
+ return (displen (l->word->word));
+}
+
+static void
+indent (from, to)
+ int from, to;
+{
+ while (from < to)
+ {
+ if ((to / tabsize) > (from / tabsize))
+ {
+ putc ('\t', stderr);
+ from += tabsize - from % tabsize;
+ }
+ else
+ {
+ putc (' ', stderr);
+ from++;
+ }
+ }
+}
+
+static void
+print_select_list (list, list_len, max_elem_len, indices_len)
+ WORD_LIST *list;
+ int list_len, max_elem_len, indices_len;
+{
+ int ind, row, elem_len, pos, cols, rows;
+ int first_column_indices_len, other_indices_len;
+
+ if (list == 0)
+ {
+ putc ('\n', stderr);
+ return;
+ }
+
+ cols = max_elem_len ? COLS / max_elem_len : 1;
+ if (cols == 0)
+ cols = 1;
+ rows = list_len ? list_len / cols + (list_len % cols != 0) : 1;
+ cols = list_len ? list_len / rows + (list_len % rows != 0) : 1;
+
+ if (rows == 1)
+ {
+ rows = cols;
+ cols = 1;
+ }
+
+ first_column_indices_len = NUMBER_LEN (rows);
+ other_indices_len = indices_len;
+
+ for (row = 0; row < rows; row++)
+ {
+ ind = row;
+ pos = 0;
+ while (1)
+ {
+ indices_len = (pos == 0) ? first_column_indices_len : other_indices_len;
+ elem_len = print_index_and_element (indices_len, ind + 1, list);
+ elem_len += indices_len + RP_SPACE_LEN;
+ ind += rows;
+ if (ind >= list_len)
+ break;
+ indent (pos + elem_len, pos + max_elem_len);
+ pos += max_elem_len;
+ }
+ putc ('\n', stderr);
+ }
+}
+
+/* Print the elements of LIST, one per line, preceded by an index from 1 to
+ LIST_LEN. Then display PROMPT and wait for the user to enter a number.
+ If the number is between 1 and LIST_LEN, return that selection. If EOF
+ is read, return a null string. If a blank line is entered, or an invalid
+ number is entered, the loop is executed again. */
+static char *
+select_query (list, list_len, prompt, print_menu)
+ WORD_LIST *list;
+ int list_len;
+ char *prompt;
+ int print_menu;
+{
+ int max_elem_len, indices_len, len;
+ intmax_t reply;
+ WORD_LIST *l;
+ char *repl_string, *t;
+
+#if 0
+ t = get_string_value ("LINES");
+ LINES = (t && *t) ? atoi (t) : 24;
+#endif
+ t = get_string_value ("COLUMNS");
+ COLS = (t && *t) ? atoi (t) : 80;
+
+#if 0
+ t = get_string_value ("TABSIZE");
+ tabsize = (t && *t) ? atoi (t) : 8;
+ if (tabsize <= 0)
+ tabsize = 8;
+#else
+ tabsize = 8;
+#endif
+
+ max_elem_len = 0;
+ for (l = list; l; l = l->next)
+ {
+ len = displen (l->word->word);
+ if (len > max_elem_len)
+ max_elem_len = len;
+ }
+ indices_len = NUMBER_LEN (list_len);
+ max_elem_len += indices_len + RP_SPACE_LEN + 2;
+
+ while (1)
+ {
+ if (print_menu)
+ print_select_list (list, list_len, max_elem_len, indices_len);
+ fprintf (stderr, "%s", prompt);
+ fflush (stderr);
+ QUIT;
+
+ if (read_builtin ((WORD_LIST *)NULL) != EXECUTION_SUCCESS)
+ {
+ putchar ('\n');
+ return ((char *)NULL);
+ }
+ repl_string = get_string_value ("REPLY");
+ if (*repl_string == 0)
+ {
+ print_menu = 1;
+ continue;
+ }
+ if (legal_number (repl_string, &reply) == 0)
+ return "";
+ if (reply < 1 || reply > list_len)
+ return "";
+
+ for (l = list; l && --reply; l = l->next)
+ ;
+ return (l->word->word);
+ }
+}
+
+/* Execute a SELECT command. The syntax is:
+ SELECT word IN list DO command_list DONE
+ Only `break' or `return' in command_list will terminate
+ the command. */
+static int
+execute_select_command (select_command)
+ SELECT_COM *select_command;
+{
+ WORD_LIST *releaser, *list;
+ SHELL_VAR *v;
+ char *identifier, *ps3_prompt, *selection;
+ int retval, list_len, show_menu, save_line_number;
+
+ if (check_identifier (select_command->name, 1) == 0)
+ return (EXECUTION_FAILURE);
+
+ save_line_number = line_number;
+ line_number = select_command->line;
+
+ command_string_index = 0;
+ print_select_command_head (select_command);
+
+ if (echo_command_at_execute)
+ xtrace_print_select_command_head (select_command);
+
+#if 0
+ if (signal_in_progress (DEBUG_TRAP) == 0 && (this_command_name == 0 || (STREQ (this_command_name, "trap") == 0)))
+#else
+ if (signal_in_progress (DEBUG_TRAP) == 0 && running_trap == 0)
+#endif
+ {
+ FREE (the_printed_command_except_trap);
+ the_printed_command_except_trap = savestring (the_printed_command);
+ }
+
+ retval = run_debug_trap ();
+#if defined (DEBUGGER)
+ /* In debugging mode, if the DEBUG trap returns a non-zero status, we
+ skip the command. */
+ if (debugging_mode && retval != EXECUTION_SUCCESS)
+ return (EXECUTION_SUCCESS);
+#endif
+
+ loop_level++;
+ identifier = select_command->name->word;
+
+ /* command and arithmetic substitution, parameter and variable expansion,
+ word splitting, pathname expansion, and quote removal. */
+ list = releaser = expand_words_no_vars (select_command->map_list);
+ list_len = list_length (list);
+ if (list == 0 || list_len == 0)
+ {
+ if (list)
+ dispose_words (list);
+ line_number = save_line_number;
+ return (EXECUTION_SUCCESS);
+ }
+
+ begin_unwind_frame ("select");
+ add_unwind_protect (dispose_words, releaser);
+
+ if (select_command->flags & CMD_IGNORE_RETURN)
+ select_command->action->flags |= CMD_IGNORE_RETURN;
+
+ retval = EXECUTION_SUCCESS;
+ show_menu = 1;
+
+ while (1)
+ {
+ line_number = select_command->line;
+ ps3_prompt = get_string_value ("PS3");
+ if (ps3_prompt == 0)
+ ps3_prompt = "#? ";
+
+ QUIT;
+ selection = select_query (list, list_len, ps3_prompt, show_menu);
+ QUIT;
+ if (selection == 0)
+ {
+ /* select_query returns EXECUTION_FAILURE if the read builtin
+ fails, so we want to return failure in this case. */
+ retval = EXECUTION_FAILURE;
+ break;
+ }
+
+ v = bind_variable (identifier, selection, 0);
+ if (readonly_p (v) || noassign_p (v))
+ {
+ if (readonly_p (v) && interactive_shell == 0 && posixly_correct)
+ {
+ last_command_exit_value = EXECUTION_FAILURE;
+ jump_to_top_level (FORCE_EOF);
+ }
+ else
+ {
+ dispose_words (releaser);
+ discard_unwind_frame ("select");
+ loop_level--;
+ line_number = save_line_number;
+ return (EXECUTION_FAILURE);
+ }
+ }
+
+ retval = execute_command (select_command->action);
+
+ REAP ();
+ QUIT;
+
+ if (breaking)
+ {
+ breaking--;
+ break;
+ }
+
+ if (continuing)
+ {
+ continuing--;
+ if (continuing)
+ break;
+ }
+
+#if defined (KSH_COMPATIBLE_SELECT)
+ show_menu = 0;
+ selection = get_string_value ("REPLY");
+ if (selection && *selection == '\0')
+ show_menu = 1;
+#endif
+ }
+
+ loop_level--;
+ line_number = save_line_number;
+
+ dispose_words (releaser);
+ discard_unwind_frame ("select");
+ return (retval);
+}
+#endif /* SELECT_COMMAND */
+
+/* Execute a CASE command. The syntax is: CASE word_desc IN pattern_list ESAC.
+ The pattern_list is a linked list of pattern clauses; each clause contains
+ some patterns to compare word_desc against, and an associated command to
+ execute. */
+static int
+execute_case_command (case_command)
+ CASE_COM *case_command;
+{
+ register WORD_LIST *list;
+ WORD_LIST *wlist, *es;
+ PATTERN_LIST *clauses;
+ char *word, *pattern;
+ int retval, match, ignore_return, save_line_number;
+
+ save_line_number = line_number;
+ line_number = case_command->line;
+
+ command_string_index = 0;
+ print_case_command_head (case_command);
+
+ if (echo_command_at_execute)
+ xtrace_print_case_command_head (case_command);
+
+#if 0
+ if (signal_in_progress (DEBUG_TRAP) == 0 && (this_command_name == 0 || (STREQ (this_command_name, "trap") == 0)))
+#else
+ if (signal_in_progress (DEBUG_TRAP) == 0 && running_trap == 0)
+#endif
+ {
+ FREE (the_printed_command_except_trap);
+ the_printed_command_except_trap = savestring (the_printed_command);
+ }
+
+ retval = run_debug_trap();
+#if defined (DEBUGGER)
+ /* In debugging mode, if the DEBUG trap returns a non-zero status, we
+ skip the command. */
+ if (debugging_mode && retval != EXECUTION_SUCCESS)
+ {
+ line_number = save_line_number;
+ return (EXECUTION_SUCCESS);
+ }
+#endif
+
+ wlist = expand_word_unsplit (case_command->word, 0);
+ word = wlist ? string_list (wlist) : savestring ("");
+ dispose_words (wlist);
+
+ retval = EXECUTION_SUCCESS;
+ ignore_return = case_command->flags & CMD_IGNORE_RETURN;
+
+ begin_unwind_frame ("case");
+ add_unwind_protect ((Function *)xfree, word);
+
+#define EXIT_CASE() goto exit_case_command
+
+ for (clauses = case_command->clauses; clauses; clauses = clauses->next)
+ {
+ QUIT;
+ for (list = clauses->patterns; list; list = list->next)
+ {
+ es = expand_word_leave_quoted (list->word, 0);
+
+ if (es && es->word && es->word->word && *(es->word->word))
+ pattern = quote_string_for_globbing (es->word->word, QGLOB_CVTNULL);
+ else
+ {
+ pattern = (char *)xmalloc (1);
+ pattern[0] = '\0';
+ }
+
+ /* Since the pattern does not undergo quote removal (as per
+ Posix.2, section 3.9.4.3), the strmatch () call must be able
+ to recognize backslashes as escape characters. */
+ match = strmatch (pattern, word, FNMATCH_EXTFLAG|FNMATCH_IGNCASE) != FNM_NOMATCH;
+ free (pattern);
+
+ dispose_words (es);
+
+ if (match)
+ {
+ do
+ {
+ if (clauses->action && ignore_return)
+ clauses->action->flags |= CMD_IGNORE_RETURN;
+ retval = execute_command (clauses->action);
+ }
+ while ((clauses->flags & CASEPAT_FALLTHROUGH) && (clauses = clauses->next));
+ if (clauses == 0 || (clauses->flags & CASEPAT_TESTNEXT) == 0)
+ EXIT_CASE ();
+ else
+ break;
+ }
+
+ QUIT;
+ }
+ }
+
+exit_case_command:
+ free (word);
+ discard_unwind_frame ("case");
+ line_number = save_line_number;
+ return (retval);
+}
+
+#define CMD_WHILE 0
+#define CMD_UNTIL 1
+
+/* The WHILE command. Syntax: WHILE test DO action; DONE.
+ Repeatedly execute action while executing test produces
+ EXECUTION_SUCCESS. */
+static int
+execute_while_command (while_command)
+ WHILE_COM *while_command;
+{
+ return (execute_while_or_until (while_command, CMD_WHILE));
+}
+
+/* UNTIL is just like WHILE except that the test result is negated. */
+static int
+execute_until_command (while_command)
+ WHILE_COM *while_command;
+{
+ return (execute_while_or_until (while_command, CMD_UNTIL));
+}
+
+/* The body for both while and until. The only difference between the
+ two is that the test value is treated differently. TYPE is
+ CMD_WHILE or CMD_UNTIL. The return value for both commands should
+ be EXECUTION_SUCCESS if no commands in the body are executed, and
+ the status of the last command executed in the body otherwise. */
+static int
+execute_while_or_until (while_command, type)
+ WHILE_COM *while_command;
+ int type;
+{
+ int return_value, body_status;
+
+ body_status = EXECUTION_SUCCESS;
+ loop_level++;
+
+ while_command->test->flags |= CMD_IGNORE_RETURN;
+ if (while_command->flags & CMD_IGNORE_RETURN)
+ while_command->action->flags |= CMD_IGNORE_RETURN;
+
+ while (1)
+ {
+ return_value = execute_command (while_command->test);
+ REAP ();
+
+ /* Need to handle `break' in the test when we would break out of the
+ loop. The job control code will set `breaking' to loop_level
+ when a job in a loop is stopped with SIGTSTP. If the stopped job
+ is in the loop test, `breaking' will not be reset unless we do
+ this, and the shell will cease to execute commands. */
+ if (type == CMD_WHILE && return_value != EXECUTION_SUCCESS)
+ {
+ if (breaking)
+ breaking--;
+ break;
+ }
+ if (type == CMD_UNTIL && return_value == EXECUTION_SUCCESS)
+ {
+ if (breaking)
+ breaking--;
+ break;
+ }
+
+ QUIT;
+ body_status = execute_command (while_command->action);
+ QUIT;
+
+ if (breaking)
+ {
+ breaking--;
+ break;
+ }
+
+ if (continuing)
+ {
+ continuing--;
+ if (continuing)
+ break;
+ }
+ }
+ loop_level--;
+
+ return (body_status);
+}
+
+/* IF test THEN command [ELSE command].
+ IF also allows ELIF in the place of ELSE IF, but
+ the parser makes *that* stupidity transparent. */
+static int
+execute_if_command (if_command)
+ IF_COM *if_command;
+{
+ int return_value, save_line_number;
+
+ save_line_number = line_number;
+ if_command->test->flags |= CMD_IGNORE_RETURN;
+ return_value = execute_command (if_command->test);
+ line_number = save_line_number;
+
+ if (return_value == EXECUTION_SUCCESS)
+ {
+ QUIT;
+
+ if (if_command->true_case && (if_command->flags & CMD_IGNORE_RETURN))
+ if_command->true_case->flags |= CMD_IGNORE_RETURN;
+
+ return (execute_command (if_command->true_case));
+ }
+ else
+ {
+ QUIT;
+
+ if (if_command->false_case && (if_command->flags & CMD_IGNORE_RETURN))
+ if_command->false_case->flags |= CMD_IGNORE_RETURN;
+
+ return (execute_command (if_command->false_case));
+ }
+}
+
+#if defined (DPAREN_ARITHMETIC)
+static int
+execute_arith_command (arith_command)
+ ARITH_COM *arith_command;
+{
+ int expok, save_line_number, retval;
+ intmax_t expresult;
+ WORD_LIST *new;
+ char *exp;
+
+ expresult = 0;
+
+ save_line_number = line_number;
+ this_command_name = "(("; /* )) */
+ line_number = arith_command->line;
+ /* If we're in a function, update the line number information. */
+ if (variable_context && interactive_shell)
+ line_number -= function_line_number;
+
+ command_string_index = 0;
+ print_arith_command (arith_command->exp);
+
+ if (signal_in_progress (DEBUG_TRAP) == 0)
+ {
+ FREE (the_printed_command_except_trap);
+ the_printed_command_except_trap = savestring (the_printed_command);
+ }
+
+ /* Run the debug trap before each arithmetic command, but do it after we
+ update the line number information and before we expand the various
+ words in the expression. */
+ retval = run_debug_trap ();
+#if defined (DEBUGGER)
+ /* In debugging mode, if the DEBUG trap returns a non-zero status, we
+ skip the command. */
+ if (debugging_mode && retval != EXECUTION_SUCCESS)
+ {
+ line_number = save_line_number;
+ return (EXECUTION_SUCCESS);
+ }
+#endif
+
+ new = expand_words_no_vars (arith_command->exp);
+
+ /* If we're tracing, make a new word list with `((' at the front and `))'
+ at the back and print it. */
+ if (echo_command_at_execute)
+ xtrace_print_arith_cmd (new);
+
+ if (new)
+ {
+ exp = new->next ? string_list (new) : new->word->word;
+ expresult = evalexp (exp, &expok);
+ line_number = save_line_number;
+ if (exp != new->word->word)
+ free (exp);
+ dispose_words (new);
+ }
+ else
+ {
+ expresult = 0;
+ expok = 1;
+ }
+
+ if (expok == 0)
+ return (EXECUTION_FAILURE);
+
+ return (expresult == 0 ? EXECUTION_FAILURE : EXECUTION_SUCCESS);
+}
+#endif /* DPAREN_ARITHMETIC */
+
+#if defined (COND_COMMAND)
+
+static char * const nullstr = "";
+
+static int
+execute_cond_node (cond)
+ COND_COM *cond;
+{
+ int result, invert, patmatch, rmatch, mflags, ignore;
+ char *arg1, *arg2;
+
+ invert = (cond->flags & CMD_INVERT_RETURN);
+ ignore = (cond->flags & CMD_IGNORE_RETURN);
+ if (ignore)
+ {
+ if (cond->left)
+ cond->left->flags |= CMD_IGNORE_RETURN;
+ if (cond->right)
+ cond->right->flags |= CMD_IGNORE_RETURN;
+ }
+
+ if (cond->type == COND_EXPR)
+ result = execute_cond_node (cond->left);
+ else if (cond->type == COND_OR)
+ {
+ result = execute_cond_node (cond->left);
+ if (result != EXECUTION_SUCCESS)
+ result = execute_cond_node (cond->right);
+ }
+ else if (cond->type == COND_AND)
+ {
+ result = execute_cond_node (cond->left);
+ if (result == EXECUTION_SUCCESS)
+ result = execute_cond_node (cond->right);
+ }
+ else if (cond->type == COND_UNARY)
+ {
+ if (ignore)
+ comsub_ignore_return++;
+ arg1 = cond_expand_word (cond->left->op, 0);
+ if (ignore)
+ comsub_ignore_return--;
+ if (arg1 == 0)
+ arg1 = nullstr;
+ if (echo_command_at_execute)
+ xtrace_print_cond_term (cond->type, invert, cond->op, arg1, (char *)NULL);
+ result = unary_test (cond->op->word, arg1) ? EXECUTION_SUCCESS : EXECUTION_FAILURE;
+ if (arg1 != nullstr)
+ free (arg1);
+ }
+ else if (cond->type == COND_BINARY)
+ {
+ rmatch = 0;
+ patmatch = ((cond->op->word[1] == '=') && (cond->op->word[2] == '\0') &&
+ (cond->op->word[0] == '!' || cond->op->word[0] == '=') ||
+ (cond->op->word[0] == '=' && cond->op->word[1] == '\0'));
+#if defined (COND_REGEXP)
+ rmatch = (cond->op->word[0] == '=' && cond->op->word[1] == '~' &&
+ cond->op->word[2] == '\0');
+#endif
+
+ if (ignore)
+ comsub_ignore_return++;
+ arg1 = cond_expand_word (cond->left->op, 0);
+ if (ignore)
+ comsub_ignore_return--;
+ if (arg1 == 0)
+ arg1 = nullstr;
+ if (ignore)
+ comsub_ignore_return++;
+ arg2 = cond_expand_word (cond->right->op,
+ (rmatch && shell_compatibility_level > 31) ? 2 : (patmatch ? 1 : 0));
+ if (ignore)
+ comsub_ignore_return--;
+ if (arg2 == 0)
+ arg2 = nullstr;
+
+ if (echo_command_at_execute)
+ xtrace_print_cond_term (cond->type, invert, cond->op, arg1, arg2);
+
+#if defined (COND_REGEXP)
+ if (rmatch)
+ {
+ mflags = SHMAT_PWARN;
+#if defined (ARRAY_VARS)
+ mflags |= SHMAT_SUBEXP;
+#endif
+
+ result = sh_regmatch (arg1, arg2, mflags);
+ }
+ else
+#endif /* COND_REGEXP */
+ {
+ int oe;
+ oe = extended_glob;
+ extended_glob = 1;
+ result = binary_test (cond->op->word, arg1, arg2, TEST_PATMATCH|TEST_ARITHEXP|TEST_LOCALE)
+ ? EXECUTION_SUCCESS
+ : EXECUTION_FAILURE;
+ extended_glob = oe;
+ }
+ if (arg1 != nullstr)
+ free (arg1);
+ if (arg2 != nullstr)
+ free (arg2);
+ }
+ else
+ {
+ command_error ("execute_cond_node", CMDERR_BADTYPE, cond->type, 0);
+ jump_to_top_level (DISCARD);
+ result = EXECUTION_FAILURE;
+ }
+
+ if (invert)
+ result = (result == EXECUTION_SUCCESS) ? EXECUTION_FAILURE : EXECUTION_SUCCESS;
+
+ return result;
+}
+
+static int
+execute_cond_command (cond_command)
+ COND_COM *cond_command;
+{
+ int retval, save_line_number;
+
+ retval = EXECUTION_SUCCESS;
+ save_line_number = line_number;
+
+ this_command_name = "[[";
+ line_number = cond_command->line;
+ /* If we're in a function, update the line number information. */
+ if (variable_context && interactive_shell)
+ line_number -= function_line_number;
+ command_string_index = 0;
+ print_cond_command (cond_command);
+
+ if (signal_in_progress (DEBUG_TRAP) == 0)
+ {
+ FREE (the_printed_command_except_trap);
+ the_printed_command_except_trap = savestring (the_printed_command);
+ }
+
+ /* Run the debug trap before each conditional command, but do it after we
+ update the line number information. */
+ retval = run_debug_trap ();
+#if defined (DEBUGGER)
+ /* In debugging mode, if the DEBUG trap returns a non-zero status, we
+ skip the command. */
+ if (debugging_mode && retval != EXECUTION_SUCCESS)
+ {
+ line_number = save_line_number;
+ return (EXECUTION_SUCCESS);
+ }
+#endif
+
+#if 0
+ debug_print_cond_command (cond_command);
+#endif
+
+ last_command_exit_value = retval = execute_cond_node (cond_command);
+ line_number = save_line_number;
+ return (retval);
+}
+#endif /* COND_COMMAND */
+
+static void
+bind_lastarg (arg)
+ char *arg;
+{
+ SHELL_VAR *var;
+
+ if (arg == 0)
+ arg = "";
+ var = bind_variable ("_", arg, 0);
+ VUNSETATTR (var, att_exported);
+}
+
+/* Execute a null command. Fork a subshell if the command uses pipes or is
+ to be run asynchronously. This handles all the side effects that are
+ supposed to take place. */
+static int
+execute_null_command (redirects, pipe_in, pipe_out, async)
+ REDIRECT *redirects;
+ int pipe_in, pipe_out, async;
+{
+ int r;
+ int forcefork;
+ REDIRECT *rd;
+
+ 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. */
+ if (make_child ((char *)NULL, async) == 0)
+ {
+ /* Cancel traps, in trap.c. */
+ restore_original_signals (); /* XXX */
+
+ do_piping (pipe_in, pipe_out);
+
+#if defined (COPROCESS_SUPPORT)
+ coproc_closeall ();
+#endif
+
+ subshell_environment = 0;
+ if (async)
+ subshell_environment |= SUBSHELL_ASYNC;
+ if (pipe_in != NO_PIPE || pipe_out != NO_PIPE)
+ subshell_environment |= SUBSHELL_PIPE;
+
+ if (do_redirections (redirects, RX_ACTIVE) == 0)
+ exit (EXECUTION_SUCCESS);
+ else
+ exit (EXECUTION_FAILURE);
+ }
+ else
+ {
+ close_pipes (pipe_in, pipe_out);
+#if defined (PROCESS_SUBSTITUTION) && defined (HAVE_DEV_FD)
+ unlink_fifo_list ();
+#endif
+ return (EXECUTION_SUCCESS);
+ }
+ }
+ else
+ {
+ /* Even if there aren't any command names, pretend to do the
+ redirections that are specified. The user expects the side
+ effects to take place. If the redirections fail, then return
+ failure. Otherwise, if a command substitution took place while
+ expanding the command or a redirection, return the value of that
+ substitution. Otherwise, return EXECUTION_SUCCESS. */
+
+ r = do_redirections (redirects, RX_ACTIVE|RX_UNDOABLE);
+ cleanup_redirects (redirection_undo_list);
+ redirection_undo_list = (REDIRECT *)NULL;
+
+ if (r != 0)
+ return (EXECUTION_FAILURE);
+ else if (last_command_subst_pid != NO_PID)
+ return (last_command_exit_value);
+ else
+ return (EXECUTION_SUCCESS);
+ }
+}
+
+/* This is a hack to suppress word splitting for assignment statements
+ given as arguments to builtins with the ASSIGNMENT_BUILTIN flag set. */
+static void
+fix_assignment_words (words)
+ WORD_LIST *words;
+{
+ WORD_LIST *w, *wcmd;
+ struct builtin *b;
+ int assoc;
+
+ if (words == 0)
+ return;
+
+ b = 0;
+ assoc = 0;
+
+ wcmd = words;
+ for (w = words; w; w = w->next)
+ if (w->word->flags & W_ASSIGNMENT)
+ {
+ if (b == 0)
+ {
+ while (posixly_correct && wcmd && wcmd->word && wcmd->word->word && STREQ (wcmd->word->word, "command"))
+ wcmd = wcmd->next;
+ b = builtin_address_internal (wcmd->word->word, 0);
+ if (b == 0 || (b->flags & ASSIGNMENT_BUILTIN) == 0)
+ return;
+ else if (b && (b->flags & ASSIGNMENT_BUILTIN))
+ wcmd->word->flags |= W_ASSNBLTIN;
+ }
+ w->word->flags |= (W_NOSPLIT|W_NOGLOB|W_TILDEEXP|W_ASSIGNARG);
+#if defined (ARRAY_VARS)
+ if (assoc)
+ w->word->flags |= W_ASSIGNASSOC;
+#endif
+ }
+#if defined (ARRAY_VARS)
+ /* Note that we saw an associative array option to a builtin that takes
+ assignment statements. This is a bit of a kludge. */
+ else if (w->word->word[0] == '-' && strchr (w->word->word, 'A'))
+ {
+ if (b == 0)
+ {
+ b = builtin_address_internal (wcmd->word->word, 0);
+ if (b == 0 || (b->flags & ASSIGNMENT_BUILTIN) == 0)
+ return;
+ else if (b && (b->flags & ASSIGNMENT_BUILTIN))
+ wcmd->word->flags |= W_ASSNBLTIN;
+ }
+ if (wcmd->word->flags & W_ASSNBLTIN)
+ assoc = 1;
+ }
+#endif
+}
+
+/* Return 1 if the file found by searching $PATH for PATHNAME, defaulting
+ to PATHNAME, is a directory. Used by the autocd code below. */
+static int
+is_dirname (pathname)
+ char *pathname;
+{
+ char *temp;
+ temp = search_for_command (pathname);
+ return (temp ? file_isdir (temp) : file_isdir (pathname));
+}
+
+/* The meaty part of all the executions. We have to start hacking the
+ real execution of commands here. Fork a process, set things up,
+ execute the command. */
+static int
+execute_simple_command (simple_command, pipe_in, pipe_out, async, fds_to_close)
+ SIMPLE_COM *simple_command;
+ int pipe_in, pipe_out, async;
+ struct fd_bitmap *fds_to_close;
+{
+ WORD_LIST *words, *lastword;
+ char *command_line, *lastarg, *temp;
+ int first_word_quoted, result, builtin_is_special, already_forked, dofork;
+ pid_t old_last_async_pid;
+ sh_builtin_func_t *builtin;
+ SHELL_VAR *func;
+ volatile int old_builtin, old_command_builtin;
+
+ result = EXECUTION_SUCCESS;
+ special_builtin_failed = builtin_is_special = 0;
+ command_line = (char *)0;
+
+ QUIT;
+
+ /* If we're in a function, update the line number information. */
+ if (variable_context && interactive_shell && sourcelevel == 0)
+ line_number -= function_line_number;
+
+ /* Remember what this command line looks like at invocation. */
+ command_string_index = 0;
+ print_simple_command (simple_command);
+
+#if 0
+ if (signal_in_progress (DEBUG_TRAP) == 0 && (this_command_name == 0 || (STREQ (this_command_name, "trap") == 0)))
+#else
+ if (signal_in_progress (DEBUG_TRAP) == 0 && running_trap == 0)
+#endif
+ {
+ FREE (the_printed_command_except_trap);
+ the_printed_command_except_trap = the_printed_command ? savestring (the_printed_command) : (char *)0;
+ }
+
+ /* Run the debug trap before each simple command, but do it after we
+ update the line number information. */
+ result = run_debug_trap ();
+#if defined (DEBUGGER)
+ /* In debugging mode, if the DEBUG trap returns a non-zero status, we
+ skip the command. */
+ if (debugging_mode && result != EXECUTION_SUCCESS)
+ return (EXECUTION_SUCCESS);
+#endif
+
+ first_word_quoted =
+ simple_command->words ? (simple_command->words->word->flags & W_QUOTED) : 0;
+
+ last_command_subst_pid = NO_PID;
+ old_last_async_pid = last_asynchronous_pid;
+
+ already_forked = dofork = 0;
+
+ /* If we're in a pipeline or run in the background, set DOFORK so we
+ make the child early, before word expansion. This keeps assignment
+ statements from affecting the parent shell's environment when they
+ should not. */
+ dofork = pipe_in != NO_PIPE || pipe_out != NO_PIPE || async;
+
+ /* Something like `%2 &' should restart job 2 in the background, not cause
+ the shell to fork here. */
+ if (dofork && pipe_in == NO_PIPE && pipe_out == NO_PIPE &&
+ simple_command->words && simple_command->words->word &&
+ simple_command->words->word->word &&
+ (simple_command->words->word->word[0] == '%'))
+ dofork = 0;
+
+ if (dofork)
+ {
+ /* Do this now, because execute_disk_command will do it anyway in the
+ vast majority of cases. */
+ maybe_make_export_env ();
+
+ /* Don't let a DEBUG trap overwrite the command string to be saved with
+ the process/job associated with this child. */
+ if (make_child (savestring (the_printed_command_except_trap), async) == 0)
+ {
+ already_forked = 1;
+ simple_command->flags |= CMD_NO_FORK;
+
+ subshell_environment = SUBSHELL_FORK;
+ if (pipe_in != NO_PIPE || pipe_out != NO_PIPE)
+ subshell_environment |= SUBSHELL_PIPE;
+ if (async)
+ subshell_environment |= SUBSHELL_ASYNC;
+
+ /* We need to do this before piping to handle some really
+ pathological cases where one of the pipe file descriptors
+ is < 2. */
+ if (fds_to_close)
+ close_fd_bitmap (fds_to_close);
+
+ do_piping (pipe_in, pipe_out);
+ pipe_in = pipe_out = NO_PIPE;
+#if defined (COPROCESS_SUPPORT)
+ coproc_closeall ();
+#endif
+
+ last_asynchronous_pid = old_last_async_pid;
+ }
+ else
+ {
+ /* Don't let simple commands that aren't the last command in a
+ pipeline change $? for the rest of the pipeline (or at all). */
+ if (pipe_out != NO_PIPE)
+ result = last_command_exit_value;
+ close_pipes (pipe_in, pipe_out);
+#if defined (PROCESS_SUBSTITUTION) && defined (HAVE_DEV_FD)
+ unlink_fifo_list ();
+#endif
+ command_line = (char *)NULL; /* don't free this. */
+ bind_lastarg ((char *)NULL);
+ return (result);
+ }
+ }
+
+ /* If we are re-running this as the result of executing the `command'
+ builtin, do not expand the command words a second time. */
+ if ((simple_command->flags & CMD_INHIBIT_EXPANSION) == 0)
+ {
+ current_fds_to_close = fds_to_close;
+ fix_assignment_words (simple_command->words);
+ /* Pass the ignore return flag down to command substitutions */
+ if (simple_command->flags & CMD_IGNORE_RETURN) /* XXX */
+ comsub_ignore_return++;
+ words = expand_words (simple_command->words);
+ if (simple_command->flags & CMD_IGNORE_RETURN)
+ comsub_ignore_return--;
+ current_fds_to_close = (struct fd_bitmap *)NULL;
+ }
+ else
+ words = copy_word_list (simple_command->words);
+
+ /* It is possible for WORDS not to have anything left in it.
+ Perhaps all the words consisted of `$foo', and there was
+ no variable `$foo'. */
+ if (words == 0)
+ {
+ this_command_name = 0;
+ result = execute_null_command (simple_command->redirects,
+ pipe_in, pipe_out,
+ already_forked ? 0 : async);
+ if (already_forked)
+ exit (result);
+ else
+ {
+ bind_lastarg ((char *)NULL);
+ set_pipestatus_from_exit (result);
+ return (result);
+ }
+ }
+
+ lastarg = (char *)NULL;
+
+ begin_unwind_frame ("simple-command");
+
+ if (echo_command_at_execute)
+ xtrace_print_word_list (words, 1);
+
+ builtin = (sh_builtin_func_t *)NULL;
+ func = (SHELL_VAR *)NULL;
+ if ((simple_command->flags & CMD_NO_FUNCTIONS) == 0)
+ {
+ /* Posix.2 says special builtins are found before functions. We
+ don't set builtin_is_special anywhere other than here, because
+ this path is followed only when the `command' builtin is *not*
+ being used, and we don't want to exit the shell if a special
+ builtin executed with `command builtin' fails. `command' is not
+ a special builtin. */
+ if (posixly_correct)
+ {
+ builtin = find_special_builtin (words->word->word);
+ if (builtin)
+ builtin_is_special = 1;
+ }
+ if (builtin == 0)
+ func = find_function (words->word->word);
+ }
+
+ /* In POSIX mode, assignment errors in the temporary environment cause a
+ non-interactive shell to exit. */
+ if (builtin_is_special && interactive_shell == 0 && tempenv_assign_error)
+ {
+ last_command_exit_value = EXECUTION_FAILURE;
+ jump_to_top_level (ERREXIT);
+ }
+
+ add_unwind_protect (dispose_words, words);
+ QUIT;
+
+ /* Bind the last word in this command to "$_" after execution. */
+ for (lastword = words; lastword->next; lastword = lastword->next)
+ ;
+ lastarg = lastword->word->word;
+
+#if defined (JOB_CONTROL)
+ /* Is this command a job control related thing? */
+ if (words->word->word[0] == '%' && already_forked == 0)
+ {
+ this_command_name = async ? "bg" : "fg";
+ last_shell_builtin = this_shell_builtin;
+ this_shell_builtin = builtin_address (this_command_name);
+ result = (*this_shell_builtin) (words);
+ goto return_result;
+ }
+
+ /* One other possiblilty. The user may want to resume an existing job.
+ If they do, find out whether this word is a candidate for a running
+ job. */
+ if (job_control && already_forked == 0 && async == 0 &&
+ !first_word_quoted &&
+ !words->next &&
+ words->word->word[0] &&
+ !simple_command->redirects &&
+ pipe_in == NO_PIPE &&
+ pipe_out == NO_PIPE &&
+ (temp = get_string_value ("auto_resume")))
+ {
+ int job, jflags, started_status;
+
+ jflags = JM_STOPPED|JM_FIRSTMATCH;
+ if (STREQ (temp, "exact"))
+ jflags |= JM_EXACT;
+ else if (STREQ (temp, "substring"))
+ jflags |= JM_SUBSTRING;
+ else
+ jflags |= JM_PREFIX;
+ job = get_job_by_name (words->word->word, jflags);
+ if (job != NO_JOB)
+ {
+ run_unwind_frame ("simple-command");
+ this_command_name = "fg";
+ last_shell_builtin = this_shell_builtin;
+ this_shell_builtin = builtin_address ("fg");
+
+ started_status = start_job (job, 1);
+ return ((started_status < 0) ? EXECUTION_FAILURE : started_status);
+ }
+ }
+#endif /* JOB_CONTROL */
+
+run_builtin:
+ /* Remember the name of this command globally. */
+ this_command_name = words->word->word;
+
+ QUIT;
+
+ /* This command could be a shell builtin or a user-defined function.
+ We have already found special builtins by this time, so we do not
+ set builtin_is_special. If this is a function or builtin, and we
+ have pipes, then fork a subshell in here. Otherwise, just execute
+ the command directly. */
+ if (func == 0 && builtin == 0)
+ builtin = find_shell_builtin (this_command_name);
+
+ last_shell_builtin = this_shell_builtin;
+ this_shell_builtin = builtin;
+
+ if (builtin || func)
+ {
+ if (builtin)
+ {
+ old_builtin = executing_builtin;
+ old_command_builtin = executing_command_builtin;
+ unwind_protect_int (executing_builtin); /* modified in execute_builtin */
+ unwind_protect_int (executing_command_builtin); /* ditto */
+ }
+ if (already_forked)
+ {
+ /* reset_terminating_signals (); */ /* XXX */
+ /* Reset the signal handlers in the child, but don't free the
+ trap strings. Set a flag noting that we have to free the
+ trap strings if we run trap to change a signal disposition. */
+ reset_signal_handlers ();
+ subshell_environment |= SUBSHELL_RESETTRAP;
+
+ if (async)
+ {
+ if ((simple_command->flags & CMD_STDIN_REDIR) &&
+ pipe_in == NO_PIPE &&
+ (stdin_redirects (simple_command->redirects) == 0))
+ async_redirect_stdin ();
+ setup_async_signals ();
+ }
+
+ subshell_level++;
+ execute_subshell_builtin_or_function
+ (words, simple_command->redirects, builtin, func,
+ pipe_in, pipe_out, async, fds_to_close,
+ simple_command->flags);
+ subshell_level--;
+ }
+ else
+ {
+ result = execute_builtin_or_function
+ (words, builtin, func, simple_command->redirects, fds_to_close,
+ simple_command->flags);
+ if (builtin)
+ {
+ if (result > EX_SHERRBASE)
+ {
+ result = builtin_status (result);
+ if (builtin_is_special)
+ special_builtin_failed = 1;
+ }
+ /* In POSIX mode, if there are assignment statements preceding
+ a special builtin, they persist after the builtin
+ completes. */
+ if (posixly_correct && builtin_is_special && temporary_env)
+ merge_temporary_env ();
+ }
+ else /* function */
+ {
+ if (result == EX_USAGE)
+ result = EX_BADUSAGE;
+ else if (result > EX_SHERRBASE)
+ result = EXECUTION_FAILURE;
+ }
+
+ set_pipestatus_from_exit (result);
+
+ goto return_result;
+ }
+ }
+
+ if (autocd && interactive && words->word && is_dirname (words->word->word))
+ {
+ words = make_word_list (make_word ("cd"), words);
+ xtrace_print_word_list (words, 0);
+ goto run_builtin;
+ }
+
+ if (command_line == 0)
+ command_line = savestring (the_printed_command_except_trap);
+
+#if defined (PROCESS_SUBSTITUTION)
+ if ((subshell_environment & SUBSHELL_COMSUB) && (simple_command->flags & CMD_NO_FORK) && fifos_pending() > 0)
+ simple_command->flags &= ~CMD_NO_FORK;
+#endif
+
+ result = execute_disk_command (words, simple_command->redirects, command_line,
+ pipe_in, pipe_out, async, fds_to_close,
+ simple_command->flags);
+
+ return_result:
+ bind_lastarg (lastarg);
+ FREE (command_line);
+ dispose_words (words);
+ if (builtin)
+ {
+ executing_builtin = old_builtin;
+ executing_command_builtin = old_command_builtin;
+ }
+ discard_unwind_frame ("simple-command");
+ this_command_name = (char *)NULL; /* points to freed memory now */
+ return (result);
+}
+
+/* Translate the special builtin exit statuses. We don't really need a
+ function for this; it's a placeholder for future work. */
+static int
+builtin_status (result)
+ int result;
+{
+ int r;
+
+ switch (result)
+ {
+ case EX_USAGE:
+ r = EX_BADUSAGE;
+ break;
+ case EX_REDIRFAIL:
+ case EX_BADSYNTAX:
+ case EX_BADASSIGN:
+ case EX_EXPFAIL:
+ r = EXECUTION_FAILURE;
+ break;
+ default:
+ r = EXECUTION_SUCCESS;
+ break;
+ }
+ return (r);
+}
+
+static int
+execute_builtin (builtin, words, flags, subshell)
+ sh_builtin_func_t *builtin;
+ WORD_LIST *words;
+ int flags, subshell;
+{
+ int old_e_flag, result, eval_unwind;
+ int isbltinenv;
+ char *error_trap;
+
+ error_trap = 0;
+ old_e_flag = exit_immediately_on_error;
+ /* The eval builtin calls parse_and_execute, which does not know about
+ the setting of flags, and always calls the execution functions with
+ flags that will exit the shell on an error if -e is set. If the
+ eval builtin is being called, and we're supposed to ignore the exit
+ value of the command, we turn the -e flag off ourselves and disable
+ the ERR trap, then restore them when the command completes. This is
+ also a problem (as below) for the command and source/. builtins. */
+ if (subshell == 0 && (flags & CMD_IGNORE_RETURN) &&
+ (builtin == eval_builtin || builtin == command_builtin || builtin == source_builtin))
+ {
+ begin_unwind_frame ("eval_builtin");
+ unwind_protect_int (exit_immediately_on_error);
+ error_trap = TRAP_STRING (ERROR_TRAP);
+ if (error_trap)
+ {
+ error_trap = savestring (error_trap);
+ add_unwind_protect (xfree, error_trap);
+ add_unwind_protect (set_error_trap, error_trap);
+ restore_default_signal (ERROR_TRAP);
+ }
+ exit_immediately_on_error = 0;
+ eval_unwind = 1;
+ }
+ else
+ eval_unwind = 0;
+
+ /* The temporary environment for a builtin is supposed to apply to
+ all commands executed by that builtin. Currently, this is a
+ problem only with the `unset', `source' and `eval' builtins. */
+
+ isbltinenv = (builtin == source_builtin || builtin == eval_builtin || builtin == unset_builtin);
+
+ if (isbltinenv)
+ {
+ if (subshell == 0)
+ begin_unwind_frame ("builtin_env");
+
+ if (temporary_env)
+ {
+ push_scope (VC_BLTNENV, temporary_env);
+ if (subshell == 0)
+ add_unwind_protect (pop_scope, (flags & CMD_COMMAND_BUILTIN) ? 0 : "1");
+ temporary_env = (HASH_TABLE *)NULL;
+ }
+ }
+
+ /* `return' does a longjmp() back to a saved environment in execute_function.
+ If a variable assignment list preceded the command, and the shell is
+ running in POSIX mode, we need to merge that into the shell_variables
+ table, since `return' is a POSIX special builtin. */
+ if (posixly_correct && subshell == 0 && builtin == return_builtin && temporary_env)
+ {
+ begin_unwind_frame ("return_temp_env");
+ add_unwind_protect (merge_temporary_env, (char *)NULL);
+ }
+
+ executing_builtin++;
+ executing_command_builtin |= builtin == command_builtin;
+ result = ((*builtin) (words->next));
+
+ /* This shouldn't happen, but in case `return' comes back instead of
+ longjmp'ing, we need to unwind. */
+ if (posixly_correct && subshell == 0 && builtin == return_builtin && temporary_env)
+ discard_unwind_frame ("return_temp_env");
+
+ if (subshell == 0 && isbltinenv)
+ run_unwind_frame ("builtin_env");
+
+ if (eval_unwind)
+ {
+ exit_immediately_on_error += old_e_flag;
+ if (error_trap)
+ {
+ set_error_trap (error_trap);
+ xfree (error_trap);
+ }
+ discard_unwind_frame ("eval_builtin");
+ }
+
+ return (result);
+}
+
+static int
+execute_function (var, words, flags, fds_to_close, async, subshell)
+ SHELL_VAR *var;
+ WORD_LIST *words;
+ int flags;
+ struct fd_bitmap *fds_to_close;
+ int async, subshell;
+{
+ int return_val, result;
+ COMMAND *tc, *fc, *save_current;
+ char *debug_trap, *error_trap, *return_trap;
+#if defined (ARRAY_VARS)
+ SHELL_VAR *funcname_v, *nfv, *bash_source_v, *bash_lineno_v;
+ ARRAY *funcname_a;
+ volatile ARRAY *bash_source_a;
+ volatile ARRAY *bash_lineno_a;
+#endif
+ FUNCTION_DEF *shell_fn;
+ char *sfile, *t;
+
+ USE_VAR(fc);
+
+ if (funcnest_max > 0 && funcnest >= funcnest_max)
+ {
+ internal_error ("%s: maximum function nesting level exceeded (%d)", var->name, funcnest);
+ funcnest = 0; /* XXX - should we reset it somewhere else? */
+ jump_to_top_level (DISCARD);
+ }
+
+#if defined (ARRAY_VARS)
+ GET_ARRAY_FROM_VAR ("FUNCNAME", funcname_v, funcname_a);
+ GET_ARRAY_FROM_VAR ("BASH_SOURCE", bash_source_v, bash_source_a);
+ GET_ARRAY_FROM_VAR ("BASH_LINENO", bash_lineno_v, bash_lineno_a);
+#endif
+
+ tc = (COMMAND *)copy_command (function_cell (var));
+ if (tc && (flags & CMD_IGNORE_RETURN))
+ tc->flags |= CMD_IGNORE_RETURN;
+
+ if (subshell == 0)
+ {
+ begin_unwind_frame ("function_calling");
+ push_context (var->name, subshell, temporary_env);
+ add_unwind_protect (pop_context, (char *)NULL);
+ unwind_protect_int (line_number);
+ unwind_protect_int (return_catch_flag);
+ unwind_protect_jmp_buf (return_catch);
+ add_unwind_protect (dispose_command, (char *)tc);
+ unwind_protect_pointer (this_shell_function);
+ unwind_protect_int (loop_level);
+ unwind_protect_int (funcnest);
+ }
+ else
+ push_context (var->name, subshell, temporary_env); /* don't unwind-protect for subshells */
+
+ temporary_env = (HASH_TABLE *)NULL;
+
+ this_shell_function = var;
+ make_funcname_visible (1);
+
+ debug_trap = TRAP_STRING(DEBUG_TRAP);
+ error_trap = TRAP_STRING(ERROR_TRAP);
+ return_trap = TRAP_STRING(RETURN_TRAP);
+
+ /* The order of the unwind protects for debug_trap, error_trap and
+ return_trap is important here! unwind-protect commands are run
+ in reverse order of registration. If this causes problems, take
+ out the xfree unwind-protect calls and live with the small memory leak. */
+
+ /* function_trace_mode != 0 means that all functions inherit the DEBUG trap.
+ if the function has the trace attribute set, it inherits the DEBUG trap */
+ if (debug_trap && ((trace_p (var) == 0) && function_trace_mode == 0))
+ {
+ if (subshell == 0)
+ {
+ debug_trap = savestring (debug_trap);
+ add_unwind_protect (xfree, debug_trap);
+ add_unwind_protect (set_debug_trap, debug_trap);
+ }
+ restore_default_signal (DEBUG_TRAP);
+ }
+
+ /* error_trace_mode != 0 means that functions inherit the ERR trap. */
+ if (error_trap && error_trace_mode == 0)
+ {
+ if (subshell == 0)
+ {
+ error_trap = savestring (error_trap);
+ add_unwind_protect (xfree, error_trap);
+ add_unwind_protect (set_error_trap, error_trap);
+ }
+ restore_default_signal (ERROR_TRAP);
+ }
+
+ /* Shell functions inherit the RETURN trap if function tracing is on
+ globally or on individually for this function. */
+#if 0
+ if (return_trap && ((trace_p (var) == 0) && function_trace_mode == 0))
+#else
+ if (return_trap && (signal_in_progress (DEBUG_TRAP) || ((trace_p (var) == 0) && function_trace_mode == 0)))
+#endif
+ {
+ if (subshell == 0)
+ {
+ return_trap = savestring (return_trap);
+ add_unwind_protect (xfree, return_trap);
+ add_unwind_protect (set_return_trap, return_trap);
+ }
+ restore_default_signal (RETURN_TRAP);
+ }
+
+ funcnest++;
+#if defined (ARRAY_VARS)
+ /* This is quite similar to the code in shell.c and elsewhere. */
+ shell_fn = find_function_def (this_shell_function->name);
+ sfile = shell_fn ? shell_fn->source_file : "";
+ array_push ((ARRAY *)funcname_a, this_shell_function->name);
+
+ array_push ((ARRAY *)bash_source_a, sfile);
+ t = itos (executing_line_number ());
+ array_push ((ARRAY *)bash_lineno_a, t);
+ free (t);
+#endif
+
+ /* The temporary environment for a function is supposed to apply to
+ all commands executed within the function body. */
+
+ remember_args (words->next, 1);
+
+ /* Update BASH_ARGV and BASH_ARGC */
+ if (debugging_mode)
+ push_args (words->next);
+
+ /* Number of the line on which the function body starts. */
+ line_number = function_line_number = tc->line;
+
+#if defined (JOB_CONTROL)
+ if (subshell)
+ stop_pipeline (async, (COMMAND *)NULL);
+#endif
+
+ fc = tc;
+
+ return_catch_flag++;
+ return_val = setjmp (return_catch);
+
+ if (return_val)
+ {
+ result = return_catch_value;
+ /* Run the RETURN trap in the function's context. */
+ save_current = currently_executing_command;
+ run_return_trap ();
+ currently_executing_command = save_current;
+ }
+ else
+ {
+ /* Run the debug trap here so we can trap at the start of a function's
+ execution rather than the execution of the body's first command. */
+ showing_function_line = 1;
+ save_current = currently_executing_command;
+ result = run_debug_trap ();
+#if defined (DEBUGGER)
+ /* In debugging mode, if the DEBUG trap returns a non-zero status, we
+ skip the command. */
+ if (debugging_mode == 0 || result == EXECUTION_SUCCESS)
+ {
+ showing_function_line = 0;
+ currently_executing_command = save_current;
+ result = execute_command_internal (fc, 0, NO_PIPE, NO_PIPE, fds_to_close);
+
+ /* Run the RETURN trap in the function's context */
+ save_current = currently_executing_command;
+ run_return_trap ();
+ currently_executing_command = save_current;
+ }
+#else
+ result = execute_command_internal (fc, 0, NO_PIPE, NO_PIPE, fds_to_close);
+
+ save_current = currently_executing_command;
+ run_return_trap ();
+ currently_executing_command = save_current;
+#endif
+ showing_function_line = 0;
+ }
+
+ /* Restore BASH_ARGC and BASH_ARGV */
+ if (debugging_mode)
+ pop_args ();
+
+ if (subshell == 0)
+ run_unwind_frame ("function_calling");
+
+#if defined (ARRAY_VARS)
+ /* These two variables cannot be unset, and cannot be affected by the
+ function. */
+ array_pop ((ARRAY *)bash_source_a);
+ array_pop ((ARRAY *)bash_lineno_a);
+
+ /* FUNCNAME can be unset, and so can potentially be changed by the
+ function. */
+ GET_ARRAY_FROM_VAR ("FUNCNAME", nfv, funcname_a);
+ if (nfv == funcname_v)
+ array_pop (funcname_a);
+#endif
+
+ if (variable_context == 0 || this_shell_function == 0)
+ {
+ make_funcname_visible (0);
+#if defined (PROCESS_SUBSTITUTION)
+ unlink_fifo_list ();
+#endif
+ }
+
+ return (result);
+}
+
+/* A convenience routine for use by other parts of the shell to execute
+ a particular shell function. */
+int
+execute_shell_function (var, words)
+ SHELL_VAR *var;
+ WORD_LIST *words;
+{
+ int ret;
+ struct fd_bitmap *bitmap;
+
+ bitmap = new_fd_bitmap (FD_BITMAP_DEFAULT_SIZE);
+ begin_unwind_frame ("execute-shell-function");
+ add_unwind_protect (dispose_fd_bitmap, (char *)bitmap);
+
+ ret = execute_function (var, words, 0, bitmap, 0, 0);
+
+ dispose_fd_bitmap (bitmap);
+ discard_unwind_frame ("execute-shell-function");
+
+ return ret;
+}
+
+/* Execute a shell builtin or function in a subshell environment. This
+ routine does not return; it only calls exit(). If BUILTIN is non-null,
+ it points to a function to call to execute a shell builtin; otherwise
+ VAR points at the body of a function to execute. WORDS is the arguments
+ to the command, REDIRECTS specifies redirections to perform before the
+ command is executed. */
+static void
+execute_subshell_builtin_or_function (words, redirects, builtin, var,
+ pipe_in, pipe_out, async, fds_to_close,
+ flags)
+ WORD_LIST *words;
+ REDIRECT *redirects;
+ sh_builtin_func_t *builtin;
+ SHELL_VAR *var;
+ int pipe_in, pipe_out, async;
+ struct fd_bitmap *fds_to_close;
+ int flags;
+{
+ int result, r, funcvalue;
+#if defined (JOB_CONTROL)
+ int jobs_hack;
+
+ jobs_hack = (builtin == jobs_builtin) &&
+ ((subshell_environment & SUBSHELL_ASYNC) == 0 || pipe_out != NO_PIPE);
+#endif
+
+ /* A subshell is neither a login shell nor interactive. */
+ login_shell = interactive = 0;
+
+ if (async)
+ subshell_environment |= SUBSHELL_ASYNC;
+ if (pipe_in != NO_PIPE || pipe_out != NO_PIPE)
+ subshell_environment |= SUBSHELL_PIPE;
+
+ maybe_make_export_env (); /* XXX - is this needed? */
+
+#if defined (JOB_CONTROL)
+ /* Eradicate all traces of job control after we fork the subshell, so
+ all jobs begun by this subshell are in the same process group as
+ the shell itself. */
+
+ /* Allow the output of `jobs' to be piped. */
+ if (jobs_hack)
+ kill_current_pipeline ();
+ else
+ without_job_control ();
+
+ set_sigchld_handler ();
+#endif /* JOB_CONTROL */
+
+ set_sigint_handler ();
+
+ if (fds_to_close)
+ close_fd_bitmap (fds_to_close);
+
+ do_piping (pipe_in, pipe_out);
+
+ if (do_redirections (redirects, RX_ACTIVE) != 0)
+ exit (EXECUTION_FAILURE);
+
+ if (builtin)
+ {
+ /* Give builtins a place to jump back to on failure,
+ so we don't go back up to main(). */
+ result = setjmp (top_level);
+
+ /* Give the return builtin a place to jump to when executed in a subshell
+ or pipeline */
+ funcvalue = 0;
+ if (return_catch_flag && builtin == return_builtin)
+ funcvalue = setjmp (return_catch);
+
+ if (result == EXITPROG)
+ exit (last_command_exit_value);
+ else if (result)
+ exit (EXECUTION_FAILURE);
+ else if (funcvalue)
+ exit (return_catch_value);
+ else
+ {
+ r = execute_builtin (builtin, words, flags, 1);
+ fflush (stdout);
+ if (r == EX_USAGE)
+ r = EX_BADUSAGE;
+ exit (r);
+ }
+ }
+ else
+ {
+ r = execute_function (var, words, flags, fds_to_close, async, 1);
+ fflush (stdout);
+ exit (r);
+ }
+}
+
+/* Execute a builtin or function in the current shell context. If BUILTIN
+ is non-null, it is the builtin command to execute, otherwise VAR points
+ to the body of a function. WORDS are the command's arguments, REDIRECTS
+ are the redirections to perform. FDS_TO_CLOSE is the usual bitmap of
+ file descriptors to close.
+
+ If BUILTIN is exec_builtin, the redirections specified in REDIRECTS are
+ not undone before this function returns. */
+static int
+execute_builtin_or_function (words, builtin, var, redirects,
+ fds_to_close, flags)
+ WORD_LIST *words;
+ sh_builtin_func_t *builtin;
+ SHELL_VAR *var;
+ REDIRECT *redirects;
+ struct fd_bitmap *fds_to_close;
+ int flags;
+{
+ int result;
+ REDIRECT *saved_undo_list;
+#if defined (PROCESS_SUBSTITUTION)
+ int ofifo, nfifo, osize;
+ char *ofifo_list;
+#endif
+
+
+#if defined (PROCESS_SUBSTITUTION)
+ ofifo = num_fifos ();
+ ofifo_list = copy_fifo_list (&osize);
+#endif
+
+ if (do_redirections (redirects, RX_ACTIVE|RX_UNDOABLE) != 0)
+ {
+ cleanup_redirects (redirection_undo_list);
+ redirection_undo_list = (REDIRECT *)NULL;
+ dispose_exec_redirects ();
+#if defined (PROCESS_SUBSTITUTION)
+ free (ofifo_list);
+#endif
+ return (EX_REDIRFAIL); /* was EXECUTION_FAILURE */
+ }
+
+ saved_undo_list = redirection_undo_list;
+
+ /* Calling the "exec" builtin changes redirections forever. */
+ if (builtin == exec_builtin)
+ {
+ dispose_redirects (saved_undo_list);
+ saved_undo_list = exec_redirection_undo_list;
+ exec_redirection_undo_list = (REDIRECT *)NULL;
+ }
+ else
+ dispose_exec_redirects ();
+
+ if (saved_undo_list)
+ {
+ begin_unwind_frame ("saved redirects");
+ add_unwind_protect (cleanup_redirects, (char *)saved_undo_list);
+ }
+
+ redirection_undo_list = (REDIRECT *)NULL;
+
+ if (builtin)
+ result = execute_builtin (builtin, words, flags, 0);
+ else
+ result = execute_function (var, words, flags, fds_to_close, 0, 0);
+
+ /* We do this before undoing the effects of any redirections. */
+ fflush (stdout);
+ fpurge (stdout);
+ if (ferror (stdout))
+ clearerr (stdout);
+
+ /* If we are executing the `command' builtin, but this_shell_builtin is
+ set to `exec_builtin', we know that we have something like
+ `command exec [redirection]', since otherwise `exec' would have
+ overwritten the shell and we wouldn't get here. In this case, we
+ want to behave as if the `command' builtin had not been specified
+ and preserve the redirections. */
+ if (builtin == command_builtin && this_shell_builtin == exec_builtin)
+ {
+ int discard;
+
+ discard = 0;
+ if (saved_undo_list)
+ {
+ dispose_redirects (saved_undo_list);
+ discard = 1;
+ }
+ redirection_undo_list = exec_redirection_undo_list;
+ saved_undo_list = exec_redirection_undo_list = (REDIRECT *)NULL;
+ if (discard)
+ discard_unwind_frame ("saved redirects");
+ }
+
+ if (saved_undo_list)
+ {
+ redirection_undo_list = saved_undo_list;
+ discard_unwind_frame ("saved redirects");
+ }
+
+ if (redirection_undo_list)
+ {
+ cleanup_redirects (redirection_undo_list);
+ redirection_undo_list = (REDIRECT *)NULL;
+ }
+
+#if defined (PROCESS_SUBSTITUTION)
+ /* Close any FIFOs created by this builtin or function. */
+ nfifo = num_fifos ();
+ if (nfifo > ofifo)
+ close_new_fifos (ofifo_list, osize);
+ free (ofifo_list);
+#endif
+
+ return (result);
+}
+
+void
+setup_async_signals ()
+{
+#if defined (__BEOS__)
+ set_signal_handler (SIGHUP, SIG_IGN); /* they want csh-like behavior */
+#endif
+
+#if defined (JOB_CONTROL)
+ if (job_control == 0)
+#endif
+ {
+ set_signal_handler (SIGINT, SIG_IGN);
+ set_signal_ignored (SIGINT);
+ set_signal_handler (SIGQUIT, SIG_IGN);
+ set_signal_ignored (SIGQUIT);
+ }
+}
+
+/* Execute a simple command that is hopefully defined in a disk file
+ somewhere.
+
+ 1) fork ()
+ 2) connect pipes
+ 3) look up the command
+ 4) do redirections
+ 5) execve ()
+ 6) If the execve failed, see if the file has executable mode set.
+ If so, and it isn't a directory, then execute its contents as
+ a shell script.
+
+ Note that the filename hashing stuff has to take place up here,
+ in the parent. This is probably why the Bourne style shells
+ don't handle it, since that would require them to go through
+ this gnarly hair, for no good reason.
+
+ NOTE: callers expect this to fork or exit(). */
+
+/* Name of a shell function to call when a command name is not found. */
+#ifndef NOTFOUND_HOOK
+# define NOTFOUND_HOOK "command_not_found_handle"
+#endif
+
+static int
+execute_disk_command (words, redirects, command_line, pipe_in, pipe_out,
+ async, fds_to_close, cmdflags)
+ WORD_LIST *words;
+ REDIRECT *redirects;
+ char *command_line;
+ int pipe_in, pipe_out, async;
+ struct fd_bitmap *fds_to_close;
+ int cmdflags;
+{
+ char *pathname, *command, **args;
+ int nofork, result;
+ pid_t pid;
+ SHELL_VAR *hookf;
+ WORD_LIST *wl;
+
+ nofork = (cmdflags & CMD_NO_FORK); /* Don't fork, just exec, if no pipes */
+ pathname = words->word->word;
+
+ result = EXECUTION_SUCCESS;
+#if defined (RESTRICTED_SHELL)
+ command = (char *)NULL;
+ if (restricted && mbschr (pathname, '/'))
+ {
+ internal_error (_("%s: restricted: cannot specify `/' in command names"),
+ pathname);
+ result = last_command_exit_value = EXECUTION_FAILURE;
+
+ /* If we're not going to fork below, we must already be in a child
+ process or a context in which it's safe to call exit(2). */
+ if (nofork && pipe_in == NO_PIPE && pipe_out == NO_PIPE)
+ exit (last_command_exit_value);
+ else
+ goto parent_return;
+ }
+#endif /* RESTRICTED_SHELL */
+
+ command = search_for_command (pathname);
+
+ if (command)
+ {
+ maybe_make_export_env ();
+ put_command_name_into_env (command);
+ }
+
+ /* We have to make the child before we check for the non-existence
+ of COMMAND, since we want the error messages to be redirected. */
+ /* If we can get away without forking and there are no pipes to deal with,
+ don't bother to fork, just directly exec the command. */
+ if (nofork && pipe_in == NO_PIPE && pipe_out == NO_PIPE)
+ pid = 0;
+ else
+ pid = make_child (savestring (command_line), async);
+
+ if (pid == 0)
+ {
+ int old_interactive;
+
+#if 0
+ /* This has been disabled for the time being. */
+#if !defined (ARG_MAX) || ARG_MAX >= 10240
+ if (posixly_correct == 0)
+ put_gnu_argv_flags_into_env ((long)getpid (), glob_argv_flags);
+#endif
+#endif
+
+ reset_terminating_signals (); /* XXX */
+ /* Cancel traps, in trap.c. */
+ restore_original_signals ();
+
+ /* restore_original_signals may have undone the work done
+ by make_child to ensure that SIGINT and SIGQUIT are ignored
+ in asynchronous children. */
+ if (async)
+ {
+ if ((cmdflags & CMD_STDIN_REDIR) &&
+ pipe_in == NO_PIPE &&
+ (stdin_redirects (redirects) == 0))
+ async_redirect_stdin ();
+ setup_async_signals ();
+ }
+
+ /* This functionality is now provided by close-on-exec of the
+ file descriptors manipulated by redirection and piping.
+ Some file descriptors still need to be closed in all children
+ because of the way bash does pipes; fds_to_close is a
+ bitmap of all such file descriptors. */
+ if (fds_to_close)
+ close_fd_bitmap (fds_to_close);
+
+ do_piping (pipe_in, pipe_out);
+
+ old_interactive = interactive;
+ if (async)
+ interactive = 0;
+
+ subshell_environment = SUBSHELL_FORK;
+
+ if (redirects && (do_redirections (redirects, RX_ACTIVE) != 0))
+ {
+#if defined (PROCESS_SUBSTITUTION)
+ /* Try to remove named pipes that may have been created as the
+ result of redirections. */
+ unlink_fifo_list ();
+#endif /* PROCESS_SUBSTITUTION */
+ exit (EXECUTION_FAILURE);
+ }
+
+ if (async)
+ interactive = old_interactive;
+
+ if (command == 0)
+ {
+ hookf = find_function (NOTFOUND_HOOK);
+ if (hookf == 0)
+ {
+ /* Make sure filenames are displayed using printable characters */
+ if (ansic_shouldquote (pathname))
+ pathname = ansic_quote (pathname, 0, NULL);
+ internal_error (_("%s: command not found"), pathname);
+ exit (EX_NOTFOUND); /* Posix.2 says the exit status is 127 */
+ }
+
+ wl = make_word_list (make_word (NOTFOUND_HOOK), words);
+ exit (execute_shell_function (hookf, wl));
+ }
+
+ /* Execve expects the command name to be in args[0]. So we
+ leave it there, in the same format that the user used to
+ type it in. */
+ args = strvec_from_word_list (words, 0, 0, (int *)NULL);
+ exit (shell_execve (command, args, export_env));
+ }
+ else
+ {
+parent_return:
+ QUIT;
+
+ /* Make sure that the pipes are closed in the parent. */
+ close_pipes (pipe_in, pipe_out);
+#if defined (PROCESS_SUBSTITUTION) && defined (HAVE_DEV_FD)
+ if (variable_context == 0)
+ unlink_fifo_list ();
+#endif
+ FREE (command);
+ return (result);
+ }
+}
+
+/* CPP defines to decide whether a particular index into the #! line
+ corresponds to a valid interpreter name or argument character, or
+ whitespace. The MSDOS define is to allow \r to be treated the same
+ as \n. */
+
+#if !defined (MSDOS)
+# define STRINGCHAR(ind) \
+ (ind < sample_len && !whitespace (sample[ind]) && sample[ind] != '\n')
+# define WHITECHAR(ind) \
+ (ind < sample_len && whitespace (sample[ind]))
+#else /* MSDOS */
+# define STRINGCHAR(ind) \
+ (ind < sample_len && !whitespace (sample[ind]) && sample[ind] != '\n' && sample[ind] != '\r')
+# define WHITECHAR(ind) \
+ (ind < sample_len && whitespace (sample[ind]))
+#endif /* MSDOS */
+
+static char *
+getinterp (sample, sample_len, endp)
+ char *sample;
+ int sample_len, *endp;
+{
+ register int i;
+ char *execname;
+ int start;
+
+ /* Find the name of the interpreter to exec. */
+ for (i = 2; i < sample_len && whitespace (sample[i]); i++)
+ ;
+
+ for (start = i; STRINGCHAR(i); i++)
+ ;
+
+ execname = substring (sample, start, i);
+
+ if (endp)
+ *endp = i;
+ return execname;
+}
+
+#if !defined (HAVE_HASH_BANG_EXEC)
+/* If the operating system on which we're running does not handle
+ the #! executable format, then help out. SAMPLE is the text read
+ from the file, SAMPLE_LEN characters. COMMAND is the name of
+ the script; it and ARGS, the arguments given by the user, will
+ become arguments to the specified interpreter. ENV is the environment
+ to pass to the interpreter.
+
+ The word immediately following the #! is the interpreter to execute.
+ A single argument to the interpreter is allowed. */
+
+static int
+execute_shell_script (sample, sample_len, command, args, env)
+ char *sample;
+ int sample_len;
+ char *command;
+ char **args, **env;
+{
+ char *execname, *firstarg;
+ int i, start, size_increment, larry;
+
+ /* Find the name of the interpreter to exec. */
+ execname = getinterp (sample, sample_len, &i);
+ size_increment = 1;
+
+ /* Now the argument, if any. */
+ for (firstarg = (char *)NULL, start = i; WHITECHAR(i); i++)
+ ;
+
+ /* If there is more text on the line, then it is an argument for the
+ interpreter. */
+
+ if (STRINGCHAR(i))
+ {
+ for (start = i; STRINGCHAR(i); i++)
+ ;
+ firstarg = substring ((char *)sample, start, i);
+ size_increment = 2;
+ }
+
+ larry = strvec_len (args) + size_increment;
+ args = strvec_resize (args, larry + 1);
+
+ for (i = larry - 1; i; i--)
+ args[i] = args[i - size_increment];
+
+ args[0] = execname;
+ if (firstarg)
+ {
+ args[1] = firstarg;
+ args[2] = command;
+ }
+ else
+ args[1] = command;
+
+ args[larry] = (char *)NULL;
+
+ return (shell_execve (execname, args, env));
+}
+#undef STRINGCHAR
+#undef WHITECHAR
+
+#endif /* !HAVE_HASH_BANG_EXEC */
+
+static void
+initialize_subshell ()
+{
+#if defined (ALIAS)
+ /* Forget about any aliases that we knew of. We are in a subshell. */
+ delete_all_aliases ();
+#endif /* ALIAS */
+
+#if defined (HISTORY)
+ /* Forget about the history lines we have read. This is a non-interactive
+ subshell. */
+ history_lines_this_session = 0;
+#endif
+
+#if defined (JOB_CONTROL)
+ /* Forget about the way job control was working. We are in a subshell. */
+ without_job_control ();
+ set_sigchld_handler ();
+ init_job_stats ();
+#endif /* JOB_CONTROL */
+
+ /* Reset the values of the shell flags and options. */
+ reset_shell_flags ();
+ reset_shell_options ();
+ reset_shopt_options ();
+
+ /* Zero out builtin_env, since this could be a shell script run from a
+ sourced file with a temporary environment supplied to the `source/.'
+ builtin. Such variables are not supposed to be exported (empirical
+ testing with sh and ksh). Just throw it away; don't worry about a
+ memory leak. */
+ if (vc_isbltnenv (shell_variables))
+ shell_variables = shell_variables->down;
+
+ clear_unwind_protect_list (0);
+ /* XXX -- are there other things we should be resetting here? */
+ parse_and_execute_level = 0; /* nothing left to restore it */
+
+ /* We're no longer inside a shell function. */
+ variable_context = return_catch_flag = funcnest = 0;
+
+ executing_list = 0; /* XXX */
+
+ /* If we're not interactive, close the file descriptor from which we're
+ reading the current shell script. */
+ if (interactive_shell == 0)
+ unset_bash_input (0);
+}
+
+#if defined (HAVE_SETOSTYPE) && defined (_POSIX_SOURCE)
+# define SETOSTYPE(x) __setostype(x)
+#else
+# define SETOSTYPE(x)
+#endif
+
+#define READ_SAMPLE_BUF(file, buf, len) \
+ do \
+ { \
+ fd = open(file, O_RDONLY); \
+ if (fd >= 0) \
+ { \
+ len = read (fd, buf, 80); \
+ close (fd); \
+ } \
+ else \
+ len = -1; \
+ } \
+ while (0)
+
+/* Call execve (), handling interpreting shell scripts, and handling
+ exec failures. */
+int
+shell_execve (command, args, env)
+ char *command;
+ char **args, **env;
+{
+ int larray, i, fd;
+ char sample[80];
+ int sample_len;
+
+ SETOSTYPE (0); /* Some systems use for USG/POSIX semantics */
+ execve (command, args, env);
+ i = errno; /* error from execve() */
+ CHECK_TERMSIG;
+ SETOSTYPE (1);
+
+ /* If we get to this point, then start checking out the file.
+ Maybe it is something we can hack ourselves. */
+ if (i != ENOEXEC)
+ {
+ if (file_isdir (command))
+#if defined (EISDIR)
+ internal_error (_("%s: %s"), command, strerror (EISDIR));
+#else
+ internal_error (_("%s: is a directory"), command);
+#endif
+ else if (executable_file (command) == 0)
+ {
+ errno = i;
+ file_error (command);
+ }
+ /* errors not involving the path argument to execve. */
+ else if (i == E2BIG || i == ENOMEM)
+ {
+ errno = i;
+ file_error (command);
+ }
+ else
+ {
+ /* The file has the execute bits set, but the kernel refuses to
+ run it for some reason. See why. */
+#if defined (HAVE_HASH_BANG_EXEC)
+ READ_SAMPLE_BUF (command, sample, sample_len);
+ if (sample_len > 2 && sample[0] == '#' && sample[1] == '!')
+ {
+ char *interp;
+ int ilen;
+
+ interp = getinterp (sample, sample_len, (int *)NULL);
+ ilen = strlen (interp);
+ errno = i;
+ if (interp[ilen - 1] == '\r')
+ {
+ interp = xrealloc (interp, ilen + 2);
+ interp[ilen - 1] = '^';
+ interp[ilen] = 'M';
+ interp[ilen + 1] = '\0';
+ }
+ sys_error (_("%s: %s: bad interpreter"), command, interp ? interp : "");
+ FREE (interp);
+ return (EX_NOEXEC);
+ }
+#endif
+ errno = i;
+ file_error (command);
+ }
+ return ((i == ENOENT) ? EX_NOTFOUND : EX_NOEXEC); /* XXX Posix.2 says that exit status is 126 */
+ }
+
+ /* This file is executable.
+ If it begins with #!, then help out people with losing operating
+ systems. Otherwise, check to see if it is a binary file by seeing
+ if the contents of the first line (or up to 80 characters) are in the
+ ASCII set. If it's a text file, execute the contents as shell commands,
+ otherwise return 126 (EX_BINARY_FILE). */
+ READ_SAMPLE_BUF (command, sample, sample_len);
+
+ if (sample_len == 0)
+ return (EXECUTION_SUCCESS);
+
+ /* Is this supposed to be an executable script?
+ If so, the format of the line is "#! interpreter [argument]".
+ A single argument is allowed. The BSD kernel restricts
+ the length of the entire line to 32 characters (32 bytes
+ being the size of the BSD exec header), but we allow 80
+ characters. */
+ if (sample_len > 0)
+ {
+#if !defined (HAVE_HASH_BANG_EXEC)
+ if (sample_len > 2 && sample[0] == '#' && sample[1] == '!')
+ return (execute_shell_script (sample, sample_len, command, args, env));
+ else
+#endif
+ if (check_binary_file (sample, sample_len))
+ {
+ internal_error (_("%s: cannot execute binary file"), command);
+ return (EX_BINARY_FILE);
+ }
+ }
+
+ /* We have committed to attempting to execute the contents of this file
+ as shell commands. */
+
+ initialize_subshell ();
+
+ set_sigint_handler ();
+
+ /* Insert the name of this shell into the argument list. */
+ larray = strvec_len (args) + 1;
+ args = strvec_resize (args, larray + 1);
+
+ for (i = larray - 1; i; i--)
+ args[i] = args[i - 1];
+
+ args[0] = shell_name;
+ args[1] = command;
+ args[larray] = (char *)NULL;
+
+ if (args[0][0] == '-')
+ args[0]++;
+
+#if defined (RESTRICTED_SHELL)
+ if (restricted)
+ change_flag ('r', FLAG_OFF);
+#endif
+
+ if (subshell_argv)
+ {
+ /* Can't free subshell_argv[0]; that is shell_name. */
+ for (i = 1; i < subshell_argc; i++)
+ free (subshell_argv[i]);
+ free (subshell_argv);
+ }
+
+ dispose_command (currently_executing_command); /* XXX */
+ currently_executing_command = (COMMAND *)NULL;
+
+ subshell_argc = larray;
+ subshell_argv = args;
+ subshell_envp = env;
+
+ unbind_args (); /* remove the positional parameters */
+
+ longjmp (subshell_top_level, 1);
+ /*NOTREACHED*/
+}
+
+static int
+execute_intern_function (name, function)
+ WORD_DESC *name;
+ COMMAND *function;
+{
+ SHELL_VAR *var;
+
+ if (check_identifier (name, posixly_correct) == 0)
+ {
+ if (posixly_correct && interactive_shell == 0)
+ {
+ last_command_exit_value = EX_BADUSAGE;
+ jump_to_top_level (ERREXIT);
+ }
+ return (EXECUTION_FAILURE);
+ }
+
+ var = find_function (name->word);
+ if (var && (readonly_p (var) || noassign_p (var)))
+ {
+ if (readonly_p (var))
+ internal_error (_("%s: readonly function"), var->name);
+ return (EXECUTION_FAILURE);
+ }
+
+ bind_function (name->word, function);
+ return (EXECUTION_SUCCESS);
+}
+
+#if defined (INCLUDE_UNUSED)
+#if defined (PROCESS_SUBSTITUTION)
+void
+close_all_files ()
+{
+ register int i, fd_table_size;
+
+ fd_table_size = getdtablesize ();
+ if (fd_table_size > 256) /* clamp to a reasonable value */
+ fd_table_size = 256;
+
+ for (i = 3; i < fd_table_size; i++)
+ close (i);
+}
+#endif /* PROCESS_SUBSTITUTION */
+#endif
+
+static void
+close_pipes (in, out)
+ int in, out;
+{
+ if (in >= 0)
+ close (in);
+ if (out >= 0)
+ close (out);
+}
+
+static void
+dup_error (oldd, newd)
+ int oldd, newd;
+{
+ sys_error (_("cannot duplicate fd %d to fd %d"), oldd, newd);
+}
+
+/* Redirect input and output to be from and to the specified pipes.
+ NO_PIPE and REDIRECT_BOTH are handled correctly. */
+static void
+do_piping (pipe_in, pipe_out)
+ int pipe_in, pipe_out;
+{
+ if (pipe_in != NO_PIPE)
+ {
+ if (dup2 (pipe_in, 0) < 0)
+ dup_error (pipe_in, 0);
+ if (pipe_in > 0)
+ close (pipe_in);
+#ifdef __CYGWIN__
+ /* Let stdio know the fd may have changed from text to binary mode. */
+ freopen (NULL, "r", stdin);
+#endif /* __CYGWIN__ */
+ }
+ if (pipe_out != NO_PIPE)
+ {
+ if (pipe_out != REDIRECT_BOTH)
+ {
+ if (dup2 (pipe_out, 1) < 0)
+ dup_error (pipe_out, 1);
+ if (pipe_out == 0 || pipe_out > 1)
+ close (pipe_out);
+ }
+ else
+ {
+ if (dup2 (1, 2) < 0)
+ dup_error (1, 2);
+ }
+#ifdef __CYGWIN__
+ /* Let stdio know the fd may have changed from text to binary mode, and
+ make sure to preserve stdout line buffering. */
+ freopen (NULL, "w", stdout);
+ sh_setlinebuf (stdout);
+#endif /* __CYGWIN__ */
+ }
+}
if (special)
{
+ if ((op == DIV || op == MOD) && value == 0)
+ {
+ if (noeval == 0)
+ evalerror (_("division by 0"));
+ else
+ value = 1;
+ }
+
switch (op)
{
case MUL:
lvalue *= value;
break;
case DIV:
- if (value == 0)
- evalerror (_("division by 0"));
lvalue /= value;
break;
case MOD:
- if (value == 0)
- evalerror (_("division by 0"));
lvalue %= value;
break;
case PLUS:
val2 = exppower ();
if (((op == DIV) || (op == MOD)) && (val2 == 0))
- evalerror (_("division by 0"));
+ {
+ if (noeval == 0)
+ evalerror (_("division by 0"));
+ else
+ val2 = 1;
+ }
if (op == MUL)
val1 *= val2;
--- /dev/null
+/* expr.c -- arithmetic expression evaluation. */
+
+/* Copyright (C) 1990-2010 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/>.
+*/
+
+/*
+ All arithmetic is done as intmax_t integers with no checking for overflow
+ (though division by 0 is caught and flagged as an error).
+
+ The following operators are handled, grouped into a set of levels in
+ order of decreasing precedence.
+
+ "id++", "id--" [post-increment and post-decrement]
+ "++id", "--id" [pre-increment and pre-decrement]
+ "-", "+" [(unary operators)]
+ "!", "~"
+ "**" [(exponentiation)]
+ "*", "/", "%"
+ "+", "-"
+ "<<", ">>"
+ "<=", ">=", "<", ">"
+ "==", "!="
+ "&"
+ "^"
+ "|"
+ "&&"
+ "||"
+ "expr ? expr : expr"
+ "=", "*=", "/=", "%=", "+=", "-=", "<<=", ">>=", "&=", "^=", "|="
+ , [comma]
+
+ (Note that most of these operators have special meaning to bash, and an
+ entire expression should be quoted, e.g. "a=$a+1" or "a=a+1" to ensure
+ that it is passed intact to the evaluator when using `let'. When using
+ the $[] or $(( )) forms, the text between the `[' and `]' or `((' and `))'
+ is treated as if in double quotes.)
+
+ Sub-expressions within parentheses have a precedence level greater than
+ all of the above levels and are evaluated first. Within a single prece-
+ dence group, evaluation is left-to-right, except for the arithmetic
+ assignment operator (`='), which is evaluated right-to-left (as in C).
+
+ The expression evaluator returns the value of the expression (assignment
+ statements have as a value what is returned by the RHS). The `let'
+ builtin, on the other hand, returns 0 if the last expression evaluates to
+ a non-zero, and 1 otherwise.
+
+ Implementation is a recursive-descent parser.
+
+ Chet Ramey
+ chet@ins.CWRU.Edu
+*/
+
+#include "config.h"
+
+#include <stdio.h>
+#include "bashansi.h"
+
+#if defined (HAVE_UNISTD_H)
+# ifdef _MINIX
+# include <sys/types.h>
+# endif
+# include <unistd.h>
+#endif
+
+#include "chartypes.h"
+#include "bashintl.h"
+
+#include "shell.h"
+
+/* Because of the $((...)) construct, expressions may include newlines.
+ Here is a macro which accepts newlines, tabs and spaces as whitespace. */
+#define cr_whitespace(c) (whitespace(c) || ((c) == '\n'))
+
+/* Size be which the expression stack grows when neccessary. */
+#define EXPR_STACK_GROW_SIZE 10
+
+/* Maximum amount of recursion allowed. This prevents a non-integer
+ variable such as "num=num+2" from infinitely adding to itself when
+ "let num=num+2" is given. */
+#define MAX_EXPR_RECURSION_LEVEL 1024
+
+/* The Tokens. Singing "The Lion Sleeps Tonight". */
+
+#define EQEQ 1 /* "==" */
+#define NEQ 2 /* "!=" */
+#define LEQ 3 /* "<=" */
+#define GEQ 4 /* ">=" */
+#define STR 5 /* string */
+#define NUM 6 /* number */
+#define LAND 7 /* "&&" Logical AND */
+#define LOR 8 /* "||" Logical OR */
+#define LSH 9 /* "<<" Left SHift */
+#define RSH 10 /* ">>" Right SHift */
+#define OP_ASSIGN 11 /* op= expassign as in Posix.2 */
+#define COND 12 /* exp1 ? exp2 : exp3 */
+#define POWER 13 /* exp1**exp2 */
+#define PREINC 14 /* ++var */
+#define PREDEC 15 /* --var */
+#define POSTINC 16 /* var++ */
+#define POSTDEC 17 /* var-- */
+#define EQ '='
+#define GT '>'
+#define LT '<'
+#define PLUS '+'
+#define MINUS '-'
+#define MUL '*'
+#define DIV '/'
+#define MOD '%'
+#define NOT '!'
+#define LPAR '('
+#define RPAR ')'
+#define BAND '&' /* Bitwise AND */
+#define BOR '|' /* Bitwise OR. */
+#define BXOR '^' /* Bitwise eXclusive OR. */
+#define BNOT '~' /* Bitwise NOT; Two's complement. */
+#define QUES '?'
+#define COL ':'
+#define COMMA ','
+
+/* This should be the function corresponding to the operator with the
+ highest precedence. */
+#define EXP_HIGHEST expcomma
+
+#ifndef MAX_INT_LEN
+# define MAX_INT_LEN 32
+#endif
+
+struct lvalue
+{
+ char *tokstr; /* possibly-rewritten lvalue if not NULL */
+ intmax_t tokval; /* expression evaluated value */
+ SHELL_VAR *tokvar; /* variable described by array or var reference */
+ intmax_t ind; /* array index if not -1 */
+};
+
+/* A structure defining a single expression context. */
+typedef struct {
+ int curtok, lasttok;
+ char *expression, *tp, *lasttp;
+ intmax_t tokval;
+ char *tokstr;
+ int noeval;
+ struct lvalue lval;
+} EXPR_CONTEXT;
+
+static char *expression; /* The current expression */
+static char *tp; /* token lexical position */
+static char *lasttp; /* pointer to last token position */
+static int curtok; /* the current token */
+static int lasttok; /* the previous token */
+static int assigntok; /* the OP in OP= */
+static char *tokstr; /* current token string */
+static intmax_t tokval; /* current token value */
+static int noeval; /* set to 1 if no assignment to be done */
+static procenv_t evalbuf;
+
+static struct lvalue curlval = {0, 0, 0, -1};
+static struct lvalue lastlval = {0, 0, 0, -1};
+
+static int _is_arithop __P((int));
+static void readtok __P((void)); /* lexical analyzer */
+
+static void init_lvalue __P((struct lvalue *));
+static struct lvalue *alloc_lvalue __P((void));
+static void free_lvalue __P((struct lvalue *));
+
+static intmax_t expr_streval __P((char *, int, struct lvalue *));
+static intmax_t strlong __P((char *));
+static void evalerror __P((const char *));
+
+static void pushexp __P((void));
+static void popexp __P((void));
+static void expr_unwind __P((void));
+static void expr_bind_variable __P((char *, char *));
+static void expr_bind_array_element __P((char *, arrayind_t, char *));
+
+static intmax_t subexpr __P((char *));
+
+static intmax_t expcomma __P((void));
+static intmax_t expassign __P((void));
+static intmax_t expcond __P((void));
+static intmax_t explor __P((void));
+static intmax_t expland __P((void));
+static intmax_t expbor __P((void));
+static intmax_t expbxor __P((void));
+static intmax_t expband __P((void));
+static intmax_t exp5 __P((void));
+static intmax_t exp4 __P((void));
+static intmax_t expshift __P((void));
+static intmax_t exp3 __P((void));
+static intmax_t exp2 __P((void));
+static intmax_t exppower __P((void));
+static intmax_t exp1 __P((void));
+static intmax_t exp0 __P((void));
+
+/* Global var which contains the stack of expression contexts. */
+static EXPR_CONTEXT **expr_stack;
+static int expr_depth; /* Location in the stack. */
+static int expr_stack_size; /* Number of slots already allocated. */
+
+extern char *this_command_name;
+extern int unbound_vars_is_error, last_command_exit_value;
+
+#if defined (ARRAY_VARS)
+extern const char * const bash_badsub_errmsg;
+#endif
+
+#define SAVETOK(X) \
+ do { \
+ (X)->curtok = curtok; \
+ (X)->lasttok = lasttok; \
+ (X)->tp = tp; \
+ (X)->lasttp = lasttp; \
+ (X)->tokval = tokval; \
+ (X)->tokstr = tokstr; \
+ (X)->noeval = noeval; \
+ (X)->lval = curlval; \
+ } while (0)
+
+#define RESTORETOK(X) \
+ do { \
+ curtok = (X)->curtok; \
+ lasttok = (X)->lasttok; \
+ tp = (X)->tp; \
+ lasttp = (X)->lasttp; \
+ tokval = (X)->tokval; \
+ tokstr = (X)->tokstr; \
+ noeval = (X)->noeval; \
+ curlval = (X)->lval; \
+ } while (0)
+
+/* Push and save away the contents of the globals describing the
+ current expression context. */
+static void
+pushexp ()
+{
+ EXPR_CONTEXT *context;
+
+ if (expr_depth >= MAX_EXPR_RECURSION_LEVEL)
+ evalerror (_("expression recursion level exceeded"));
+
+ if (expr_depth >= expr_stack_size)
+ {
+ expr_stack_size += EXPR_STACK_GROW_SIZE;
+ expr_stack = (EXPR_CONTEXT **)xrealloc (expr_stack, expr_stack_size * sizeof (EXPR_CONTEXT *));
+ }
+
+ context = (EXPR_CONTEXT *)xmalloc (sizeof (EXPR_CONTEXT));
+
+ context->expression = expression;
+ SAVETOK(context);
+
+ expr_stack[expr_depth++] = context;
+}
+
+/* Pop the the contents of the expression context stack into the
+ globals describing the current expression context. */
+static void
+popexp ()
+{
+ EXPR_CONTEXT *context;
+
+ if (expr_depth == 0)
+ evalerror (_("recursion stack underflow"));
+
+ context = expr_stack[--expr_depth];
+
+ expression = context->expression;
+ RESTORETOK (context);
+
+ free (context);
+}
+
+static void
+expr_unwind ()
+{
+ while (--expr_depth > 0)
+ {
+ if (expr_stack[expr_depth]->tokstr)
+ free (expr_stack[expr_depth]->tokstr);
+
+ if (expr_stack[expr_depth]->expression)
+ free (expr_stack[expr_depth]->expression);
+
+ free (expr_stack[expr_depth]);
+ }
+ free (expr_stack[expr_depth]); /* free the allocated EXPR_CONTEXT */
+
+ noeval = 0; /* XXX */
+}
+
+static void
+expr_bind_variable (lhs, rhs)
+ char *lhs, *rhs;
+{
+ SHELL_VAR *v;
+
+ v = bind_int_variable (lhs, rhs);
+ if (v && (readonly_p (v) || noassign_p (v)))
+ longjmp (evalbuf, 1); /* variable assignment error */
+ stupidly_hack_special_variables (lhs);
+}
+
+/* Rewrite tok, which is of the form vname[expression], to vname[ind], where
+ IND is the already-calculated value of expression. */
+static void
+expr_bind_array_element (tok, ind, rhs)
+ char *tok;
+ arrayind_t ind;
+ char *rhs;
+{
+ char *lhs, *vname;
+ size_t llen;
+ char ibuf[INT_STRLEN_BOUND (arrayind_t) + 1], *istr;
+
+ istr = fmtumax (ind, 10, ibuf, sizeof (ibuf), 0);
+ vname = array_variable_name (tok, (char **)NULL, (int *)NULL);
+
+ llen = strlen (vname) + sizeof (ibuf) + 3;
+ lhs = xmalloc (llen);
+
+ sprintf (lhs, "%s[%s]", vname, istr); /* XXX */
+
+ expr_bind_variable (lhs, rhs);
+/*itrace("expr_bind_array_element: %s=%s", lhs, rhs);*/
+ free (vname);
+ free (lhs);
+}
+
+/* Evaluate EXPR, and return the arithmetic result. If VALIDP is
+ non-null, a zero is stored into the location to which it points
+ if the expression is invalid, non-zero otherwise. If a non-zero
+ value is returned in *VALIDP, the return value of evalexp() may
+ be used.
+
+ The `while' loop after the longjmp is caught relies on the above
+ implementation of pushexp and popexp leaving in expr_stack[0] the
+ values that the variables had when the program started. That is,
+ the first things saved are the initial values of the variables that
+ were assigned at program startup or by the compiler. Therefore, it is
+ safe to let the loop terminate when expr_depth == 0, without freeing up
+ any of the expr_depth[0] stuff. */
+intmax_t
+evalexp (expr, validp)
+ char *expr;
+ int *validp;
+{
+ intmax_t val;
+ int c;
+ procenv_t oevalbuf;
+
+ val = 0;
+ noeval = 0;
+
+ FASTCOPY (evalbuf, oevalbuf, sizeof (evalbuf));
+
+ c = setjmp (evalbuf);
+
+ if (c)
+ {
+ FREE (tokstr);
+ FREE (expression);
+ tokstr = expression = (char *)NULL;
+
+ expr_unwind ();
+
+ if (validp)
+ *validp = 0;
+ return (0);
+ }
+
+ val = subexpr (expr);
+
+ if (validp)
+ *validp = 1;
+
+ FASTCOPY (oevalbuf, evalbuf, sizeof (evalbuf));
+
+ return (val);
+}
+
+static intmax_t
+subexpr (expr)
+ char *expr;
+{
+ intmax_t val;
+ char *p;
+
+ for (p = expr; p && *p && cr_whitespace (*p); p++)
+ ;
+
+ if (p == NULL || *p == '\0')
+ return (0);
+
+ pushexp ();
+ expression = savestring (expr);
+ tp = expression;
+
+ curtok = lasttok = 0;
+ tokstr = (char *)NULL;
+ tokval = 0;
+ init_lvalue (&curlval);
+ lastlval = curlval;
+
+ readtok ();
+
+ val = EXP_HIGHEST ();
+
+ if (curtok != 0)
+ evalerror (_("syntax error in expression"));
+
+ FREE (tokstr);
+ FREE (expression);
+
+ popexp ();
+
+ return val;
+}
+
+static intmax_t
+expcomma ()
+{
+ register intmax_t value;
+
+ value = expassign ();
+ while (curtok == COMMA)
+ {
+ readtok ();
+ value = expassign ();
+ }
+
+ return value;
+}
+
+static intmax_t
+expassign ()
+{
+ register intmax_t value;
+ char *lhs, *rhs;
+ arrayind_t lind;
+
+ value = expcond ();
+ if (curtok == EQ || curtok == OP_ASSIGN)
+ {
+ int special, op;
+ intmax_t lvalue;
+
+ special = curtok == OP_ASSIGN;
+
+ if (lasttok != STR)
+ evalerror (_("attempted assignment to non-variable"));
+
+ if (special)
+ {
+ op = assigntok; /* a OP= b */
+ lvalue = value;
+ }
+
+ lhs = savestring (tokstr);
+ /* save ind in case rhs is string var and evaluation overwrites it */
+ lind = curlval.ind;
+ readtok ();
+ value = expassign ();
+
+ if (special)
+ {
+ if ((op == DIV || op == MOD) && value == 0)
+ {
+ if (noeval == 0)
+ evalerror (_("division by 0"));
+ else
+ value = 1;
+ }
+
+ switch (op)
+ {
+ case MUL:
+ lvalue *= value;
+ break;
+ case DIV:
+ lvalue /= value;
+ break;
+ case MOD:
+ lvalue %= value;
+ break;
+ case PLUS:
+ lvalue += value;
+ break;
+ case MINUS:
+ lvalue -= value;
+ break;
+ case LSH:
+ lvalue <<= value;
+ break;
+ case RSH:
+ lvalue >>= value;
+ break;
+ case BAND:
+ lvalue &= value;
+ break;
+ case BOR:
+ lvalue |= value;
+ break;
+ case BXOR:
+ lvalue ^= value;
+ break;
+ default:
+ free (lhs);
+ evalerror (_("bug: bad expassign token"));
+ break;
+ }
+ value = lvalue;
+ }
+
+ rhs = itos (value);
+ if (noeval == 0)
+ {
+ if (lind != -1)
+ expr_bind_array_element (lhs, lind, rhs);
+ else
+ expr_bind_variable (lhs, rhs);
+ }
+ free (rhs);
+ free (lhs);
+ FREE (tokstr);
+ tokstr = (char *)NULL; /* For freeing on errors. */
+ }
+ return (value);
+}
+
+/* Conditional expression (expr?expr:expr) */
+static intmax_t
+expcond ()
+{
+ intmax_t cval, val1, val2, rval;
+ int set_noeval;
+ EXPR_CONTEXT ec;
+
+ set_noeval = 0;
+ rval = cval = explor ();
+ if (curtok == QUES) /* found conditional expr */
+ {
+ readtok ();
+ if (curtok == 0 || curtok == COL)
+ evalerror (_("expression expected"));
+ if (cval == 0)
+ {
+ set_noeval = 1;
+ noeval++;
+ }
+
+ val1 = EXP_HIGHEST ();
+
+ if (set_noeval)
+ noeval--;
+ if (curtok != COL)
+ evalerror (_("`:' expected for conditional expression"));
+ readtok ();
+ if (curtok == 0)
+ evalerror (_("expression expected"));
+ set_noeval = 0;
+ if (cval)
+ {
+ set_noeval = 1;
+ noeval++;
+ }
+
+ val2 = expcond ();
+ if (set_noeval)
+ noeval--;
+ rval = cval ? val1 : val2;
+ lasttok = COND;
+ }
+ return rval;
+}
+
+/* Logical OR. */
+static intmax_t
+explor ()
+{
+ register intmax_t val1, val2;
+ int set_noeval;
+
+ val1 = expland ();
+
+ while (curtok == LOR)
+ {
+ set_noeval = 0;
+ if (val1 != 0)
+ {
+ noeval++;
+ set_noeval = 1;
+ }
+ readtok ();
+ val2 = expland ();
+ if (set_noeval)
+ noeval--;
+ val1 = val1 || val2;
+ lasttok = LOR;
+ }
+
+ return (val1);
+}
+
+/* Logical AND. */
+static intmax_t
+expland ()
+{
+ register intmax_t val1, val2;
+ int set_noeval;
+
+ val1 = expbor ();
+
+ while (curtok == LAND)
+ {
+ set_noeval = 0;
+ if (val1 == 0)
+ {
+ set_noeval = 1;
+ noeval++;
+ }
+ readtok ();
+ val2 = expbor ();
+ if (set_noeval)
+ noeval--;
+ val1 = val1 && val2;
+ lasttok = LAND;
+ }
+
+ return (val1);
+}
+
+/* Bitwise OR. */
+static intmax_t
+expbor ()
+{
+ register intmax_t val1, val2;
+
+ val1 = expbxor ();
+
+ while (curtok == BOR)
+ {
+ readtok ();
+ val2 = expbxor ();
+ val1 = val1 | val2;
+ }
+
+ return (val1);
+}
+
+/* Bitwise XOR. */
+static intmax_t
+expbxor ()
+{
+ register intmax_t val1, val2;
+
+ val1 = expband ();
+
+ while (curtok == BXOR)
+ {
+ readtok ();
+ val2 = expband ();
+ val1 = val1 ^ val2;
+ }
+
+ return (val1);
+}
+
+/* Bitwise AND. */
+static intmax_t
+expband ()
+{
+ register intmax_t val1, val2;
+
+ val1 = exp5 ();
+
+ while (curtok == BAND)
+ {
+ readtok ();
+ val2 = exp5 ();
+ val1 = val1 & val2;
+ }
+
+ return (val1);
+}
+
+static intmax_t
+exp5 ()
+{
+ register intmax_t val1, val2;
+
+ val1 = exp4 ();
+
+ while ((curtok == EQEQ) || (curtok == NEQ))
+ {
+ int op = curtok;
+
+ readtok ();
+ val2 = exp4 ();
+ if (op == EQEQ)
+ val1 = (val1 == val2);
+ else if (op == NEQ)
+ val1 = (val1 != val2);
+ }
+ return (val1);
+}
+
+static intmax_t
+exp4 ()
+{
+ register intmax_t val1, val2;
+
+ val1 = expshift ();
+ while ((curtok == LEQ) ||
+ (curtok == GEQ) ||
+ (curtok == LT) ||
+ (curtok == GT))
+ {
+ int op = curtok;
+
+ readtok ();
+ val2 = expshift ();
+
+ if (op == LEQ)
+ val1 = val1 <= val2;
+ else if (op == GEQ)
+ val1 = val1 >= val2;
+ else if (op == LT)
+ val1 = val1 < val2;
+ else /* (op == GT) */
+ val1 = val1 > val2;
+ }
+ return (val1);
+}
+
+/* Left and right shifts. */
+static intmax_t
+expshift ()
+{
+ register intmax_t val1, val2;
+
+ val1 = exp3 ();
+
+ while ((curtok == LSH) || (curtok == RSH))
+ {
+ int op = curtok;
+
+ readtok ();
+ val2 = exp3 ();
+
+ if (op == LSH)
+ val1 = val1 << val2;
+ else
+ val1 = val1 >> val2;
+ }
+
+ return (val1);
+}
+
+static intmax_t
+exp3 ()
+{
+ register intmax_t val1, val2;
+
+ val1 = exp2 ();
+
+ while ((curtok == PLUS) || (curtok == MINUS))
+ {
+ int op = curtok;
+
+ readtok ();
+ val2 = exp2 ();
+
+ if (op == PLUS)
+ val1 += val2;
+ else if (op == MINUS)
+ val1 -= val2;
+ }
+ return (val1);
+}
+
+static intmax_t
+exp2 ()
+{
+ register intmax_t val1, val2;
+
+ val1 = exppower ();
+
+ while ((curtok == MUL) ||
+ (curtok == DIV) ||
+ (curtok == MOD))
+ {
+ int op = curtok;
+
+ readtok ();
+
+ val2 = exppower ();
+
+ if (((op == DIV) || (op == MOD)) && (val2 == 0))
+ {
+ if (noeval == 0)
+ evalerror (_("division by 0"));
+ else
+ val2 = 1;
+ }
+
+ if (op == MUL)
+ val1 *= val2;
+ else if (op == DIV)
+ val1 /= val2;
+ else if (op == MOD)
+ val1 %= val2;
+ }
+ return (val1);
+}
+
+static intmax_t
+exppower ()
+{
+ register intmax_t val1, val2, c;
+
+ val1 = exp1 ();
+ while (curtok == POWER)
+ {
+ readtok ();
+ val2 = exppower (); /* exponentiation is right-associative */
+ if (val2 == 0)
+ return (1);
+ if (val2 < 0)
+ evalerror (_("exponent less than 0"));
+ for (c = 1; val2--; c *= val1)
+ ;
+ val1 = c;
+ }
+ return (val1);
+}
+
+static intmax_t
+exp1 ()
+{
+ register intmax_t val;
+
+ if (curtok == NOT)
+ {
+ readtok ();
+ val = !exp1 ();
+ }
+ else if (curtok == BNOT)
+ {
+ readtok ();
+ val = ~exp1 ();
+ }
+ else if (curtok == MINUS)
+ {
+ readtok ();
+ val = - exp1 ();
+ }
+ else if (curtok == PLUS)
+ {
+ readtok ();
+ val = exp1 ();
+ }
+ else
+ val = exp0 ();
+
+ return (val);
+}
+
+static intmax_t
+exp0 ()
+{
+ register intmax_t val = 0, v2;
+ char *vincdec;
+ int stok;
+ EXPR_CONTEXT ec;
+
+ /* XXX - might need additional logic here to decide whether or not
+ pre-increment or pre-decrement is legal at this point. */
+ if (curtok == PREINC || curtok == PREDEC)
+ {
+ stok = lasttok = curtok;
+ readtok ();
+ if (curtok != STR)
+ /* readtok() catches this */
+ evalerror (_("identifier expected after pre-increment or pre-decrement"));
+
+ v2 = tokval + ((stok == PREINC) ? 1 : -1);
+ vincdec = itos (v2);
+ if (noeval == 0)
+ {
+ if (curlval.ind != -1)
+ expr_bind_array_element (curlval.tokstr, curlval.ind, vincdec);
+ else
+ expr_bind_variable (tokstr, vincdec);
+ }
+ free (vincdec);
+ val = v2;
+
+ curtok = NUM; /* make sure --x=7 is flagged as an error */
+ readtok ();
+ }
+ else if (curtok == LPAR)
+ {
+ readtok ();
+ val = EXP_HIGHEST ();
+
+ if (curtok != RPAR) /* ( */
+ evalerror (_("missing `)'"));
+
+ /* Skip over closing paren. */
+ readtok ();
+ }
+ else if ((curtok == NUM) || (curtok == STR))
+ {
+ val = tokval;
+ if (curtok == STR)
+ {
+ SAVETOK (&ec);
+ tokstr = (char *)NULL; /* keep it from being freed */
+ noeval = 1;
+ readtok ();
+ stok = curtok;
+
+ /* post-increment or post-decrement */
+ if (stok == POSTINC || stok == POSTDEC)
+ {
+ /* restore certain portions of EC */
+ tokstr = ec.tokstr;
+ noeval = ec.noeval;
+ curlval = ec.lval;
+ lasttok = STR; /* ec.curtok */
+
+ v2 = val + ((stok == POSTINC) ? 1 : -1);
+ vincdec = itos (v2);
+ if (noeval == 0)
+ {
+ if (curlval.ind != -1)
+ expr_bind_array_element (curlval.tokstr, curlval.ind, vincdec);
+ else
+ expr_bind_variable (tokstr, vincdec);
+ }
+ free (vincdec);
+ curtok = NUM; /* make sure x++=7 is flagged as an error */
+ }
+ else
+ {
+ if (stok == STR) /* free new tokstr before old one is restored */
+ FREE (tokstr);
+ RESTORETOK (&ec);
+ }
+
+ }
+
+ readtok ();
+ }
+ else
+ evalerror (_("syntax error: operand expected"));
+
+ return (val);
+}
+
+static void
+init_lvalue (lv)
+ struct lvalue *lv;
+{
+ lv->tokstr = 0;
+ lv->tokvar = 0;
+ lv->tokval = lv->ind = -1;
+}
+
+static struct lvalue *
+alloc_lvalue ()
+{
+ struct lvalue *lv;
+
+ lv = xmalloc (sizeof (struct lvalue));
+ init_lvalue (lv);
+ return (lv);
+}
+
+static void
+free_lvalue (lv)
+ struct lvalue *lv;
+{
+ free (lv); /* should be inlined */
+}
+
+static intmax_t
+expr_streval (tok, e, lvalue)
+ char *tok;
+ int e;
+ struct lvalue *lvalue;
+{
+ SHELL_VAR *v;
+ char *value;
+ intmax_t tval;
+#if defined (ARRAY_VARS)
+ arrayind_t ind;
+#endif
+
+ /* [[[[[ */
+#if defined (ARRAY_VARS)
+ v = (e == ']') ? array_variable_part (tok, (char **)0, (int *)0) : find_variable (tok);
+#else
+ v = find_variable (tok);
+#endif
+
+ if ((v == 0 || invisible_p (v)) && unbound_vars_is_error)
+ {
+#if defined (ARRAY_VARS)
+ value = (e == ']') ? array_variable_name (tok, (char **)0, (int *)0) : tok;
+#else
+ value = tok;
+#endif
+
+ last_command_exit_value = EXECUTION_FAILURE;
+ err_unboundvar (value);
+
+#if defined (ARRAY_VARS)
+ if (e == ']')
+ FREE (value); /* array_variable_name returns new memory */
+#endif
+
+ if (interactive_shell)
+ {
+ expr_unwind ();
+ top_level_cleanup ();
+ jump_to_top_level (DISCARD);
+ }
+ else
+ jump_to_top_level (FORCE_EOF);
+ }
+
+ ind = -1;
+#if defined (ARRAY_VARS)
+ /* Second argument of 0 to get_array_value means that we don't allow
+ references like array[@]. In this case, get_array_value is just
+ like get_variable_value in that it does not return newly-allocated
+ memory or quote the results. */
+ value = (e == ']') ? get_array_value (tok, 0, (int *)NULL, &ind) : get_variable_value (v);
+#else
+ value = get_variable_value (v);
+#endif
+
+ tval = (value && *value) ? subexpr (value) : 0;
+
+ if (lvalue)
+ {
+ lvalue->tokstr = tok; /* XXX */
+ lvalue->tokval = tval;
+ lvalue->tokvar = v; /* XXX */
+ lvalue->ind = ind;
+ }
+
+ return (tval);
+}
+
+static int
+_is_multiop (c)
+ int c;
+{
+ switch (c)
+ {
+ case EQEQ:
+ case NEQ:
+ case LEQ:
+ case GEQ:
+ case LAND:
+ case LOR:
+ case LSH:
+ case RSH:
+ case OP_ASSIGN:
+ case COND:
+ case POWER:
+ case PREINC:
+ case PREDEC:
+ case POSTINC:
+ case POSTDEC:
+ return 1;
+ default:
+ return 0;
+ }
+}
+
+static int
+_is_arithop (c)
+ int c;
+{
+ switch (c)
+ {
+ case EQ:
+ case GT:
+ case LT:
+ case PLUS:
+ case MINUS:
+ case MUL:
+ case DIV:
+ case MOD:
+ case NOT:
+ case LPAR:
+ case RPAR:
+ case BAND:
+ case BOR:
+ case BXOR:
+ case BNOT:
+ return 1; /* operator tokens */
+ case QUES:
+ case COL:
+ case COMMA:
+ return 1; /* questionable */
+ default:
+ return 0; /* anything else is invalid */
+ }
+}
+
+/* Lexical analyzer/token reader for the expression evaluator. Reads the
+ next token and puts its value into curtok, while advancing past it.
+ Updates value of tp. May also set tokval (for number) or tokstr (for
+ string). */
+static void
+readtok ()
+{
+ register char *cp, *xp;
+ register unsigned char c, c1;
+ register int e;
+ struct lvalue lval;
+
+ /* Skip leading whitespace. */
+ cp = tp;
+ c = e = 0;
+ while (cp && (c = *cp) && (cr_whitespace (c)))
+ cp++;
+
+ if (c)
+ cp++;
+
+ if (c == '\0')
+ {
+ lasttok = curtok;
+ curtok = 0;
+ tp = cp;
+ return;
+ }
+ lasttp = tp = cp - 1;
+
+ if (legal_variable_starter (c))
+ {
+ /* variable names not preceded with a dollar sign are shell variables. */
+ char *savecp;
+ EXPR_CONTEXT ec;
+ int peektok;
+
+ while (legal_variable_char (c))
+ c = *cp++;
+
+ c = *--cp;
+
+#if defined (ARRAY_VARS)
+ if (c == '[')
+ {
+ e = skipsubscript (cp, 0, 0);
+ if (cp[e] == ']')
+ {
+ cp += e + 1;
+ c = *cp;
+ e = ']';
+ }
+ else
+ evalerror (bash_badsub_errmsg);
+ }
+#endif /* ARRAY_VARS */
+
+ *cp = '\0';
+ FREE (tokstr);
+ tokstr = savestring (tp);
+ *cp = c;
+
+ /* XXX - make peektok part of saved token state? */
+ SAVETOK (&ec);
+ tokstr = (char *)NULL; /* keep it from being freed */
+ tp = savecp = cp;
+ noeval = 1;
+ curtok = STR;
+ readtok ();
+ peektok = curtok;
+ if (peektok == STR) /* free new tokstr before old one is restored */
+ FREE (tokstr);
+ RESTORETOK (&ec);
+ cp = savecp;
+
+ /* The tests for PREINC and PREDEC aren't strictly correct, but they
+ preserve old behavior if a construct like --x=9 is given. */
+ if (lasttok == PREINC || lasttok == PREDEC || peektok != EQ)
+ {
+ lastlval = curlval;
+ tokval = expr_streval (tokstr, e, &curlval);
+ }
+ else
+ tokval = 0;
+
+ lasttok = curtok;
+ curtok = STR;
+ }
+ else if (DIGIT(c))
+ {
+ while (ISALNUM (c) || c == '#' || c == '@' || c == '_')
+ c = *cp++;
+
+ c = *--cp;
+ *cp = '\0';
+
+ tokval = strlong (tp);
+ *cp = c;
+ lasttok = curtok;
+ curtok = NUM;
+ }
+ else
+ {
+ c1 = *cp++;
+ if ((c == EQ) && (c1 == EQ))
+ c = EQEQ;
+ else if ((c == NOT) && (c1 == EQ))
+ c = NEQ;
+ else if ((c == GT) && (c1 == EQ))
+ c = GEQ;
+ else if ((c == LT) && (c1 == EQ))
+ c = LEQ;
+ else if ((c == LT) && (c1 == LT))
+ {
+ if (*cp == '=') /* a <<= b */
+ {
+ assigntok = LSH;
+ c = OP_ASSIGN;
+ cp++;
+ }
+ else
+ c = LSH;
+ }
+ else if ((c == GT) && (c1 == GT))
+ {
+ if (*cp == '=')
+ {
+ assigntok = RSH; /* a >>= b */
+ c = OP_ASSIGN;
+ cp++;
+ }
+ else
+ c = RSH;
+ }
+ else if ((c == BAND) && (c1 == BAND))
+ c = LAND;
+ else if ((c == BOR) && (c1 == BOR))
+ c = LOR;
+ else if ((c == '*') && (c1 == '*'))
+ c = POWER;
+ else if ((c == '-' || c == '+') && c1 == c && curtok == STR)
+ c = (c == '-') ? POSTDEC : POSTINC;
+ else if ((c == '-' || c == '+') && c1 == c)
+ {
+ /* Quickly scan forward to see if this is followed by optional
+ whitespace and an identifier. */
+ xp = cp;
+ while (xp && *xp && cr_whitespace (*xp))
+ xp++;
+ if (legal_variable_starter ((unsigned char)*xp))
+ c = (c == '-') ? PREDEC : PREINC;
+ else
+ cp--; /* not preinc or predec, so unget the character */
+ }
+ else if (c1 == EQ && member (c, "*/%+-&^|"))
+ {
+ assigntok = c; /* a OP= b */
+ c = OP_ASSIGN;
+ }
+ else if (_is_arithop (c) == 0)
+ {
+ cp--;
+ /* use curtok, since it hasn't been copied to lasttok yet */
+ if (curtok == 0 || _is_arithop (curtok) || _is_multiop (curtok))
+ evalerror (_("syntax error: operand expected"));
+ else
+ evalerror (_("syntax error: invalid arithmetic operator"));
+ }
+ else
+ cp--; /* `unget' the character */
+
+ /* Should check here to make sure that the current character is one
+ of the recognized operators and flag an error if not. Could create
+ a character map the first time through and check it on subsequent
+ calls. */
+ lasttok = curtok;
+ curtok = c;
+ }
+ tp = cp;
+}
+
+static void
+evalerror (msg)
+ const char *msg;
+{
+ char *name, *t;
+
+ name = this_command_name;
+ for (t = expression; whitespace (*t); t++)
+ ;
+ internal_error (_("%s%s%s: %s (error token is \"%s\")"),
+ name ? name : "", name ? ": " : "", t,
+ msg, (lasttp && *lasttp) ? lasttp : "");
+ longjmp (evalbuf, 1);
+}
+
+/* Convert a string to an intmax_t integer, with an arbitrary base.
+ 0nnn -> base 8
+ 0[Xx]nn -> base 16
+ Anything else: [base#]number (this is implemented to match ksh93)
+
+ Base may be >=2 and <=64. If base is <= 36, the numbers are drawn
+ from [0-9][a-zA-Z], and lowercase and uppercase letters may be used
+ interchangably. If base is > 36 and <= 64, the numbers are drawn
+ from [0-9][a-z][A-Z]_@ (a = 10, z = 35, A = 36, Z = 61, @ = 62, _ = 63 --
+ you get the picture). */
+
+static intmax_t
+strlong (num)
+ char *num;
+{
+ register char *s;
+ register unsigned char c;
+ int base, foundbase;
+ intmax_t val;
+
+ s = num;
+
+ base = 10;
+ foundbase = 0;
+ if (*s == '0')
+ {
+ s++;
+
+ if (*s == '\0')
+ return 0;
+
+ /* Base 16? */
+ if (*s == 'x' || *s == 'X')
+ {
+ base = 16;
+ s++;
+ }
+ else
+ base = 8;
+ foundbase++;
+ }
+
+ val = 0;
+ for (c = *s++; c; c = *s++)
+ {
+ if (c == '#')
+ {
+ if (foundbase)
+ evalerror (_("invalid number"));
+
+ /* Illegal base specifications raise an evaluation error. */
+ if (val < 2 || val > 64)
+ evalerror (_("invalid arithmetic base"));
+
+ base = val;
+ val = 0;
+ foundbase++;
+ }
+ else if (ISALNUM(c) || (c == '_') || (c == '@'))
+ {
+ if (DIGIT(c))
+ c = TODIGIT(c);
+ else if (c >= 'a' && c <= 'z')
+ c -= 'a' - 10;
+ else if (c >= 'A' && c <= 'Z')
+ c -= 'A' - ((base <= 36) ? 10 : 36);
+ else if (c == '@')
+ c = 62;
+ else if (c == '_')
+ c = 63;
+
+ if (c >= base)
+ evalerror (_("value too great for base"));
+
+ val = (val * base) + c;
+ }
+ else
+ break;
+ }
+
+ return (val);
+}
+
+#if defined (EXPR_TEST)
+void *
+xmalloc (n)
+ int n;
+{
+ return (malloc (n));
+}
+
+void *
+xrealloc (s, n)
+ char *s;
+ int n;
+{
+ return (realloc (s, n));
+}
+
+SHELL_VAR *find_variable () { return 0;}
+SHELL_VAR *bind_variable () { return 0; }
+
+char *get_string_value () { return 0; }
+
+procenv_t top_level;
+
+main (argc, argv)
+ int argc;
+ char **argv;
+{
+ register int i;
+ intmax_t v;
+ int expok;
+
+ if (setjmp (top_level))
+ exit (0);
+
+ for (i = 1; i < argc; i++)
+ {
+ v = evalexp (argv[i], &expok);
+ if (expok == 0)
+ fprintf (stderr, _("%s: expression error\n"), argv[i]);
+ else
+ printf ("'%s' -> %ld\n", argv[i], v);
+ }
+ exit (0);
+}
+
+int
+builtin_error (format, arg1, arg2, arg3, arg4, arg5)
+ char *format;
+{
+ fprintf (stderr, "expr: ");
+ fprintf (stderr, format, arg1, arg2, arg3, arg4, arg5);
+ fprintf (stderr, "\n");
+ return 0;
+}
+
+char *
+itos (n)
+ intmax_t n;
+{
+ return ("42");
+}
+
+#endif /* EXPR_TEST */
whenever a complete line of input is ready. The user must then
call rl_callback_read_char() every time some input is available, and
rl_callback_read_char() will call the user's function with the complete
- text read in at each end of line. The terminal is kept prepped and
- signals handled all the time, except during calls to the user's function. */
+ text read in at each end of line. The terminal is kept prepped
+ all the time, except during calls to the user's function. Signal
+ handlers are only installed when the application calls back into
+ readline, so readline doesn't `steal' signals from the application. */
rl_vcpfunc_t *rl_linefunc; /* user callback function */
static int in_handler; /* terminal_prepped and signals set? */
if (rl_prep_term_function)
(*rl_prep_term_function) (_rl_meta_flag);
-
-#if defined (HANDLE_SIGNALS)
- rl_set_signals ();
-#endif
}
readline_internal_setup ();
return;
}
+#if defined (HANDLE_SIGNALS)
+ /* Install signal handlers only when readline has control. */
+ rl_set_signals ();
+#endif
+
do
{
RL_CHECK_SIGNALS ();
--- /dev/null
+/* callback.c -- functions to use readline as an X `callback' mechanism. */
+
+/* Copyright (C) 1987-2009 Free Software Foundation, Inc.
+
+ This file is part of the GNU Readline Library (Readline), a library
+ for reading lines of text with interactive input and history editing.
+
+ Readline 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.
+
+ Readline 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 Readline. If not, see <http://www.gnu.org/licenses/>.
+*/
+
+#define READLINE_LIBRARY
+
+#if defined (HAVE_CONFIG_H)
+# include <config.h>
+#endif
+
+#include "rlconf.h"
+
+#if defined (READLINE_CALLBACKS)
+
+#include <sys/types.h>
+
+#ifdef HAVE_STDLIB_H
+# include <stdlib.h>
+#else
+# include "ansi_stdlib.h"
+#endif
+
+#include <stdio.h>
+
+/* System-specific feature definitions and include files. */
+#include "rldefs.h"
+#include "readline.h"
+#include "rlprivate.h"
+#include "xmalloc.h"
+
+/* Private data for callback registration functions. See comments in
+ rl_callback_read_char for more details. */
+_rl_callback_func_t *_rl_callback_func = 0;
+_rl_callback_generic_arg *_rl_callback_data = 0;
+
+/* **************************************************************** */
+/* */
+/* Callback Readline Functions */
+/* */
+/* **************************************************************** */
+
+/* Allow using readline in situations where a program may have multiple
+ things to handle at once, and dispatches them via select(). Call
+ rl_callback_handler_install() with the prompt and a function to call
+ whenever a complete line of input is ready. The user must then
+ call rl_callback_read_char() every time some input is available, and
+ rl_callback_read_char() will call the user's function with the complete
+ text read in at each end of line. The terminal is kept prepped and
+ signals handled all the time, except during calls to the user's function. */
+
+rl_vcpfunc_t *rl_linefunc; /* user callback function */
+static int in_handler; /* terminal_prepped and signals set? */
+
+/* Make sure the terminal is set up, initialize readline, and prompt. */
+static void
+_rl_callback_newline ()
+{
+ rl_initialize ();
+
+ if (in_handler == 0)
+ {
+ in_handler = 1;
+
+ if (rl_prep_term_function)
+ (*rl_prep_term_function) (_rl_meta_flag);
+ }
+
+ readline_internal_setup ();
+ RL_CHECK_SIGNALS ();
+}
+
+/* Install a readline handler, set up the terminal, and issue the prompt. */
+void
+rl_callback_handler_install (prompt, linefunc)
+ const char *prompt;
+ rl_vcpfunc_t *linefunc;
+{
+ rl_set_prompt (prompt);
+ RL_SETSTATE (RL_STATE_CALLBACK);
+ rl_linefunc = linefunc;
+ _rl_callback_newline ();
+}
+
+/* Read one character, and dispatch to the handler if it ends the line. */
+void
+rl_callback_read_char ()
+{
+ char *line;
+ int eof, jcode;
+ static procenv_t olevel;
+
+ if (rl_linefunc == NULL)
+ {
+ _rl_errmsg ("readline_callback_read_char() called with no handler!");
+ abort ();
+ }
+
+ memcpy ((void *)olevel, (void *)_rl_top_level, sizeof (procenv_t));
+ jcode = setjmp (_rl_top_level);
+ if (jcode)
+ {
+ (*rl_redisplay_function) ();
+ _rl_want_redisplay = 0;
+ memcpy ((void *)_rl_top_level, (void *)olevel, sizeof (procenv_t));
+ return;
+ }
+
+#if defined (HANDLE_SIGNALS)
+ /* Install signal handlers only when readline has control. */
+ rl_set_signals ();
+#endif
+
+ do
+ {
+ RL_CHECK_SIGNALS ();
+ if (RL_ISSTATE (RL_STATE_ISEARCH))
+ {
+ eof = _rl_isearch_callback (_rl_iscxt);
+ if (eof == 0 && (RL_ISSTATE (RL_STATE_ISEARCH) == 0) && RL_ISSTATE (RL_STATE_INPUTPENDING))
+ rl_callback_read_char ();
+
+ return;
+ }
+ else if (RL_ISSTATE (RL_STATE_NSEARCH))
+ {
+ eof = _rl_nsearch_callback (_rl_nscxt);
+ return;
+ }
+#if defined (VI_MODE)
+ else if (RL_ISSTATE (RL_STATE_VIMOTION))
+ {
+ eof = _rl_vi_domove_callback (_rl_vimvcxt);
+ /* Should handle everything, including cleanup, numeric arguments,
+ and turning off RL_STATE_VIMOTION */
+ if (RL_ISSTATE (RL_STATE_NUMERICARG) == 0)
+ _rl_internal_char_cleanup ();
+
+ return;
+ }
+#endif
+ else if (RL_ISSTATE (RL_STATE_NUMERICARG))
+ {
+ eof = _rl_arg_callback (_rl_argcxt);
+ if (eof == 0 && (RL_ISSTATE (RL_STATE_NUMERICARG) == 0) && RL_ISSTATE (RL_STATE_INPUTPENDING))
+ rl_callback_read_char ();
+ /* XXX - this should handle _rl_last_command_was_kill better */
+ else if (RL_ISSTATE (RL_STATE_NUMERICARG) == 0)
+ _rl_internal_char_cleanup ();
+
+ return;
+ }
+ else if (RL_ISSTATE (RL_STATE_MULTIKEY))
+ {
+ eof = _rl_dispatch_callback (_rl_kscxt); /* For now */
+ while ((eof == -1 || eof == -2) && RL_ISSTATE (RL_STATE_MULTIKEY) && _rl_kscxt && (_rl_kscxt->flags & KSEQ_DISPATCHED))
+ eof = _rl_dispatch_callback (_rl_kscxt);
+ if (RL_ISSTATE (RL_STATE_MULTIKEY) == 0)
+ {
+ _rl_internal_char_cleanup ();
+ _rl_want_redisplay = 1;
+ }
+ }
+ else if (_rl_callback_func)
+ {
+ /* This allows functions that simply need to read an additional
+ character (like quoted-insert) to register a function to be
+ called when input is available. _rl_callback_data is simply a
+ pointer to a struct that has the argument count originally
+ passed to the registering function and space for any additional
+ parameters. */
+ eof = (*_rl_callback_func) (_rl_callback_data);
+ /* If the function `deregisters' itself, make sure the data is
+ cleaned up. */
+ if (_rl_callback_func == 0)
+ {
+ if (_rl_callback_data)
+ {
+ _rl_callback_data_dispose (_rl_callback_data);
+ _rl_callback_data = 0;
+ }
+ _rl_internal_char_cleanup ();
+ }
+ }
+ else
+ eof = readline_internal_char ();
+
+ RL_CHECK_SIGNALS ();
+ if (rl_done == 0 && _rl_want_redisplay)
+ {
+ (*rl_redisplay_function) ();
+ _rl_want_redisplay = 0;
+ }
+
+ if (rl_done)
+ {
+ line = readline_internal_teardown (eof);
+
+ if (rl_deprep_term_function)
+ (*rl_deprep_term_function) ();
+#if defined (HANDLE_SIGNALS)
+ rl_clear_signals ();
+#endif
+ in_handler = 0;
+ (*rl_linefunc) (line);
+
+ /* If the user did not clear out the line, do it for him. */
+ if (rl_line_buffer[0])
+ _rl_init_line_state ();
+
+ /* Redisplay the prompt if readline_handler_{install,remove}
+ not called. */
+ if (in_handler == 0 && rl_linefunc)
+ _rl_callback_newline ();
+ }
+ }
+ while (rl_pending_input || _rl_pushed_input_available () || RL_ISSTATE (RL_STATE_MACROINPUT));
+}
+
+/* Remove the handler, and make sure the terminal is in its normal state. */
+void
+rl_callback_handler_remove ()
+{
+ rl_linefunc = NULL;
+ RL_UNSETSTATE (RL_STATE_CALLBACK);
+ RL_CHECK_SIGNALS ();
+ if (in_handler)
+ {
+ in_handler = 0;
+ if (rl_deprep_term_function)
+ (*rl_deprep_term_function) ();
+#if defined (HANDLE_SIGNALS)
+ rl_clear_signals ();
+#endif
+ }
+}
+
+_rl_callback_generic_arg *
+_rl_callback_data_alloc (count)
+ int count;
+{
+ _rl_callback_generic_arg *arg;
+
+ arg = (_rl_callback_generic_arg *)xmalloc (sizeof (_rl_callback_generic_arg));
+ arg->count = count;
+
+ arg->i1 = arg->i2 = 0;
+
+ return arg;
+}
+
+void _rl_callback_data_dispose (arg)
+ _rl_callback_generic_arg *arg;
+{
+ xfree (arg);
+}
+
+#endif
# define IN_CTYPE_DOMAIN(c) isascii(c)
#endif
-#if !defined (isxdigit) && !defined (HAVE_ISXDIGIT)
+#if !defined (isxdigit) && !defined (HAVE_ISXDIGIT) && !defined (__cplusplus)
# define isxdigit(c) (isdigit((c)) || ((c) >= 'a' && (c) <= 'f') || ((c) >= 'A' && (c) <= 'F'))
#endif
--- /dev/null
+/* chardefs.h -- Character definitions for readline. */
+
+/* Copyright (C) 1994-2009 Free Software Foundation, Inc.
+
+ This file is part of the GNU Readline Library (Readline), a library
+ for reading lines of text with interactive input and history editing.
+
+ Readline 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.
+
+ Readline 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 Readline. If not, see <http://www.gnu.org/licenses/>.
+*/
+
+#ifndef _CHARDEFS_H_
+#define _CHARDEFS_H_
+
+#include <ctype.h>
+
+#if defined (HAVE_CONFIG_H)
+# if defined (HAVE_STRING_H)
+# if ! defined (STDC_HEADERS) && defined (HAVE_MEMORY_H)
+# include <memory.h>
+# endif
+# include <string.h>
+# endif /* HAVE_STRING_H */
+# if defined (HAVE_STRINGS_H)
+# include <strings.h>
+# endif /* HAVE_STRINGS_H */
+#else
+# include <string.h>
+#endif /* !HAVE_CONFIG_H */
+
+#ifndef whitespace
+#define whitespace(c) (((c) == ' ') || ((c) == '\t'))
+#endif
+
+#ifdef CTRL
+# undef CTRL
+#endif
+#ifdef UNCTRL
+# undef UNCTRL
+#endif
+
+/* Some character stuff. */
+#define control_character_threshold 0x020 /* Smaller than this is control. */
+#define control_character_mask 0x1f /* 0x20 - 1 */
+#define meta_character_threshold 0x07f /* Larger than this is Meta. */
+#define control_character_bit 0x40 /* 0x000000, must be off. */
+#define meta_character_bit 0x080 /* x0000000, must be on. */
+#define largest_char 255 /* Largest character value. */
+
+#define CTRL_CHAR(c) ((c) < control_character_threshold && (((c) & 0x80) == 0))
+#define META_CHAR(c) ((c) > meta_character_threshold && (c) <= largest_char)
+
+#define CTRL(c) ((c) & control_character_mask)
+#define META(c) ((c) | meta_character_bit)
+
+#define UNMETA(c) ((c) & (~meta_character_bit))
+#define UNCTRL(c) _rl_to_upper(((c)|control_character_bit))
+
+#if defined STDC_HEADERS || (!defined (isascii) && !defined (HAVE_ISASCII))
+# define IN_CTYPE_DOMAIN(c) 1
+#else
+# define IN_CTYPE_DOMAIN(c) isascii(c)
+#endif
+
+#if !defined (isxdigit) && !defined (HAVE_ISXDIGIT)
+# define isxdigit(c) (isdigit((c)) || ((c) >= 'a' && (c) <= 'f') || ((c) >= 'A' && (c) <= 'F'))
+#endif
+
+#if defined (CTYPE_NON_ASCII)
+# define NON_NEGATIVE(c) 1
+#else
+# define NON_NEGATIVE(c) ((unsigned char)(c) == (c))
+#endif
+
+/* Some systems define these; we want our definitions. */
+#undef ISPRINT
+
+/* Beware: these only work with single-byte ASCII characters. */
+
+#define ISALNUM(c) (IN_CTYPE_DOMAIN (c) && isalnum (c))
+#define ISALPHA(c) (IN_CTYPE_DOMAIN (c) && isalpha (c))
+#define ISDIGIT(c) (IN_CTYPE_DOMAIN (c) && isdigit (c))
+#define ISLOWER(c) (IN_CTYPE_DOMAIN (c) && islower (c))
+#define ISPRINT(c) (IN_CTYPE_DOMAIN (c) && isprint (c))
+#define ISUPPER(c) (IN_CTYPE_DOMAIN (c) && isupper (c))
+#define ISXDIGIT(c) (IN_CTYPE_DOMAIN (c) && isxdigit (c))
+
+#define _rl_lowercase_p(c) (NON_NEGATIVE(c) && ISLOWER(c))
+#define _rl_uppercase_p(c) (NON_NEGATIVE(c) && ISUPPER(c))
+#define _rl_digit_p(c) ((c) >= '0' && (c) <= '9')
+
+#define _rl_pure_alphabetic(c) (NON_NEGATIVE(c) && ISALPHA(c))
+#define ALPHABETIC(c) (NON_NEGATIVE(c) && ISALNUM(c))
+
+#ifndef _rl_to_upper
+# define _rl_to_upper(c) (_rl_lowercase_p(c) ? toupper((unsigned char)c) : (c))
+# define _rl_to_lower(c) (_rl_uppercase_p(c) ? tolower((unsigned char)c) : (c))
+#endif
+
+#ifndef _rl_digit_value
+# define _rl_digit_value(x) ((x) - '0')
+#endif
+
+#ifndef _rl_isident
+# define _rl_isident(c) (ISALNUM(c) || (c) == '_')
+#endif
+
+#ifndef ISOCTAL
+# define ISOCTAL(c) ((c) >= '0' && (c) <= '7')
+#endif
+#define OCTVALUE(c) ((c) - '0')
+
+#define HEXVALUE(c) \
+ (((c) >= 'a' && (c) <= 'f') \
+ ? (c)-'a'+10 \
+ : (c) >= 'A' && (c) <= 'F' ? (c)-'A'+10 : (c)-'0')
+
+#ifndef NEWLINE
+#define NEWLINE '\n'
+#endif
+
+#ifndef RETURN
+#define RETURN CTRL('M')
+#endif
+
+#ifndef RUBOUT
+#define RUBOUT 0x7f
+#endif
+
+#ifndef TAB
+#define TAB '\t'
+#endif
+
+#ifdef ABORT_CHAR
+#undef ABORT_CHAR
+#endif
+#define ABORT_CHAR CTRL('G')
+
+#ifdef PAGE
+#undef PAGE
+#endif
+#define PAGE CTRL('L')
+
+#ifdef SPACE
+#undef SPACE
+#endif
+#define SPACE ' ' /* XXX - was 0x20 */
+
+#ifdef ESC
+#undef ESC
+#endif
+#define ESC CTRL('[')
+
+#endif /* _CHARDEFS_H_ */
RL_UNSETSTATE(RL_STATE_MOREINPUT);
#if defined (HANDLE_MULTIBYTE)
+ /* This ends up with C (and LASTC) being set to the last byte of the
+ multibyte character. In most cases c == lastc == mb[0] */
if (MB_CUR_MAX > 1 && rl_byte_oriented == 0)
c = cxt->lastc = _rl_read_mbstring (cxt->lastc, cxt->mb, MB_LEN_MAX);
#endif
interpret here. Right now we just save the most recent character
that caused the index into a new keymap. */
cxt->prevc = c;
+#if defined (HANDLE_MULTIBYTE)
+ if (MB_CUR_MAX > 1 && rl_byte_oriented == 0)
+ {
+ if (cxt->mb[1] == 0)
+ {
+ cxt->pmb[0] = c; /* XXX should be == cxt->mb[0] */
+ cxt->pmb[1] = '\0';
+ }
+ else
+ memcpy (cxt->pmb, cxt->mb, sizeof (cxt->pmb));
+ }
+#endif
return 1;
}
{
rl_stuff_char (cxt->lastc);
rl_execute_next (cxt->prevc);
+ /* XXX - do we insert everything in cxt->pmb? */
return (0);
}
- /* Otherwise, if the current character is mapped to self-insert (i.e.,
- not an editing command), and the previous character was a keymap
- index, then we need to insert both the previous character and the
- current character into the search string. */
+ /* Otherwise, if the current character is mapped to self-insert or
+ nothing (i.e., not an editing command), and the previous character
+ was a keymap index, then we need to insert both the previous
+ character and the current character into the search string. */
else if (cxt->lastc > 0 && cxt->prevc > 0 &&
cxt->keymap[cxt->prevc].type == ISKMAP &&
- cxt->okeymap[cxt->lastc].type == ISFUNC && cxt->okeymap[cxt->lastc].function == rl_insert)
+ cxt->okeymap[cxt->lastc].type == ISFUNC &&
+ (cxt->okeymap[cxt->lastc].function == rl_insert || cxt->okeymap[cxt->lastc].function == 0))
{
/* Make lastc be the next character read */
+ /* XXX - do we insert everything in cxt->mb? */
rl_execute_next (cxt->lastc);
/* Dispatch on the previous character (insert into search string) */
cxt->lastc = cxt->prevc;
+#if defined (HANDLE_MULTIBYTE)
/* Have to overwrite cxt->mb here because dispatch uses it below */
- cxt->mb[0] = cxt->lastc;
- cxt->mb[1] = '\0';
-
+ if (MB_CUR_MAX > 1 && rl_byte_oriented == 0)
+ {
+ if (cxt->pmb[1] == 0)
+ {
+ cxt->mb[0] = cxt->lastc; /* == cxt->prevc */
+ cxt->mb[1] = '\0';
+ }
+ else
+ memcpy (cxt->mb, cxt->pmb, sizeof (cxt->mb));
+ }
+#endif
cxt->prevc = 0;
}
}
if (MB_CUR_MAX > 1 && rl_byte_oriented == 0)
{
int j, l;
- for (j = 0, l = strlen (cxt->mb); j < l; )
- cxt->search_string[cxt->search_string_index++] = cxt->mb[j++];
+
+ if (cxt->mb[0] == 0 || cxt->mb[1] == 0)
+ cxt->search_string[cxt->search_string_index++] = cxt->mb[0];
+ else
+ for (j = 0, l = RL_STRLEN (cxt->mb); j < l; )
+ cxt->search_string[cxt->search_string_index++] = cxt->mb[j++];
}
else
#endif
--- /dev/null
+/* isearch.c - incremental searching */
+
+/* **************************************************************** */
+/* */
+/* I-Search and Searching */
+/* */
+/* **************************************************************** */
+
+/* Copyright (C) 1987-2011 Free Software Foundation, Inc.
+
+ This file is part of the GNU Readline Library (Readline), a library
+ for reading lines of text with interactive input and history editing.
+
+ Readline 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.
+
+ Readline 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 Readline. If not, see <http://www.gnu.org/licenses/>.
+*/
+
+#define READLINE_LIBRARY
+
+#if defined (HAVE_CONFIG_H)
+# include <config.h>
+#endif
+
+#include <sys/types.h>
+
+#include <stdio.h>
+
+#if defined (HAVE_UNISTD_H)
+# include <unistd.h>
+#endif
+
+#if defined (HAVE_STDLIB_H)
+# include <stdlib.h>
+#else
+# include "ansi_stdlib.h"
+#endif
+
+#include "rldefs.h"
+#include "rlmbutil.h"
+
+#include "readline.h"
+#include "history.h"
+
+#include "rlprivate.h"
+#include "xmalloc.h"
+
+/* Variables exported to other files in the readline library. */
+char *_rl_isearch_terminators = (char *)NULL;
+
+_rl_search_cxt *_rl_iscxt = 0;
+
+/* Variables imported from other files in the readline library. */
+extern HIST_ENTRY *_rl_saved_line_for_history;
+
+static int rl_search_history PARAMS((int, int));
+
+static _rl_search_cxt *_rl_isearch_init PARAMS((int));
+static void _rl_isearch_fini PARAMS((_rl_search_cxt *));
+static int _rl_isearch_cleanup PARAMS((_rl_search_cxt *, int));
+
+/* Last line found by the current incremental search, so we don't `find'
+ identical lines many times in a row. Now part of isearch context. */
+/* static char *prev_line_found; */
+
+/* Last search string and its length. */
+static char *last_isearch_string;
+static int last_isearch_string_len;
+
+static char * const default_isearch_terminators = "\033\012";
+
+_rl_search_cxt *
+_rl_scxt_alloc (type, flags)
+ int type, flags;
+{
+ _rl_search_cxt *cxt;
+
+ cxt = (_rl_search_cxt *)xmalloc (sizeof (_rl_search_cxt));
+
+ cxt->type = type;
+ cxt->sflags = flags;
+
+ cxt->search_string = 0;
+ cxt->search_string_size = cxt->search_string_index = 0;
+
+ cxt->lines = 0;
+ cxt->allocated_line = 0;
+ cxt->hlen = cxt->hindex = 0;
+
+ cxt->save_point = rl_point;
+ cxt->save_mark = rl_mark;
+ cxt->save_line = where_history ();
+ cxt->last_found_line = cxt->save_line;
+ cxt->prev_line_found = 0;
+
+ cxt->save_undo_list = 0;
+
+ cxt->keymap = _rl_keymap;
+ cxt->okeymap = _rl_keymap;
+
+ cxt->history_pos = 0;
+ cxt->direction = 0;
+
+ cxt->prevc = cxt->lastc = 0;
+
+ cxt->sline = 0;
+ cxt->sline_len = cxt->sline_index = 0;
+
+ cxt->search_terminators = 0;
+
+ return cxt;
+}
+
+void
+_rl_scxt_dispose (cxt, flags)
+ _rl_search_cxt *cxt;
+ int flags;
+{
+ FREE (cxt->search_string);
+ FREE (cxt->allocated_line);
+ FREE (cxt->lines);
+
+ xfree (cxt);
+}
+
+/* Search backwards through the history looking for a string which is typed
+ interactively. Start with the current line. */
+int
+rl_reverse_search_history (sign, key)
+ int sign, key;
+{
+ return (rl_search_history (-sign, key));
+}
+
+/* Search forwards through the history looking for a string which is typed
+ interactively. Start with the current line. */
+int
+rl_forward_search_history (sign, key)
+ int sign, key;
+{
+ return (rl_search_history (sign, key));
+}
+
+/* Display the current state of the search in the echo-area.
+ SEARCH_STRING contains the string that is being searched for,
+ DIRECTION is zero for forward, or non-zero for reverse,
+ WHERE is the history list number of the current line. If it is
+ -1, then this line is the starting one. */
+static void
+rl_display_search (search_string, reverse_p, where)
+ char *search_string;
+ int reverse_p, where;
+{
+ char *message;
+ int msglen, searchlen;
+
+ searchlen = (search_string && *search_string) ? strlen (search_string) : 0;
+
+ message = (char *)xmalloc (searchlen + 33);
+ msglen = 0;
+
+#if defined (NOTDEF)
+ if (where != -1)
+ {
+ sprintf (message, "[%d]", where + history_base);
+ msglen = strlen (message);
+ }
+#endif /* NOTDEF */
+
+ message[msglen++] = '(';
+
+ if (reverse_p)
+ {
+ strcpy (message + msglen, "reverse-");
+ msglen += 8;
+ }
+
+ strcpy (message + msglen, "i-search)`");
+ msglen += 10;
+
+ if (search_string)
+ {
+ strcpy (message + msglen, search_string);
+ msglen += searchlen;
+ }
+
+ strcpy (message + msglen, "': ");
+
+ rl_message ("%s", message);
+ xfree (message);
+ (*rl_redisplay_function) ();
+}
+
+static _rl_search_cxt *
+_rl_isearch_init (direction)
+ int direction;
+{
+ _rl_search_cxt *cxt;
+ register int i;
+ HIST_ENTRY **hlist;
+
+ cxt = _rl_scxt_alloc (RL_SEARCH_ISEARCH, 0);
+ if (direction < 0)
+ cxt->sflags |= SF_REVERSE;
+
+ cxt->search_terminators = _rl_isearch_terminators ? _rl_isearch_terminators
+ : default_isearch_terminators;
+
+ /* Create an arrary of pointers to the lines that we want to search. */
+ hlist = history_list ();
+ rl_maybe_replace_line ();
+ i = 0;
+ if (hlist)
+ for (i = 0; hlist[i]; i++);
+
+ /* Allocate space for this many lines, +1 for the current input line,
+ and remember those lines. */
+ cxt->lines = (char **)xmalloc ((1 + (cxt->hlen = i)) * sizeof (char *));
+ for (i = 0; i < cxt->hlen; i++)
+ cxt->lines[i] = hlist[i]->line;
+
+ if (_rl_saved_line_for_history)
+ cxt->lines[i] = _rl_saved_line_for_history->line;
+ else
+ {
+ /* Keep track of this so we can free it. */
+ cxt->allocated_line = (char *)xmalloc (1 + strlen (rl_line_buffer));
+ strcpy (cxt->allocated_line, &rl_line_buffer[0]);
+ cxt->lines[i] = cxt->allocated_line;
+ }
+
+ cxt->hlen++;
+
+ /* The line where we start the search. */
+ cxt->history_pos = cxt->save_line;
+
+ rl_save_prompt ();
+
+ /* Initialize search parameters. */
+ cxt->search_string = (char *)xmalloc (cxt->search_string_size = 128);
+ cxt->search_string[cxt->search_string_index = 0] = '\0';
+
+ /* Normalize DIRECTION into 1 or -1. */
+ cxt->direction = (direction >= 0) ? 1 : -1;
+
+ cxt->sline = rl_line_buffer;
+ cxt->sline_len = strlen (cxt->sline);
+ cxt->sline_index = rl_point;
+
+ _rl_iscxt = cxt; /* save globally */
+
+ return cxt;
+}
+
+static void
+_rl_isearch_fini (cxt)
+ _rl_search_cxt *cxt;
+{
+ /* First put back the original state. */
+ strcpy (rl_line_buffer, cxt->lines[cxt->save_line]);
+
+ rl_restore_prompt ();
+
+ /* Save the search string for possible later use. */
+ FREE (last_isearch_string);
+ last_isearch_string = cxt->search_string;
+ last_isearch_string_len = cxt->search_string_index;
+ cxt->search_string = 0;
+
+ if (cxt->last_found_line < cxt->save_line)
+ rl_get_previous_history (cxt->save_line - cxt->last_found_line, 0);
+ else
+ rl_get_next_history (cxt->last_found_line - cxt->save_line, 0);
+
+ /* If the string was not found, put point at the end of the last matching
+ line. If last_found_line == orig_line, we didn't find any matching
+ history lines at all, so put point back in its original position. */
+ if (cxt->sline_index < 0)
+ {
+ if (cxt->last_found_line == cxt->save_line)
+ cxt->sline_index = cxt->save_point;
+ else
+ cxt->sline_index = strlen (rl_line_buffer);
+ rl_mark = cxt->save_mark;
+ }
+
+ rl_point = cxt->sline_index;
+ /* Don't worry about where to put the mark here; rl_get_previous_history
+ and rl_get_next_history take care of it. */
+
+ rl_clear_message ();
+}
+
+int
+_rl_search_getchar (cxt)
+ _rl_search_cxt *cxt;
+{
+ int c;
+
+ /* Read a key and decide how to proceed. */
+ RL_SETSTATE(RL_STATE_MOREINPUT);
+ c = cxt->lastc = rl_read_key ();
+ RL_UNSETSTATE(RL_STATE_MOREINPUT);
+
+#if defined (HANDLE_MULTIBYTE)
+ /* This ends up with C (and LASTC) being set to the last byte of the
+ multibyte character. In most cases c == lastc == mb[0] */
+ if (MB_CUR_MAX > 1 && rl_byte_oriented == 0)
+ c = cxt->lastc = _rl_read_mbstring (cxt->lastc, cxt->mb, MB_LEN_MAX);
+#endif
+
+ return c;
+}
+
+#define ENDSRCH_CHAR(c) \
+ ((CTRL_CHAR (c) || META_CHAR (c) || (c) == RUBOUT) && ((c) != CTRL ('G')))
+
+/* Process just-read character C according to isearch context CXT. Return
+ -1 if the caller should just free the context and return, 0 if we should
+ break out of the loop, and 1 if we should continue to read characters. */
+int
+_rl_isearch_dispatch (cxt, c)
+ _rl_search_cxt *cxt;
+ int c;
+{
+ int n, wstart, wlen, limit, cval;
+ rl_command_func_t *f;
+
+ f = (rl_command_func_t *)NULL;
+
+ if (c < 0)
+ {
+ cxt->sflags |= SF_FAILED;
+ cxt->history_pos = cxt->last_found_line;
+ return -1;
+ }
+
+ /* If we are moving into a new keymap, modify cxt->keymap and go on.
+ This can be a problem if c == ESC and we want to terminate the
+ incremental search, so we check */
+ if (c >= 0 && cxt->keymap[c].type == ISKMAP && strchr (cxt->search_terminators, cxt->lastc) == 0)
+ {
+ cxt->keymap = FUNCTION_TO_KEYMAP (cxt->keymap, c);
+ cxt->sflags |= SF_CHGKMAP;
+ /* XXX - we should probably save this sequence, so we can do
+ something useful if this doesn't end up mapping to a command we
+ interpret here. Right now we just save the most recent character
+ that caused the index into a new keymap. */
+ cxt->prevc = c;
+#if defined (HANDLE_MULTIBYTE)
+ if (MB_CUR_MAX > 1 && rl_byte_oriented == 0)
+ {
+ if (cxt->mb[1] == 0)
+ {
+ cxt->pmb[0] = c; /* XXX should be == cxt->mb[0] */
+ cxt->pmb[1] = '\0';
+ }
+ else
+ memcpy (cxt->pmb, cxt->mb, sizeof (cxt->pmb));
+ }
+#endif
+ return 1;
+ }
+
+ /* Translate the keys we do something with to opcodes. */
+ if (c >= 0 && cxt->keymap[c].type == ISFUNC)
+ {
+ f = cxt->keymap[c].function;
+
+ if (f == rl_reverse_search_history)
+ cxt->lastc = (cxt->sflags & SF_REVERSE) ? -1 : -2;
+ else if (f == rl_forward_search_history)
+ cxt->lastc = (cxt->sflags & SF_REVERSE) ? -2 : -1;
+ else if (f == rl_rubout)
+ cxt->lastc = -3;
+ else if (c == CTRL ('G') || f == rl_abort)
+ cxt->lastc = -4;
+ else if (c == CTRL ('W') || f == rl_unix_word_rubout) /* XXX */
+ cxt->lastc = -5;
+ else if (c == CTRL ('Y') || f == rl_yank) /* XXX */
+ cxt->lastc = -6;
+ }
+
+ /* If we changed the keymap earlier while translating a key sequence into
+ a command, restore it now that we've succeeded. */
+ if (cxt->sflags & SF_CHGKMAP)
+ {
+ cxt->keymap = cxt->okeymap;
+ cxt->sflags &= ~SF_CHGKMAP;
+ /* If we indexed into a new keymap, but didn't map to a command that
+ affects the search (lastc > 0), and the character that mapped to a
+ new keymap would have ended the search (ENDSRCH_CHAR(cxt->prevc)),
+ handle that now as if the previous char would have ended the search
+ and we would have read the current character. */
+ /* XXX - should we check cxt->mb? */
+ if (cxt->lastc > 0 && ENDSRCH_CHAR (cxt->prevc))
+ {
+ rl_stuff_char (cxt->lastc);
+ rl_execute_next (cxt->prevc);
+ return (0);
+ }
+ /* Otherwise, if the current character is mapped to self-insert or
+ nothing (i.e., not an editing command), and the previous character
+ was a keymap index, then we need to insert both the previous
+ character and the current character into the search string. */
+ else if (cxt->lastc > 0 && cxt->prevc > 0 &&
+ cxt->keymap[cxt->prevc].type == ISKMAP &&
+ cxt->okeymap[cxt->lastc].type == ISFUNC &&
+ (cxt->okeymap[cxt->lastc].function == rl_insert || cxt->okeymap[cxt->lastc].function == 0))
+ {
+ /* Make lastc be the next character read */
+ rl_execute_next (cxt->lastc);
+ /* Dispatch on the previous character (insert into search string) */
+ cxt->lastc = cxt->prevc;
+#if defined (HANDLE_MULTIBYTE)
+ /* Have to overwrite cxt->mb here because dispatch uses it below */
+ if (MB_CUR_MAX > 1 && rl_byte_oriented == 0)
+ {
+ if (cxt->pmb[1] == 0)
+ {
+ cxt->mb[0] = cxt->lastc; /* == cxt->prevc */
+ cxt->mb[1] = '\0';
+ }
+ else
+ memcpy (cxt->mb, cxt->pmb, sizeof (cxt->mb));
+ }
+#endif
+ cxt->prevc = 0;
+ }
+ }
+
+ /* The characters in isearch_terminators (set from the user-settable
+ variable isearch-terminators) are used to terminate the search but
+ not subsequently execute the character as a command. The default
+ value is "\033\012" (ESC and C-J). */
+ if (cxt->lastc > 0 && strchr (cxt->search_terminators, cxt->lastc))
+ {
+ /* ESC still terminates the search, but if there is pending
+ input or if input arrives within 0.1 seconds (on systems
+ with select(2)) it is used as a prefix character
+ with rl_execute_next. WATCH OUT FOR THIS! This is intended
+ to allow the arrow keys to be used like ^F and ^B are used
+ to terminate the search and execute the movement command.
+ XXX - since _rl_input_available depends on the application-
+ settable keyboard timeout value, this could alternatively
+ use _rl_input_queued(100000) */
+ if (cxt->lastc == ESC && _rl_input_available ())
+ rl_execute_next (ESC);
+ return (0);
+ }
+
+#if defined (HANDLE_MULTIBYTE)
+ if (MB_CUR_MAX > 1 && rl_byte_oriented == 0)
+ {
+ if (cxt->lastc >= 0 && (cxt->mb[0] && cxt->mb[1] == '\0') && ENDSRCH_CHAR (cxt->lastc))
+ {
+ /* This sets rl_pending_input to LASTC; it will be picked up the next
+ time rl_read_key is called. */
+ rl_execute_next (cxt->lastc);
+ return (0);
+ }
+ }
+ else
+#endif
+ if (cxt->lastc >= 0 && ENDSRCH_CHAR (cxt->lastc))
+ {
+ /* This sets rl_pending_input to LASTC; it will be picked up the next
+ time rl_read_key is called. */
+ rl_execute_next (cxt->lastc);
+ return (0);
+ }
+
+ /* Now dispatch on the character. `Opcodes' affect the search string or
+ state. Other characters are added to the string. */
+ switch (cxt->lastc)
+ {
+ /* search again */
+ case -1:
+ if (cxt->search_string_index == 0)
+ {
+ if (last_isearch_string)
+ {
+ cxt->search_string_size = 64 + last_isearch_string_len;
+ cxt->search_string = (char *)xrealloc (cxt->search_string, cxt->search_string_size);
+ strcpy (cxt->search_string, last_isearch_string);
+ cxt->search_string_index = last_isearch_string_len;
+ rl_display_search (cxt->search_string, (cxt->sflags & SF_REVERSE), -1);
+ break;
+ }
+ return (1);
+ }
+ else if (cxt->sflags & SF_REVERSE)
+ cxt->sline_index--;
+ else if (cxt->sline_index != cxt->sline_len)
+ cxt->sline_index++;
+ else
+ rl_ding ();
+ break;
+
+ /* switch directions */
+ case -2:
+ cxt->direction = -cxt->direction;
+ if (cxt->direction < 0)
+ cxt->sflags |= SF_REVERSE;
+ else
+ cxt->sflags &= ~SF_REVERSE;
+ break;
+
+ /* delete character from search string. */
+ case -3: /* C-H, DEL */
+ /* This is tricky. To do this right, we need to keep a
+ stack of search positions for the current search, with
+ sentinels marking the beginning and end. But this will
+ do until we have a real isearch-undo. */
+ if (cxt->search_string_index == 0)
+ rl_ding ();
+ else
+ cxt->search_string[--cxt->search_string_index] = '\0';
+ break;
+
+ case -4: /* C-G, abort */
+ rl_replace_line (cxt->lines[cxt->save_line], 0);
+ rl_point = cxt->save_point;
+ rl_mark = cxt->save_mark;
+ rl_restore_prompt();
+ rl_clear_message ();
+
+ return -1;
+
+ case -5: /* C-W */
+ /* skip over portion of line we already matched and yank word */
+ wstart = rl_point + cxt->search_string_index;
+ if (wstart >= rl_end)
+ {
+ rl_ding ();
+ break;
+ }
+
+ /* if not in a word, move to one. */
+ cval = _rl_char_value (rl_line_buffer, wstart);
+ if (_rl_walphabetic (cval) == 0)
+ {
+ rl_ding ();
+ break;
+ }
+ n = MB_NEXTCHAR (rl_line_buffer, wstart, 1, MB_FIND_NONZERO);;
+ while (n < rl_end)
+ {
+ cval = _rl_char_value (rl_line_buffer, n);
+ if (_rl_walphabetic (cval) == 0)
+ break;
+ n = MB_NEXTCHAR (rl_line_buffer, n, 1, MB_FIND_NONZERO);;
+ }
+ wlen = n - wstart + 1;
+ if (cxt->search_string_index + wlen + 1 >= cxt->search_string_size)
+ {
+ cxt->search_string_size += wlen + 1;
+ cxt->search_string = (char *)xrealloc (cxt->search_string, cxt->search_string_size);
+ }
+ for (; wstart < n; wstart++)
+ cxt->search_string[cxt->search_string_index++] = rl_line_buffer[wstart];
+ cxt->search_string[cxt->search_string_index] = '\0';
+ break;
+
+ case -6: /* C-Y */
+ /* skip over portion of line we already matched and yank rest */
+ wstart = rl_point + cxt->search_string_index;
+ if (wstart >= rl_end)
+ {
+ rl_ding ();
+ break;
+ }
+ n = rl_end - wstart + 1;
+ if (cxt->search_string_index + n + 1 >= cxt->search_string_size)
+ {
+ cxt->search_string_size += n + 1;
+ cxt->search_string = (char *)xrealloc (cxt->search_string, cxt->search_string_size);
+ }
+ for (n = wstart; n < rl_end; n++)
+ cxt->search_string[cxt->search_string_index++] = rl_line_buffer[n];
+ cxt->search_string[cxt->search_string_index] = '\0';
+ break;
+
+ /* Add character to search string and continue search. */
+ default:
+ if (cxt->search_string_index + 2 >= cxt->search_string_size)
+ {
+ cxt->search_string_size += 128;
+ cxt->search_string = (char *)xrealloc (cxt->search_string, cxt->search_string_size);
+ }
+#if defined (HANDLE_MULTIBYTE)
+ if (MB_CUR_MAX > 1 && rl_byte_oriented == 0)
+ {
+ int j, l;
+
+ if (cxt->mb[0] == 0 || cxt->mb[1] == 0)
+ cxt->search_string[cxt->search_string_index++] = cxt->mb[0];
+ else
+ for (j = 0, l = RL_STRLEN (cxt->mb); j < l; )
+ cxt->search_string[cxt->search_string_index++] = cxt->mb[j++];
+ }
+ else
+#endif
+ cxt->search_string[cxt->search_string_index++] = cxt->lastc; /* XXX - was c instead of lastc */
+ cxt->search_string[cxt->search_string_index] = '\0';
+ break;
+ }
+
+ for (cxt->sflags &= ~(SF_FOUND|SF_FAILED);; )
+ {
+ limit = cxt->sline_len - cxt->search_string_index + 1;
+
+ /* Search the current line. */
+ while ((cxt->sflags & SF_REVERSE) ? (cxt->sline_index >= 0) : (cxt->sline_index < limit))
+ {
+ if (STREQN (cxt->search_string, cxt->sline + cxt->sline_index, cxt->search_string_index))
+ {
+ cxt->sflags |= SF_FOUND;
+ break;
+ }
+ else
+ cxt->sline_index += cxt->direction;
+ }
+ if (cxt->sflags & SF_FOUND)
+ break;
+
+ /* Move to the next line, but skip new copies of the line
+ we just found and lines shorter than the string we're
+ searching for. */
+ do
+ {
+ /* Move to the next line. */
+ cxt->history_pos += cxt->direction;
+
+ /* At limit for direction? */
+ if ((cxt->sflags & SF_REVERSE) ? (cxt->history_pos < 0) : (cxt->history_pos == cxt->hlen))
+ {
+ cxt->sflags |= SF_FAILED;
+ break;
+ }
+
+ /* We will need these later. */
+ cxt->sline = cxt->lines[cxt->history_pos];
+ cxt->sline_len = strlen (cxt->sline);
+ }
+ while ((cxt->prev_line_found && STREQ (cxt->prev_line_found, cxt->lines[cxt->history_pos])) ||
+ (cxt->search_string_index > cxt->sline_len));
+
+ if (cxt->sflags & SF_FAILED)
+ break;
+
+ /* Now set up the line for searching... */
+ cxt->sline_index = (cxt->sflags & SF_REVERSE) ? cxt->sline_len - cxt->search_string_index : 0;
+ }
+
+ if (cxt->sflags & SF_FAILED)
+ {
+ /* We cannot find the search string. Ding the bell. */
+ rl_ding ();
+ cxt->history_pos = cxt->last_found_line;
+ return 1;
+ }
+
+ /* We have found the search string. Just display it. But don't
+ actually move there in the history list until the user accepts
+ the location. */
+ if (cxt->sflags & SF_FOUND)
+ {
+ cxt->prev_line_found = cxt->lines[cxt->history_pos];
+ rl_replace_line (cxt->lines[cxt->history_pos], 0);
+ rl_point = cxt->sline_index;
+ cxt->last_found_line = cxt->history_pos;
+ rl_display_search (cxt->search_string, (cxt->sflags & SF_REVERSE), (cxt->history_pos == cxt->save_line) ? -1 : cxt->history_pos);
+ }
+
+ return 1;
+}
+
+static int
+_rl_isearch_cleanup (cxt, r)
+ _rl_search_cxt *cxt;
+ int r;
+{
+ if (r >= 0)
+ _rl_isearch_fini (cxt);
+ _rl_scxt_dispose (cxt, 0);
+ _rl_iscxt = 0;
+
+ RL_UNSETSTATE(RL_STATE_ISEARCH);
+
+ return (r != 0);
+}
+
+/* Search through the history looking for an interactively typed string.
+ This is analogous to i-search. We start the search in the current line.
+ DIRECTION is which direction to search; >= 0 means forward, < 0 means
+ backwards. */
+static int
+rl_search_history (direction, invoking_key)
+ int direction, invoking_key;
+{
+ _rl_search_cxt *cxt; /* local for now, but saved globally */
+ int c, r;
+
+ RL_SETSTATE(RL_STATE_ISEARCH);
+ cxt = _rl_isearch_init (direction);
+
+ rl_display_search (cxt->search_string, (cxt->sflags & SF_REVERSE), -1);
+
+ /* If we are using the callback interface, all we do is set up here and
+ return. The key is that we leave RL_STATE_ISEARCH set. */
+ if (RL_ISSTATE (RL_STATE_CALLBACK))
+ return (0);
+
+ r = -1;
+ for (;;)
+ {
+ c = _rl_search_getchar (cxt);
+ /* We might want to handle EOF here (c == 0) */
+ r = _rl_isearch_dispatch (cxt, cxt->lastc);
+ if (r <= 0)
+ break;
+ }
+
+ /* The searching is over. The user may have found the string that she
+ was looking for, or else she may have exited a failing search. If
+ LINE_INDEX is -1, then that shows that the string searched for was
+ not found. We use this to determine where to place rl_point. */
+ return (_rl_isearch_cleanup (cxt, r));
+}
+
+#if defined (READLINE_CALLBACKS)
+/* Called from the callback functions when we are ready to read a key. The
+ callback functions know to call this because RL_ISSTATE(RL_STATE_ISEARCH).
+ If _rl_isearch_dispatch finishes searching, this function is responsible
+ for turning off RL_STATE_ISEARCH, which it does using _rl_isearch_cleanup. */
+int
+_rl_isearch_callback (cxt)
+ _rl_search_cxt *cxt;
+{
+ int c, r;
+
+ c = _rl_search_getchar (cxt);
+ /* We might want to handle EOF here */
+ r = _rl_isearch_dispatch (cxt, cxt->lastc);
+
+ return (r <= 0) ? _rl_isearch_cleanup (cxt, r) : 0;
+}
+#endif
for readline. This should be included after any files that define
system-specific constants like _POSIX_VERSION or USG. */
-/* Copyright (C) 1987-2009 Free Software Foundation, Inc.
+/* Copyright (C) 1987-2011 Free Software Foundation, Inc.
This file is part of the GNU Readline Library (Readline), a library
for reading lines of text with interactive input and history editing.
: ((a)[0] == (b)[0]) && (strncmp ((a), (b), (n)) == 0))
#endif
+#if !defined (RL_STRLEN)
+# define RL_STRLEN(s) (((s) && (s)[0]) ? ((s)[1] ? ((s)[2] ? strlen(s) : 2) : 1) : 0)
+#endif
+
#if !defined (FREE)
# define FREE(x) if (x) free (x)
#endif
int lastc;
#if defined (HANDLE_MULTIBYTE)
char mb[MB_LEN_MAX];
+ char pmb[MB_LEN_MAX];
#endif
char *sline;
rl_signal_handler (sig)
int sig;
{
-#if 0
-#if defined (SIGWINCH)
- if (_rl_interrupt_immediately || (sig != SIGWINCH && RL_ISSTATE(RL_STATE_CALLBACK)))
-#else
- if (_rl_interrupt_immediately || RL_ISSTATE(RL_STATE_CALLBACK))
-#endif
-#else
if (_rl_interrupt_immediately)
-#endif
{
_rl_interrupt_immediately = 0;
_rl_handle_signal (sig);
rl_signal_handler (sig)
int sig;
{
+#if 0
+#if defined (SIGWINCH)
+ if (_rl_interrupt_immediately || (sig != SIGWINCH && RL_ISSTATE(RL_STATE_CALLBACK)))
+#else
if (_rl_interrupt_immediately || RL_ISSTATE(RL_STATE_CALLBACK))
+#endif
+#else
+ if (_rl_interrupt_immediately)
+#endif
{
_rl_interrupt_immediately = 0;
_rl_handle_signal (sig);
zsyncfd (fd)
int fd;
{
- off_t off;
- int r;
+ off_t off, r;
off = lused - lind;
r = 0;
if (off > 0)
r = lseek (fd, -off, SEEK_CUR);
- if (r >= 0)
+ if (r != -1)
lused = lind = 0;
}
--- /dev/null
+/* zread - read data from file descriptor into buffer with retries */
+
+/* Copyright (C) 1999-2002 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/>.
+*/
+
+#include <config.h>
+
+#include <sys/types.h>
+
+#if defined (HAVE_UNISTD_H)
+# include <unistd.h>
+#endif
+
+#include <errno.h>
+
+#if !defined (errno)
+extern int errno;
+#endif
+
+#ifndef SEEK_CUR
+# define SEEK_CUR 1
+#endif
+
+/* Read LEN bytes from FD into BUF. Retry the read on EINTR. Any other
+ error causes the loop to break. */
+ssize_t
+zread (fd, buf, len)
+ int fd;
+ char *buf;
+ size_t len;
+{
+ ssize_t r;
+
+ while ((r = read (fd, buf, len)) < 0 && errno == EINTR)
+ ;
+ return r;
+}
+
+/* Read LEN bytes from FD into BUF. Retry the read on EINTR, up to three
+ interrupts. Any other error causes the loop to break. */
+
+#ifdef NUM_INTR
+# undef NUM_INTR
+#endif
+#define NUM_INTR 3
+
+ssize_t
+zreadretry (fd, buf, len)
+ int fd;
+ char *buf;
+ size_t len;
+{
+ ssize_t r;
+ int nintr;
+
+ for (nintr = 0; ; )
+ {
+ r = read (fd, buf, len);
+ if (r >= 0)
+ return r;
+ if (r == -1 && errno == EINTR)
+ {
+ if (++nintr >= NUM_INTR)
+ return -1;
+ continue;
+ }
+ return r;
+ }
+}
+
+/* Call read(2) and allow it to be interrupted. Just a stub for now. */
+ssize_t
+zreadintr (fd, buf, len)
+ int fd;
+ char *buf;
+ size_t len;
+{
+ return (read (fd, buf, len));
+}
+
+/* Read one character from FD and return it in CP. Return values are as
+ in read(2). This does some local buffering to avoid many one-character
+ calls to read(2), like those the `read' builtin performs. */
+
+static char lbuf[128];
+static size_t lind, lused;
+
+ssize_t
+zreadc (fd, cp)
+ int fd;
+ char *cp;
+{
+ ssize_t nr;
+
+ if (lind == lused || lused == 0)
+ {
+ nr = zread (fd, lbuf, sizeof (lbuf));
+ lind = 0;
+ if (nr <= 0)
+ {
+ lused = 0;
+ return nr;
+ }
+ lused = nr;
+ }
+ if (cp)
+ *cp = lbuf[lind++];
+ return 1;
+}
+
+/* Don't mix calls to zreadc and zreadcintr in the same function, since they
+ use the same local buffer. */
+ssize_t
+zreadcintr (fd, cp)
+ int fd;
+ char *cp;
+{
+ ssize_t nr;
+
+ if (lind == lused || lused == 0)
+ {
+ nr = zreadintr (fd, lbuf, sizeof (lbuf));
+ lind = 0;
+ if (nr <= 0)
+ {
+ lused = 0;
+ return nr;
+ }
+ lused = nr;
+ }
+ if (cp)
+ *cp = lbuf[lind++];
+ return 1;
+}
+
+void
+zreset ()
+{
+ lind = lused = 0;
+}
+
+/* Sync the seek pointer for FD so that the kernel's idea of the last char
+ read is the last char returned by zreadc. */
+void
+zsyncfd (fd)
+ int fd;
+{
+ off_t off, r;
+
+ off = lused - lind;
+ r = 0;
+ if (off > 0)
+ r = lseek (fd, -off, SEEK_CUR);
+
+ if (r >= 0)
+ lused = lind = 0;
+}
2004,2005,2006,2007,2008,2009,2010,2011
Free Software Foundation, Inc.
+See the file COPYING in the bash distribution root directory for copying
+and usage restrictions.
+
The file ifs-posix.tests is Copyright (C) 2005 Glen Fowler.
-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
--- /dev/null
+BUILD_DIR=/usr/local/build/chet/bash/bash-current
+THIS_SH=$BUILD_DIR/bash
+PATH=$PATH:$BUILD_DIR
+
+export THIS_SH PATH
+
+rm -f /tmp/xx
+
+/bin/sh "$@"