From: Chet Ramey Date: Sat, 3 Dec 2011 17:53:44 +0000 (-0500) Subject: commit bash-20040121 snapshot X-Git-Tag: bash-3.0-beta~5 X-Git-Url: http://git.ipfire.org/?a=commitdiff_plain;h=12d937f9afd58569e8f0c714df6326f68bcda237;p=thirdparty%2Fbash.git commit bash-20040121 snapshot --- diff --git a/CHANGES b/CHANGES index 673b76570..986a30074 100644 --- a/CHANGES +++ b/CHANGES @@ -1,5 +1,5 @@ -This document details the changes between this version, bash-3.0-alpha, -and the previous version, bash-2.05b-release. +This document details the changes between this version, bash-3.0-beta1, +and the previous version, bash-3.0-alpha. 1. Changes to Bash @@ -62,6 +62,19 @@ r. Fixes to the pattern removal and pattern replacement expansions to deal s. Fix to the substring expansion (${param:off[:len]}) to deal with (possibly multibyte) characters instead of raw bytes. +t. Fixed a bug that caused some key bindings set in an inputrc to be ignored + at shell startup. + +u. Fixed a bug that caused unsetting a local variable within a function to + not work correctly. + +v. Fixed a bug that caused invalid variables to be created when using + `read -a'. + +w. Fixed a bug that caused "$@" to expand incorrectly when used as the right + hand side of a parameter expansion such as ${word:="$@"} if the first + character of $IFS was not a space. + 2. Changes to Readline a. Change to history expansion functions to treat `^' as equivalent to word @@ -97,6 +110,12 @@ b. `echo -e' understands two new escape sequences: \" and \?. c. The GNU `gettext' package and libintl have been integrated; the shell's messages can be translated into different languages. +d. The `\W' prompt expansion now abbreviates $HOME as `~', like `\w'. + +e. The error message printed when bash cannot open a shell script supplied + as argument 1 now includes the name of the shell, to better identify + the error as coming from bash. + 4. New Features in Readline a. New application variable, rl_completion_quote_character, set to any diff --git a/CHANGES~ b/CHANGES~ index 0c4b8aeec..acc4cec23 100644 --- a/CHANGES~ +++ b/CHANGES~ @@ -1,5 +1,5 @@ -This document details the changes between this version, bash-3.0-alpha, -and the previous version, bash-2.05b-release. +This document details the changes between this version, bash-3.0-beta1, +and the previous version, bash-3.0-alpha. 1. Changes to Bash @@ -62,6 +62,19 @@ r. Fixes to the pattern removal and pattern replacement expansions to deal s. Fix to the substring expansion (${param:off[:len]}) to deal with (possibly multibyte) characters instead of raw bytes. +t. Fixed a bug that caused some key bindings set in an inputrc to be ignored + at shell startup. + +u. Fixed a bug that caused unsetting a local variable within a function to + not work correctly. + +v. Fixed a bug that caused invalid variables to be created when using + `read -a'. + +w. Fixed a bug that caused "$@" to expand incorrectly when used as the right + hand side of a parameter expansion such as ${word:="$@"} if the first + character of $IFS was not a space. + 2. Changes to Readline a. Change to history expansion functions to treat `^' as equivalent to word @@ -83,6 +96,11 @@ e. Fixed a bug that could cause incorrect filename quoting when f. Fixed a bug in redisplay triggered when the prompt string contains invisible characters. +g. Fixed some display (and other) bugs encountered in multibyte locales + when a non-ascii character was the last character on a line. + +h. Fixed some display bugs caused by multibyte characters in prompt strings. + 3. New Features in Bash a. printf builtin understands two new escape sequences: \" and \?. @@ -92,6 +110,8 @@ b. `echo -e' understands two new escape sequences: \" and \?. c. The GNU `gettext' package and libintl have been integrated; the shell's messages can be translated into different languages. +d. The `\W' prompt expansion now abbreviates $HOME as `~', like `\w'. + 4. New Features in Readline a. New application variable, rl_completion_quote_character, set to any diff --git a/CWRU/CWRU.chlog b/CWRU/CWRU.chlog index fb44ae1a6..a7e42b6d5 100644 --- a/CWRU/CWRU.chlog +++ b/CWRU/CWRU.chlog @@ -8994,3 +8994,82 @@ lib/readline/mbutil.c back past it with ^B, and other display problems caused by the same situation + 1/15 + ---- +lib/readline/doc/rltech.texi + - document RL_PROMPT_START_IGNORE and RL_PROMPT_END_IGNORE in the + description of rl_expand_prompt() + + 1/20 + ---- +bashline.c + - in initialize_readline, make sure M-C-j and M-C-m are still bound to + vi-editing-mode before unbinding them -- they may have been rebound + in an inputrc + +variables.c + - in unbind_variable, unset attributes other than `local' and exported + (if the variable came from a temporary environment) when unsetting a + local variable inside a function + + 1/21 + ---- +configure.in + - add libintl build directory to the list of include directories if + it's being built (using INTL_BUILDDIR) + +Makefile.in,{builtins,lib/{sh,malloc}}/Makefile.in + - substitute LIBBUILD as ${BUILD_DIR}/${LIBSUBDIR} + - define INTL_BUILDDIR as ${LIBBUILD}/intl + +{builtins,lib/sh}/Makefile.in + - make sure INTL_INC is added to the list of include directories + - make sure INTL_LIBSRC is defined with the correct value + +{configure,Makefile,{builtins,lib/sh}/Makefile}.in + - substitute LIBINTL_H as ${INTL_BUILDDIR}/libintl.h + +Makefile.in,builtins/Makefile.iin + - all files depending on bashintl.h also depend on ${LIBINTL_H} + (which may be empty) + +Makefile.in + - make a rule telling how to build lib/intl/libintl.h if necessary + + 1/24 + ---- +builtins/read.def + - make sure that the array name supplied as an argument to -a is a + valid identifier + +parse.y + - make the \W expansion abbreviate $HOME with a ~ (seems to be more + useful) + +doc/{bash.1,bashref.texi} + - document new behavior of \W + +subst.c + - make sure parameter_brace_expand_rhs uses the first character of + $IFS when making the string to return from the expanded word + (which, in the case of "$@" or $@, contains multiple words that + need to be separated) + + 1/25 + ---- +builtins/common.c + - change get_job_spec to make `%' by itself or an empty argument + return NO_JOB + +jobs.h + - new possible value for a job spec return value: BAD_JOBSPEC + (for syntactically invalid specs, like the empty string) + +shell.c + - in open_shell_script, check to see whether or not we can find and + open the filename argument before setting dollar_vars[0] or + manipulating BASH_SOURCE, so the error messages come out better + +subst.c + - in string_list_internal, short-circuit right away to savestring() + if the list only has a single element diff --git a/CWRU/CWRU.chlog~ b/CWRU/CWRU.chlog~ index 04caa29f5..e11323c80 100644 --- a/CWRU/CWRU.chlog~ +++ b/CWRU/CWRU.chlog~ @@ -8955,10 +8955,117 @@ subst.c - new static function, mb_getcharlens, allocates and returns an array of character lengths for (possibly multibyte) characters in the argument string - - change pattern matching operations to use while loops instead of for - loops to handle multibyte characters better (no more simple increment - or decrement); use multibyte character operations instead of simple - increments and decrements. Don't use BACKUP_CHAR_P -- use the - mblen array instead, because that avoids the N**2 behavior of having - to count from the beginning of the string each time you want to - back up one character. Changes to remove_pattern and match_pattern + - change pattern matching operations to use while loops instead of + for loops to handle multibyte characters better (no more simple + increment or decrement) + - change pattern matching operations to use multibyte character + operations instead of simple increments and decrements. Don't + use BACKUP_CHAR_P -- use the mblen array instead, because that + avoids the N**2 behavior of having to count from the beginning + of the string each time you want to back up one character. Changes + to remove_pattern and match_pattern + + 1/12 + ---- +lib/readline/display.c + - make expand_prompt count multbyte characters in the prompt string + by using _rl_find_next_mbchar (and copying possibly more than one + byte) instead of a simple increment and single byte copy + + 1/13 + ---- +lib/readline/display.c + - expand_prompt takes a new reference argument -- it returns + the actual count of (possibly multibyte) characters displayed + on the screen + - don't short-circuit in expand_prompt unless we're not going to + be using any multibyte characters + - change calls to expand_prompt to pass an argument for the + number of physical characters the prompt occupies + (prompt_physical_chars) + - initialize `lpos' (the physical cursor position) from + prompt_physical_chars in rl_redisplay + +lib/readline/mbutil.c + - in _rl_find_prev_mbchar_internal, if mbrtowc returns -1 or -2, and + we assume that the character is a single-byte char, make sure we + update `prev' so it doesn't get lost. Fixes problems encountered + when a non-ascii char is the last char on the line and we're moving + back past it with ^B, and other display problems caused by the same + situation + + 1/15 + ---- +lib/readline/doc/rltech.texi + - document RL_PROMPT_START_IGNORE and RL_PROMPT_END_IGNORE in the + description of rl_expand_prompt() + + 1/20 + ---- +bashline.c + - in initialize_readline, make sure M-C-j and M-C-m are still bound to + vi-editing-mode before unbinding them -- they may have been rebound + in an inputrc + +variables.c + - in unbind_variable, unset attributes other than `local' and exported + (if the variable came from a temporary environment) when unsetting a + local variable inside a function + + 1/21 + ---- +configure.in + - add libintl build directory to the list of include directories if + it's being built (using INTL_BUILDDIR) + +Makefile.in,{builtins,lib/{sh,malloc}}/Makefile.in + - substitute LIBBUILD as ${BUILD_DIR}/${LIBSUBDIR} + - define INTL_BUILDDIR as ${LIBBUILD}/intl + +{builtins,lib/sh}/Makefile.in + - make sure INTL_INC is added to the list of include directories + - make sure INTL_LIBSRC is defined with the correct value + +{configure,Makefile,{builtins,lib/sh}/Makefile}.in + - substitute LIBINTL_H as ${INTL_BUILDDIR}/libintl.h + +Makefile.in,builtins/Makefile.iin + - all files depending on bashintl.h also depend on ${LIBINTL_H} + (which may be empty) + +Makefile.in + - make a rule telling how to build lib/intl/libintl.h if necessary + + 1/24 + ---- +builtins/read.def + - make sure that the array name supplied as an argument to -a is a + valid identifier + +parse.y + - make the \W expansion abbreviate $HOME with a ~ (seems to be more + useful) + +doc/{bash.1,bashref.texi} + - document new behavior of \W + +subst.c + - make sure parameter_brace_expand_rhs uses the first character of + $IFS when making the string to return from the expanded word + (which, in the case of "$@" or $@, contains multiple words that + need to be separated) + + 1/25 + ---- +builtins/common.c + - change get_job_spec to make `%' by itself or an empty argument + return NO_JOB + +jobs.h + - new possible value for a job spec return value: BAD_JOBSPEC + (for syntactically invalid specs, like the empty string) + +shell.c + - in open_shell_script, check to see whether or not we can find and + open the filename argument before setting dollar_vars[0] or + manipulating BASH_SOURCE, so the error messages come out better diff --git a/MANIFEST b/MANIFEST index 6dff94fd9..fd70fd460 100644 --- a/MANIFEST +++ b/MANIFEST @@ -707,6 +707,7 @@ tests/dbg-support.tests f tests/dbg-support2.right f tests/dbg-support2.tests f tests/dollar-at-star f +tests/dollar-at1.sub f tests/dollar-star1.sub f tests/dollar.right f tests/dstack.tests f diff --git a/MANIFEST~ b/MANIFEST~ new file mode 100644 index 000000000..6dff94fd9 --- /dev/null +++ b/MANIFEST~ @@ -0,0 +1,955 @@ +# +# Master distribution manifest for bash +# +# +# Filename type +# +CWRU d +CWRU/misc d +builtins d +cross-build d +doc d +examples d +examples/bashdb d +examples/obashdb d +examples/complete d +examples/functions d +examples/scripts d +examples/scripts.v2 d +examples/scripts.noah d +examples/startup-files d +examples/startup-files/apple d +examples/misc d +examples/loadables d +examples/loadables/perl d +include d +lib d +lib/glob d +lib/glob/doc d +lib/intl d +lib/malloc d +lib/readline d +lib/readline/doc d +lib/readline/examples d +lib/sh d +lib/termcap d +lib/termcap/grot d +lib/tilde d +lib/tilde/doc d +po d +support d +tests d +tests/misc d +ABOUT-NLS f +CHANGES f +COMPAT f +COPYING f +INSTALL f +MANIFEST f +NEWS f +NOTES f +POSIX f +README f +RBASH f +AUTHORS f +Y2K f +configure.in f +configure f +Makefile.in f +config-top.h f +config-bot.h f +config.h.in f +aclocal.m4 f +array.c f +arrayfunc.c f +eval.c f +print_cmd.c f +general.c f +list.c f +locale.c f +stringlib.c f +variables.c f +make_cmd.c f +copy_cmd.c f +unwind_prot.c f +dispose_cmd.c f +bashhist.c f +hashcmd.c f +hashlib.c f +parse.y f +pathexp.c f +subst.c f +shell.c f +trap.c f +sig.c f +siglist.c f +version.c f +flags.c f +jobs.c f +input.c f +mailcheck.c f +test.c f +expr.c f +alias.c f +execute_cmd.c f +findcmd.c f +redir.c f +bashline.c f +braces.c f +bracecomp.c f +nojobs.c f +error.c f +xmalloc.c f +pcomplete.c f +pcomplib.c f +mksyntax.c f +alias.h f +builtins.h f +bashhist.h f +bashline.h f +conftypes.h f +patchlevel.h f +variables.h f +array.h f +arrayfunc.h f +jobs.h f +findcmd.h f +hashlib.h f +quit.h f +flags.h f +shell.h f +syntax.h f +pathexp.h f +parser.h f +pcomplete.h f +sig.h f +test.h f +trap.h f +general.h f +unwind_prot.h f +input.h f +error.h f +command.h f +externs.h f +siglist.h f +subst.h f +dispose_cmd.h f +hashcmd.h f +bashansi.h f +bashjmp.h f +bashintl.h f +make_cmd.h f +execute_cmd.h f +redir.h f +bashtypes.h f +mailcheck.h f +xmalloc.h f +y.tab.c f +y.tab.h f +parser-built f +pathnames.h.in f +builtins/Makefile.in f +builtins/alias.def f +builtins/bind.def f +builtins/break.def f +builtins/builtin.def f +builtins/caller.def f +builtins/cd.def f +builtins/colon.def f +builtins/command.def f +builtins/complete.def f +builtins/common.c f +builtins/declare.def f +builtins/echo.def f +builtins/enable.def f +builtins/eval.def f +builtins/evalfile.c f +builtins/evalstring.c f +builtins/exec.def f +builtins/exit.def f +builtins/fc.def f +builtins/fg_bg.def f +builtins/getopt.c f +builtins/getopt.h f +builtins/getopts.def f +builtins/hash.def f +builtins/help.def f +builtins/let.def f +builtins/history.def f +builtins/jobs.def f +builtins/kill.def f +builtins/mkbuiltins.c f +builtins/printf.def f +builtins/pushd.def f +builtins/read.def f +builtins/reserved.def f +builtins/return.def f +builtins/set.def f +builtins/setattr.def f +builtins/shift.def f +builtins/shopt.def f +builtins/source.def f +builtins/suspend.def f +builtins/test.def f +builtins/times.def f +builtins/trap.def f +builtins/type.def f +builtins/ulimit.def f +builtins/umask.def f +builtins/wait.def f +builtins/psize.c f +builtins/psize.sh f +builtins/inlib.def f +builtins/bashgetopt.c f +builtins/common.h f +builtins/bashgetopt.h f +cross-build/cygwin32.cache f +cross-build/win32sig.h f +cross-build/x86-beos.cache f +cross-build/beos-sig.h f +cross-build/opennt.cache f +include/ansi_stdlib.h f +include/chartypes.h f +include/filecntl.h f +include/gettext.h f +include/maxpath.h f +include/memalloc.h f +include/ocache.h f +include/posixdir.h f +include/posixjmp.h f +include/posixstat.h f +include/posixtime.h f +include/posixwait.h f +include/shmbutil.h f +include/shtty.h f +include/stdc.h f +include/systimes.h f +include/typemax.h f +include/unionwait.h f +lib/glob/Makefile.in f +lib/glob/sm_loop.c f +lib/glob/smatch.c f +lib/glob/strmatch.c f +lib/glob/strmatch.h f +lib/glob/glob.c f +lib/glob/glob.h f +lib/glob/glob_loop.c f +lib/glob/xmbsrtowcs.c f +lib/glob/collsyms.h f +lib/glob/doc/Makefile f +lib/glob/doc/glob.texi f +lib/glob/ndir.h f +lib/intl/ChangeLog f +lib/intl/Makefile.in f +lib/intl/VERSION f +lib/intl/bindtextdom.c f +lib/intl/config.charset f +lib/intl/dcgettext.c f +lib/intl/dcigettext.c f +lib/intl/dcngettext.c f +lib/intl/dgettext.c f +lib/intl/dngettext.c f +lib/intl/eval-plural.h f +lib/intl/explodename.c f +lib/intl/finddomain.c f +lib/intl/gettext.c f +lib/intl/gettextP.h f +lib/intl/gmo.h f +lib/intl/hash-string.h f +lib/intl/intl-compat.c f +lib/intl/l10nflist.c f +lib/intl/libgnuintl.h.in f +lib/intl/loadinfo.h f +lib/intl/loadmsgcat.c f +lib/intl/localcharset.c f +lib/intl/localcharset.h f +lib/intl/locale.alias f +lib/intl/localealias.c f +lib/intl/localename.c f +lib/intl/log.c f +lib/intl/ngettext.c f +lib/intl/os2compat.c f +lib/intl/os2compat.h f +lib/intl/osdep.c f +lib/intl/plural-exp.c f +lib/intl/plural-exp.h f +lib/intl/plural.c f +lib/intl/plural.y f +lib/intl/ref-add.sin f +lib/intl/ref-del.sin f +lib/intl/relocatable.c f +lib/intl/relocatable.h f +lib/intl/textdomain.c f +lib/malloc/Makefile.in f +lib/malloc/getpagesize.h f +lib/malloc/imalloc.h f +lib/malloc/mstats.h f +lib/malloc/shmalloc.h f +lib/malloc/table.h f +lib/malloc/watch.h f +lib/malloc/alloca.c f +lib/malloc/malloc.c f +lib/malloc/stats.c f +lib/malloc/table.c f +lib/malloc/trace.c f +lib/malloc/watch.c f +lib/malloc/xmalloc.c f +lib/malloc/xleaktrace f 755 +lib/malloc/stub.c f +lib/malloc/i386-alloca.s f +lib/malloc/x386-alloca.s f +lib/readline/COPYING f +lib/readline/Makefile.in f +lib/readline/ChangeLog f +lib/readline/README f +lib/readline/STANDALONE f +lib/readline/readline.c f +lib/readline/vi_mode.c f +lib/readline/emacs_keymap.c f +lib/readline/vi_keymap.c f +lib/readline/history.c f +lib/readline/histexpand.c f +lib/readline/histsearch.c f +lib/readline/histfile.c f +lib/readline/funmap.c f +lib/readline/keymaps.c f +lib/readline/util.c f +lib/readline/terminal.c f +lib/readline/xmalloc.c f +lib/readline/search.c f +lib/readline/isearch.c f +lib/readline/parens.c f +lib/readline/rltty.c f +lib/readline/compat.c f +lib/readline/complete.c f +lib/readline/bind.c f +lib/readline/display.c f +lib/readline/signals.c f +lib/readline/kill.c f +lib/readline/text.c f +lib/readline/undo.c f +lib/readline/macro.c f +lib/readline/input.c f +lib/readline/callback.c f +lib/readline/mbutil.c f +lib/readline/misc.c f +lib/readline/nls.c f +lib/readline/shell.c f +lib/readline/savestring.c f +lib/readline/tilde.c f +lib/readline/tilde.h f +lib/readline/rldefs.h f +lib/readline/rlconf.h f +lib/readline/rlmbutil.h f +lib/readline/rlshell.h f +lib/readline/rltty.h f +lib/readline/rltypedefs.h f +lib/readline/rlwinsize.h f +lib/readline/readline.h f +lib/readline/tcap.h f +lib/readline/keymaps.h f +lib/readline/history.h f +lib/readline/histlib.h f +lib/readline/chardefs.h f +lib/readline/posixdir.h f +lib/readline/posixjmp.h f +lib/readline/posixstat.h f +lib/readline/ansi_stdlib.h f +lib/readline/rlstdc.h f +lib/readline/rlprivate.h f +lib/readline/xmalloc.h f +lib/readline/doc/Makefile f +lib/readline/doc/version.texi f +lib/readline/doc/rlman.texi f +lib/readline/doc/rltech.texi f +lib/readline/doc/rluser.texi f +lib/readline/doc/rluserman.texi f +lib/readline/doc/history.texi f +lib/readline/doc/hstech.texi f +lib/readline/doc/hsuser.texi f +lib/readline/doc/fdl.texi f +lib/readline/examples/Makefile f +lib/readline/examples/excallback.c f +lib/readline/examples/fileman.c f +lib/readline/examples/manexamp.c f +lib/readline/examples/histexamp.c f +lib/readline/examples/rltest.c f +lib/readline/examples/rl.c f +lib/readline/examples/rlcat.c f +lib/readline/examples/Inputrc f +lib/sh/Makefile.in f +lib/sh/clktck.c f +lib/sh/clock.c f +lib/sh/fmtullong.c f +lib/sh/fmtulong.c f +lib/sh/fmtumax.c f +lib/sh/getcwd.c f +lib/sh/getenv.c f +lib/sh/inet_aton.c f +lib/sh/itos.c f +lib/sh/mailstat.c f +lib/sh/makepath.c f +lib/sh/memset.c f +lib/sh/mktime.c f +lib/sh/netconn.c f +lib/sh/netopen.c f +lib/sh/oslib.c f +lib/sh/pathcanon.c f +lib/sh/pathphys.c f +lib/sh/rename.c f +lib/sh/setlinebuf.c f +lib/sh/shmatch.c f +lib/sh/shquote.c f +lib/sh/shtty.c f +lib/sh/snprintf.c f +lib/sh/spell.c f +lib/sh/strcasecmp.c f +lib/sh/strerror.c f +lib/sh/strftime.c f +lib/sh/strindex.c f +lib/sh/stringlist.c f +lib/sh/stringvec.c f +lib/sh/strpbrk.c f +lib/sh/strstr.c f +lib/sh/strtod.c f +lib/sh/strtoimax.c f +lib/sh/strtol.c f +lib/sh/strtoll.c f +lib/sh/strtoul.c f +lib/sh/strtoull.c f +lib/sh/strtoumax.c f +lib/sh/strtrans.c f +lib/sh/times.c f +lib/sh/timeval.c f +lib/sh/tmpfile.c f +lib/sh/vprint.c f +lib/sh/xstrchr.c f +lib/sh/zcatfd.c f +lib/sh/zread.c f +lib/sh/zwrite.c f +lib/termcap/Makefile.in f +lib/termcap/ltcap.h f +lib/termcap/termcap.c f +lib/termcap/termcap.h f +lib/termcap/tparam.c f +lib/termcap/version.c f +lib/termcap/grot/termcap.info f +lib/termcap/grot/termcap.info-1 f +lib/termcap/grot/termcap.info-2 f +lib/termcap/grot/termcap.info-3 f +lib/termcap/grot/termcap.info-4 f +lib/termcap/grot/NEWS f +lib/termcap/grot/INSTALL f +lib/termcap/grot/ChangeLog f +lib/termcap/grot/texinfo.tex f +lib/termcap/grot/termcap.texi f +lib/termcap/grot/Makefile.in f +lib/termcap/grot/configure f +lib/termcap/grot/configure.in f +lib/termcap/grot/COPYING f +lib/termcap/grot/README f +lib/tilde/README f +lib/tilde/Makefile.in f +lib/tilde/doc/tilde.texi f +lib/tilde/doc/Makefile f +lib/tilde/tilde.c f +lib/tilde/tilde.h f +lib/tilde/shell.c f +po/LINGUAS f +po/Makefile.in.in f +po/Makevars f +po/POTFILES.in f +po/Rules-builtins f +po/Rules-quot f +po/bash.pot f +po/boldquot.sed f +po/builtins.pot f +po/en@quot.header f +po/en@boldquot.header f +po/en@quot.po f +po/en@boldquot.po f +po/en@quot.gmo f +po/en@boldquot.gmo f +po/insert-header.sin f +po/quot.sed f +po/remove-potcdate.sin f +CWRU/misc/open-files.c f +CWRU/misc/sigs.c f +CWRU/misc/sigstat.c f +CWRU/misc/bison f +CWRU/misc/errlist.c f +CWRU/misc/hpux10-dlfcn.h f +CWRU/PLATFORMS f +CWRU/README f +CWRU/changelog f +CWRU/sh-redir-hack f +CWRU/mh-folder-comp f +doc/FAQ f +doc/Makefile.in f +doc/bash.1 f +doc/bashbug.1 f +doc/builtins.1 f +doc/rbash.1 f +doc/README f +doc/INTRO f +doc/texinfo.tex f +doc/bashref.texi f +doc/version.texi f +doc/bashref.info f +doc/article.ms f +doc/htmlpost.sh f 755 +doc/infopost.sh f 755 +doc/fdl.texi f +doc/fdl.txt f +support/Makefile.in f +support/bashversion.c f +support/config.guess f +support/config.rpath f 755 +support/config.sub f +support/printenv.sh f 755 +support/printenv.c f +support/bash.xbm f +support/missing f 755 +support/mkclone f 755 +support/mkconffiles f 755 +support/mkdirs f 755 +support/mkinstalldirs f 755 +support/mkversion.sh f 755 +support/mksignames.c f +support/bashbug.sh f +support/man2html.c f +support/recho.c f +support/zecho.c f +support/SYMLINKS f +support/fixlinks f 755 +support/install.sh f 755 +support/texi2dvi f 755 +support/texi2html f 755 +support/xenix-link.sh f 755 +support/shobj-conf f 755 +support/rlvers.sh f 755 +examples/bashdb/PERMISSION f +examples/bashdb/bashdb f +examples/bashdb/bashdb.el f +examples/obashdb/PERMISSION f +examples/obashdb/README f +examples/obashdb/bashdb f +examples/obashdb/bashdb.fns f +examples/obashdb/bashdb.pre f +examples/complete/complete-examples f +examples/complete/complete.ianmac f +examples/complete/complete2.ianmac f +examples/complete/complete.freebsd f +examples/complete/complete.gnu-longopt f +examples/complete/bashcc-1.0.1.tar.gz f +examples/loadables/README f +examples/loadables/template.c f +examples/loadables/Makefile.in f +examples/loadables/necho.c f +examples/loadables/hello.c f +examples/loadables/print.c f +examples/loadables/realpath.c f +examples/loadables/sleep.c f +examples/loadables/strftime.c f +examples/loadables/truefalse.c f +examples/loadables/getconf.h f +examples/loadables/getconf.c f +examples/loadables/finfo.c f +examples/loadables/cat.c f +examples/loadables/cut.c f +examples/loadables/logname.c f +examples/loadables/basename.c f +examples/loadables/dirname.c f +examples/loadables/tty.c f +examples/loadables/pathchk.c f +examples/loadables/tee.c f +examples/loadables/rmdir.c f +examples/loadables/head.c f +examples/loadables/printenv.c f +examples/loadables/push.c f +examples/loadables/id.c f +examples/loadables/whoami.c f +examples/loadables/uname.c f +examples/loadables/sync.c f +examples/loadables/mkdir.c f +examples/loadables/ln.c f +examples/loadables/unlink.c f +examples/loadables/perl/Makefile.in f +examples/loadables/perl/README f +examples/loadables/perl/bperl.c f +examples/loadables/perl/iperl.c f +examples/functions/array-stuff f +examples/functions/array-to-string f +examples/functions/autoload f +examples/functions/autoload.v2 f +examples/functions/autoload.v3 f +examples/functions/basename f +examples/functions/basename2 f +examples/functions/coproc.bash f +examples/functions/coshell.README f +examples/functions/coshell.bash f +examples/functions/csh-compat f +examples/functions/dirfuncs f +examples/functions/dirname f +examples/functions/emptydir f +examples/functions/exitstat f +examples/functions/external f +examples/functions/fact f +examples/functions/fstty f +examples/functions/func f +examples/functions/gethtml f +examples/functions/getoptx.bash f +examples/functions/inetaddr f +examples/functions/inpath f +examples/functions/isnum.bash f +examples/functions/isnum2 f +examples/functions/isvalidip f +examples/functions/jdate.bash f +examples/functions/jj.bash f +examples/functions/keep f +examples/functions/ksh-cd f +examples/functions/ksh-compat-test f +examples/functions/kshenv f +examples/functions/login f +examples/functions/lowercase f +examples/functions/manpage f +examples/functions/mhfold f +examples/functions/notify.bash f +examples/functions/pathfuncs f +examples/functions/recurse f +examples/functions/repeat2 f +examples/functions/repeat3 f +examples/functions/seq f +examples/functions/seq2 f +examples/functions/shcat f +examples/functions/shcat2 f +examples/functions/sort-pos-params f +examples/functions/substr f +examples/functions/substr2 f +examples/functions/term f +examples/functions/whatis f +examples/functions/whence f +examples/functions/which f +examples/functions/xalias.bash f +examples/functions/xfind.bash f +examples/scripts/adventure.sh f +examples/scripts/bcsh.sh f +examples/scripts/cat.sh f +examples/scripts/center f +examples/scripts/dd-ex.sh f +examples/scripts/fixfiles.bash f +examples/scripts/hanoi.bash f +examples/scripts/inpath f +examples/scripts/krand.bash f +examples/scripts/line-input.bash f +examples/scripts/nohup.bash f +examples/scripts/precedence f +examples/scripts/randomcard.bash f +examples/scripts/scrollbar f +examples/scripts/scrollbar2 f +examples/scripts/self-repro f +examples/scripts/showperm.bash f +examples/scripts/shprompt f +examples/scripts/spin.bash f +examples/scripts/timeout f +examples/scripts/vtree2 f +examples/scripts/vtree3 f +examples/scripts/vtree3a f +examples/scripts/websrv.sh f +examples/scripts/xterm_title f +examples/scripts/zprintf f +examples/startup-files/README f +examples/startup-files/Bashrc.bfox f +examples/startup-files/Bash_aliases f +examples/startup-files/Bash_profile f +examples/startup-files/bash-profile f +examples/startup-files/bashrc f +examples/startup-files/apple/README f +examples/startup-files/apple/aliases f +examples/startup-files/apple/bash.defaults f +examples/startup-files/apple/environment f +examples/startup-files/apple/login f +examples/startup-files/apple/logout f +examples/startup-files/apple/rc f +examples/misc/suncmd.termcap f +examples/misc/aliasconv.sh f +examples/misc/aliasconv.bash f +examples/misc/cshtobash f +tests/README f +tests/alias.tests f +tests/alias.right f +tests/arith-for.tests f +tests/arith-for.right f +tests/arith.tests f +tests/arith.right f +tests/array.tests f +tests/array.right f +tests/array-at-star f +tests/array2.right f +tests/braces.tests f +tests/braces.right f +tests/builtins.tests f +tests/builtins.right f +tests/builtins1.sub f +tests/builtins2.sub f +tests/source1.sub f +tests/source2.sub f +tests/source3.sub f +tests/source4.sub f +tests/source5.sub f +tests/cond.tests f +tests/cond.right f +tests/cprint.tests f +tests/cprint.right f +tests/dbg-support.right f +tests/dbg-support.sub f +tests/dbg-support.tests f +tests/dbg-support2.right f +tests/dbg-support2.tests f +tests/dollar-at-star f +tests/dollar-star1.sub f +tests/dollar.right f +tests/dstack.tests f +tests/dstack.right f +tests/dstack2.tests f +tests/dstack2.right f +tests/errors.tests f +tests/errors.right f +tests/execscript f +tests/exec.right f +tests/exec1.sub f 755 +tests/exec2.sub f +tests/exec3.sub f +tests/exec4.sub f +tests/exec5.sub f +tests/exec6.sub f +tests/exec7.sub f +tests/exp-tests f +tests/exp.right f +tests/extglob.tests f +tests/extglob.right f +tests/extglob2.tests f +tests/extglob2.right f +tests/func.tests f +tests/func.right f +tests/func1.sub f +tests/func2.sub f +tests/func3.sub f +tests/getopts.tests f +tests/getopts.right f +tests/getopts1.sub f +tests/getopts2.sub f +tests/getopts3.sub f +tests/getopts4.sub f +tests/getopts5.sub f +tests/getopts6.sub f +tests/getopts7.sub f +tests/glob-test f +tests/glob1.sub f +tests/glob.right f +tests/heredoc.tests f +tests/heredoc.right f +tests/herestr.tests f +tests/herestr.right f +tests/histexp.tests f +tests/histexp.right f +tests/history.tests f +tests/history.right f +tests/history.list f +tests/ifs.tests f +tests/ifs.right f +tests/input-line.sh f +tests/input-line.sub f +tests/input.right f +tests/invert.tests f +tests/invert.right f +tests/jobs.tests f +tests/jobs1.sub f +tests/jobs2.sub f +tests/jobs3.sub f +tests/jobs.right f +tests/more-exp.tests f +tests/more-exp.right f +tests/new-exp.tests f +tests/new-exp1.sub f +tests/new-exp2.sub f +tests/new-exp3.sub f +tests/new-exp4.sub f +tests/new-exp.right f +tests/nquote.tests f +tests/nquote.right f +tests/nquote1.tests f +tests/nquote1.right f +tests/nquote2.tests f +tests/nquote2.right f +tests/nquote3.tests f +tests/nquote3.right f +tests/nquote4.tests f +tests/nquote4.right f +tests/posix2.tests f +tests/posix2.right f +tests/posixpat.tests f +tests/posixpat.right f +tests/prec.right f +tests/precedence f +tests/printf.tests f +tests/printf.right f +tests/quote.tests f +tests/quote.right f +tests/read.tests f +tests/read.right f +tests/read1.sub f +tests/read2.sub f +tests/read3.sub f +tests/read4.sub f +tests/redir.tests f +tests/redir.right f +tests/redir1.sub f +tests/redir2.sub f +tests/redir3.sub f +tests/redir3.in1 f +tests/redir3.in2 f +tests/redir4.sub f +tests/redir4.in1 f +tests/redir5.sub f +tests/redir6.sub f +tests/rhs-exp.tests f +tests/rhs-exp.right f +tests/rsh.tests f +tests/rsh.right f +tests/run-all f +tests/run-minimal f +tests/run-alias f +tests/run-arith-for f +tests/run-arith f +tests/run-array f +tests/run-array2 f +tests/run-braces f +tests/run-builtins f +tests/run-cond f +tests/run-cprint f +tests/run-dbg-support f +tests/run-dbg-support2 f +tests/run-dirstack f +tests/run-dollars f +tests/run-errors f +tests/run-execscript f +tests/run-exp-tests f +tests/run-extglob f +tests/run-extglob2 f +tests/run-func f +tests/run-getopts f +tests/run-glob-test f +tests/run-heredoc f +tests/run-herestr f +tests/run-histexpand f +tests/run-history f +tests/run-ifs f +tests/run-input-test f +tests/run-invert f +tests/run-jobs f +tests/run-more-exp f +tests/run-new-exp f +tests/run-nquote f +tests/run-nquote1 f +tests/run-nquote2 f +tests/run-nquote3 f +tests/run-nquote4 f +tests/run-posix2 f +tests/run-posixpat f +tests/run-precedence f +tests/run-printf f +tests/run-quote f +tests/run-read f +tests/run-redir f +tests/run-rhs-exp f +tests/run-rsh f +tests/run-set-e f +tests/run-set-x f +tests/run-shopt f +tests/run-strip f +tests/run-test f +tests/run-tilde f +tests/run-trap f +tests/run-type f +tests/run-varenv f +tests/set-e-test f +tests/set-e.right f +tests/set-x.tests f +tests/set-x.right f +tests/shopt.tests f +tests/shopt.right f +tests/strip.tests f +tests/strip.right f +tests/test.tests f +tests/test.right f +tests/tilde-tests f +tests/tilde.right f +tests/trap.tests f +tests/trap.right f +tests/trap1.sub f 755 +tests/trap2.sub f 755 +tests/trap2a.sub f 755 +tests/type.tests f +tests/type.right f +tests/varenv.right f +tests/varenv.sh f +tests/varenv1.sub f +tests/varenv2.sub f +tests/version f +tests/version.mini f +tests/misc/dev-tcp.tests f +tests/misc/perf-script f +tests/misc/perftest f +tests/misc/read-nchars.tests f +tests/misc/redir-t2.sh f +tests/misc/run-r2.sh f +tests/misc/sigint-1.sh f +tests/misc/sigint-2.sh f +tests/misc/sigint-3.sh f +tests/misc/sigint-4.sh f +tests/misc/test-minus-e.1 f +tests/misc/test-minus-e.2 f +tests/misc/wait-bg.tests f +examples/scripts.v2/PERMISSION f +examples/scripts.v2/README f +examples/scripts.v2/arc2tarz f +examples/scripts.v2/bashrand f +examples/scripts.v2/cal2day.bash f +examples/scripts.v2/cdhist.bash f +examples/scripts.v2/corename f +examples/scripts.v2/fman f +examples/scripts.v2/frcp f +examples/scripts.v2/lowercase f +examples/scripts.v2/ncp f +examples/scripts.v2/newext f +examples/scripts.v2/nmv f +examples/scripts.v2/pages f +examples/scripts.v2/pf f +examples/scripts.v2/ren f +examples/scripts.v2/rename f +examples/scripts.v2/repeat f +examples/scripts.v2/untar f +examples/scripts.v2/uudec f +examples/scripts.v2/uuenc f +examples/scripts.v2/vtree f +examples/scripts.v2/where f +examples/scripts.v2/pmtop f +examples/scripts.v2/shprof f +examples/scripts.noah/PERMISSION f +examples/scripts.noah/README f +examples/scripts.noah/aref.bash f +examples/scripts.noah/bash.sub.bash f +examples/scripts.noah/bash_version.bash f +examples/scripts.noah/meta.bash f +examples/scripts.noah/mktmp.bash f +examples/scripts.noah/number.bash f +examples/scripts.noah/prompt.bash f +examples/scripts.noah/remap_keys.bash f +examples/scripts.noah/require.bash f +examples/scripts.noah/send_mail.bash f +examples/scripts.noah/shcat.bash f +examples/scripts.noah/source.bash f +examples/scripts.noah/string.bash f +examples/scripts.noah/stty.bash f +examples/scripts.noah/y_or_n_p.bash f diff --git a/Makefile.in b/Makefile.in index 4c9433601..edf4e7d24 100644 --- a/Makefile.in +++ b/Makefile.in @@ -159,6 +159,8 @@ dot = . LIBSUBDIR = lib LIBSRC = $(srcdir)/$(LIBSUBDIR) +LIBBUILD = ${BUILD_DIR}/${LIBSUBDIR} + SUBDIR_INCLUDES = -I. @RL_INCLUDE@ -I$(topdir) -I$(topdir)/$(LIBSUBDIR) BUILD_INCLUDED_LIBINTL = @BUILD_INCLUDED_LIBINTL@ @@ -319,12 +321,15 @@ TILDE_OBJ = $(TILDE_LIBDIR)/tilde.o INTL_LIBSRC = $(LIBSRC)/intl INTL_LIBDIR = $(dot)/$(LIBSUBDIR)/intl INTL_ABSSRC = ${topdir}/$(INTL_LIB) +INTL_BUILDDIR = ${LIBBUILD}/intl INTL_LIB = @LIBINTL@ INTL_LIBRARY = $(INTL_LIBDIR)/libintl.a INTL_DEP = @INTL_DEP@ INTL_INC = @INTL_INC@ +LIBINTL_H = @LIBINTL_H@ + # tests LIBINTL = @LIBINTL@ LTLIBINTL = @LTLIBINTL@ @@ -598,7 +603,9 @@ $(SHLIB_LIBRARY): config.h ${SHLIB_SOURCE} ${INTL_LIBRARY}: config.h ${INTL_LIBDIR}/Makefile @echo making $@ in ${INTL_LIBDIR} @(cd ${INTL_LIBDIR} && \ - $(MAKE) $(MFLAGS) libintl.a) || exit 1 + $(MAKE) $(MFLAGS) all) || exit 1 + +${LIBINTL_H}: ${INTL_LIBRARY} mksignames$(EXEEXT): $(SUPPORT_SRC)mksignames.c $(CC_FOR_BUILD) $(CCFLAGS_FOR_BUILD) -o $@ $(SUPPORT_SRC)mksignames.c @@ -897,7 +904,7 @@ list.o: shell.h syntax.h config.h bashjmp.h ${BASHINCDIR}/posixjmp.h command.h $ list.o: general.h xmalloc.h bashtypes.h variables.h arrayfunc.h conftypes.h array.h hashlib.h list.o: quit.h ${BASHINCDIR}/maxpath.h unwind_prot.h dispose_cmd.h list.o: make_cmd.h subst.h sig.h pathnames.h externs.h -locale.o: config.h bashtypes.h bashintl.h bashansi.h ${BASHINCDIR}/ansi_stdlib.h +locale.o: config.h bashtypes.h bashintl.h ${LIBINTL_H} bashansi.h ${BASHINCDIR}/ansi_stdlib.h locale.o: shell.h syntax.h config.h bashjmp.h ${BASHINCDIR}/posixjmp.h command.h ${BASHINCDIR}/stdc.h error.h locale.o: general.h xmalloc.h bashtypes.h variables.h arrayfunc.h conftypes.h array.h hashlib.h locale.o: quit.h ${BASHINCDIR}/maxpath.h unwind_prot.h dispose_cmd.h @@ -1105,34 +1112,34 @@ subst.o: $(TILDE_LIBSRC)/tilde.h variables.o: $(TILDE_LIBSRC)/tilde.h # libintl dependencies -arrayfunc.o: bashintl.h $(BASHINCDIR)/gettext.h -bashhist.o: bashintl.h $(BASHINCDIR)/gettext.h -bashline.o: bashintl.h $(BASHINCDIR)/gettext.h -braces.o: bashintl.h $(BASHINCDIR)/gettext.h -error.o: bashintl.h $(BASHINCDIR)/gettext.h -eval.o: bashintl.h $(BASHINCDIR)/gettext.h -execute_cmd.o: bashintl.h $(BASHINCDIR)/gettext.h -expr.o: bashintl.h $(BASHINCDIR)/gettext.h -general.o: bashintl.h $(BASHINCDIR)/gettext.h -input.o: bashintl.h $(BASHINCDIR)/gettext.h -jobs.o: bashintl.h $(BASHINCDIR)/gettext.h -mailcheck.o: bashintl.h $(BASHINCDIR)/gettext.h -make_cmd.o: bashintl.h $(BASHINCDIR)/gettext.h -nojobs.o: bashintl.h $(BASHINCDIR)/gettext.h -parse.y: bashintl.h $(BASHINCDIR)/gettext.h -pcomplete.o: bashintl.h $(BASHINCDIR)/gettext.h -pcomplib.o: bashintl.h $(BASHINCDIR)/gettext.h -print_cmd.o: bashintl.h $(BASHINCDIR)/gettext.h -redir.o: bashintl.h $(BASHINCDIR)/gettext.h -shell.o: bashintl.h $(BASHINCDIR)/gettext.h -sig.o: bashintl.h $(BASHINCDIR)/gettext.h -siglist.o: bashintl.h $(BASHINCDIR)/gettext.h -subst.o: bashintl.h $(BASHINCDIR)/gettext.h -test.o: bashintl.h $(BASHINCDIR)/gettext.h -trap.o: bashintl.h $(BASHINCDIR)/gettext.h -variables.o: bashintl.h $(BASHINCDIR)/gettext.h -version.o: bashintl.h $(BASHINCDIR)/gettext.h -xmalloc.o: bashintl.h $(BASHINCDIR)/gettext.h +arrayfunc.o: bashintl.h ${LIBINTL_H} $(BASHINCDIR)/gettext.h +bashhist.o: bashintl.h ${LIBINTL_H} $(BASHINCDIR)/gettext.h +bashline.o: bashintl.h ${LIBINTL_H} $(BASHINCDIR)/gettext.h +braces.o: bashintl.h ${LIBINTL_H} $(BASHINCDIR)/gettext.h +error.o: bashintl.h ${LIBINTL_H} $(BASHINCDIR)/gettext.h +eval.o: bashintl.h ${LIBINTL_H} $(BASHINCDIR)/gettext.h +execute_cmd.o: bashintl.h ${LIBINTL_H} $(BASHINCDIR)/gettext.h +expr.o: bashintl.h ${LIBINTL_H} $(BASHINCDIR)/gettext.h +general.o: bashintl.h ${LIBINTL_H} $(BASHINCDIR)/gettext.h +input.o: bashintl.h ${LIBINTL_H} $(BASHINCDIR)/gettext.h +jobs.o: bashintl.h ${LIBINTL_H} $(BASHINCDIR)/gettext.h +mailcheck.o: bashintl.h ${LIBINTL_H} $(BASHINCDIR)/gettext.h +make_cmd.o: bashintl.h ${LIBINTL_H} $(BASHINCDIR)/gettext.h +nojobs.o: bashintl.h ${LIBINTL_H} $(BASHINCDIR)/gettext.h +parse.y: bashintl.h ${LIBINTL_H} $(BASHINCDIR)/gettext.h +pcomplete.o: bashintl.h ${LIBINTL_H} $(BASHINCDIR)/gettext.h +pcomplib.o: bashintl.h ${LIBINTL_H} $(BASHINCDIR)/gettext.h +print_cmd.o: bashintl.h ${LIBINTL_H} $(BASHINCDIR)/gettext.h +redir.o: bashintl.h ${LIBINTL_H} $(BASHINCDIR)/gettext.h +shell.o: bashintl.h ${LIBINTL_H} $(BASHINCDIR)/gettext.h +sig.o: bashintl.h ${LIBINTL_H} $(BASHINCDIR)/gettext.h +siglist.o: bashintl.h ${LIBINTL_H} $(BASHINCDIR)/gettext.h +subst.o: bashintl.h ${LIBINTL_H} $(BASHINCDIR)/gettext.h +test.o: bashintl.h ${LIBINTL_H} $(BASHINCDIR)/gettext.h +trap.o: bashintl.h ${LIBINTL_H} $(BASHINCDIR)/gettext.h +variables.o: bashintl.h ${LIBINTL_H} $(BASHINCDIR)/gettext.h +version.o: bashintl.h ${LIBINTL_H} $(BASHINCDIR)/gettext.h +xmalloc.o: bashintl.h ${LIBINTL_H} $(BASHINCDIR)/gettext.h # XXX - dependencies checked through here @@ -1337,41 +1344,41 @@ builtins/complete.o: pcomplete.h builtins/complete.o: ${DEFSRC}/common.h ${DEFSRC}/bashgetopt.h # libintl dependencies -builtins/bind.o: ${topdir}/bashintl.h $(BASHINCDIR)/gettext.h -builtins/break.o: ${topdir}/bashintl.h $(BASHINCDIR)/gettext.h -builtins/caller.o: ${topdir}/bashintl.h $(BASHINCDIR)/gettext.h -builtins/cd.o: ${topdir}/bashintl.h $(BASHINCDIR)/gettext.h -builtins/common.c: ${topdir}/bashintl.h $(BASHINCDIR)/gettext.h -builtins/complete.o: ${topdir}/bashintl.h $(BASHINCDIR)/gettext.h -builtins/declare.o: ${topdir}/bashintl.h $(BASHINCDIR)/gettext.h -builtins/enable.o: ${topdir}/bashintl.h $(BASHINCDIR)/gettext.h -builtins/evalfile.c: ${topdir}/bashintl.h $(BASHINCDIR)/gettext.h -builtins/exec.o: ${topdir}/bashintl.h $(BASHINCDIR)/gettext.h -builtins/exit.o: ${topdir}/bashintl.h $(BASHINCDIR)/gettext.h -builtins/fc.o: ${topdir}/bashintl.h $(BASHINCDIR)/gettext.h -builtins/fg_bg.o: ${topdir}/bashintl.h $(BASHINCDIR)/gettext.h -builtins/getopt.c: ${topdir}/bashintl.h $(BASHINCDIR)/gettext.h -builtins/hash.o: ${topdir}/bashintl.h $(BASHINCDIR)/gettext.h -builtins/help.o: ${topdir}/bashintl.h $(BASHINCDIR)/gettext.h -builtins/history.o: ${topdir}/bashintl.h $(BASHINCDIR)/gettext.h -builtins/inlib.o: ${topdir}/bashintl.h $(BASHINCDIR)/gettext.h -builtins/jobs.o: ${topdir}/bashintl.h $(BASHINCDIR)/gettext.h -builtins/kill.o: ${topdir}/bashintl.h $(BASHINCDIR)/gettext.h -builtins/let.o: ${topdir}/bashintl.h $(BASHINCDIR)/gettext.h -builtins/mkbuiltins.c: ${topdir}/bashintl.h $(BASHINCDIR)/gettext.h -builtins/printf.o: ${topdir}/bashintl.h $(BASHINCDIR)/gettext.h -builtins/pushd.o: ${topdir}/bashintl.h $(BASHINCDIR)/gettext.h -builtins/read.o: ${topdir}/bashintl.h $(BASHINCDIR)/gettext.h -builtins/return.o: ${topdir}/bashintl.h $(BASHINCDIR)/gettext.h -builtins/set.o: ${topdir}/bashintl.h $(BASHINCDIR)/gettext.h -builtins/setattr.o: ${topdir}/bashintl.h $(BASHINCDIR)/gettext.h -builtins/shift.o: ${topdir}/bashintl.h $(BASHINCDIR)/gettext.h -builtins/shopt.o: ${topdir}/bashintl.h $(BASHINCDIR)/gettext.h -builtins/source.o: ${topdir}/bashintl.h $(BASHINCDIR)/gettext.h -builtins/suspend.o: ${topdir}/bashintl.h $(BASHINCDIR)/gettext.h -builtins/type.o: ${topdir}/bashintl.h $(BASHINCDIR)/gettext.h -builtins/ulimit.o: ${topdir}/bashintl.h $(BASHINCDIR)/gettext.h -builtins/umask.o: ${topdir}/bashintl.h $(BASHINCDIR)/gettext.h +builtins/bind.o: ${topdir}/bashintl.h ${LIBINTL_H} $(BASHINCDIR)/gettext.h +builtins/break.o: ${topdir}/bashintl.h ${LIBINTL_H} $(BASHINCDIR)/gettext.h +builtins/caller.o: ${topdir}/bashintl.h ${LIBINTL_H} $(BASHINCDIR)/gettext.h +builtins/cd.o: ${topdir}/bashintl.h ${LIBINTL_H} $(BASHINCDIR)/gettext.h +builtins/common.c: ${topdir}/bashintl.h ${LIBINTL_H} $(BASHINCDIR)/gettext.h +builtins/complete.o: ${topdir}/bashintl.h ${LIBINTL_H} $(BASHINCDIR)/gettext.h +builtins/declare.o: ${topdir}/bashintl.h ${LIBINTL_H} $(BASHINCDIR)/gettext.h +builtins/enable.o: ${topdir}/bashintl.h ${LIBINTL_H} $(BASHINCDIR)/gettext.h +builtins/evalfile.c: ${topdir}/bashintl.h ${LIBINTL_H} $(BASHINCDIR)/gettext.h +builtins/exec.o: ${topdir}/bashintl.h ${LIBINTL_H} $(BASHINCDIR)/gettext.h +builtins/exit.o: ${topdir}/bashintl.h ${LIBINTL_H} $(BASHINCDIR)/gettext.h +builtins/fc.o: ${topdir}/bashintl.h ${LIBINTL_H} $(BASHINCDIR)/gettext.h +builtins/fg_bg.o: ${topdir}/bashintl.h ${LIBINTL_H} $(BASHINCDIR)/gettext.h +builtins/getopt.c: ${topdir}/bashintl.h ${LIBINTL_H} $(BASHINCDIR)/gettext.h +builtins/hash.o: ${topdir}/bashintl.h ${LIBINTL_H} $(BASHINCDIR)/gettext.h +builtins/help.o: ${topdir}/bashintl.h ${LIBINTL_H} $(BASHINCDIR)/gettext.h +builtins/history.o: ${topdir}/bashintl.h ${LIBINTL_H} $(BASHINCDIR)/gettext.h +builtins/inlib.o: ${topdir}/bashintl.h ${LIBINTL_H} $(BASHINCDIR)/gettext.h +builtins/jobs.o: ${topdir}/bashintl.h ${LIBINTL_H} $(BASHINCDIR)/gettext.h +builtins/kill.o: ${topdir}/bashintl.h ${LIBINTL_H} $(BASHINCDIR)/gettext.h +builtins/let.o: ${topdir}/bashintl.h ${LIBINTL_H} $(BASHINCDIR)/gettext.h +builtins/mkbuiltins.c: ${topdir}/bashintl.h ${LIBINTL_H} $(BASHINCDIR)/gettext.h +builtins/printf.o: ${topdir}/bashintl.h ${LIBINTL_H} $(BASHINCDIR)/gettext.h +builtins/pushd.o: ${topdir}/bashintl.h ${LIBINTL_H} $(BASHINCDIR)/gettext.h +builtins/read.o: ${topdir}/bashintl.h ${LIBINTL_H} $(BASHINCDIR)/gettext.h +builtins/return.o: ${topdir}/bashintl.h ${LIBINTL_H} $(BASHINCDIR)/gettext.h +builtins/set.o: ${topdir}/bashintl.h ${LIBINTL_H} $(BASHINCDIR)/gettext.h +builtins/setattr.o: ${topdir}/bashintl.h ${LIBINTL_H} $(BASHINCDIR)/gettext.h +builtins/shift.o: ${topdir}/bashintl.h ${LIBINTL_H} $(BASHINCDIR)/gettext.h +builtins/shopt.o: ${topdir}/bashintl.h ${LIBINTL_H} $(BASHINCDIR)/gettext.h +builtins/source.o: ${topdir}/bashintl.h ${LIBINTL_H} $(BASHINCDIR)/gettext.h +builtins/suspend.o: ${topdir}/bashintl.h ${LIBINTL_H} $(BASHINCDIR)/gettext.h +builtins/type.o: ${topdir}/bashintl.h ${LIBINTL_H} $(BASHINCDIR)/gettext.h +builtins/ulimit.o: ${topdir}/bashintl.h ${LIBINTL_H} $(BASHINCDIR)/gettext.h +builtins/umask.o: ${topdir}/bashintl.h ${LIBINTL_H} $(BASHINCDIR)/gettext.h # builtin library dependencies builtins/bind.o: $(RL_LIBSRC)/chardefs.h $(RL_LIBSRC)/readline.h diff --git a/Makefile.in~ b/Makefile.in~ new file mode 100644 index 000000000..75f489baf --- /dev/null +++ b/Makefile.in~ @@ -0,0 +1,1435 @@ +# Makefile for bash-3.0, version 2.152 +# +# Copyright (C) 1996-2002 Free Software Foundation, Inc. + +# This program is free software; you can redistribute it and/or modify +# it under the terms of the GNU General Public License as published by +# the Free Software Foundation; either version 2, or (at your option) +# any later version. + +# This program is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU General Public License for more details. + +# You should have received a copy of the GNU General Public License +# along with this program; if not, write to the Free Software +# Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111 USA. + +# Make sure the first target in the makefile is the right one +all: .made + +PACKAGE = @PACKAGE_NAME@ +VERSION = @PACKAGE_VERSION@ + +PACKAGE_BUGREPORT = @PACKAGE_BUGREPORT@ +PACKAGE_NAME = @PACKAGE_NAME@ +PACKAGE_STRING = @PACKAGE_STRING@ +PACKAGE_VERSION = @PACKAGE_VERSION@ + +# Include some boilerplate Gnu makefile definitions. +prefix = @prefix@ + +exec_prefix = @exec_prefix@ +bindir = @bindir@ +libdir = @libdir@ +infodir = @infodir@ +includedir = @includedir@ +datadir = @datadir@ +localedir = $(datadir)/locale + +mandir = @mandir@ +manpfx = man + +man1ext = .1 +man1dir = $(mandir)/$(manpfx)1 +man3ext = .3 +man3dir = $(mandir)/$(manpfx)3 + +htmldir = @htmldir@ + +# Support an alternate destination root directory for package building +DESTDIR = + +topdir = @top_srcdir@ +BUILD_DIR = @BUILD_DIR@ +top_builddir = @BUILD_DIR@ +srcdir = @srcdir@ +VPATH = .:@srcdir@ + +@SET_MAKE@ +CC = @CC@ +CC_FOR_BUILD = @CC_FOR_BUILD@ +YACC = @YACC@ +SHELL = @MAKE_SHELL@ +CP = cp +RM = rm -f +AR = @AR@ +ARFLAGS = @ARFLAGS@ +RANLIB = @RANLIB@ + +INSTALL = @INSTALL@ +INSTALL_PROGRAM = @INSTALL_PROGRAM@ +INSTALL_SCRIPT = @INSTALL_SCRIPT@ +INSTALL_DATA = @INSTALL_DATA@ +INSTALLMODE= -m 0755 +INSTALLMODE2 = -m 0555 + +TESTSCRIPT = @TESTSCRIPT@ + +#If you have purify, and want to use it, uncomment this definition or +# run the make as `make PURIFY=purify' +# or run configure with the --with-purify argument. +PURIFY = @PURIFY@ + +# Here is a rule for making .o files from .c files that does not +# force the type of the machine (like -M_MACHINE) into the flags. +.c.o: + $(RM) $@ + $(CC) $(CCFLAGS) -c $< + +EXEEXT = @EXEEXT@ +OBJEXT = @OBJEXT@ + +# The name of this program and some version information. +VERSPROG = bashversion$(EXEEXT) +VERSOBJ = bashversion.$(OBJEXT) + +Program = bash$(EXEEXT) +Version = @BASHVERS@ +PatchLevel = `$(BUILD_DIR)/$(VERSPROG) -p` +RELSTATUS = @RELSTATUS@ + +Machine = @host_cpu@ +OS = @host_os@ +VENDOR = @host_vendor@ +MACHTYPE = @host@ + +# comment out for release +DEBUG = @DEBUG@ +MALLOC_DEBUG = @MALLOC_DEBUG@ + +THIS_SH = $(BUILD_DIR)/$(Program) + +# PROFILE_FLAGS is either -pg, to generate profiling info for use +# with gprof, or nothing (the default). +PROFILE_FLAGS= @PROFILE_FLAGS@ + +CFLAGS = @CFLAGS@ +CFLAGS_FOR_BUILD = @CFLAGS_FOR_BUILD@ +CPPFLAGS = @CPPFLAGS@ +CPPFLAGS_FOR_BUILD = @CPPFLAGS_FOR_BUILD@ +LOCAL_CFLAGS = @LOCAL_CFLAGS@ ${DEBUG} +DEFS = @DEFS@ +LOCAL_DEFS = @LOCAL_DEFS@ + +LOCALE_DEFS = -DLOCALEDIR='"$(localedir)"' -DPACKAGE='"$(PACKAGE)"' + +LOCAL_LIBS = @LOCAL_LIBS@ +LIBS = $(BUILTINS_LIB) $(LIBRARIES) @LIBS@ +STATIC_LD = @STATIC_LD@ +LOCAL_LDFLAGS = @LOCAL_LDFLAGS@ + +SYSTEM_FLAGS = -DPROGRAM='"$(Program)"' -DCONF_HOSTTYPE='"$(Machine)"' -DCONF_OSTYPE='"$(OS)"' -DCONF_MACHTYPE='"$(MACHTYPE)"' -DCONF_VENDOR='"$(VENDOR)"' $(LOCALE_DEFS) + +BASE_CCFLAGS = $(PROFILE_FLAGS) $(SYSTEM_FLAGS) $(LOCAL_DEFS) \ + $(DEFS) $(LOCAL_CFLAGS) $(INCLUDES) + +CCFLAGS = $(BASE_CCFLAGS) $(CPPFLAGS) $(CFLAGS) + +CCFLAGS_FOR_BUILD = $(BASE_CCFLAGS) $(CPPFLAGS_FOR_BUILD) $(CFLAGS_FOR_BUILD) + +LDFLAGS = @LDFLAGS@ $(STATIC_LD) $(LOCAL_LDFLAGS) $(PROFILE_FLAGS) $(CFLAGS) +LDFLAGS_FOR_BUILD = $(LDFLAGS) + +INCLUDES = -I. @RL_INCLUDE@ -I$(srcdir) -I$(BASHINCDIR) -I$(LIBSRC) $(INTL_INC) + +GCC_LINT_FLAGS = -Wall -Wshadow -Wpointer-arith -Wcast-qual \ + -Wcast-align -Wstrict-prototypes -Wconversion \ + -Wmissing-prototypes -Wtraditional -Wredundant-decls -pedantic + +GCC_LINT_CFLAGS = $(BASE_CCFLAGS) $(CPPFLAGS) $(GCC_LINT_FLAGS) + +# +# Support libraries +# + +dot = . + +LIBSUBDIR = lib +LIBSRC = $(srcdir)/$(LIBSUBDIR) + +LIBBUILD = ${BUILD_DIR}/${LIBSUBDIR} + +SUBDIR_INCLUDES = -I. @RL_INCLUDE@ -I$(topdir) -I$(topdir)/$(LIBSUBDIR) + +BUILD_INCLUDED_LIBINTL = @BUILD_INCLUDED_LIBINTL@ +USE_INCLUDED_LIBINTL = @USE_INCLUDED_LIBINTL@ + +# the bash library +# the library is a mix of functions that the C library does not provide on +# some platforms and general shell utility functions +SH_LIBSRC = $(LIBSRC)/sh +SH_LIBDIR = $(dot)/${LIBSUBDIR}/sh +SH_ABSSRC = ${topdir}/${SH_LIBSRC} + +SHLIB_SOURCE = ${SH_LIBSRC}/clktck.c ${SH_LIBSRC}/getcwd.c \ + ${SH_LIBSRC}/getenv.c ${SH_LIBSRC}/oslib.c \ + ${SH_LIBSRC}/setlinebuf.c \ + ${SH_LIBSRC}/strcasecmp.c ${SH_LIBSRC}/strerror.c \ + ${SH_LIBSRC}/strtod.c ${SH_LIBSRC}/strtol.c \ + ${SH_LIBSRC}/strtoul.c ${SH_LIBSRC}/vprint.c \ + ${SH_LIBSRC}/itos.c ${SH_LIBSRC}/rename.c \ + ${SH_LIBSRC}/zread.c ${SH_LIBSRC}/zwrite.c \ + ${SH_LIBSRC}/shtty.c ${SH_LIBSRC}/inet_aton.c \ + ${SH_LIBSRC}/netopen.c ${SH_LIBSRC}/strpbrk.c \ + ${SH_LIBSRC}/timeval.c ${SH_LIBSRC}/clock.c \ + ${SH_LIBSRC}/makepath.c ${SH_LIBSRC}/pathcanon.c \ + ${SH_LIBSRC}/pathphys.c ${SH_LIBSRC}/stringlist.c \ + ${SH_LIBSRC}/stringvec.c ${SH_LIBSRC}/tmpfile.c \ + ${SH_LIBSRC}/spell.c ${SH_LIBSRC}/strtrans.c \ + ${SH_LIBSRC}/strindex.c ${SH_LIBSRC}/shquote.c \ + ${SH_LIBSRC}/snprintf.c ${SH_LIBSRC}/mailstat.c \ + ${SH_LIBSRC}/fmtulong.c ${SH_LIBSRC}/fmtullong.c \ + ${SH_LIBSRC}/strtoll.c ${SH_LIBSRC}/strtoull.c \ + ${SH_LIBSRC}/strtoimax.c ${SH_LIBSRC}/strtoumax.c \ + ${SH_LIBSRC}/fmtumax.c ${SH_LIBSRC}/netconn.c \ + ${SH_LIBSRC}/mktime.c ${SH_LIBSRC}/strftime.c \ + ${SH_LIBSRC}/memset.c ${SH_LIBSRC}/xstrchr.c \ + ${SH_LIBSRC}/zcatfd.c ${SH_LIBSRC}/shmatch.c + +SHLIB_LIB = -lsh +SHLIB_LIBNAME = libsh.a +SHLIB_LIBRARY = ${SH_LIBDIR}/${SHLIB_LIBNAME} +SHLIB_LDFLAGS = -L${SH_LIBDIR} +SHLIB_DEP = ${SHLIB_LIBRARY} + +# we assume for now that readline source is being shipped with bash +RL_LIBSRC = $(LIBSRC)/readline +RL_LIBDOC = $(RL_LIBSRC)/doc +RL_LIBDIR = @RL_LIBDIR@ +RL_ABSSRC = ${topdir}/$(RL_LIBDIR) + +RL_INCLUDEDIR = @RL_INCLUDEDIR@ + +READLINE_LIB = @READLINE_LIB@ +READLINE_LIBRARY = $(RL_LIBDIR)/libreadline.a +READLINE_LDFLAGS = -L${RL_LIBDIR} +READLINE_DEP = @READLINE_DEP@ + +# The source, object and documentation of the GNU Readline library. +READLINE_SOURCE = $(RL_LIBSRC)/rldefs.h $(RL_LIBSRC)/rlconf.h \ + $(RL_LIBSRC)/readline.h $(RL_LIBSRC)/tcap.h \ + $(RL_LIBSRC)/chardefs.h $(RL_LIBSRC)/keymaps.h \ + $(RL_LIBSRC)/history.h $(RL_LIBSRC)/histlib.h \ + $(RL_LIBSRC)/posixstat.h $(RL_LIBSRC)/tilde.h \ + $(RL_LIBSRC)/rlstdc.h ${RL_LIBSRC}/xmalloc.h \ + $(RL_LIBSRC)/rlshell.h ${RL_LIBSRC}/rlprivate.h \ + $(RL_LIBSRC)/funmap.c $(RL_LIBSRC)/emacs_keymap.c \ + $(RL_LIBSRC)/search.c $(RL_LIBSRC)/vi_keymap.c \ + $(RL_LIBSRC)/keymaps.c $(RL_LIBSRC)/parens.c \ + $(RL_LIBSRC)/vi_mode.c $(RL_LIBSRC)/callback.c \ + $(RL_LIBSRC)/readline.c $(RL_LIBSRC)/tilde.c \ + $(RL_LIBSRC)/rltty.c $(RL_LIBSRC)/complete.c \ + $(RL_LIBSRC)/bind.c $(RL_LIBSRC)/isearch.c \ + $(RL_LIBSRC)/display.c $(RL_LIBSRC)/signals.c \ + $(RL_LIBSRC)/util.c $(RL_LIBSRC)/kill.c $(RL_LIBSRC)/text.c \ + $(RL_LIBSRC)/undo.c $(RL_LIBSRC)/macro.c \ + $(RL_LIBSRC)/terminal.c $(RL_LIBSRC)/nls.c \ + $(RL_LIBSRC)/input.c $(RL_LIBSRC)/xmalloc.c \ + $(RL_LIBSRC)/shell.c $(RL_LIBSRC)/savestring.c \ + $(RL_LIBSRC)/misc.c $(RL_LIBSRC)/mbutil.c $(RL_LIBSRC)/compat.c \ + $(RL_LIBSRC)/histexpand.c $(RL_LIBSRC)/history.c \ + $(RL_LIBSRC)/histsearch.c $(RL_LIBSRC)/histfile.c + +READLINE_OBJ = $(RL_LIBDIR)/readline.o $(RL_LIBDIR)/funmap.o \ + $(RL_LIBDIR)/parens.o $(RL_LIBDIR)/search.o \ + $(RL_LIBDIR)/keymaps.o $(RL_LIBDIR)/xmalloc.o \ + $(RL_LIBDIR)/rltty.o $(RL_LIBDIR)/complete.o \ + $(RL_LIBDIR)/bind.o $(RL_LIBDIR)/isearch.o \ + $(RL_LIBDIR)/display.o $(RL_LIBDIR)/signals.o \ + $(RL_LIBDIR)/tilde.o $(RL_LIBDIR)/util.o \ + $(RL_LIBDIR)/kill.o $(RL_LIBDIR)/undo.o $(RL_LIBDIR)/nls.o \ + $(RL_LIBDIR)/macro.o $(RL_LIBDIR)/input.o \ + $(RL_LIBDIR)/terminal.o $(RL_LIBDIR)/callback.o \ + $(RL_LIBDIR)/shell.o $(RL_LIBDIR)/savestring.o \ + $(RL_LIBDIR)/mbutil.o $(RL_LIBDIR)/compat.o \ + $(RL_LIBDIR)/history.o $(RL_LIBDIR)/histexpand.o \ + $(RL_LIBDIR)/histsearch.o $(RL_LIBDIR)/histfile.o + +HIST_LIBSRC = $(LIBSRC)/readline +HIST_LIBDIR = @HIST_LIBDIR@ +HIST_ABSSRC = ${topdir}/$(HIST_LIBDIR) + +HISTORY_LIB = @HISTORY_LIB@ +HISTORY_LIBRARY = $(HIST_LIBDIR)/libhistory.a +HISTORY_LDFLAGS = -L$(HIST_LIBDIR) +HISTORY_DEP = @HISTORY_DEP@ + +# The source, object and documentation of the history library. +HISTORY_SOURCE = $(HIST_LIBSRC)/history.c $(HIST_LIBSRC)/histexpand.c \ + $(HIST_LIBSRC)/histsearch.c $(HIST_LIBSRC)/histfile.c \ + $(HIST_LIBSRC)/shell.c \ + $(HIST_LIBSRC)/history.h $(HIST_LIBSRC)/histlib.h +HISTORY_OBJ = $(HIST_LIBDIR)/history.o $(HIST_LIBDIR)/histexpand.o \ + $(HIST_LIBDIR)/histsearch.o $(HIST_LIBDIR)/histfile.o \ + $(HIST_LIBDIR)/shell.o + +# You only need termcap (or curses) if you are linking with GNU Readline. +TERM_LIBSRC = $(LIBSRC)/termcap +TERM_LIBDIR = $(dot)/$(LIBSUBDIR)/termcap +TERM_ABSSRC = ${topdir}/$(TERM_LIBDIR) + +TERMCAP_LIB = @TERMCAP_LIB@ +TERMCAP_LIBRARY = $(TERM_LIBDIR)/libtermcap.a +TERMCAP_LDFLAGS = -L$(TERM_LIBDIR) +TERMCAP_DEP = @TERMCAP_DEP@ + +TERMCAP_SOURCE = $(TERM_LIBSRC)/termcap.c $(TERM_LIBSRC)/tparam.c +TERMCAP_OBJ = $(TERM_LIBDIR)/termcap.o $(TERM_LIBDIR)/tparam.o + +GLOB_LIBSRC = $(LIBSRC)/glob +GLOB_LIBDIR = $(dot)/$(LIBSUBDIR)/glob +GLOB_ABSSRC = ${topdir}/$(GLOB_LIBDIR) + +GLOB_LIB = -lglob +GLOB_LIBRARY = $(GLOB_LIBDIR)/libglob.a +GLOB_LDFLAGS = -L$(GLOB_LIBDIR) +GLOB_DEP = $(GLOB_LIBRARY) + +GLOB_SOURCE = $(GLOB_LIBSRC)/glob.c $(GLOB_LIBSRC)/strmatch.c \ + $(GLOB_LIBSRC)/smatch.c $(GLOB_LIBSRC)/xmbsrtowcs.c \ + $(GLOB_LIBSRC)/glob_loop.c $(GLOB_LIBSRC)/sm_loop.c \ + $(GLOB_LIBSRC)/glob.h $(GLOB_LIBSRC)/strmatch.h +GLOB_OBJ = $(GLOB_LIBDIR)/glob.o $(GLOB_LIBDIR)/strmatch.o \ + $(GLOB_LIBDIR)/smatch.o $(GLOB_LIBDIR)/xmbsrtowcs.o + +# The source, object and documentation for the GNU Tilde library. +TILDE_LIBSRC = $(LIBSRC)/tilde +TILDE_LIBDIR = $(dot)/$(LIBSUBDIR)/tilde +TILDE_ABSSRC = ${topdir}/$(TILDE_LIBDIR) + +TILDE_LIB = -ltilde +TILDE_LIBRARY = $(TILDE_LIBDIR)/libtilde.a +TILDE_LDFLAGS = -L$(TILDE_LIBDIR) +TILDE_DEP = $(TILDE_LIBRARY) + +TILDE_SOURCE = $(TILDE_LIBSRC)/tilde.c $(TILDE_LIBSRC)/tilde.h +TILDE_OBJ = $(TILDE_LIBDIR)/tilde.o + +# libintl +INTL_LIBSRC = $(LIBSRC)/intl +INTL_LIBDIR = $(dot)/$(LIBSUBDIR)/intl +INTL_ABSSRC = ${topdir}/$(INTL_LIB) +INTL_BUILDDIR = ${LIBBUILD}/intl + +INTL_LIB = @LIBINTL@ +INTL_LIBRARY = $(INTL_LIBDIR)/libintl.a +INTL_DEP = @INTL_DEP@ +INTL_INC = @INTL_INC@ + +LIBINTL_H = @LIBINTL_H@ + +# tests +LIBINTL = @LIBINTL@ +LTLIBINTL = @LTLIBINTL@ +INTLLIBS = @INTLLIBS@ +INTLOBJS = @INTLOBJS@ + +# Our malloc. +MALLOC_TARGET = @MALLOC_TARGET@ + +# set to alloca.o if we are using the C alloca in lib/malloc +ALLOCA = @ALLOCA@ + +ALLOC_LIBSRC = $(LIBSRC)/malloc +ALLOC_LIBDIR = $(dot)/$(LIBSUBDIR)/malloc +ALLOC_ABSSRC = ${topdir}/$(ALLOC_LIBDIR) + +MALLOC_SRC = @MALLOC_SRC@ +MALLOC_OTHERSRC = ${ALLOC_LIBSRC}/trace.c ${ALLOC_LIBSRC}/stats.c \ + ${ALLOC_LIBSRC}/table.c ${ALLOC_LIBSRC}/watch.c +MALLOC_SOURCE = ${ALLOC_LIBSRC}/${MALLOC_SRC} ${MALLOC_OTHERSRC} +MALLOC_CFLAGS = -DRCHECK -Dbotch=programming_error ${MALLOC_DEBUG} + +MALLOC_LIB = @MALLOC_LIB@ +MALLOC_LIBRARY = @MALLOC_LIBRARY@ +MALLOC_LDFLAGS = @MALLOC_LDFLAGS@ +MALLOC_DEP = @MALLOC_DEP@ + +ALLOC_HEADERS = $(ALLOC_LIBSRC)/getpagesize.h $(ALLOC_LIBSRC)/shmalloc.h \ + $(ALLOC_LIBSRC)/imalloc.h $(ALLOC_LIBSRC)/mstats.h \ + $(ALLOC_LIBSRC)/table.h $(ALLOC_LIBSRC)/watch.h + +$(MALLOC_LIBRARY): ${MALLOC_SOURCE} ${ALLOC_HEADERS} config.h + @(cd $(ALLOC_LIBDIR) && \ + $(MAKE) $(MFLAGS) \ + MALLOC_CFLAGS="$(MALLOC_CFLAGS)" ${MALLOC_TARGET} ) || exit 1 + +BASHINCDIR = ${srcdir}/include +BASHINCFILES = $(BASHINCDIR)/posixstat.h $(BASHINCDIR)/ansi_stdlib.h \ + $(BASHINCDIR)/filecntl.h $(BASHINCDIR)/posixdir.h \ + $(BASHINCDIR)/memalloc.h $(BASHINCDIR)/stdc.h \ + $(BASHINCDIR)/posixjmp.h $(BASHINCDIR)/posixwait.h \ + $(BASHINCDIR)/posixtime.h $(BASHINCDIR)/systimes.h \ + $(BASHINCDIR)/unionwait.h $(BASHINCDIR)/maxpath.h \ + $(BASHINCDIR)/shtty.h $(BASHINCDIR)/typemax.h \ + $(BASHINCDIR)/ocache.h + +LIBRARIES = $(SHLIB_LIB) $(READLINE_LIB) $(HISTORY_LIB) $(TERMCAP_LIB) $(GLOB_LIB) \ + $(TILDE_LIB) $(MALLOC_LIB) $(INTL_LIB) $(LOCAL_LIBS) + +LIBDEP = $(SHLIB_DEP) $(INTL_DEP) $(READLINE_DEP) $(HISTORY_DEP) $(TERMCAP_DEP) $(GLOB_DEP) \ + $(TILDE_DEP) $(MALLOC_DEP) + +LIBRARY_LDFLAGS = $(READLINE_LDFLAGS) $(HISTORY_LDFLAGS) $(GLOB_LDFLAGS) \ + $(TILDE_LDFLAGS) $(MALLOC_LDFLAGS) $(SHLIB_LDFLAGS) + +# +# The shell itself +# + +# The main source code for the Bourne Again SHell. +CSOURCES = shell.c eval.c parse.y general.c make_cmd.c print_cmd.c y.tab.c \ + dispose_cmd.c execute_cmd.c variables.c $(GLOBC) version.c \ + expr.c copy_cmd.c flags.c subst.c hashcmd.c hashlib.c mailcheck.c \ + test.c trap.c alias.c jobs.c nojobs.c $(ALLOC_FILES) braces.c \ + input.c bashhist.c array.c arrayfunc.c sig.c pathexp.c \ + unwind_prot.c siglist.c bashline.c bracecomp.c error.c \ + list.c stringlib.c locale.c findcmd.c redir.c \ + pcomplete.c pcomplib.c syntax.c xmalloc.c + +HSOURCES = shell.h flags.h trap.h hashcmd.h hashlib.h jobs.h builtins.h \ + general.h variables.h config.h $(ALLOC_HEADERS) alias.h \ + quit.h unwind_prot.h syntax.h ${GRAM_H} \ + command.h input.h error.h bashansi.h dispose_cmd.h make_cmd.h \ + subst.h externs.h siglist.h bashhist.h bashline.h bashtypes.h \ + array.h arrayfunc.h sig.h mailcheck.h bashintl.h bashjmp.h \ + execute_cmd.h parser.h pathexp.h pathnames.h pcomplete.h \ + $(BASHINCFILES) + +SOURCES = $(CSOURCES) $(HSOURCES) $(BUILTIN_DEFS) + +# header files chosen based on running of configure +SIGNAMES_H = @SIGNAMES_H@ + +# object files chosen based on running of configure +JOBS_O = @JOBS_O@ +SIGLIST_O = @SIGLIST_O@ + +# Matching object files. +OBJECTS = shell.o eval.o y.tab.o general.o make_cmd.o print_cmd.o $(GLOBO) \ + dispose_cmd.o execute_cmd.o variables.o copy_cmd.o error.o \ + expr.o flags.o $(JOBS_O) subst.o hashcmd.o hashlib.o mailcheck.o \ + trap.o input.o unwind_prot.o pathexp.o sig.o test.o version.o \ + alias.o array.o arrayfunc.o braces.o bracecomp.o bashhist.o \ + bashline.o $(SIGLIST_O) list.o stringlib.o locale.o findcmd.o redir.o \ + pcomplete.o pcomplib.o syntax.o xmalloc.o + +# Where the source code of the shell builtins resides. +BUILTIN_SRCDIR=$(srcdir)/builtins +DEFSRC=$(BUILTIN_SRCDIR) +BUILTIN_ABSSRC=${topdir}/builtins +DEFDIR = $(dot)/builtins +DEBUGGER_DIR = $(dot)/debugger + +BUILTIN_DEFS = $(DEFSRC)/alias.def $(DEFSRC)/bind.def $(DEFSRC)/break.def \ + $(DEFSRC)/builtin.def $(DEFSRC)/cd.def $(DEFSRC)/colon.def \ + $(DEFSRC)/command.def ${DEFSRC}/complete.def \ + $(DEFSRC)/caller.def $(DEFSRC)/declare.def \ + $(DEFSRC)/echo.def $(DEFSRC)/enable.def $(DEFSRC)/eval.def \ + $(DEFSRC)/exec.def $(DEFSRC)/exit.def $(DEFSRC)/fc.def \ + $(DEFSRC)/fg_bg.def $(DEFSRC)/hash.def $(DEFSRC)/help.def \ + $(DEFSRC)/history.def $(DEFSRC)/jobs.def $(DEFSRC)/kill.def \ + $(DEFSRC)/let.def $(DEFSRC)/read.def $(DEFSRC)/return.def \ + $(DEFSRC)/set.def $(DEFSRC)/setattr.def $(DEFSRC)/shift.def \ + $(DEFSRC)/source.def $(DEFSRC)/suspend.def $(DEFSRC)/test.def \ + $(DEFSRC)/times.def $(DEFSRC)/trap.def $(DEFSRC)/type.def \ + $(DEFSRC)/ulimit.def $(DEFSRC)/umask.def $(DEFSRC)/wait.def \ + $(DEFSRC)/getopts.def $(DEFSRC)/reserved.def \ + $(DEFSRC)/pushd.def $(DEFSRC)/shopt.def $(DEFSRC)/printf.def +BUILTIN_C_SRC = $(DEFSRC)/mkbuiltins.c $(DEFSRC)/common.c \ + $(DEFSRC)/evalstring.c $(DEFSRC)/evalfile.c \ + $(DEFSRC)/bashgetopt.c $(GETOPT_SOURCE) +BUILTIN_C_OBJ = $(DEFDIR)/common.o $(DEFDIR)/evalstring.o \ + $(DEFDIR)/evalfile.o $(DEFDIR)/bashgetopt.o +BUILTIN_OBJS = $(DEFDIR)/alias.o $(DEFDIR)/bind.o $(DEFDIR)/break.o \ + $(DEFDIR)/builtin.o $(DEFDIR)/cd.o $(DEFDIR)/colon.o \ + $(DEFDIR)/command.o $(DEFDIR)/caller.o $(DEFDIR)/declare.o \ + $(DEFDIR)/echo.o $(DEFDIR)/enable.o $(DEFDIR)/eval.o \ + $(DEFDIR)/exec.o $(DEFDIR)/exit.o $(DEFDIR)/fc.o \ + $(DEFDIR)/fg_bg.o $(DEFDIR)/hash.o $(DEFDIR)/help.o \ + $(DEFDIR)/history.o $(DEFDIR)/jobs.o $(DEFDIR)/kill.o \ + $(DEFDIR)/let.o $(DEFDIR)/pushd.o $(DEFDIR)/read.o \ + $(DEFDIR)/return.o $(DEFDIR)/shopt.o $(DEFDIR)/printf.o \ + $(DEFDIR)/set.o $(DEFDIR)/setattr.o $(DEFDIR)/shift.o \ + $(DEFDIR)/source.o $(DEFDIR)/suspend.o $(DEFDIR)/test.o \ + $(DEFDIR)/times.o $(DEFDIR)/trap.o $(DEFDIR)/type.o \ + $(DEFDIR)/ulimit.o $(DEFDIR)/umask.o $(DEFDIR)/wait.o \ + $(DEFDIR)/getopts.o $(BUILTIN_C_OBJ) +GETOPT_SOURCE = $(DEFSRC)/getopt.c $(DEFSRC)/getopt.h +PSIZE_SOURCE = $(DEFSRC)/psize.sh $(DEFSRC)/psize.c + +BUILTINS_LIBRARY = $(DEFDIR)/libbuiltins.a +BUILTINS_LIB = -lbuiltins +BUILTINS_LDFLAGS = -L$(DEFDIR) +BUILTINS_DEP = $(BUILTINS_LIBRARY) + +# Documentation for the shell. +DOCSRC = $(srcdir)/doc +DOCDIR = $(dot)/doc + +# Translations and other i18n support files +PO_SRC = $(srcdir)/po/ +PO_DIR = $(dot)/po/ + +SIGNAMES_SUPPORT = $(SUPPORT_SRC)mksignames.c + +SUPPORT_SRC = $(srcdir)/support/ +SDIR = $(dot)/support/ + +TESTS_SUPPORT = recho$(EXEEXT) zecho$(EXEEXT) printenv$(EXEEXT) +CREATED_SUPPORT = signames.h recho$(EXEEXT) zecho$(EXEEXT) printenv$(EXEEXT) \ + tests/recho$(EXEEXT) tests/zecho$(EXEEXT) \ + tests/printenv$(EXEEXT) mksignames$(EXEEXT) lsignames.h \ + mksyntax${EXEEXT} syntax.c $(VERSPROG) $(VERSOBJ) \ + buildversion.o +CREATED_CONFIGURE = config.h config.cache config.status config.log \ + stamp-h po/POTFILES +CREATED_MAKEFILES = Makefile builtins/Makefile doc/Makefile \ + lib/readline/Makefile lib/glob/Makefile \ + lib/sh/Makefile lib/tilde/Makefile lib/malloc/Makefile \ + lib/termcap/Makefile examples/loadables/Makefile \ + examples/loadables/perl/Makefile support/Makefile \ + lib/intl/Makefile po/Makefile po/Makefile.in + +# Keep GNU Make from exporting the entire environment for small machines. +.NOEXPORT: + +.made: $(Program) bashbug + @echo "$(Program) last made for a $(Machine) running $(OS)" >.made + +$(Program): .build $(OBJECTS) $(BUILTINS_DEP) $(LIBDEP) + $(RM) $@ + $(PURIFY) $(CC) $(BUILTINS_LDFLAGS) $(LIBRARY_LDFLAGS) $(LDFLAGS) -o $(Program) $(OBJECTS) $(LIBS) + ls -l $(Program) + size $(Program) + +.build: $(SOURCES) config.h Makefile version.h $(VERSPROG) + @echo + @echo " ***********************************************************" + @echo " * *" + @echo " * `$(BUILD_DIR)/$(VERSPROG) -l`" + @echo " * *" + @echo " ***********************************************************" + @echo + +bashbug: $(SUPPORT_SRC)bashbug.sh config.h Makefile $(VERSPROG) + @sed -e "s%!MACHINE!%$(Machine)%" -e "s%!OS!%$(OS)%" \ + -e "s%!CFLAGS!%$(CCFLAGS)%" -e "s%!CC!%$(CC)%" \ + -e "s%!RELEASE!%$(Version)%" -e "s%!PATCHLEVEL!%$(PatchLevel)%" \ + -e "s%!MACHTYPE!%$(MACHTYPE)%" -e "s%!RELSTATUS!%$(RELSTATUS)%" \ + $(SUPPORT_SRC)bashbug.sh > $@ + @chmod a+rx bashbug + +strip: $(Program) .made + strip $(Program) + ls -l $(Program) + size $(Program) + +lint: + ${MAKE} ${MFLAGS} CFLAGS='${GCC_LINT_FLAGS}' .made + +version.h: $(SOURCES) config.h Makefile + $(SHELL) $(SUPPORT_SRC)mkversion.sh -b -S ${topdir} -s $(RELSTATUS) -d $(Version) -o newversion.h \ + && mv newversion.h version.h + +bashversion$(EXEEXT): patchlevel.h conftypes.h version.h buildversion.o $(SUPPORT_SRC)bashversion.c + $(CC_FOR_BUILD) $(CCFLAGS_FOR_BUILD) -o $@ $(SUPPORT_SRC)bashversion.c buildversion.o + +buildversion.o: version.h conftypes.h patchlevel.h $(srcdir)/version.c + $(CC_FOR_BUILD) $(CCFLAGS_FOR_BUILD) -DBUILDTOOL -c -o $@ $(srcdir)/version.c + +# old rules +GRAM_H = parser-built +y.tab.o: y.tab.c ${GRAM_H} command.h ${BASHINCDIR}/stdc.h input.h +${GRAM_H}: y.tab.h + @-if test -f y.tab.h ; then \ + cmp -s $@ y.tab.h 2>/dev/null || cp -p y.tab.h $@; \ + fi +y.tab.c y.tab.h: parse.y +# -if test -f y.tab.h; then mv -f y.tab.h old-y.tab.h; fi + $(YACC) -d $(srcdir)/parse.y + touch parser-built +# -if cmp -s old-y.tab.h y.tab.h; then mv old-y.tab.h y.tab.h; else cp -p y.tab.h ${GRAM_H}; fi + +# experimental new rules - work with GNU make but not BSD (or OSF) make +#y.tab.o: y.tab.c y.tab.h +#y.tab.c y.tab.h: parse.y command.h ${BASHINCDIR}/stdc.h input.h +# -if test -f y.tab.h; then mv -f y.tab.h old-y.tab.h; fi +# $(YACC) -d $(srcdir)/parse.y +# -if cmp -s old-y.tab.h y.tab.h; then mv old-y.tab.h y.tab.h; fi + +$(READLINE_LIBRARY): config.h $(READLINE_SOURCE) + @echo making $@ in ${RL_LIBDIR} + @( { test "${RL_LIBDIR}" = "${libdir}" && exit 0; } || \ + cd ${RL_LIBDIR} && $(MAKE) $(MFLAGS) libreadline.a) || exit 1 + +$(HISTORY_LIBRARY): config.h $(HISTORY_SOURCE) + @echo making $@ in ${HIST_LIBDIR} + @( { test "${HIST_LIBDIR}" = "${libdir}" && exit 0; } || \ + cd ${HIST_LIBDIR} && $(MAKE) $(MFLAGS) libhistory.a) || exit 1 + +$(GLOB_LIBRARY): config.h $(GLOB_SOURCE) + @echo making $@ in ${GLOB_LIBDIR} + @(cd ${GLOB_LIBDIR} && \ + $(MAKE) $(MFLAGS) DEBUG=${DEBUG} libglob.a) || exit 1 + +$(TILDE_LIBRARY): config.h $(TILDE_SOURCE) + @echo making $@ in ${TILDE_LIBDIR} + @(cd ${TILDE_LIBDIR} && \ + $(MAKE) $(MFLAGS) libtilde.a) || exit 1 + +$(TERMCAP_LIBRARY): config.h ${TERMCAP_SOURCE} + @echo making $@ in ${TERM_LIBDIR} + @(cd ${TERM_LIBDIR} && \ + $(MAKE) $(MFLAGS) libtermcap.a) || exit 1 + +$(SHLIB_LIBRARY): config.h ${SHLIB_SOURCE} + @echo making $@ in ${SH_LIBDIR} + @(cd ${SH_LIBDIR} && \ + $(MAKE) $(MFLAGS) DEBUG=${DEBUG} ${SHLIB_LIBNAME}) || exit 1 + +${INTL_LIBRARY}: config.h ${INTL_LIBDIR}/Makefile + @echo making $@ in ${INTL_LIBDIR} + @(cd ${INTL_LIBDIR} && \ + $(MAKE) $(MFLAGS) libintl.a) || exit 1 + +${LIBINTL_H}: ${INTL_LIBRARY} + +mksignames$(EXEEXT): $(SUPPORT_SRC)mksignames.c + $(CC_FOR_BUILD) $(CCFLAGS_FOR_BUILD) -o $@ $(SUPPORT_SRC)mksignames.c + +mksyntax$(EXEEXT): ${srcdir}/mksyntax.c config.h syntax.h ${BASHINCDIR}/chartypes.h + ${CC_FOR_BUILD} ${CCFLAGS_FOR_BUILD} -o $@ ${srcdir}/mksyntax.c + +# make a list of signals for the local system -- this is done when we're +# *not* cross-compiling +lsignames.h: mksignames$(EXEEXT) + $(RM) $@ + ./mksignames $@ + +# copy the correct signames header file to signames.h +signames.h: $(SIGNAMES_H) + -if cmp -s $(SIGNAMES_H) $@ ; then :; else $(RM) $@ ; $(CP) $(SIGNAMES_H) $@ ; fi + +syntax.c: mksyntax${EXEEXT} $(srcdir)/syntax.h + $(RM) $@ + ./mksyntax -o $@ + +$(BUILTINS_LIBRARY): $(BUILTIN_DEFS) $(BUILTIN_C_SRC) config.h ${BASHINCDIR}/memalloc.h version.h + @(cd $(DEFDIR) && $(MAKE) $(MFLAGS) DEBUG=${DEBUG} libbuiltins.a ) || exit 1 + +# these require special rules to circumvent make builtin rules +${DEFDIR}/common.o: $(BUILTIN_SRCDIR)/common.c + @(cd $(DEFDIR) && $(MAKE) $(MFLAGS) DEBUG=${DEBUG} common.o) || exit 1 + +${DEFDIR}/bashgetopt.o: $(BUILTIN_SRCDIR)/bashgetopt.c + @(cd $(DEFDIR) && $(MAKE) $(MFLAGS) DEBUG=${DEBUG} bashgetopt.o) || exit 1 + +${DEFDIR}/builtext.h: $(BUILTIN_DEFS) + @(cd $(DEFDIR) && $(MAKE) $(MFLAGS) builtext.h ) || exit 1 + +# For the justification of the following Makefile rules, see node +# `Automatic Remaking' in GNU Autoconf documentation. + +Makefile makefile: config.status $(srcdir)/Makefile.in + CONFIG_FILES=Makefile CONFIG_HEADERS= $(SHELL) ./config.status + +pathnames.h: config.status $(srcdir)/Makefile.in + CONFIG_HEADERS= $(SHELL) ./config.status + +Makefiles makefiles: config.status $(srcdir)/Makefile.in + @for mf in $(CREATED_MAKEFILES); do \ + CONFIG_FILES=$$mf CONFIG_HEADERS= $(SHELL) ./config.status ; \ + done + +config.h: stamp-h + +stamp-h: config.status $(srcdir)/config.h.in $(srcdir)/config-top.h $(srcdir)/config-bot.h + CONFIG_FILES= CONFIG_HEADERS=config.h $(SHELL) ./config.status + +config.status: $(srcdir)/configure + $(SHELL) ./config.status --recheck + +# comment out for distribution +$(srcdir)/configure: $(srcdir)/configure.in $(srcdir)/aclocal.m4 $(srcdir)/config.h.in + cd $(srcdir) && autoconf + +# for chet +reconfig: force + sh $(srcdir)/configure + +#newversion: mkversion +# $(RM) .build +# ./mkversion -dir $(srcdir) -dist +# mv -f newversion.h version.h +# $(MAKE) -f $(srcdir)/Makefile $(MFLAGS) srcdir=$(srcdir) + +doc documentation: force + @(cd $(DOCDIR) ; $(MAKE) $(MFLAGS) ) + +info dvi ps: force + @(cd $(DOCDIR) ; $(MAKE) $(MFLAGS) CFLAGS='$(CCFLAGS)' $@ ) + +force: + +tags: $(SOURCES) $(BUILTIN_C_SRC) $(LIBRARY_SOURCE) + etags $(SOURCES) $(BUILTIN_C_SRC) $(LIBRARY_SOURCE) + +TAGS: $(SOURCES) $(BUILTIN_C_SRC) $(LIBRARY_SOURCE) + ctags -x $(SOURCES) $(BUILTIN_C_SRC) $(LIBRARY_SOURCE) > $@ + +# Targets that actually do things not part of the build + +installdirs: + @${SHELL} $(SUPPORT_SRC)mkinstalldirs $(DESTDIR)$(bindir) + @${SHELL} $(SUPPORT_SRC)mkinstalldirs $(DESTDIR)$(man1dir) + @${SHELL} $(SUPPORT_SRC)mkinstalldirs $(DESTDIR)$(infodir) + -( cd $(PO_DIR) ; $(MAKE) $(MFLAGS) DESTDIR=$(DESTDIR) $@ ) + +install: .made installdirs + $(INSTALL_PROGRAM) $(INSTALLMODE) $(Program) $(DESTDIR)$(bindir)/$(Program) + $(INSTALL_SCRIPT) $(INSTALLMODE2) bashbug $(DESTDIR)$(bindir)/bashbug + -( cd $(DOCDIR) ; $(MAKE) $(MFLAGS) \ + man1dir=$(man1dir) man1ext=$(man1ext) \ + man3dir=$(man3dir) man3ext=$(man3ext) \ + infodir=$(infodir) htmldir=$(htmldir) DESTDIR=$(DESTDIR) $@ ) + -( cd $(DEFDIR) ; $(MAKE) $(MFLAGS) DESTDIR=$(DESTDIR) $@ ) + -( cd $(PO_DIR) ; $(MAKE) $(MFLAGS) DESTDIR=$(DESTDIR) $@ ) + +install-strip: + $(MAKE) $(MFLAGS) INSTALL_PROGRAM='$(INSTALL_PROGRAM) -s' \ + prefix=${prefix} exec_prefix=${exec_prefix} \ + DESTDIR=$(DESTDIR) install + +uninstall: .made + $(RM) $(DESTDIR)$(bindir)/$(Program) $(DESTDIR)$(bindir)/bashbug + -( cd $(DOCDIR) ; $(MAKE) $(MFLAGS) \ + man1dir=$(man1dir) man1ext=$(man1ext) \ + man3dir=$(man3dir) man3ext=$(man3ext) \ + infodir=$(infodir) htmldir=$(htmldir) DESTDIR=$(DESTDIR) $@ ) + -( cd $(PO_DIR) ; $(MAKE) $(MFLAGS) DESTDIR=$(DESTDIR) $@ ) + +.PHONY: basic-clean clean realclean maintainer-clean distclean mostlyclean maybe-clean + +LIB_SUBDIRS = ${RL_LIBDIR} ${HIST_LIBDIR} ${TERM_LIBDIR} ${GLOB_LIBDIR} \ + ${INTL_LIBDIR} ${TILDE_LIBDIR} ${ALLOC_LIBDIR} ${SH_LIBDIR} + +basic-clean: + $(RM) $(OBJECTS) $(Program) bashbug + $(RM) .build .made version.h pathnames.h + +clean: basic-clean + ( cd $(DOCDIR) && $(MAKE) $(MFLAGS) $@ ) + ( cd builtins && $(MAKE) $(MFLAGS) $@ ) + -( cd $(SDIR) && $(MAKE) $(MFLAGS) $@ ) + -for libdir in ${LIB_SUBDIRS}; do \ + (cd $$libdir && test -f Makefile && $(MAKE) $(MFLAGS) $@) ;\ + done + -( cd $(PO_DIR) ; $(MAKE) $(MFLAGS) DESTDIR=$(DESTDIR) $@ ) + $(RM) $(CREATED_SUPPORT) + +mostlyclean: basic-clean + ( cd $(DOCDIR) && $(MAKE) $(MFLAGS) $@ ) + ( cd builtins && $(MAKE) $(MFLAGS) $@ ) + -( cd $(SDIR) && $(MAKE) $(MFLAGS) $@ ) + -for libdir in ${LIB_SUBDIRS}; do \ + (cd $$libdir && test -f Makefile && $(MAKE) $(MFLAGS) $@) ;\ + done + -( cd $(PO_DIR) ; $(MAKE) $(MFLAGS) DESTDIR=$(DESTDIR) $@ ) + +distclean: basic-clean maybe-clean + ( cd $(DOCDIR) && $(MAKE) $(MFLAGS) $@ ) + ( cd builtins && $(MAKE) $(MFLAGS) $@ ) + -( cd $(SDIR) && $(MAKE) $(MFLAGS) $@ ) + -for libdir in ${LIB_SUBDIRS}; do \ + (cd $$libdir && test -f Makefile && $(MAKE) $(MFLAGS) $@) ;\ + done + -( cd $(PO_DIR) ; $(MAKE) $(MFLAGS) DESTDIR=$(DESTDIR) $@ ) + $(RM) $(CREATED_CONFIGURE) tags TAGS + $(RM) $(CREATED_SUPPORT) Makefile $(CREATED_MAKEFILES) + +maintainer-clean: basic-clean + @echo This command is intended for maintainers to use. + @echo It deletes files that may require special tools to rebuild. + $(RM) y.tab.c y.tab.h parser-built tags TAGS + ( cd $(DOCDIR) && $(MAKE) $(MFLAGS) $@ ) + ( cd builtins && $(MAKE) $(MFLAGS) $@ ) + ( cd $(SDIR) && $(MAKE) $(MFLAGS) $@ ) + -for libdir in ${LIB_SUBDIRS}; do \ + (cd $$libdir && test -f Makefile && $(MAKE) $(MFLAGS) $@) ;\ + done + -( cd $(PO_DIR) ; $(MAKE) $(MFLAGS) DESTDIR=$(DESTDIR) $@ ) + $(RM) $(CREATED_CONFIGURE) $(CREATED_MAKEFILES) + $(RM) $(CREATED_SUPPORT) Makefile + +maybe-clean: + -if test "X$(topdir)" != "X$(BUILD_DIR)" ; then \ + $(RM) parser-built y.tab.c y.tab.h ; \ + fi + +recho$(EXEEXT): $(SUPPORT_SRC)recho.c + @$(CC_FOR_BUILD) $(CCFLAGS_FOR_BUILD) -o $@ $(SUPPORT_SRC)recho.c + +zecho$(EXEEXT): $(SUPPORT_SRC)zecho.c + @$(CC_FOR_BUILD) $(CCFLAGS_FOR_BUILD) -o $@ $(SUPPORT_SRC)zecho.c + +printenv$(EXEEXT): $(SUPPORT_SRC)printenv.c + @$(CC_FOR_BUILD) $(CCFLAGS_FOR_BUILD) -o $@ $(SUPPORT_SRC)printenv.c + +test tests check: force $(Program) $(TESTS_SUPPORT) + @-test -d tests || mkdir tests + @cp $(TESTS_SUPPORT) tests + @( cd $(srcdir)/tests && \ + PATH=$$PATH:$(BUILD_DIR)/tests THIS_SH=$(THIS_SH) $(SHELL) ${TESTSCRIPT} ) + +symlinks: + $(SHELL) $(SUPPORT_SRC)fixlinks -s $(srcdir) + +dist: force + @echo Bash distributions are created using $(srcdir)/support/mkdist. + @echo Here is a sample of the necessary commands: + @echo $(Program) $(srcdir)/support/mkdist -m $(srcdir)/MANIFEST -s $(srcdir) -r ${PACKAGE} $(PACKAGE_VERSION) + @echo tar cf $(PACKAGE)-${PACKAGE_VERSION}.tar ${PACKAGE}-$(PACKAGE_VERSION) + @echo gzip $(PACKAGE)-$(PACKAGE_VERSION).tar + +depend: depends + +depends: force + $(Program) $(SUPPORT_SRC)mkdep -c ${CC} -- ${CCFLAGS} ${CSOURCES} + +#### PRIVATE TARGETS #### +hashtest: hashlib.c + $(CC) -DTEST_HASHING $(CCFLAGS) -o $@ $(srcdir)/hashlib.c + +############################ DEPENDENCIES ############################### + +# Files that depend on the definitions in config-top.h, which are not meant +# to be changed +shell.o: config-top.h +input.o: config-top.h +y.tab.o: config-top.h +jobs.o: config-top.h +nojobs.o: config-top.h +execute_cmd.o: config-top.h +variables.o: config-top.h +builtins/command.o: config-top.h +builtins/common.o: config-top.h +builtins/break.o: config-top.h +builtins/echo.o: config-top.h +builtins/evalstring.o: config-top.h +builtins/exit.o: config-top.h +builtins/kill.o: config-top.h + +# shell basics +copy_cmd.o: shell.h syntax.h config.h bashjmp.h ${BASHINCDIR}/posixjmp.h command.h ${BASHINCDIR}/stdc.h error.h +copy_cmd.o: general.h xmalloc.h bashtypes.h variables.h arrayfunc.h conftypes.h array.h hashlib.h +copy_cmd.o: quit.h ${BASHINCDIR}/maxpath.h unwind_prot.h dispose_cmd.h +copy_cmd.o: make_cmd.h subst.h sig.h pathnames.h externs.h +dispose_cmd.o: bashansi.h ${BASHINCDIR}/ansi_stdlib.h +dispose_cmd.o: shell.h syntax.h config.h bashjmp.h ${BASHINCDIR}/posixjmp.h command.h ${BASHINCDIR}/stdc.h +dispose_cmd.o: error.h general.h xmalloc.h bashtypes.h variables.h arrayfunc.h conftypes.h array.h hashlib.h +dispose_cmd.o: quit.h ${BASHINCDIR}/maxpath.h unwind_prot.h dispose_cmd.h +dispose_cmd.o: make_cmd.h subst.h sig.h pathnames.h externs.h +dispose_cmd.o: ${BASHINCDIR}/ocache.h +error.o: config.h bashtypes.h bashansi.h ${BASHINCDIR}/ansi_stdlib.h flags.h ${BASHINCDIR}/stdc.h error.h +error.o: command.h general.h xmalloc.h externs.h input.h bashhist.h +error.o: shell.h syntax.h config.h bashjmp.h ${BASHINCDIR}/posixjmp.h command.h ${BASHINCDIR}/stdc.h error.h +error.o: general.h xmalloc.h bashtypes.h variables.h arrayfunc.h conftypes.h array.h hashlib.h +error.o: quit.h ${BASHINCDIR}/maxpath.h unwind_prot.h dispose_cmd.h +error.o: make_cmd.h subst.h sig.h pathnames.h externs.h +error.o: input.h execute_cmd.h +eval.o: config.h bashansi.h ${BASHINCDIR}/ansi_stdlib.h trap.h flags.h ${DEFSRC}/common.h +eval.o: shell.h syntax.h config.h bashjmp.h ${BASHINCDIR}/posixjmp.h command.h ${BASHINCDIR}/stdc.h error.h +eval.o: general.h xmalloc.h bashtypes.h variables.h arrayfunc.h conftypes.h array.h hashlib.h +eval.o: quit.h ${BASHINCDIR}/maxpath.h unwind_prot.h dispose_cmd.h +eval.o: make_cmd.h subst.h sig.h pathnames.h externs.h +eval.o: input.h execute_cmd.h +execute_cmd.o: config.h bashtypes.h ${BASHINCDIR}/filecntl.h ${BASHINCDIR}/posixstat.h bashansi.h ${BASHINCDIR}/ansi_stdlib.h +execute_cmd.o: shell.h syntax.h config.h bashjmp.h ${BASHINCDIR}/posixjmp.h command.h ${BASHINCDIR}/stdc.h error.h +execute_cmd.o: general.h xmalloc.h bashtypes.h variables.h arrayfunc.h conftypes.h array.h hashlib.h +execute_cmd.o: quit.h ${BASHINCDIR}/maxpath.h unwind_prot.h dispose_cmd.h +execute_cmd.o: make_cmd.h subst.h sig.h pathnames.h externs.h +execute_cmd.o: ${BASHINCDIR}/memalloc.h ${GRAM_H} flags.h builtins.h jobs.h quit.h siglist.h +execute_cmd.o: execute_cmd.h findcmd.h redir.h trap.h test.h pathexp.h +execute_cmd.o: $(DEFSRC)/common.h ${DEFDIR}/builtext.h ${GLOB_LIBSRC}/strmatch.h +execute_cmd.o: ${BASHINCDIR}/posixtime.h ${BASHINCDIR}/chartypes.h +expr.o: config.h bashansi.h ${BASHINCDIR}/ansi_stdlib.h +expr.o: shell.h syntax.h config.h bashjmp.h ${BASHINCDIR}/posixjmp.h command.h ${BASHINCDIR}/stdc.h error.h +expr.o: general.h xmalloc.h bashtypes.h variables.h arrayfunc.h conftypes.h array.h hashlib.h +expr.o: quit.h ${BASHINCDIR}/maxpath.h unwind_prot.h dispose_cmd.h +expr.o: make_cmd.h subst.h sig.h pathnames.h externs.h +expr.o: ${BASHINCDIR}/chartypes.h +findcmd.o: config.h bashtypes.h ${BASHINCDIR}/filecntl.h ${BASHINCDIR}/posixstat.h bashansi.h +findcmd.o: ${BASHINCDIR}/ansi_stdlib.h ${BASHINCDIR}/memalloc.h shell.h syntax.h bashjmp.h ${BASHINCDIR}/posixjmp.h command.h +findcmd.o: ${BASHINCDIR}/stdc.h error.h general.h xmalloc.h variables.h arrayfunc.h conftypes.h quit.h ${BASHINCDIR}/maxpath.h unwind_prot.h +findcmd.o: dispose_cmd.h make_cmd.h subst.h sig.h pathnames.h externs.h +findcmd.o: flags.h hashlib.h pathexp.h hashcmd.h +findcmd.o: ${BASHINCDIR}/chartypes.h +flags.o: config.h flags.h +flags.o: shell.h syntax.h config.h bashjmp.h ${BASHINCDIR}/posixjmp.h command.h ${BASHINCDIR}/stdc.h error.h +flags.o: general.h xmalloc.h bashtypes.h variables.h arrayfunc.h conftypes.h array.h hashlib.h +flags.o: quit.h ${BASHINCDIR}/maxpath.h unwind_prot.h dispose_cmd.h +flags.o: make_cmd.h subst.h sig.h pathnames.h externs.h bashhist.h +general.o: config.h bashtypes.h ${BASHINCDIR}/posixstat.h ${BASHINCDIR}/filecntl.h bashansi.h ${BASHINCDIR}/ansi_stdlib.h +general.o: shell.h syntax.h config.h bashjmp.h ${BASHINCDIR}/posixjmp.h command.h ${BASHINCDIR}/stdc.h error.h +general.o: general.h xmalloc.h bashtypes.h variables.h arrayfunc.h conftypes.h array.h hashlib.h +general.o: quit.h ${BASHINCDIR}/maxpath.h unwind_prot.h dispose_cmd.h +general.o: make_cmd.h subst.h sig.h pathnames.h externs.h +general.o: ${BASHINCDIR}/maxpath.h ${BASHINCDIR}/posixtime.h +general.o: ${BASHINCDIR}/chartypes.h +hashcmd.o: config.h ${BASHINCDIR}/posixstat.h bashtypes.h bashansi.h ${BASHINCDIR}/ansi_stdlib.h +hashcmd.o: shell.h syntax.h config.h bashjmp.h ${BASHINCDIR}/posixjmp.h command.h ${BASHINCDIR}/stdc.h error.h +hashcmd.o: general.h xmalloc.h bashtypes.h variables.h arrayfunc.h conftypes.h array.h hashcmd.h +hashcmd.o: execute_cmd.h findcmd.h ${BASHINCDIR}/stdc.h hashlib.h +hashlib.o: config.h bashansi.h ${BASHINCDIR}/ansi_stdlib.h +hashlib.o: shell.h syntax.h config.h bashjmp.h ${BASHINCDIR}/posixjmp.h command.h ${BASHINCDIR}/stdc.h error.h +hashlib.o: general.h xmalloc.h bashtypes.h variables.h arrayfunc.h conftypes.h array.h hashlib.h +hashlib.o: quit.h ${BASHINCDIR}/maxpath.h unwind_prot.h dispose_cmd.h +hashlib.o: make_cmd.h subst.h sig.h pathnames.h externs.h +input.o: config.h bashtypes.h ${BASHINCDIR}/filecntl.h ${BASHINCDIR}/posixstat.h bashansi.h ${BASHINCDIR}/ansi_stdlib.h +input.o: command.h ${BASHINCDIR}/stdc.h general.h xmalloc.h input.h error.h externs.h +list.o: shell.h syntax.h config.h bashjmp.h ${BASHINCDIR}/posixjmp.h command.h ${BASHINCDIR}/stdc.h error.h +list.o: general.h xmalloc.h bashtypes.h variables.h arrayfunc.h conftypes.h array.h hashlib.h +list.o: quit.h ${BASHINCDIR}/maxpath.h unwind_prot.h dispose_cmd.h +list.o: make_cmd.h subst.h sig.h pathnames.h externs.h +locale.o: config.h bashtypes.h bashintl.h ${LIBINTL_H} bashansi.h ${BASHINCDIR}/ansi_stdlib.h +locale.o: shell.h syntax.h config.h bashjmp.h ${BASHINCDIR}/posixjmp.h command.h ${BASHINCDIR}/stdc.h error.h +locale.o: general.h xmalloc.h bashtypes.h variables.h arrayfunc.h conftypes.h array.h hashlib.h +locale.o: quit.h ${BASHINCDIR}/maxpath.h unwind_prot.h dispose_cmd.h +locale.o: make_cmd.h subst.h sig.h pathnames.h externs.h +locale.o: ${BASHINCDIR}/chartypes.h +mailcheck.o: config.h bashtypes.h ${BASHINCDIR}/posixstat.h bashansi.h ${BASHINCDIR}/ansi_stdlib.h +mailcheck.o: ${BASHINCDIR}/posixtime.h +mailcheck.o: shell.h syntax.h config.h bashjmp.h ${BASHINCDIR}/posixjmp.h command.h ${BASHINCDIR}/stdc.h error.h +mailcheck.o: general.h xmalloc.h bashtypes.h variables.h arrayfunc.h conftypes.h array.h hashlib.h +mailcheck.o: quit.h ${BASHINCDIR}/maxpath.h unwind_prot.h dispose_cmd.h +mailcheck.o: make_cmd.h subst.h sig.h pathnames.h externs.h +mailcheck.o: execute_cmd.h mailcheck.h +make_cmd.o: config.h bashtypes.h ${BASHINCDIR}/filecntl.h bashansi.h +make_cmd.o: command.h ${BASHINCDIR}/stdc.h general.h xmalloc.h error.h flags.h make_cmd.h +make_cmd.o: variables.h arrayfunc.h conftypes.h array.h hashlib.h subst.h input.h externs.h +make_cmd.o: jobs.h quit.h siglist.h syntax.h dispose_cmd.h +make_cmd.o: ${BASHINCDIR}/shmbutil.h ${BASHINCDIR}/ocache.h +y.tab.o: config.h bashtypes.h bashansi.h ${BASHINCDIR}/ansi_stdlib.h ${BASHINCDIR}/memalloc.h +y.tab.o: shell.h syntax.h config.h bashjmp.h ${BASHINCDIR}/posixjmp.h command.h ${BASHINCDIR}/stdc.h error.h +y.tab.o: general.h xmalloc.h bashtypes.h variables.h arrayfunc.h conftypes.h array.h hashlib.h +y.tab.o: quit.h ${BASHINCDIR}/maxpath.h unwind_prot.h dispose_cmd.h +y.tab.o: make_cmd.h subst.h sig.h pathnames.h externs.h test.h +y.tab.o: trap.h flags.h parser.h input.h mailcheck.h $(DEFSRC)/common.h +y.tab.o: $(DEFDIR)/builtext.h bashline.h bashhist.h jobs.h siglist.h alias.h +pathexp.o: config.h bashtypes.h bashansi.h ${BASHINCDIR}/ansi_stdlib.h +pathexp.o: shell.h syntax.h config.h bashjmp.h ${BASHINCDIR}/posixjmp.h command.h ${BASHINCDIR}/stdc.h error.h +pathexp.o: general.h xmalloc.h bashtypes.h variables.h arrayfunc.h conftypes.h array.h hashlib.h +pathexp.o: quit.h ${BASHINCDIR}/maxpath.h unwind_prot.h dispose_cmd.h +pathexp.o: make_cmd.h subst.h sig.h pathnames.h externs.h +pathexp.o: pathexp.h flags.h +pathexp.o: $(GLOB_LIBSRC)/glob.h $(GLOB_LIBSRC)/strmatch.h +pathexp.o: ${BASHINCDIR}/shmbutil.h +print_cmd.o: config.h bashansi.h ${BASHINCDIR}/ansi_stdlib.h +print_cmd.o: shell.h syntax.h config.h bashjmp.h ${BASHINCDIR}/posixjmp.h command.h ${BASHINCDIR}/stdc.h error.h +print_cmd.o: general.h xmalloc.h bashtypes.h variables.h arrayfunc.h conftypes.h array.h hashlib.h +print_cmd.o: quit.h ${BASHINCDIR}/maxpath.h unwind_prot.h dispose_cmd.h +print_cmd.o: make_cmd.h subst.h sig.h pathnames.h externs.h +print_cmd.o: ${GRAM_H} $(DEFSRC)/common.h +redir.o: config.h bashtypes.h ${BASHINCDIR}/posixstat.h bashansi.h ${BASHINCDIR}/ansi_stdlib.h ${BASHINCDIR}/filecntl.h +redir.o: ${BASHINCDIR}/memalloc.h shell.h syntax.h bashjmp.h ${BASHINCDIR}/posixjmp.h command.h ${BASHINCDIR}/stdc.h error.h +redir.o: general.h xmalloc.h variables.h arrayfunc.h conftypes.h array.h hashlib.h quit.h ${BASHINCDIR}/maxpath.h unwind_prot.h +redir.o: dispose_cmd.h make_cmd.h subst.h sig.h pathnames.h externs.h +redir.o: flags.h execute_cmd.h redir.h input.h +shell.o: config.h bashtypes.h ${BASHINCDIR}/posixstat.h bashansi.h ${BASHINCDIR}/ansi_stdlib.h ${BASHINCDIR}/filecntl.h +shell.o: shell.h syntax.h config.h bashjmp.h ${BASHINCDIR}/posixjmp.h command.h ${BASHINCDIR}/stdc.h error.h +shell.o: general.h xmalloc.h bashtypes.h variables.h arrayfunc.h conftypes.h array.h hashlib.h +shell.o: quit.h ${BASHINCDIR}/maxpath.h unwind_prot.h dispose_cmd.h +shell.o: make_cmd.h subst.h sig.h pathnames.h externs.h +shell.o: flags.h trap.h mailcheck.h builtins.h $(DEFSRC)/common.h +shell.o: jobs.h siglist.h input.h execute_cmd.h findcmd.h bashhist.h +shell.o: ${GLOB_LIBSRC}/strmatch.h ${BASHINCDIR}/posixtime.h +sig.o: config.h bashtypes.h +sig.o: shell.h syntax.h config.h bashjmp.h ${BASHINCDIR}/posixjmp.h command.h ${BASHINCDIR}/stdc.h error.h +sig.o: general.h xmalloc.h bashtypes.h variables.h arrayfunc.h conftypes.h array.h hashlib.h +sig.o: quit.h ${BASHINCDIR}/maxpath.h unwind_prot.h dispose_cmd.h +sig.o: make_cmd.h subst.h sig.h pathnames.h externs.h +sig.o: jobs.h siglist.h trap.h $(DEFSRC)/common.h bashline.h bashhist.h +siglist.o: config.h bashtypes.h siglist.h trap.h +stringlib.o: bashtypes.h ${BASHINCDIR}/chartypes.h +stringlib.o: shell.h syntax.h config.h bashjmp.h ${BASHINCDIR}/posixjmp.h command.h ${BASHINCDIR}/stdc.h error.h +stringlib.o: general.h xmalloc.h bashtypes.h variables.h arrayfunc.h conftypes.h array.h hashlib.h +stringlib.o: quit.h ${BASHINCDIR}/maxpath.h unwind_prot.h dispose_cmd.h +stringlib.o: make_cmd.h subst.h sig.h pathnames.h externs.h +stringlib.o: ${GLOB_LIBSRC}/glob.h ${GLOB_LIBSRC}/strmatch.h +subst.o: config.h bashtypes.h bashansi.h ${BASHINCDIR}/ansi_stdlib.h ${BASHINCDIR}/posixstat.h +subst.o: shell.h syntax.h config.h bashjmp.h ${BASHINCDIR}/posixjmp.h command.h ${BASHINCDIR}/stdc.h error.h +subst.o: general.h xmalloc.h bashtypes.h variables.h arrayfunc.h conftypes.h array.h hashlib.h +subst.o: quit.h ${BASHINCDIR}/maxpath.h unwind_prot.h dispose_cmd.h +subst.o: make_cmd.h subst.h sig.h pathnames.h externs.h +subst.o: flags.h jobs.h siglist.h execute_cmd.h ${BASHINCDIR}/filecntl.h trap.h pathexp.h +subst.o: mailcheck.h input.h $(DEFSRC)/getopt.h $(DEFSRC)/common.h +subst.o: bashline.h bashhist.h ${GLOB_LIBSRC}/strmatch.h +subst.o: ${BASHINCDIR}/chartypes.h +subst.o: ${BASHINCDIR}/shmbutil.h +test.o: bashtypes.h ${BASHINCDIR}/posixstat.h ${BASHINCDIR}/filecntl.h +test.o: shell.h syntax.h config.h bashjmp.h ${BASHINCDIR}/posixjmp.h command.h ${BASHINCDIR}/stdc.h error.h +test.o: general.h xmalloc.h bashtypes.h variables.h arrayfunc.h conftypes.h array.h hashlib.h +test.o: quit.h ${BASHINCDIR}/maxpath.h unwind_prot.h dispose_cmd.h +test.o: make_cmd.h subst.h sig.h pathnames.h externs.h test.h +test.o: ${DEFSRC}/common.h +trap.o: config.h bashtypes.h trap.h bashansi.h ${BASHINCDIR}/ansi_stdlib.h +trap.o: shell.h syntax.h config.h bashjmp.h ${BASHINCDIR}/posixjmp.h command.h ${BASHINCDIR}/stdc.h error.h +trap.o: general.h xmalloc.h bashtypes.h variables.h arrayfunc.h conftypes.h array.h hashlib.h +trap.o: quit.h ${BASHINCDIR}/maxpath.h unwind_prot.h dispose_cmd.h +trap.o: make_cmd.h subst.h sig.h pathnames.h externs.h +trap.o: signames.h $(DEFSRC)/common.h +trap.o: ${DEFDIR}/builtext.h +unwind_prot.o: config.h bashtypes.h bashansi.h ${BASHINCDIR}/ansi_stdlib.h command.h ${BASHINCDIR}/stdc.h +unwind_prot.o: general.h xmalloc.h unwind_prot.h quit.h sig.h +variables.o: config.h bashtypes.h ${BASHINCDIR}/posixstat.h bashansi.h ${BASHINCDIR}/ansi_stdlib.h +variables.o: shell.h syntax.h config.h bashjmp.h ${BASHINCDIR}/posixjmp.h command.h ${BASHINCDIR}/stdc.h error.h +variables.o: general.h xmalloc.h bashtypes.h variables.h arrayfunc.h conftypes.h array.h hashlib.h +variables.o: quit.h ${BASHINCDIR}/maxpath.h unwind_prot.h dispose_cmd.h +variables.o: make_cmd.h subst.h sig.h pathnames.h externs.h +variables.o: flags.h execute_cmd.h mailcheck.h input.h $(DEFSRC)/common.h +variables.o: findcmd.h bashhist.h hashcmd.h pathexp.h +variables.o: pcomplete.h ${BASHINCDIR}/chartypes.h +variables.o: ${BASHINCDIR}/posixtime.h +version.o: conftypes.h patchlevel.h version.h +xmalloc.o: config.h bashtypes.h ${BASHINCDIR}/ansi_stdlib.h error.h + +# job control + +jobs.o: config.h bashtypes.h trap.h ${BASHINCDIR}/filecntl.h input.h ${BASHINCDIR}/shtty.h +jobs.o: bashansi.h ${BASHINCDIR}/ansi_stdlib.h +jobs.o: shell.h syntax.h config.h bashjmp.h ${BASHINCDIR}/posixjmp.h command.h ${BASHINCDIR}/stdc.h error.h +jobs.o: general.h xmalloc.h bashtypes.h variables.h arrayfunc.h conftypes.h array.h hashlib.h +jobs.o: quit.h ${BASHINCDIR}/maxpath.h unwind_prot.h dispose_cmd.h +jobs.o: make_cmd.h subst.h sig.h pathnames.h externs.h +jobs.o: jobs.h flags.h $(DEFSRC)/common.h $(DEFDIR)/builtext.h +jobs.o: ${BASHINCDIR}/posixwait.h ${BASHINCDIR}/unionwait.h +jobs.o: ${BASHINCDIR}/posixtime.h +nojobs.o: config.h bashtypes.h ${BASHINCDIR}/filecntl.h bashjmp.h ${BASHINCDIR}/posixjmp.h +nojobs.o: command.h ${BASHINCDIR}/stdc.h general.h xmalloc.h jobs.h quit.h siglist.h externs.h +nojobs.o: sig.h error.h ${BASHINCDIR}/shtty.h input.h + +# shell features that may be compiled in + +array.o: config.h bashansi.h ${BASHINCDIR}/ansi_stdlib.h +array.o: shell.h syntax.h config.h bashjmp.h ${BASHINCDIR}/posixjmp.h command.h ${BASHINCDIR}/stdc.h error.h +array.o: general.h xmalloc.h bashtypes.h variables.h arrayfunc.h conftypes.h array.h hashlib.h +array.o: quit.h ${BASHINCDIR}/maxpath.h unwind_prot.h dispose_cmd.h +array.o: make_cmd.h subst.h sig.h pathnames.h externs.h +array.o: $(DEFSRC)/common.h +arrayfunc.o: config.h bashansi.h ${BASHINCDIR}/ansi_stdlib.h +arrayfunc.o: shell.h syntax.h config.h bashjmp.h ${BASHINCDIR}/posixjmp.h command.h ${BASHINCDIR}/stdc.h error.h +arrayfunc.o: general.h xmalloc.h bashtypes.h variables.h arrayfunc.h conftypes.h array.h hashlib.h +arrayfunc.o: quit.h ${BASHINCDIR}/maxpath.h unwind_prot.h dispose_cmd.h +arrayfunc.o: make_cmd.h subst.h sig.h pathnames.h externs.h +arrayfunc.o: $(DEFSRC)/common.h +arrayfunc.o: ${BASHINCDIR}/shmbutil.h +braces.o: config.h bashansi.h ${BASHINCDIR}/ansi_stdlib.h +braces.o: shell.h syntax.h config.h bashjmp.h ${BASHINCDIR}/posixjmp.h command.h ${BASHINCDIR}/stdc.h error.h +braces.o: general.h xmalloc.h bashtypes.h variables.h arrayfunc.h conftypes.h array.h hashlib.h +braces.o: quit.h ${BASHINCDIR}/maxpath.h unwind_prot.h dispose_cmd.h +braces.o: make_cmd.h subst.h sig.h pathnames.h externs.h +braces.o: ${BASHINCDIR}/shmbutil.h +alias.o: config.h bashansi.h ${BASHINCDIR}/ansi_stdlib.h command.h ${BASHINCDIR}/stdc.h +alias.o: general.h xmalloc.h bashtypes.h externs.h alias.h +alias.o: pcomplete.h +alias.o: ${BASHINCDIR}/chartypes.h + +pcomplib.o: config.h bashansi.h ${BASHINCDIR}/ansi_stdlib.h bashtypes.h +pcomplib.o: ${BASHINCDIR}/stdc.h hashlib.h pcomplete.h shell.h syntax.h +pcomplib.o: bashjmp.h command.h general.h xmalloc.h error.h variables.h arrayfunc.h conftypes.h quit.h +pcomplib.o: unwind_prot.h dispose_cmd.h make_cmd.h subst.h sig.h pathnames.h +pcomplib.o: externs.h ${BASHINCDIR}/maxpath.h + +pcomplete.o: config.h bashansi.h ${BASHINCDIR}/ansi_stdlib.h bashtypes.h +pcomplete.o: ${BASHINCDIR}/stdc.h hashlib.h pcomplete.h shell.h syntax.h +pcomplete.o: bashjmp.h command.h general.h xmalloc.h error.h variables.h arrayfunc.h conftypes.h quit.h +pcomplete.o: unwind_prot.h dispose_cmd.h make_cmd.h subst.h sig.h pathnames.h +pcomplete.o: externs.h ${BASHINCDIR}/maxpath.h execute_cmd.h + +# library support files + +bashhist.o: config.h bashtypes.h bashansi.h ${BASHINCDIR}/ansi_stdlib.h ${BASHINCDIR}/posixstat.h +bashhist.o: ${BASHINCDIR}/filecntl.h +bashhist.o: shell.h syntax.h config.h bashjmp.h ${BASHINCDIR}/posixjmp.h command.h ${BASHINCDIR}/stdc.h error.h +bashhist.o: general.h xmalloc.h bashtypes.h variables.h arrayfunc.h conftypes.h array.h hashlib.h +bashhist.o: quit.h ${BASHINCDIR}/maxpath.h unwind_prot.h dispose_cmd.h +bashhist.o: make_cmd.h subst.h sig.h pathnames.h externs.h +bashhist.o: flags.h input.h parser.h pathexp.h $(DEFSRC)/common.h bashline.h +bashhist.o: $(GLOB_LIBSRC)/strmatch.h +bashline.o: config.h bashtypes.h ${BASHINCDIR}/posixstat.h bashansi.h ${BASHINCDIR}/ansi_stdlib.h +bashline.o: shell.h syntax.h config.h bashjmp.h ${BASHINCDIR}/posixjmp.h command.h ${BASHINCDIR}/stdc.h error.h +bashline.o: general.h xmalloc.h bashtypes.h variables.h arrayfunc.h conftypes.h array.h hashlib.h +bashline.o: quit.h ${BASHINCDIR}/maxpath.h unwind_prot.h dispose_cmd.h +bashline.o: make_cmd.h subst.h sig.h pathnames.h externs.h +bashline.o: builtins.h bashhist.h bashline.h execute_cmd.h findcmd.h pathexp.h +bashline.o: $(DEFSRC)/common.h $(GLOB_LIBSRC)/glob.h alias.h +bashline.o: pcomplete.h ${BASHINCDIR}/chartypes.h input.h +bracecomp.o: config.h bashansi.h ${BASHINCDIR}/ansi_stdlib.h +bracecomp.o: shell.h syntax.h config.h bashjmp.h ${BASHINCDIR}/posixjmp.h command.h ${BASHINCDIR}/stdc.h error.h +bracecomp.o: general.h xmalloc.h bashtypes.h variables.h arrayfunc.h conftypes.h array.h hashlib.h +bracecomp.o: quit.h ${BASHINCDIR}/maxpath.h unwind_prot.h dispose_cmd.h +bracecomp.o: make_cmd.h subst.h sig.h pathnames.h externs.h +bracecomp.o: shell.h syntax.h bashjmp.h ${BASHINCDIR}/posixjmp.h sig.h command.h hashlib.h builtins.h general.h xmalloc.h +bracecomp.o: quit.h alias.h config.h variables.h arrayfunc.h conftypes.h +bracecomp.o: dispose_cmd.h make_cmd.h subst.h externs.h ${BASHINCDIR}/stdc.h + +# library dependencies + +bashline.o: $(RL_LIBSRC)/rlconf.h +bashline.o: $(RL_LIBSRC)/keymaps.h $(RL_LIBSRC)/rlstdc.h +bashline.o: $(RL_LIBSRC)/chardefs.h $(RL_LIBSRC)/readline.h +bracecomp.o: $(RL_LIBSRC)/keymaps.h $(RL_LIBSRC)/chardefs.h +bracecomp.o: $(RL_LIBSRC)/readline.h $(RL_LIBSRC)/rlstdc.h +y.tab.o: $(RL_LIBSRC)/keymaps.h $(RL_LIBSRC)/chardefs.h +y.tab.o: $(RL_LIBSRC)/readline.h $(RL_LIBSRC)/rlstdc.h +subst.o: $(RL_LIBSRC)/keymaps.h $(RL_LIBSRC)/chardefs.h +subst.o: $(RL_LIBSRC)/readline.h $(RL_LIBSRC)/rlstdc.h + +shell.o: $(HIST_LIBSRC)/history.h $(HIST_LIBSRC)/rlstdc.h +subst.o: $(HIST_LIBSRC)/history.h $(HIST_LIBSRC)/rlstdc.h +bashline.o: $(HIST_LIBSRC)/history.h $(HIST_LIBSRC)/rlstdc.h +bashhist.o: $(HIST_LIBSRC)/history.h $(HIST_LIBSRC)/rlstdc.h +y.tab.o: $(HIST_LIBSRC)/history.h $(HIST_LIBSRC)/rlstdc.h + +execute_cmd.o: $(TILDE_LIBSRC)/tilde.h +general.o: $(TILDE_LIBSRC)/tilde.h +mailcheck.o: $(TILDE_LIBSRC)/tilde.h +shell.o: $(TILDE_LIBSRC)/tilde.h +subst.o: $(TILDE_LIBSRC)/tilde.h +variables.o: $(TILDE_LIBSRC)/tilde.h + +# libintl dependencies +arrayfunc.o: bashintl.h ${LIBINTL_H} $(BASHINCDIR)/gettext.h +bashhist.o: bashintl.h ${LIBINTL_H} $(BASHINCDIR)/gettext.h +bashline.o: bashintl.h ${LIBINTL_H} $(BASHINCDIR)/gettext.h +braces.o: bashintl.h ${LIBINTL_H} $(BASHINCDIR)/gettext.h +error.o: bashintl.h ${LIBINTL_H} $(BASHINCDIR)/gettext.h +eval.o: bashintl.h ${LIBINTL_H} $(BASHINCDIR)/gettext.h +execute_cmd.o: bashintl.h ${LIBINTL_H} $(BASHINCDIR)/gettext.h +expr.o: bashintl.h ${LIBINTL_H} $(BASHINCDIR)/gettext.h +general.o: bashintl.h ${LIBINTL_H} $(BASHINCDIR)/gettext.h +input.o: bashintl.h ${LIBINTL_H} $(BASHINCDIR)/gettext.h +jobs.o: bashintl.h ${LIBINTL_H} $(BASHINCDIR)/gettext.h +mailcheck.o: bashintl.h ${LIBINTL_H} $(BASHINCDIR)/gettext.h +make_cmd.o: bashintl.h ${LIBINTL_H} $(BASHINCDIR)/gettext.h +nojobs.o: bashintl.h ${LIBINTL_H} $(BASHINCDIR)/gettext.h +parse.y: bashintl.h ${LIBINTL_H} $(BASHINCDIR)/gettext.h +pcomplete.o: bashintl.h ${LIBINTL_H} $(BASHINCDIR)/gettext.h +pcomplib.o: bashintl.h ${LIBINTL_H} $(BASHINCDIR)/gettext.h +print_cmd.o: bashintl.h ${LIBINTL_H} $(BASHINCDIR)/gettext.h +redir.o: bashintl.h ${LIBINTL_H} $(BASHINCDIR)/gettext.h +shell.o: bashintl.h ${LIBINTL_H} $(BASHINCDIR)/gettext.h +sig.o: bashintl.h ${LIBINTL_H} $(BASHINCDIR)/gettext.h +siglist.o: bashintl.h ${LIBINTL_H} $(BASHINCDIR)/gettext.h +subst.o: bashintl.h ${LIBINTL_H} $(BASHINCDIR)/gettext.h +test.o: bashintl.h ${LIBINTL_H} $(BASHINCDIR)/gettext.h +trap.o: bashintl.h ${LIBINTL_H} $(BASHINCDIR)/gettext.h +variables.o: bashintl.h ${LIBINTL_H} $(BASHINCDIR)/gettext.h +version.o: bashintl.h ${LIBINTL_H} $(BASHINCDIR)/gettext.h +xmalloc.o: bashintl.h ${LIBINTL_H} $(BASHINCDIR)/gettext.h + +# XXX - dependencies checked through here + +# builtin c sources +builtins/bashgetopt.o: config.h bashansi.h ${BASHINCDIR}/ansi_stdlib.h +builtins/bashgetopt.o: shell.h syntax.h config.h bashjmp.h command.h general.h xmalloc.h error.h +builtins/bashgetopt.o: variables.h arrayfunc.h conftypes.h quit.h ${BASHINCDIR}/maxpath.h unwind_prot.h dispose_cmd.h +builtins/bashgetopt.o: make_cmd.h subst.h sig.h pathnames.h externs.h +builtins/bashgetopt.o: $(DEFSRC)/common.h +builtins/bashgetopt.o: ${BASHINCDIR}/chartypes.h +builtins/common.o: bashtypes.h ${BASHINCDIR}/posixstat.h bashansi.h ${BASHINCDIR}/ansi_stdlib.h +builtins/common.o: shell.h syntax.h config.h bashjmp.h ${BASHINCDIR}/posixjmp.h sig.h command.h +builtins/common.o: ${BASHINCDIR}/memalloc.h variables.h arrayfunc.h conftypes.h input.h siglist.h +builtins/common.o: quit.h unwind_prot.h ${BASHINCDIR}/maxpath.h jobs.h builtins.h +builtins/common.o: dispose_cmd.h make_cmd.h subst.h externs.h bashhist.h +builtins/common.o: execute_cmd.h ${BASHINCDIR}/stdc.h general.h xmalloc.h error.h pathnames.h +builtins/common.o: ${DEFDIR}/builtext.h +builtins/common.o: ${BASHINCDIR}/chartypes.h +builtins/evalfile.o: bashtypes.h ${BASHINCDIR}/posixstat.h ${BASHINCDIR}/filecntl.h bashansi.h ${BASHINCDIR}/ansi_stdlib.h +builtins/evalfile.o: shell.h syntax.h config.h bashjmp.h command.h general.h xmalloc.h error.h +builtins/evalfile.o: variables.h arrayfunc.h conftypes.h quit.h ${BASHINCDIR}/maxpath.h unwind_prot.h dispose_cmd.h +builtins/evalfile.o: make_cmd.h subst.h sig.h pathnames.h externs.h +builtins/evalfile.o: jobs.h builtins.h flags.h input.h execute_cmd.h +builtins/evalfile.o: bashhist.h $(DEFSRC)/common.h +builtins/evalstring.o: config.h bashansi.h ${BASHINCDIR}/ansi_stdlib.h +builtins/evalstring.o: shell.h syntax.h bashjmp.h ${BASHINCDIR}/posixjmp.h sig.h command.h siglist.h +builtins/evalstring.o: ${BASHINCDIR}/memalloc.h variables.h arrayfunc.h conftypes.h input.h +builtins/evalstring.o: quit.h unwind_prot.h ${BASHINCDIR}/maxpath.h jobs.h builtins.h +builtins/evalstring.o: dispose_cmd.h make_cmd.h subst.h externs.h +builtins/evalstring.o: jobs.h builtins.h flags.h input.h execute_cmd.h +builtins/evalstring.o: bashhist.h $(DEFSRC)/common.h +builtins/getopt.o: config.h ${BASHINCDIR}/memalloc.h +builtins/getopt.o: shell.h syntax.h bashjmp.h command.h general.h xmalloc.h error.h +builtins/getopt.o: variables.h arrayfunc.h conftypes.h quit.h ${BASHINCDIR}/maxpath.h unwind_prot.h dispose_cmd.h +builtins/getopt.o: make_cmd.h subst.h sig.h pathnames.h externs.h +builtins/getopt.o: $(DEFSRC)/getopt.h +builtins/mkbuiltins.o: config.h bashtypes.h ${BASHINCDIR}/posixstat.h ${BASHINCDIR}/filecntl.h +builtins/mkbuiltins.o: bashansi.h ${BASHINCDIR}/ansi_stdlib.h + +# builtin def files +builtins/alias.o: command.h config.h ${BASHINCDIR}/memalloc.h error.h general.h xmalloc.h ${BASHINCDIR}/maxpath.h +builtins/alias.o: quit.h $(DEFSRC)/common.h +builtins/alias.o: shell.h syntax.h bashjmp.h ${BASHINCDIR}/posixjmp.h sig.h command.h ${BASHINCDIR}/stdc.h unwind_prot.h +builtins/alias.o: dispose_cmd.h make_cmd.h subst.h externs.h variables.h arrayfunc.h conftypes.h +builtins/bind.o: command.h config.h ${BASHINCDIR}/memalloc.h error.h general.h xmalloc.h ${BASHINCDIR}/maxpath.h +builtins/bind.o: dispose_cmd.h make_cmd.h subst.h externs.h ${BASHINCDIR}/stdc.h +builtins/bind.o: shell.h syntax.h bashjmp.h ${BASHINCDIR}/posixjmp.h sig.h unwind_prot.h variables.h arrayfunc.h conftypes.h quit.h +builtins/bind.o: $(DEFSRC)/bashgetopt.h +builtins/break.o: command.h config.h ${BASHINCDIR}/memalloc.h error.h general.h xmalloc.h ${BASHINCDIR}/maxpath.h +builtins/break.o: shell.h syntax.h bashjmp.h ${BASHINCDIR}/posixjmp.h sig.h unwind_prot.h variables.h arrayfunc.h conftypes.h quit.h +builtins/break.o: dispose_cmd.h make_cmd.h subst.h externs.h ${BASHINCDIR}/stdc.h +builtins/builtin.o: command.h config.h ${BASHINCDIR}/memalloc.h error.h general.h xmalloc.h ${BASHINCDIR}/maxpath.h +builtins/builtin.o: quit.h $(DEFSRC)/common.h $(DEFSRC)/bashgetopt.h +builtins/builtin.o: shell.h syntax.h bashjmp.h ${BASHINCDIR}/posixjmp.h sig.h unwind_prot.h variables.h arrayfunc.h conftypes.h +builtins/builtin.o: dispose_cmd.h make_cmd.h subst.h externs.h ${BASHINCDIR}/stdc.h +builtins/caller.o: command.h config.h ${BASHINCDIR}/memalloc.h error.h general.h xmalloc.h ${BASHINCDIR}/maxpath.h +builtins/caller.o: shell.h syntax.h bashjmp.h ${BASHINCDIR}/posixjmp.h sig.h unwind_prot.h variables.h arrayfunc.h conftypes.h +builtins/caller.o: dispose_cmd.h make_cmd.h subst.h externs.h ${BASHINCDIR}/stdc.h +builtins/caller.o: $(DEFSRC)/common.h quit.h +builtins/caller.o: ${BASHINCDIR}/chartypes.h bashtypes.h +builtins/caller.o: ${DEFDIR}/builtext.h +builtins/cd.o: command.h config.h ${BASHINCDIR}/memalloc.h error.h general.h xmalloc.h ${BASHINCDIR}/maxpath.h +builtins/cd.o: shell.h syntax.h bashjmp.h ${BASHINCDIR}/posixjmp.h sig.h unwind_prot.h variables.h arrayfunc.h conftypes.h +builtins/cd.o: dispose_cmd.h make_cmd.h subst.h externs.h ${BASHINCDIR}/stdc.h +builtins/cd.o: $(DEFSRC)/common.h quit.h +builtins/command.o: command.h config.h ${BASHINCDIR}/memalloc.h error.h general.h xmalloc.h ${BASHINCDIR}/maxpath.h +builtins/command.o: quit.h $(DEFSRC)/bashgetopt.h +builtins/command.o: shell.h syntax.h bashjmp.h ${BASHINCDIR}/posixjmp.h sig.h unwind_prot.h variables.h arrayfunc.h conftypes.h +builtins/command.o: dispose_cmd.h make_cmd.h subst.h externs.h ${BASHINCDIR}/stdc.h +builtins/declare.o: command.h config.h ${BASHINCDIR}/memalloc.h error.h general.h xmalloc.h ${BASHINCDIR}/maxpath.h +builtins/declare.o: shell.h syntax.h bashjmp.h ${BASHINCDIR}/posixjmp.h sig.h unwind_prot.h variables.h arrayfunc.h conftypes.h quit.h +builtins/declare.o: dispose_cmd.h make_cmd.h subst.h externs.h ${BASHINCDIR}/stdc.h +builtins/declare.o: $(DEFSRC)/bashgetopt.h +builtins/echo.o: command.h config.h ${BASHINCDIR}/memalloc.h error.h general.h xmalloc.h ${BASHINCDIR}/maxpath.h +builtins/echo.o: shell.h syntax.h bashjmp.h ${BASHINCDIR}/posixjmp.h sig.h unwind_prot.h variables.h arrayfunc.h conftypes.h quit.h +builtins/echo.o: dispose_cmd.h make_cmd.h subst.h externs.h ${BASHINCDIR}/stdc.h +builtins/enable.o: command.h config.h ${BASHINCDIR}/memalloc.h error.h general.h xmalloc.h ${BASHINCDIR}/maxpath.h +builtins/enable.o: shell.h syntax.h bashjmp.h ${BASHINCDIR}/posixjmp.h sig.h unwind_prot.h variables.h arrayfunc.h conftypes.h quit.h +builtins/enable.o: dispose_cmd.h make_cmd.h subst.h externs.h ${BASHINCDIR}/stdc.h +builtins/enable.o: pcomplete.h +builtins/eval.o: command.h config.h ${BASHINCDIR}/memalloc.h error.h general.h xmalloc.h ${BASHINCDIR}/maxpath.h +builtins/eval.o: shell.h syntax.h bashjmp.h ${BASHINCDIR}/posixjmp.h sig.h unwind_prot.h variables.h arrayfunc.h conftypes.h quit.h +builtins/eval.o: dispose_cmd.h make_cmd.h subst.h externs.h ${BASHINCDIR}/stdc.h +builtins/exec.o: bashtypes.h +builtins/exec.o: command.h config.h ${BASHINCDIR}/memalloc.h error.h general.h xmalloc.h ${BASHINCDIR}/maxpath.h +builtins/exec.o: shell.h syntax.h bashjmp.h ${BASHINCDIR}/posixjmp.h sig.h unwind_prot.h variables.h arrayfunc.h conftypes.h +builtins/exec.o: dispose_cmd.h make_cmd.h subst.h externs.h execute_cmd.h +builtins/exec.o: findcmd.h flags.h quit.h $(DEFSRC)/common.h ${BASHINCDIR}/stdc.h +builtins/exit.o: bashtypes.h +builtins/exit.o: command.h config.h ${BASHINCDIR}/memalloc.h error.h general.h xmalloc.h ${BASHINCDIR}/maxpath.h +builtins/exit.o: shell.h syntax.h bashjmp.h ${BASHINCDIR}/posixjmp.h sig.h unwind_prot.h variables.h arrayfunc.h conftypes.h quit.h +builtins/exit.o: dispose_cmd.h make_cmd.h subst.h externs.h ${BASHINCDIR}/stdc.h +builtins/fc.o: bashtypes.h ${BASHINCDIR}/posixstat.h +builtins/fc.o: bashansi.h ${BASHINCDIR}/ansi_stdlib.h builtins.h command.h ${BASHINCDIR}/stdc.h +builtins/fc.o: command.h config.h ${BASHINCDIR}/memalloc.h error.h general.h xmalloc.h ${BASHINCDIR}/maxpath.h +builtins/fc.o: flags.h unwind_prot.h variables.h arrayfunc.h conftypes.h shell.h syntax.h bashjmp.h ${BASHINCDIR}/posixjmp.h sig.h +builtins/fc.o: dispose_cmd.h make_cmd.h subst.h externs.h ${BASHINCDIR}/stdc.h quit.h +builtins/fc.o: $(DEFSRC)/bashgetopt.h bashhist.h +builtins/fc.o: ${BASHINCDIR}/chartypes.h +builtins/fg_bg.o: bashtypes.h $(DEFSRC)/bashgetopt.h +builtins/fg_bg.o: command.h config.h ${BASHINCDIR}/memalloc.h error.h general.h xmalloc.h ${BASHINCDIR}/maxpath.h +builtins/fg_bg.o: shell.h syntax.h bashjmp.h ${BASHINCDIR}/posixjmp.h sig.h unwind_prot.h variables.h arrayfunc.h conftypes.h quit.h +builtins/fg_bg.o: dispose_cmd.h make_cmd.h subst.h externs.h ${BASHINCDIR}/stdc.h +builtins/getopts.o: command.h config.h ${BASHINCDIR}/memalloc.h error.h general.h xmalloc.h ${BASHINCDIR}/maxpath.h +builtins/getopts.o: shell.h syntax.h bashjmp.h ${BASHINCDIR}/posixjmp.h sig.h unwind_prot.h variables.h arrayfunc.h conftypes.h quit.h +builtins/getopts.o: dispose_cmd.h make_cmd.h subst.h externs.h ${BASHINCDIR}/stdc.h +builtins/hash.o: bashtypes.h +builtins/hash.o: builtins.h command.h findcmd.h ${BASHINCDIR}/stdc.h $(DEFSRC)/common.h +builtins/hash.o: command.h config.h ${BASHINCDIR}/memalloc.h error.h general.h xmalloc.h ${BASHINCDIR}/maxpath.h +builtins/hash.o: shell.h syntax.h bashjmp.h ${BASHINCDIR}/posixjmp.h sig.h unwind_prot.h variables.h arrayfunc.h conftypes.h quit.h +builtins/help.o: command.h config.h ${BASHINCDIR}/memalloc.h error.h general.h xmalloc.h ${BASHINCDIR}/maxpath.h +builtins/help.o: dispose_cmd.h make_cmd.h subst.h externs.h ${BASHINCDIR}/stdc.h +builtins/help.o: shell.h syntax.h bashjmp.h ${BASHINCDIR}/posixjmp.h sig.h unwind_prot.h variables.h arrayfunc.h conftypes.h quit.h +builtins/help.o: $(GLOB_LIBSRC)/glob.h +builtins/history.o: bashtypes.h +builtins/history.o: command.h config.h ${BASHINCDIR}/memalloc.h error.h general.h xmalloc.h ${BASHINCDIR}/maxpath.h +builtins/history.o: quit.h dispose_cmd.h make_cmd.h subst.h externs.h ${BASHINCDIR}/stdc.h +builtins/history.o: ${BASHINCDIR}/filecntl.h shell.h syntax.h bashjmp.h ${BASHINCDIR}/posixjmp.h sig.h unwind_prot.h +builtins/history.o: bashhist.h variables.h arrayfunc.h conftypes.h +builtins/inlib.o: command.h config.h ${BASHINCDIR}/memalloc.h error.h general.h xmalloc.h ${BASHINCDIR}/maxpath.h +builtins/inlib.o: shell.h syntax.h bashjmp.h ${BASHINCDIR}/posixjmp.h sig.h unwind_prot.h variables.h arrayfunc.h conftypes.h quit.h +builtins/inlib.o: dispose_cmd.h make_cmd.h subst.h externs.h ${BASHINCDIR}/stdc.h +builtins/jobs.o: command.h config.h ${BASHINCDIR}/memalloc.h error.h general.h xmalloc.h ${BASHINCDIR}/maxpath.h +builtins/jobs.o: quit.h $(DEFSRC)/bashgetopt.h +builtins/jobs.o: shell.h syntax.h bashjmp.h ${BASHINCDIR}/posixjmp.h sig.h unwind_prot.h variables.h arrayfunc.h conftypes.h +builtins/jobs.o: dispose_cmd.h make_cmd.h subst.h externs.h ${BASHINCDIR}/stdc.h +builtins/kill.o: command.h config.h ${BASHINCDIR}/memalloc.h error.h general.h xmalloc.h ${BASHINCDIR}/maxpath.h +builtins/kill.o: quit.h dispose_cmd.h make_cmd.h subst.h externs.h ${BASHINCDIR}/stdc.h +builtins/kill.o: shell.h syntax.h bashjmp.h ${BASHINCDIR}/posixjmp.h sig.h trap.h unwind_prot.h variables.h arrayfunc.h conftypes.h +builtins/let.o: command.h config.h ${BASHINCDIR}/memalloc.h error.h general.h xmalloc.h ${BASHINCDIR}/maxpath.h +builtins/let.o: quit.h dispose_cmd.h make_cmd.h subst.h externs.h ${BASHINCDIR}/stdc.h +builtins/let.o: shell.h syntax.h bashjmp.h ${BASHINCDIR}/posixjmp.h sig.h unwind_prot.h variables.h arrayfunc.h conftypes.h +builtins/printf.o: config.h ${BASHINCDIR}/memalloc.h bashjmp.h command.h error.h +builtins/printf.o: general.h xmalloc.h quit.h dispose_cmd.h make_cmd.h subst.h +builtins/printf.o: externs.h sig.h pathnames.h shell.h syntax.h unwind_prot.h +builtins/printf.o: variables.h arrayfunc.h conftypes.h ${BASHINCDIR}/stdc.h $(DEFSRC)/bashgetopt.h +builtins/printf.o: ${BASHINCDIR}/chartypes.h +builtins/pushd.o: command.h config.h ${BASHINCDIR}/memalloc.h error.h general.h xmalloc.h ${BASHINCDIR}/maxpath.h +builtins/pushd.o: quit.h dispose_cmd.h make_cmd.h subst.h externs.h ${BASHINCDIR}/stdc.h +builtins/pushd.o: shell.h syntax.h bashjmp.h ${BASHINCDIR}/posixjmp.h sig.h unwind_prot.h variables.h arrayfunc.h conftypes.h +builtins/pushd.o: $(DEFSRC)/common.h +builtins/read.o: command.h config.h ${BASHINCDIR}/memalloc.h error.h general.h xmalloc.h ${BASHINCDIR}/maxpath.h +builtins/read.o: quit.h dispose_cmd.h make_cmd.h subst.h externs.h ${BASHINCDIR}/stdc.h +builtins/read.o: shell.h syntax.h bashjmp.h ${BASHINCDIR}/posixjmp.h sig.h unwind_prot.h variables.h arrayfunc.h conftypes.h +builtins/return.o: command.h config.h ${BASHINCDIR}/memalloc.h error.h general.h xmalloc.h ${BASHINCDIR}/maxpath.h +builtins/return.o: quit.h dispose_cmd.h make_cmd.h subst.h externs.h ${BASHINCDIR}/stdc.h +builtins/return.o: shell.h syntax.h bashjmp.h ${BASHINCDIR}/posixjmp.h sig.h unwind_prot.h variables.h arrayfunc.h conftypes.h +builtins/set.o: command.h config.h ${BASHINCDIR}/memalloc.h error.h general.h xmalloc.h ${BASHINCDIR}/maxpath.h +builtins/set.o: quit.h dispose_cmd.h make_cmd.h subst.h externs.h ${BASHINCDIR}/stdc.h +builtins/set.o: shell.h syntax.h bashjmp.h ${BASHINCDIR}/posixjmp.h sig.h unwind_prot.h variables.h arrayfunc.h conftypes.h flags.h +builtins/setattr.o: command.h config.h ${BASHINCDIR}/memalloc.h error.h general.h xmalloc.h ${BASHINCDIR}/maxpath.h +builtins/setattr.o: quit.h $(DEFSRC)/common.h $(DEFSRC)/bashgetopt.h +builtins/setattr.o: shell.h syntax.h bashjmp.h ${BASHINCDIR}/posixjmp.h sig.h unwind_prot.h variables.h arrayfunc.h conftypes.h +builtins/setattr.o: dispose_cmd.h make_cmd.h subst.h externs.h ${BASHINCDIR}/stdc.h +builtins/shift.o: command.h config.h ${BASHINCDIR}/memalloc.h error.h general.h xmalloc.h ${BASHINCDIR}/maxpath.h +builtins/shift.o: quit.h dispose_cmd.h make_cmd.h subst.h externs.h ${BASHINCDIR}/stdc.h +builtins/shift.o: shell.h syntax.h bashjmp.h ${BASHINCDIR}/posixjmp.h sig.h unwind_prot.h variables.h arrayfunc.h conftypes.h +builtins/shift.o: dispose_cmd.h make_cmd.h subst.h externs.h ${BASHINCDIR}/stdc.h +builtins/shopt.o: command.h config.h ${BASHINCDIR}/memalloc.h error.h general.h xmalloc.h +builtins/shopt.o: quit.h dispose_cmd.h make_cmd.h subst.h externs.h +builtins/shopt.o: shell.h syntax.h bashjmp.h ${BASHINCDIR}/posixjmp.h unwind_prot.h variables.h arrayfunc.h conftypes.h ${BASHINCDIR}/maxpath.h +builtins/shopt.o: $(DEFSRC)/common.h $(DEFSRC)/bashgetopt.h +builtins/source.o: command.h config.h ${BASHINCDIR}/memalloc.h error.h general.h xmalloc.h ${BASHINCDIR}/maxpath.h +builtins/source.o: quit.h dispose_cmd.h make_cmd.h subst.h externs.h ${BASHINCDIR}/stdc.h +builtins/source.o: shell.h syntax.h bashjmp.h ${BASHINCDIR}/posixjmp.h sig.h unwind_prot.h variables.h arrayfunc.h conftypes.h +builtins/source.o: findcmd.h $(DEFSRC)/bashgetopt.h flags.h trap.h +builtins/suspend.o: command.h config.h ${BASHINCDIR}/memalloc.h error.h general.h xmalloc.h ${BASHINCDIR}/maxpath.h +builtins/suspend.o: quit.h dispose_cmd.h make_cmd.h subst.h externs.h ${BASHINCDIR}/stdc.h +builtins/suspend.o: shell.h syntax.h bashjmp.h ${BASHINCDIR}/posixjmp.h sig.h unwind_prot.h variables.h arrayfunc.h conftypes.h +builtins/test.o: command.h config.h ${BASHINCDIR}/memalloc.h error.h general.h xmalloc.h ${BASHINCDIR}/maxpath.h +builtins/test.o: quit.h dispose_cmd.h make_cmd.h subst.h externs.h ${BASHINCDIR}/stdc.h +builtins/test.o: shell.h syntax.h bashjmp.h ${BASHINCDIR}/posixjmp.h sig.h unwind_prot.h variables.h arrayfunc.h conftypes.h +builtins/test.o: test.h +builtins/times.o: command.h config.h ${BASHINCDIR}/memalloc.h error.h general.h xmalloc.h ${BASHINCDIR}/maxpath.h +builtins/times.o: quit.h dispose_cmd.h make_cmd.h subst.h externs.h ${BASHINCDIR}/stdc.h +builtins/times.o: shell.h syntax.h bashjmp.h ${BASHINCDIR}/posixjmp.h sig.h unwind_prot.h variables.h arrayfunc.h conftypes.h +builtins/trap.o: command.h config.h ${BASHINCDIR}/memalloc.h error.h general.h xmalloc.h ${BASHINCDIR}/maxpath.h +builtins/trap.o: quit.h $(DEFSRC)/common.h +builtins/trap.o: shell.h syntax.h bashjmp.h ${BASHINCDIR}/posixjmp.h sig.h unwind_prot.h variables.h arrayfunc.h conftypes.h +builtins/trap.o: dispose_cmd.h make_cmd.h subst.h externs.h ${BASHINCDIR}/stdc.h +builtins/type.o: command.h config.h ${BASHINCDIR}/memalloc.h error.h general.h xmalloc.h ${BASHINCDIR}/maxpath.h +builtins/type.o: quit.h $(DEFSRC)/common.h findcmd.h +builtins/type.o: shell.h syntax.h bashjmp.h ${BASHINCDIR}/posixjmp.h sig.h unwind_prot.h variables.h arrayfunc.h conftypes.h +builtins/type.o: dispose_cmd.h make_cmd.h subst.h externs.h ${BASHINCDIR}/stdc.h +builtins/ulimit.o: command.h config.h ${BASHINCDIR}/memalloc.h error.h general.h xmalloc.h ${BASHINCDIR}/maxpath.h +builtins/ulimit.o: quit.h dispose_cmd.h make_cmd.h subst.h externs.h ${BASHINCDIR}/stdc.h +builtins/ulimit.o: shell.h syntax.h bashjmp.h ${BASHINCDIR}/posixjmp.h sig.h unwind_prot.h variables.h arrayfunc.h conftypes.h +builtins/umask.o: command.h config.h ${BASHINCDIR}/memalloc.h error.h general.h xmalloc.h ${BASHINCDIR}/maxpath.h +builtins/umask.o: quit.h dispose_cmd.h make_cmd.h subst.h externs.h ${BASHINCDIR}/stdc.h +builtins/umask.o: shell.h syntax.h bashjmp.h ${BASHINCDIR}/posixjmp.h sig.h unwind_prot.h variables.h arrayfunc.h conftypes.h +builtins/umask.o: ${BASHINCDIR}/chartypes.h +builtins/wait.o: command.h config.h ${BASHINCDIR}/memalloc.h error.h general.h xmalloc.h ${BASHINCDIR}/maxpath.h +builtins/wait.o: quit.h dispose_cmd.h make_cmd.h subst.h externs.h ${BASHINCDIR}/stdc.h +builtins/wait.o: shell.h syntax.h bashjmp.h ${BASHINCDIR}/posixjmp.h sig.h unwind_prot.h variables.h arrayfunc.h conftypes.h +builtins/wait.o: ${BASHINCDIR}/chartypes.h + +builtins/complete.o: config.h shell.h syntax.h bashjmp.h ${BASHINCDIR}/posixjmp.h sig.h +builtins/complete.o: unwind_prot.h variables.h arrayfunc.h conftypes.h +builtins/complete.o: bashtypes.h bashansi.h ${BASHINCDIR}/ansi_stdlib.h +builtins/complete.o: builtins.h +builtins/complete.o: pcomplete.h +builtins/complete.o: ${DEFSRC}/common.h ${DEFSRC}/bashgetopt.h + +# libintl dependencies +builtins/bind.o: ${topdir}/bashintl.h ${LIBINTL_H} $(BASHINCDIR)/gettext.h +builtins/break.o: ${topdir}/bashintl.h ${LIBINTL_H} $(BASHINCDIR)/gettext.h +builtins/caller.o: ${topdir}/bashintl.h ${LIBINTL_H} $(BASHINCDIR)/gettext.h +builtins/cd.o: ${topdir}/bashintl.h ${LIBINTL_H} $(BASHINCDIR)/gettext.h +builtins/common.c: ${topdir}/bashintl.h ${LIBINTL_H} $(BASHINCDIR)/gettext.h +builtins/complete.o: ${topdir}/bashintl.h ${LIBINTL_H} $(BASHINCDIR)/gettext.h +builtins/declare.o: ${topdir}/bashintl.h ${LIBINTL_H} $(BASHINCDIR)/gettext.h +builtins/enable.o: ${topdir}/bashintl.h ${LIBINTL_H} $(BASHINCDIR)/gettext.h +builtins/evalfile.c: ${topdir}/bashintl.h ${LIBINTL_H} $(BASHINCDIR)/gettext.h +builtins/exec.o: ${topdir}/bashintl.h ${LIBINTL_H} $(BASHINCDIR)/gettext.h +builtins/exit.o: ${topdir}/bashintl.h ${LIBINTL_H} $(BASHINCDIR)/gettext.h +builtins/fc.o: ${topdir}/bashintl.h ${LIBINTL_H} $(BASHINCDIR)/gettext.h +builtins/fg_bg.o: ${topdir}/bashintl.h ${LIBINTL_H} $(BASHINCDIR)/gettext.h +builtins/getopt.c: ${topdir}/bashintl.h ${LIBINTL_H} $(BASHINCDIR)/gettext.h +builtins/hash.o: ${topdir}/bashintl.h ${LIBINTL_H} $(BASHINCDIR)/gettext.h +builtins/help.o: ${topdir}/bashintl.h ${LIBINTL_H} $(BASHINCDIR)/gettext.h +builtins/history.o: ${topdir}/bashintl.h ${LIBINTL_H} $(BASHINCDIR)/gettext.h +builtins/inlib.o: ${topdir}/bashintl.h ${LIBINTL_H} $(BASHINCDIR)/gettext.h +builtins/jobs.o: ${topdir}/bashintl.h ${LIBINTL_H} $(BASHINCDIR)/gettext.h +builtins/kill.o: ${topdir}/bashintl.h ${LIBINTL_H} $(BASHINCDIR)/gettext.h +builtins/let.o: ${topdir}/bashintl.h ${LIBINTL_H} $(BASHINCDIR)/gettext.h +builtins/mkbuiltins.c: ${topdir}/bashintl.h ${LIBINTL_H} $(BASHINCDIR)/gettext.h +builtins/printf.o: ${topdir}/bashintl.h ${LIBINTL_H} $(BASHINCDIR)/gettext.h +builtins/pushd.o: ${topdir}/bashintl.h ${LIBINTL_H} $(BASHINCDIR)/gettext.h +builtins/read.o: ${topdir}/bashintl.h ${LIBINTL_H} $(BASHINCDIR)/gettext.h +builtins/return.o: ${topdir}/bashintl.h ${LIBINTL_H} $(BASHINCDIR)/gettext.h +builtins/set.o: ${topdir}/bashintl.h ${LIBINTL_H} $(BASHINCDIR)/gettext.h +builtins/setattr.o: ${topdir}/bashintl.h ${LIBINTL_H} $(BASHINCDIR)/gettext.h +builtins/shift.o: ${topdir}/bashintl.h ${LIBINTL_H} $(BASHINCDIR)/gettext.h +builtins/shopt.o: ${topdir}/bashintl.h ${LIBINTL_H} $(BASHINCDIR)/gettext.h +builtins/source.o: ${topdir}/bashintl.h ${LIBINTL_H} $(BASHINCDIR)/gettext.h +builtins/suspend.o: ${topdir}/bashintl.h ${LIBINTL_H} $(BASHINCDIR)/gettext.h +builtins/type.o: ${topdir}/bashintl.h ${LIBINTL_H} $(BASHINCDIR)/gettext.h +builtins/ulimit.o: ${topdir}/bashintl.h ${LIBINTL_H} $(BASHINCDIR)/gettext.h +builtins/umask.o: ${topdir}/bashintl.h ${LIBINTL_H} $(BASHINCDIR)/gettext.h + +# builtin library dependencies +builtins/bind.o: $(RL_LIBSRC)/chardefs.h $(RL_LIBSRC)/readline.h +builtins/bind.o: $(RL_LIBSRC)/keymaps.h $(RL_LIBSRC)/rlstdc.h + +builtins/bind.o: $(HIST_LIBSRC)/history.h $(RL_LIBSRC)/rlstdc.h +builtins/fc.o: $(HIST_LIBSRC)/history.h $(RL_LIBSRC)/rlstdc.h +builtins/history.o: $(HIST_LIBSRC)/history.h $(RL_LIBSRC)/rlstdc.h + +builtins/common.o: $(TILDE_LIBSRC)/tilde.h +builtins/cd.o: $(TILDE_LIBSRC)/tilde.h + +builtins/alias.o: $(DEFSRC)/alias.def +builtins/bind.o: $(DEFSRC)/bind.def +builtins/break.o: $(DEFSRC)/break.def +builtins/builtin.o: $(DEFSRC)/builtin.def +builtins/caller.o: $(DEFSRC)/caller.def +builtins/cd.o: $(DEFSRC)/cd.def +builtins/colon.o: $(DEFSRC)/colon.def +builtins/command.o: $(DEFSRC)/command.def +builtins/complete.o: $(DEFSRC)/complete.def +builtins/declare.o: $(DEFSRC)/declare.def +builtins/echo.o: $(DEFSRC)/echo.def +builtins/enable.o: $(DEFSRC)/enable.def +builtins/eval.o: $(DEFSRC)/eval.def +builtins/exec.o: $(DEFSRC)/exec.def +builtins/exit.o: $(DEFSRC)/exit.def +builtins/fc.o: $(DEFSRC)/fc.def +builtins/fg_bg.o: $(DEFSRC)/fg_bg.def +builtins/getopts.o: $(DEFSRC)/getopts.def +builtins/hash.o: $(DEFSRC)/hash.def +builtins/help.o: $(DEFSRC)/help.def +builtins/history.o: $(DEFSRC)/history.def +builtins/inlib.o: $(DEFSRC)/inlib.def +builtins/jobs.o: $(DEFSRC)/jobs.def +builtins/kill.o: $(DEFSRC)/kill.def +builtins/let.o: $(DEFSRC)/let.def +builtins/pushd.o: $(DEFSRC)/pushd.def +builtins/read.o: $(DEFSRC)/read.def +builtins/reserved.o: $(DEFSRC)/reserved.def +builtins/return.o: $(DEFSRC)/return.def +builtins/set.o: $(DEFSRC)/set.def +builtins/setattr.o: $(DEFSRC)/setattr.def +builtins/shift.o: $(DEFSRC)/shift.def +builtins/shopt.o: $(DEFSRC)/shopt.def +builtins/source.o: $(DEFSRC)/source.def +builtins/suspend.o: $(DEFSRC)/suspend.def +builtins/test.o: $(DEFSRC)/test.def +builtins/times.o: $(DEFSRC)/times.def +builtins/trap.o: $(DEFSRC)/trap.def +builtins/type.o: $(DEFSRC)/type.def +builtins/ulimit.o: $(DEFSRC)/ulimit.def +builtins/umask.o: $(DEFSRC)/umask.def +builtins/wait.o: $(DEFSRC)/wait.def diff --git a/autom4te.cache/output.0 b/autom4te.cache/output.0 index 60d9b30f5..e65930f2d 100644 --- a/autom4te.cache/output.0 +++ b/autom4te.cache/output.0 @@ -1,5 +1,5 @@ @%:@! /bin/sh -@%:@ From configure.in for Bash 3.0, version 3.159, from autoconf version AC_ACVERSION. +@%:@ From configure.in for Bash 3.0, version 3.160, from autoconf version AC_ACVERSION. @%:@ Guess values for system-dependent variables and create Makefiles. @%:@ Generated by GNU Autoconf 2.57 for bash 3.0-beta1. @%:@ @@ -311,7 +311,7 @@ ac_includes_default="\ # include #endif" -ac_subst_vars='SHELL PATH_SEPARATOR PACKAGE_NAME PACKAGE_TARNAME PACKAGE_VERSION PACKAGE_STRING PACKAGE_BUGREPORT exec_prefix prefix program_transform_name bindir sbindir libexecdir datadir sysconfdir sharedstatedir localstatedir libdir includedir oldincludedir infodir mandir build_alias host_alias target_alias DEFS ECHO_C ECHO_N ECHO_T LIBS build build_cpu build_vendor build_os host host_cpu host_vendor host_os EMACS lispdir DEBUGGER_START_FILE TESTSCRIPT PURIFY MALLOC_TARGET MALLOC_SRC MALLOC_LIB MALLOC_LIBRARY MALLOC_LDFLAGS MALLOC_DEP htmldir HELPDIR HELPDIRDEFINE HELPINSTALL CC CFLAGS LDFLAGS CPPFLAGS ac_ct_CC EXEEXT OBJEXT CPP EGREP SIGNAMES_H CC_FOR_BUILD STATIC_LD CFLAGS_FOR_BUILD CPPFLAGS_FOR_BUILD LDFLAGS_FOR_BUILD RL_VERSION RL_MAJOR RL_MINOR READLINE_LIB READLINE_DEP RL_LIBDIR RL_INCLUDEDIR RL_INCLUDE HISTORY_LIB HISTORY_DEP HIST_LIBDIR INSTALL_PROGRAM INSTALL_SCRIPT INSTALL_DATA AR RANLIB ac_ct_RANLIB YACC SET_MAKE MAKE_SHELL MKINSTALLDIRS USE_NLS MSGFMT GMSGFMT XGETTEXT MSGMERGE ALLOCA GLIBC21 LIBICONV LTLIBICONV INTLBISON BUILD_INCLUDED_LIBINTL USE_INCLUDED_LIBINTL CATOBJEXT DATADIRNAME INSTOBJEXT GENCAT INTLOBJS INTL_LIBTOOL_SUFFIX_PREFIX INTLLIBS LIBINTL LTLIBINTL POSUB LIB@&t@OBJS INTL_DEP INTL_INC SIGLIST_O TERMCAP_LIB TERMCAP_DEP JOBS_O SHOBJ_CC SHOBJ_CFLAGS SHOBJ_LD SHOBJ_LDFLAGS SHOBJ_XLDFLAGS SHOBJ_LIBS SHOBJ_STATUS PROFILE_FLAGS incdir BUILD_DIR ARFLAGS BASHVERS RELSTATUS DEBUG MALLOC_DEBUG LOCAL_LIBS LOCAL_CFLAGS LOCAL_LDFLAGS LOCAL_DEFS LTLIBOBJS' +ac_subst_vars='SHELL PATH_SEPARATOR PACKAGE_NAME PACKAGE_TARNAME PACKAGE_VERSION PACKAGE_STRING PACKAGE_BUGREPORT exec_prefix prefix program_transform_name bindir sbindir libexecdir datadir sysconfdir sharedstatedir localstatedir libdir includedir oldincludedir infodir mandir build_alias host_alias target_alias DEFS ECHO_C ECHO_N ECHO_T LIBS build build_cpu build_vendor build_os host host_cpu host_vendor host_os EMACS lispdir DEBUGGER_START_FILE TESTSCRIPT PURIFY MALLOC_TARGET MALLOC_SRC MALLOC_LIB MALLOC_LIBRARY MALLOC_LDFLAGS MALLOC_DEP htmldir HELPDIR HELPDIRDEFINE HELPINSTALL CC CFLAGS LDFLAGS CPPFLAGS ac_ct_CC EXEEXT OBJEXT CPP EGREP SIGNAMES_H CC_FOR_BUILD STATIC_LD CFLAGS_FOR_BUILD CPPFLAGS_FOR_BUILD LDFLAGS_FOR_BUILD RL_VERSION RL_MAJOR RL_MINOR READLINE_LIB READLINE_DEP RL_LIBDIR RL_INCLUDEDIR RL_INCLUDE HISTORY_LIB HISTORY_DEP HIST_LIBDIR INSTALL_PROGRAM INSTALL_SCRIPT INSTALL_DATA AR RANLIB ac_ct_RANLIB YACC SET_MAKE MAKE_SHELL MKINSTALLDIRS USE_NLS MSGFMT GMSGFMT XGETTEXT MSGMERGE ALLOCA GLIBC21 LIBICONV LTLIBICONV INTLBISON BUILD_INCLUDED_LIBINTL USE_INCLUDED_LIBINTL CATOBJEXT DATADIRNAME INSTOBJEXT GENCAT INTLOBJS INTL_LIBTOOL_SUFFIX_PREFIX INTLLIBS LIBINTL LTLIBINTL POSUB LIB@&t@OBJS INTL_DEP INTL_INC LIBINTL_H SIGLIST_O TERMCAP_LIB TERMCAP_DEP JOBS_O SHOBJ_CC SHOBJ_CFLAGS SHOBJ_LD SHOBJ_LDFLAGS SHOBJ_XLDFLAGS SHOBJ_LIBS SHOBJ_STATUS PROFILE_FLAGS incdir BUILD_DIR ARFLAGS BASHVERS RELSTATUS DEBUG MALLOC_DEBUG LOCAL_LIBS LOCAL_CFLAGS LOCAL_LDFLAGS LOCAL_DEFS LTLIBOBJS' ac_subst_files='' # Initialize some variables set by options. @@ -13780,10 +13780,11 @@ fi done -INTL_DEP= INTL_INC= +INTL_DEP= INTL_INC= LIBINTL_H= if test "x$USE_INCLUDED_LIBINTL" = "xyes"; then INTL_DEP='${INTL_LIBDIR}/libintl.a' - INTL_INC='-I${INTL_LIBSRC}' + INTL_INC='-I${INTL_LIBSRC} -I${INTL_BUILDDIR}' + LIBINTL_H='${INTL_BUILDDIR}/libintl.h' fi @@ -13791,6 +13792,7 @@ fi + for ac_header in wctype.h do as_ac_Header=`echo "ac_cv_header_$ac_header" | $as_tr_sh` @@ -24854,6 +24856,7 @@ s,@POSUB@,$POSUB,;t t s,@LIB@&t@OBJS@,$LIB@&t@OBJS,;t t s,@INTL_DEP@,$INTL_DEP,;t t s,@INTL_INC@,$INTL_INC,;t t +s,@LIBINTL_H@,$LIBINTL_H,;t t s,@SIGLIST_O@,$SIGLIST_O,;t t s,@TERMCAP_LIB@,$TERMCAP_LIB,;t t s,@TERMCAP_DEP@,$TERMCAP_DEP,;t t diff --git a/autom4te.cache/requests b/autom4te.cache/requests index cca258e09..2617216cd 100644 --- a/autom4te.cache/requests +++ b/autom4te.cache/requests @@ -15,96 +15,96 @@ 'configure.in' ], { - 'AC_STRUCT_ST_BLOCKS' => 1, + 'AH_OUTPUT' => 1, + 'AC_FUNC_STRERROR_R' => 1, + 'AC_CHECK_HEADERS' => 1, + 'AC_HEADER_MAJOR' => 1, + 'AC_FUNC_MMAP' => 1, + 'AC_INIT' => 1, + 'AM_CONDITIONAL' => 1, + 'AC_REPLACE_FNMATCH' => 1, + 'AC_FUNC_MKTIME' => 1, 'AC_FUNC_CLOSEDIR_VOID' => 1, - 'AC_CHECK_TYPES' => 1, + 'AC_PROG_GCC_TRADITIONAL' => 1, + 'AC_FUNC_VPRINTF' => 1, + 'AC_FUNC_MBRTOWC' => 1, + 'AC_FUNC_STRTOD' => 1, + 'AC_FUNC_STRNLEN' => 1, + 'AM_AUTOMAKE_VERSION' => 1, + 'AC_PROG_CXX' => 1, + 'AC_TYPE_PID_T' => 1, + 'AC_STRUCT_ST_BLOCKS' => 1, + 'AC_PROG_INSTALL' => 1, 'AC_PROG_CC' => 1, 'AC_TYPE_OFF_T' => 1, - 'AC_PROG_YACC' => 1, - 'AC_PROG_CPP' => 1, - 'AC_C_INLINE' => 1, - 'AC_TYPE_UID_T' => 1, - 'AC_STRUCT_TM' => 1, - 'AC_FUNC_MKTIME' => 1, + 'AC_FUNC_FORK' => 1, + 'AM_INIT_AUTOMAKE' => 1, + 'AC_PROG_LN_S' => 1, + 'AC_C_VOLATILE' => 1, + 'AC_TYPE_SIZE_T' => 1, + 'AM_GNU_GETTEXT' => 1, + 'AC_C_CONST' => 1, + 'AC_PATH_X' => 1, + 'AC_DEFINE_TRACE_LITERAL' => 1, + 'AC_STRUCT_TIMEZONE' => 1, 'AC_FUNC_MEMCMP' => 1, - 'AC_CONFIG_HEADERS' => 1, - 'AC_CHECK_HEADERS' => 1, + 'AC_CHECK_TYPES' => 1, + 'AC_CANONICAL_SYSTEM' => 1, 'AC_HEADER_SYS_WAIT' => 1, - 'AC_CHECK_MEMBERS' => 1, - 'AC_HEADER_MAJOR' => 1, - 'AC_PROG_LIBTOOL' => 1, + 'AC_SUBST' => 1, + 'AC_PROG_AWK' => 1, 'AC_FUNC_REALLOC' => 1, - 'AC_FUNC_MBRTOWC' => 1, + 'AC_PROG_RANLIB' => 1, 'AC_FUNC_SELECT_ARGTYPES' => 1, - 'AH_OUTPUT' => 1, - 'AC_FUNC_MMAP' => 1, - 'AC_FUNC_SETVBUF_REVERSED' => 1, - 'AC_FUNC_ERROR_AT_LINE' => 1, + 'AC_DECL_SYS_SIGLIST' => 1, + 'AM_MAINTAINER_MODE' => 1, + 'AC_FUNC_MALLOC' => 1, 'AC_FUNC_STRCOLL' => 1, - 'AC_C_VOLATILE' => 1, + 'AC_PROG_LIBTOOL' => 1, 'AC_FUNC_GETPGRP' => 1, - 'AC_TYPE_PID_T' => 1, - 'm4_pattern_allow' => 1, - 'AC_FUNC_UTIME_NULL' => 1, - 'AC_PROG_RANLIB' => 1, - 'm4_include' => 1, - 'AC_FUNC_STRERROR_R' => 1, - 'AC_FUNC_GETMNTENT' => 1, - 'AC_PROG_GCC_TRADITIONAL' => 1, - 'AC_STRUCT_TIMEZONE' => 1, - 'include' => 1, - 'AM_AUTOMAKE_VERSION' => 1, - 'AC_LIBSOURCE' => 1, - 'AC_SUBST' => 1, 'AC_CHECK_LIB' => 1, - 'AC_C_CONST' => 1, - 'AC_FUNC_VPRINTF' => 1, - 'AC_TYPE_SIGNAL' => 1, - 'AC_FUNC_GETGROUPS' => 1, - 'AC_CANONICAL_HOST' => 1, - 'AC_HEADER_STDC' => 1, - 'AC_FUNC_STRTOD' => 1, - 'AC_PROG_LEX' => 1, - 'AC_FUNC_OBSTACK' => 1, - 'AM_MAINTAINER_MODE' => 1, - 'AC_INIT' => 1, - 'AC_PROG_LN_S' => 1, - 'AC_FUNC_SETPGRP' => 1, + 'AC_FUNC_SETVBUF_REVERSED' => 1, + 'AC_CHECK_FUNCS' => 1, + 'AC_LIBSOURCE' => 1, + 'AC_FUNC_ERROR_AT_LINE' => 1, + 'AC_STRUCT_TM' => 1, 'AC_CONFIG_SUBDIRS' => 1, - 'AC_PROG_MAKE_SET' => 1, - 'AC_HEADER_TIME' => 1, - 'AC_FUNC_FORK' => 1, - 'AC_PROG_AWK' => 1, - 'AC_FUNC_CHOWN' => 1, - 'AC_FUNC_STRNLEN' => 1, - 'AM_INIT_AUTOMAKE' => 1, - 'AC_FUNC_ALLOCA' => 1, - 'AC_DEFINE_TRACE_LITERAL' => 1, - 'AC_FUNC_STRFTIME' => 1, - 'AC_PATH_X' => 1, - 'AC_REPLACE_FNMATCH' => 1, 'AC_FUNC_WAIT3' => 1, - 'm4_pattern_forbid' => 1, - 'AC_CHECK_FUNCS' => 1, + 'AC_PROG_CPP' => 1, + 'AC_FUNC_GETLOADAVG' => 1, + 'AC_TYPE_UID_T' => 1, + 'AC_CANONICAL_HOST' => 1, + 'AC_CONFIG_FILES' => 1, 'AC_FUNC_STAT' => 1, - 'AC_CONFIG_AUX_DIR' => 1, 'AC_FUNC_LSTAT_FOLLOWS_SLASHED_SYMLINK' => 1, - 'AC_FUNC_MALLOC' => 1, - 'AC_FUNC_GETLOADAVG' => 1, - 'AC_PROG_INSTALL' => 1, - 'AC_HEADER_DIRENT' => 1, - 'AM_PROG_CC_C_O' => 1, - 'AC_TYPE_SIZE_T' => 1, + 'AC_PROG_LEX' => 1, + 'AC_PROG_MAKE_SET' => 1, + 'AC_FUNC_ALLOCA' => 1, + 'AC_C_INLINE' => 1, 'AC_FUNC_FSEEKO' => 1, - 'AC_TYPE_MODE_T' => 1, - 'AC_DECL_SYS_SIGLIST' => 1, - 'AM_GNU_GETTEXT' => 1, - 'AM_CONDITIONAL' => 1, - 'AC_CONFIG_FILES' => 1, + 'AC_CONFIG_HEADERS' => 1, + 'm4_include' => 1, + 'AC_HEADER_DIRENT' => 1, + 'AC_HEADER_STDC' => 1, + 'AC_FUNC_CHOWN' => 1, 'AC_FUNC_LSTAT' => 1, - 'AC_CANONICAL_SYSTEM' => 1, + 'AC_CHECK_MEMBERS' => 1, + 'AM_PROG_CC_C_O' => 1, + 'm4_pattern_forbid' => 1, 'AC_HEADER_STAT' => 1, - 'AC_PROG_CXX' => 1 + 'AC_FUNC_UTIME_NULL' => 1, + 'AC_FUNC_GETMNTENT' => 1, + 'AC_FUNC_SETPGRP' => 1, + 'AC_FUNC_STRFTIME' => 1, + 'AC_FUNC_OBSTACK' => 1, + 'AC_FUNC_GETGROUPS' => 1, + 'AC_HEADER_TIME' => 1, + 'AC_TYPE_MODE_T' => 1, + 'AC_PROG_YACC' => 1, + 'm4_pattern_allow' => 1, + 'AC_TYPE_SIGNAL' => 1, + 'AC_CONFIG_AUX_DIR' => 1, + 'include' => 1 } ], 'Request' ) ); diff --git a/autom4te.cache/traces.0 b/autom4te.cache/traces.0 index d2e36f998..02e6e8f17 100644 --- a/autom4te.cache/traces.0 +++ b/autom4te.cache/traces.0 @@ -869,327 +869,328 @@ m4trace:configure.in:680: -1- AH_OUTPUT([HAVE_STRCSPN], [/* Define to 1 if you h #undef HAVE_STRCSPN]) m4trace:configure.in:680: -1- AH_OUTPUT([HAVE_STRDUP], [/* Define to 1 if you have the `strdup\' function. */ #undef HAVE_STRDUP]) -m4trace:configure.in:687: -1- AC_SUBST([INTL_DEP]) -m4trace:configure.in:688: -1- AC_SUBST([INTL_INC]) -m4trace:configure.in:694: -1- AC_CHECK_HEADERS([wctype.h]) -m4trace:configure.in:694: -1- AH_OUTPUT([HAVE_WCTYPE_H], [/* Define to 1 if you have the header file. */ +m4trace:configure.in:688: -1- AC_SUBST([INTL_DEP]) +m4trace:configure.in:689: -1- AC_SUBST([INTL_INC]) +m4trace:configure.in:690: -1- AC_SUBST([LIBINTL_H]) +m4trace:configure.in:696: -1- AC_CHECK_HEADERS([wctype.h]) +m4trace:configure.in:696: -1- AH_OUTPUT([HAVE_WCTYPE_H], [/* Define to 1 if you have the header file. */ #undef HAVE_WCTYPE_H]) -m4trace:configure.in:694: -1- AC_CHECK_HEADERS([wchar.h]) -m4trace:configure.in:694: -1- AH_OUTPUT([HAVE_WCHAR_H], [/* Define to 1 if you have the header file. */ +m4trace:configure.in:696: -1- AC_CHECK_HEADERS([wchar.h]) +m4trace:configure.in:696: -1- AH_OUTPUT([HAVE_WCHAR_H], [/* Define to 1 if you have the header file. */ #undef HAVE_WCHAR_H]) -m4trace:configure.in:694: -1- AC_CHECK_HEADERS([langinfo.h]) -m4trace:configure.in:694: -1- AH_OUTPUT([HAVE_LANGINFO_H], [/* Define to 1 if you have the header file. */ +m4trace:configure.in:696: -1- AC_CHECK_HEADERS([langinfo.h]) +m4trace:configure.in:696: -1- AH_OUTPUT([HAVE_LANGINFO_H], [/* Define to 1 if you have the header file. */ #undef HAVE_LANGINFO_H]) -m4trace:configure.in:694: -2- AC_DEFINE_TRACE_LITERAL([HAVE_MBSRTOWCS]) -m4trace:configure.in:694: -2- AC_DEFINE_TRACE_LITERAL([HAVE_MBRTOWC]) -m4trace:configure.in:694: -2- AC_DEFINE_TRACE_LITERAL([HAVE_MBRLEN]) -m4trace:configure.in:694: -2- AC_DEFINE_TRACE_LITERAL([HAVE_WCTOMB]) -m4trace:configure.in:694: -2- AC_DEFINE_TRACE_LITERAL([HAVE_WCWIDTH]) -m4trace:configure.in:694: -1- AC_DEFINE_TRACE_LITERAL([HAVE_MBSTATE_T]) -m4trace:configure.in:694: -1- AC_DEFINE_TRACE_LITERAL([HAVE_LANGINFO_CODESET]) -m4trace:configure.in:698: -1- AC_CHECK_LIB([dl], [dlopen]) -m4trace:configure.in:698: -1- AH_OUTPUT([HAVE_LIBDL], [/* Define to 1 if you have the `dl\' library (-ldl). */ +m4trace:configure.in:696: -2- AC_DEFINE_TRACE_LITERAL([HAVE_MBSRTOWCS]) +m4trace:configure.in:696: -2- AC_DEFINE_TRACE_LITERAL([HAVE_MBRTOWC]) +m4trace:configure.in:696: -2- AC_DEFINE_TRACE_LITERAL([HAVE_MBRLEN]) +m4trace:configure.in:696: -2- AC_DEFINE_TRACE_LITERAL([HAVE_WCTOMB]) +m4trace:configure.in:696: -2- AC_DEFINE_TRACE_LITERAL([HAVE_WCWIDTH]) +m4trace:configure.in:696: -1- AC_DEFINE_TRACE_LITERAL([HAVE_MBSTATE_T]) +m4trace:configure.in:696: -1- AC_DEFINE_TRACE_LITERAL([HAVE_LANGINFO_CODESET]) +m4trace:configure.in:700: -1- AC_CHECK_LIB([dl], [dlopen]) +m4trace:configure.in:700: -1- AH_OUTPUT([HAVE_LIBDL], [/* Define to 1 if you have the `dl\' library (-ldl). */ #undef HAVE_LIBDL]) -m4trace:configure.in:698: -1- AC_DEFINE_TRACE_LITERAL([HAVE_LIBDL]) -m4trace:configure.in:699: -1- AC_CHECK_FUNCS([dlopen dlclose dlsym]) -m4trace:configure.in:699: -1- AH_OUTPUT([HAVE_DLOPEN], [/* Define to 1 if you have the `dlopen\' function. */ +m4trace:configure.in:700: -1- AC_DEFINE_TRACE_LITERAL([HAVE_LIBDL]) +m4trace:configure.in:701: -1- AC_CHECK_FUNCS([dlopen dlclose dlsym]) +m4trace:configure.in:701: -1- AH_OUTPUT([HAVE_DLOPEN], [/* Define to 1 if you have the `dlopen\' function. */ #undef HAVE_DLOPEN]) -m4trace:configure.in:699: -1- AH_OUTPUT([HAVE_DLCLOSE], [/* Define to 1 if you have the `dlclose\' function. */ +m4trace:configure.in:701: -1- AH_OUTPUT([HAVE_DLCLOSE], [/* Define to 1 if you have the `dlclose\' function. */ #undef HAVE_DLCLOSE]) -m4trace:configure.in:699: -1- AH_OUTPUT([HAVE_DLSYM], [/* Define to 1 if you have the `dlsym\' function. */ +m4trace:configure.in:701: -1- AH_OUTPUT([HAVE_DLSYM], [/* Define to 1 if you have the `dlsym\' function. */ #undef HAVE_DLSYM]) -m4trace:configure.in:703: -1- AC_DECL_SYS_SIGLIST -m4trace:configure.in:703: -1- AC_DEFINE_TRACE_LITERAL([HAVE_DECL_SYS_SIGLIST]) -m4trace:configure.in:703: -1- AH_OUTPUT([HAVE_DECL_SYS_SIGLIST], [/* Define to 1 if you have the declaration of `sys_siglist\', and to 0 if you +m4trace:configure.in:705: -1- AC_DECL_SYS_SIGLIST +m4trace:configure.in:705: -1- AC_DEFINE_TRACE_LITERAL([HAVE_DECL_SYS_SIGLIST]) +m4trace:configure.in:705: -1- AH_OUTPUT([HAVE_DECL_SYS_SIGLIST], [/* Define to 1 if you have the declaration of `sys_siglist\', and to 0 if you don\'t. */ #undef HAVE_DECL_SYS_SIGLIST]) -m4trace:configure.in:703: -1- AC_DEFINE_TRACE_LITERAL([HAVE_DECL_SYS_SIGLIST]) -m4trace:configure.in:707: -1- AC_DEFINE_TRACE_LITERAL([HAVE_INET_ATON]) -m4trace:configure.in:707: -1- AC_LIBSOURCE([inet_aton.c]) -m4trace:configure.in:707: -1- AC_SUBST([LIB@&t@OBJS]) -m4trace:configure.in:713: -1- AC_CHECK_LIB([sun], [getpwent]) -m4trace:configure.in:713: -1- AH_OUTPUT([HAVE_LIBSUN], [/* Define to 1 if you have the `sun\' library (-lsun). */ +m4trace:configure.in:705: -1- AC_DEFINE_TRACE_LITERAL([HAVE_DECL_SYS_SIGLIST]) +m4trace:configure.in:709: -1- AC_DEFINE_TRACE_LITERAL([HAVE_INET_ATON]) +m4trace:configure.in:709: -1- AC_LIBSOURCE([inet_aton.c]) +m4trace:configure.in:709: -1- AC_SUBST([LIB@&t@OBJS]) +m4trace:configure.in:715: -1- AC_CHECK_LIB([sun], [getpwent]) +m4trace:configure.in:715: -1- AH_OUTPUT([HAVE_LIBSUN], [/* Define to 1 if you have the `sun\' library (-lsun). */ #undef HAVE_LIBSUN]) -m4trace:configure.in:713: -1- AC_DEFINE_TRACE_LITERAL([HAVE_LIBSUN]) -m4trace:configure.in:718: -1- AC_CHECK_LIB([socket], [getpeername], [bash_cv_have_socklib=yes], [bash_cv_have_socklib=no], [-lnsl]) -m4trace:configure.in:718: -1- AC_CHECK_LIB([nsl], [t_open], [bash_cv_have_libnsl=yes], [bash_cv_have_libnsl=no]) -m4trace:configure.in:718: -1- AC_DEFINE_TRACE_LITERAL([HAVE_LIBSOCKET]) -m4trace:configure.in:718: -1- AC_DEFINE_TRACE_LITERAL([HAVE_GETPEERNAME]) -m4trace:configure.in:722: -1- AC_DEFINE_TRACE_LITERAL([HAVE_GETHOSTBYNAME]) -m4trace:configure.in:726: -1- AC_TYPE_UID_T -m4trace:configure.in:726: -1- AC_DEFINE_TRACE_LITERAL([uid_t]) -m4trace:configure.in:726: -1- AH_OUTPUT([uid_t], [/* Define to `int\' if doesn\'t define. */ +m4trace:configure.in:715: -1- AC_DEFINE_TRACE_LITERAL([HAVE_LIBSUN]) +m4trace:configure.in:720: -1- AC_CHECK_LIB([socket], [getpeername], [bash_cv_have_socklib=yes], [bash_cv_have_socklib=no], [-lnsl]) +m4trace:configure.in:720: -1- AC_CHECK_LIB([nsl], [t_open], [bash_cv_have_libnsl=yes], [bash_cv_have_libnsl=no]) +m4trace:configure.in:720: -1- AC_DEFINE_TRACE_LITERAL([HAVE_LIBSOCKET]) +m4trace:configure.in:720: -1- AC_DEFINE_TRACE_LITERAL([HAVE_GETPEERNAME]) +m4trace:configure.in:724: -1- AC_DEFINE_TRACE_LITERAL([HAVE_GETHOSTBYNAME]) +m4trace:configure.in:728: -1- AC_TYPE_UID_T +m4trace:configure.in:728: -1- AC_DEFINE_TRACE_LITERAL([uid_t]) +m4trace:configure.in:728: -1- AH_OUTPUT([uid_t], [/* Define to `int\' if doesn\'t define. */ #undef uid_t]) -m4trace:configure.in:726: -1- AC_DEFINE_TRACE_LITERAL([gid_t]) -m4trace:configure.in:726: -1- AH_OUTPUT([gid_t], [/* Define to `int\' if doesn\'t define. */ +m4trace:configure.in:728: -1- AC_DEFINE_TRACE_LITERAL([gid_t]) +m4trace:configure.in:728: -1- AH_OUTPUT([gid_t], [/* Define to `int\' if doesn\'t define. */ #undef gid_t]) -m4trace:configure.in:726: -1- AC_DEFINE_TRACE_LITERAL([GETGROUPS_T]) -m4trace:configure.in:726: -1- AH_OUTPUT([GETGROUPS_T], [/* Define to the type of elements in the array set by `getgroups\'. Usually +m4trace:configure.in:728: -1- AC_DEFINE_TRACE_LITERAL([GETGROUPS_T]) +m4trace:configure.in:728: -1- AH_OUTPUT([GETGROUPS_T], [/* Define to the type of elements in the array set by `getgroups\'. Usually this is either `int\' or `gid_t\'. */ #undef GETGROUPS_T]) -m4trace:configure.in:727: -1- AC_TYPE_OFF_T -m4trace:configure.in:727: -1- AC_DEFINE_TRACE_LITERAL([off_t]) -m4trace:configure.in:727: -1- AH_OUTPUT([off_t], [/* Define to `long\' if does not define. */ +m4trace:configure.in:729: -1- AC_TYPE_OFF_T +m4trace:configure.in:729: -1- AC_DEFINE_TRACE_LITERAL([off_t]) +m4trace:configure.in:729: -1- AH_OUTPUT([off_t], [/* Define to `long\' if does not define. */ #undef off_t]) -m4trace:configure.in:728: -1- AC_TYPE_MODE_T -m4trace:configure.in:728: -1- AC_DEFINE_TRACE_LITERAL([mode_t]) -m4trace:configure.in:728: -1- AH_OUTPUT([mode_t], [/* Define to `int\' if does not define. */ +m4trace:configure.in:730: -1- AC_TYPE_MODE_T +m4trace:configure.in:730: -1- AC_DEFINE_TRACE_LITERAL([mode_t]) +m4trace:configure.in:730: -1- AH_OUTPUT([mode_t], [/* Define to `int\' if does not define. */ #undef mode_t]) -m4trace:configure.in:729: -1- AC_TYPE_UID_T -m4trace:configure.in:729: -1- AC_DEFINE_TRACE_LITERAL([uid_t]) -m4trace:configure.in:729: -1- AH_OUTPUT([uid_t], [/* Define to `int\' if doesn\'t define. */ +m4trace:configure.in:731: -1- AC_TYPE_UID_T +m4trace:configure.in:731: -1- AC_DEFINE_TRACE_LITERAL([uid_t]) +m4trace:configure.in:731: -1- AH_OUTPUT([uid_t], [/* Define to `int\' if doesn\'t define. */ #undef uid_t]) -m4trace:configure.in:729: -1- AC_DEFINE_TRACE_LITERAL([gid_t]) -m4trace:configure.in:729: -1- AH_OUTPUT([gid_t], [/* Define to `int\' if doesn\'t define. */ +m4trace:configure.in:731: -1- AC_DEFINE_TRACE_LITERAL([gid_t]) +m4trace:configure.in:731: -1- AH_OUTPUT([gid_t], [/* Define to `int\' if doesn\'t define. */ #undef gid_t]) -m4trace:configure.in:730: -1- AC_TYPE_PID_T -m4trace:configure.in:730: -1- AC_DEFINE_TRACE_LITERAL([pid_t]) -m4trace:configure.in:730: -1- AH_OUTPUT([pid_t], [/* Define to `int\' if does not define. */ +m4trace:configure.in:732: -1- AC_TYPE_PID_T +m4trace:configure.in:732: -1- AC_DEFINE_TRACE_LITERAL([pid_t]) +m4trace:configure.in:732: -1- AH_OUTPUT([pid_t], [/* Define to `int\' if does not define. */ #undef pid_t]) -m4trace:configure.in:731: -1- AC_TYPE_SIZE_T -m4trace:configure.in:731: -1- AC_DEFINE_TRACE_LITERAL([size_t]) -m4trace:configure.in:731: -1- AH_OUTPUT([size_t], [/* Define to `unsigned\' if does not define. */ +m4trace:configure.in:733: -1- AC_TYPE_SIZE_T +m4trace:configure.in:733: -1- AC_DEFINE_TRACE_LITERAL([size_t]) +m4trace:configure.in:733: -1- AH_OUTPUT([size_t], [/* Define to `unsigned\' if does not define. */ #undef size_t]) -m4trace:configure.in:732: -1- AC_DEFINE_TRACE_LITERAL([ssize_t]) -m4trace:configure.in:732: -1- AH_OUTPUT([ssize_t], [/* Define to `int\' if does not define. */ +m4trace:configure.in:734: -1- AC_DEFINE_TRACE_LITERAL([ssize_t]) +m4trace:configure.in:734: -1- AH_OUTPUT([ssize_t], [/* Define to `int\' if does not define. */ #undef ssize_t]) -m4trace:configure.in:733: -1- AC_DEFINE_TRACE_LITERAL([time_t]) -m4trace:configure.in:733: -1- AH_OUTPUT([time_t], [/* Define to `long\' if does not define. */ +m4trace:configure.in:735: -1- AC_DEFINE_TRACE_LITERAL([time_t]) +m4trace:configure.in:735: -1- AH_OUTPUT([time_t], [/* Define to `long\' if does not define. */ #undef time_t]) -m4trace:configure.in:735: -1- AC_DEFINE_TRACE_LITERAL([HAVE_LONG_LONG]) -m4trace:configure.in:736: -1- AC_DEFINE_TRACE_LITERAL([HAVE_UNSIGNED_LONG_LONG]) -m4trace:configure.in:738: -1- AC_TYPE_SIGNAL -m4trace:configure.in:738: -1- AC_DEFINE_TRACE_LITERAL([RETSIGTYPE]) -m4trace:configure.in:738: -1- AH_OUTPUT([RETSIGTYPE], [/* Define as the return type of signal handlers (`int\' or `void\'). */ +m4trace:configure.in:737: -1- AC_DEFINE_TRACE_LITERAL([HAVE_LONG_LONG]) +m4trace:configure.in:738: -1- AC_DEFINE_TRACE_LITERAL([HAVE_UNSIGNED_LONG_LONG]) +m4trace:configure.in:740: -1- AC_TYPE_SIGNAL +m4trace:configure.in:740: -1- AC_DEFINE_TRACE_LITERAL([RETSIGTYPE]) +m4trace:configure.in:740: -1- AH_OUTPUT([RETSIGTYPE], [/* Define as the return type of signal handlers (`int\' or `void\'). */ #undef RETSIGTYPE]) -m4trace:configure.in:740: -1- AC_DEFINE_TRACE_LITERAL([SIZEOF_CHAR]) -m4trace:configure.in:740: -1- AH_OUTPUT([SIZEOF_CHAR], [/* The size of a `char\', as computed by sizeof. */ +m4trace:configure.in:742: -1- AC_DEFINE_TRACE_LITERAL([SIZEOF_CHAR]) +m4trace:configure.in:742: -1- AH_OUTPUT([SIZEOF_CHAR], [/* The size of a `char\', as computed by sizeof. */ #undef SIZEOF_CHAR]) -m4trace:configure.in:741: -1- AC_DEFINE_TRACE_LITERAL([SIZEOF_SHORT]) -m4trace:configure.in:741: -1- AH_OUTPUT([SIZEOF_SHORT], [/* The size of a `short\', as computed by sizeof. */ +m4trace:configure.in:743: -1- AC_DEFINE_TRACE_LITERAL([SIZEOF_SHORT]) +m4trace:configure.in:743: -1- AH_OUTPUT([SIZEOF_SHORT], [/* The size of a `short\', as computed by sizeof. */ #undef SIZEOF_SHORT]) -m4trace:configure.in:742: -1- AC_DEFINE_TRACE_LITERAL([SIZEOF_INT]) -m4trace:configure.in:742: -1- AH_OUTPUT([SIZEOF_INT], [/* The size of a `int\', as computed by sizeof. */ +m4trace:configure.in:744: -1- AC_DEFINE_TRACE_LITERAL([SIZEOF_INT]) +m4trace:configure.in:744: -1- AH_OUTPUT([SIZEOF_INT], [/* The size of a `int\', as computed by sizeof. */ #undef SIZEOF_INT]) -m4trace:configure.in:743: -1- AC_DEFINE_TRACE_LITERAL([SIZEOF_LONG]) -m4trace:configure.in:743: -1- AH_OUTPUT([SIZEOF_LONG], [/* The size of a `long\', as computed by sizeof. */ +m4trace:configure.in:745: -1- AC_DEFINE_TRACE_LITERAL([SIZEOF_LONG]) +m4trace:configure.in:745: -1- AH_OUTPUT([SIZEOF_LONG], [/* The size of a `long\', as computed by sizeof. */ #undef SIZEOF_LONG]) -m4trace:configure.in:744: -1- AC_DEFINE_TRACE_LITERAL([SIZEOF_CHAR_P]) -m4trace:configure.in:744: -1- AH_OUTPUT([SIZEOF_CHAR_P], [/* The size of a `char *\', as computed by sizeof. */ +m4trace:configure.in:746: -1- AC_DEFINE_TRACE_LITERAL([SIZEOF_CHAR_P]) +m4trace:configure.in:746: -1- AH_OUTPUT([SIZEOF_CHAR_P], [/* The size of a `char *\', as computed by sizeof. */ #undef SIZEOF_CHAR_P]) -m4trace:configure.in:745: -1- AC_DEFINE_TRACE_LITERAL([SIZEOF_DOUBLE]) -m4trace:configure.in:745: -1- AH_OUTPUT([SIZEOF_DOUBLE], [/* The size of a `double\', as computed by sizeof. */ +m4trace:configure.in:747: -1- AC_DEFINE_TRACE_LITERAL([SIZEOF_DOUBLE]) +m4trace:configure.in:747: -1- AH_OUTPUT([SIZEOF_DOUBLE], [/* The size of a `double\', as computed by sizeof. */ #undef SIZEOF_DOUBLE]) -m4trace:configure.in:746: -1- AC_DEFINE_TRACE_LITERAL([SIZEOF_LONG_LONG]) -m4trace:configure.in:746: -1- AH_OUTPUT([SIZEOF_LONG_LONG], [/* The size of a `long long\', as computed by sizeof. */ +m4trace:configure.in:748: -1- AC_DEFINE_TRACE_LITERAL([SIZEOF_LONG_LONG]) +m4trace:configure.in:748: -1- AH_OUTPUT([SIZEOF_LONG_LONG], [/* The size of a `long long\', as computed by sizeof. */ #undef SIZEOF_LONG_LONG]) -m4trace:configure.in:748: -1- AC_DEFINE_TRACE_LITERAL([u_int]) -m4trace:configure.in:748: -1- AH_OUTPUT([u_int], [/* Define to `unsigned int\' if does not define. */ +m4trace:configure.in:750: -1- AC_DEFINE_TRACE_LITERAL([u_int]) +m4trace:configure.in:750: -1- AH_OUTPUT([u_int], [/* Define to `unsigned int\' if does not define. */ #undef u_int]) -m4trace:configure.in:749: -1- AC_DEFINE_TRACE_LITERAL([u_long]) -m4trace:configure.in:749: -1- AH_OUTPUT([u_long], [/* Define to `unsigned long\' if does not define. */ +m4trace:configure.in:751: -1- AC_DEFINE_TRACE_LITERAL([u_long]) +m4trace:configure.in:751: -1- AH_OUTPUT([u_long], [/* Define to `unsigned long\' if does not define. */ #undef u_long]) -m4trace:configure.in:751: -1- AC_DEFINE_TRACE_LITERAL([bits16_t]) -m4trace:configure.in:751: -1- AH_OUTPUT([bits16_t], [/* Define to `short\' if does not define. */ +m4trace:configure.in:753: -1- AC_DEFINE_TRACE_LITERAL([bits16_t]) +m4trace:configure.in:753: -1- AH_OUTPUT([bits16_t], [/* Define to `short\' if does not define. */ #undef bits16_t]) -m4trace:configure.in:751: -1- AC_DEFINE_TRACE_LITERAL([bits16_t]) -m4trace:configure.in:751: -1- AH_OUTPUT([bits16_t], [/* Define to `char\' if does not define. */ +m4trace:configure.in:753: -1- AC_DEFINE_TRACE_LITERAL([bits16_t]) +m4trace:configure.in:753: -1- AH_OUTPUT([bits16_t], [/* Define to `char\' if does not define. */ #undef bits16_t]) -m4trace:configure.in:751: -1- AC_DEFINE_TRACE_LITERAL([bits16_t]) -m4trace:configure.in:751: -1- AH_OUTPUT([bits16_t], [/* Define to `short\' if does not define. */ +m4trace:configure.in:753: -1- AC_DEFINE_TRACE_LITERAL([bits16_t]) +m4trace:configure.in:753: -1- AH_OUTPUT([bits16_t], [/* Define to `short\' if does not define. */ #undef bits16_t]) -m4trace:configure.in:752: -1- AC_DEFINE_TRACE_LITERAL([u_bits16_t]) -m4trace:configure.in:752: -1- AH_OUTPUT([u_bits16_t], [/* Define to `unsigned short\' if does not define. */ +m4trace:configure.in:754: -1- AC_DEFINE_TRACE_LITERAL([u_bits16_t]) +m4trace:configure.in:754: -1- AH_OUTPUT([u_bits16_t], [/* Define to `unsigned short\' if does not define. */ #undef u_bits16_t]) -m4trace:configure.in:752: -1- AC_DEFINE_TRACE_LITERAL([u_bits16_t]) -m4trace:configure.in:752: -1- AH_OUTPUT([u_bits16_t], [/* Define to `unsigned char\' if does not define. */ +m4trace:configure.in:754: -1- AC_DEFINE_TRACE_LITERAL([u_bits16_t]) +m4trace:configure.in:754: -1- AH_OUTPUT([u_bits16_t], [/* Define to `unsigned char\' if does not define. */ #undef u_bits16_t]) -m4trace:configure.in:752: -1- AC_DEFINE_TRACE_LITERAL([u_bits16_t]) -m4trace:configure.in:752: -1- AH_OUTPUT([u_bits16_t], [/* Define to `unsigned short\' if does not define. */ +m4trace:configure.in:754: -1- AC_DEFINE_TRACE_LITERAL([u_bits16_t]) +m4trace:configure.in:754: -1- AH_OUTPUT([u_bits16_t], [/* Define to `unsigned short\' if does not define. */ #undef u_bits16_t]) -m4trace:configure.in:753: -1- AC_DEFINE_TRACE_LITERAL([bits32_t]) -m4trace:configure.in:753: -1- AH_OUTPUT([bits32_t], [/* Define to `int\' if does not define. */ +m4trace:configure.in:755: -1- AC_DEFINE_TRACE_LITERAL([bits32_t]) +m4trace:configure.in:755: -1- AH_OUTPUT([bits32_t], [/* Define to `int\' if does not define. */ #undef bits32_t]) -m4trace:configure.in:753: -1- AC_DEFINE_TRACE_LITERAL([bits32_t]) -m4trace:configure.in:753: -1- AH_OUTPUT([bits32_t], [/* Define to `long\' if does not define. */ +m4trace:configure.in:755: -1- AC_DEFINE_TRACE_LITERAL([bits32_t]) +m4trace:configure.in:755: -1- AH_OUTPUT([bits32_t], [/* Define to `long\' if does not define. */ #undef bits32_t]) -m4trace:configure.in:753: -1- AC_DEFINE_TRACE_LITERAL([bits32_t]) -m4trace:configure.in:753: -1- AH_OUTPUT([bits32_t], [/* Define to `int\' if does not define. */ +m4trace:configure.in:755: -1- AC_DEFINE_TRACE_LITERAL([bits32_t]) +m4trace:configure.in:755: -1- AH_OUTPUT([bits32_t], [/* Define to `int\' if does not define. */ #undef bits32_t]) -m4trace:configure.in:754: -1- AC_DEFINE_TRACE_LITERAL([u_bits32_t]) -m4trace:configure.in:754: -1- AH_OUTPUT([u_bits32_t], [/* Define to `unsigned int\' if does not define. */ +m4trace:configure.in:756: -1- AC_DEFINE_TRACE_LITERAL([u_bits32_t]) +m4trace:configure.in:756: -1- AH_OUTPUT([u_bits32_t], [/* Define to `unsigned int\' if does not define. */ #undef u_bits32_t]) -m4trace:configure.in:754: -1- AC_DEFINE_TRACE_LITERAL([u_bits32_t]) -m4trace:configure.in:754: -1- AH_OUTPUT([u_bits32_t], [/* Define to `unsigned long\' if does not define. */ +m4trace:configure.in:756: -1- AC_DEFINE_TRACE_LITERAL([u_bits32_t]) +m4trace:configure.in:756: -1- AH_OUTPUT([u_bits32_t], [/* Define to `unsigned long\' if does not define. */ #undef u_bits32_t]) -m4trace:configure.in:754: -1- AC_DEFINE_TRACE_LITERAL([u_bits32_t]) -m4trace:configure.in:754: -1- AH_OUTPUT([u_bits32_t], [/* Define to `unsigned int\' if does not define. */ +m4trace:configure.in:756: -1- AC_DEFINE_TRACE_LITERAL([u_bits32_t]) +m4trace:configure.in:756: -1- AH_OUTPUT([u_bits32_t], [/* Define to `unsigned int\' if does not define. */ #undef u_bits32_t]) -m4trace:configure.in:755: -1- AC_DEFINE_TRACE_LITERAL([bits64_t]) -m4trace:configure.in:755: -1- AH_OUTPUT([bits64_t], [/* Define to `char *\' if does not define. */ +m4trace:configure.in:757: -1- AC_DEFINE_TRACE_LITERAL([bits64_t]) +m4trace:configure.in:757: -1- AH_OUTPUT([bits64_t], [/* Define to `char *\' if does not define. */ #undef bits64_t]) -m4trace:configure.in:755: -1- AC_DEFINE_TRACE_LITERAL([bits64_t]) -m4trace:configure.in:755: -1- AH_OUTPUT([bits64_t], [/* Define to `double\' if does not define. */ +m4trace:configure.in:757: -1- AC_DEFINE_TRACE_LITERAL([bits64_t]) +m4trace:configure.in:757: -1- AH_OUTPUT([bits64_t], [/* Define to `double\' if does not define. */ #undef bits64_t]) -m4trace:configure.in:755: -1- AC_DEFINE_TRACE_LITERAL([bits64_t]) -m4trace:configure.in:755: -1- AH_OUTPUT([bits64_t], [/* Define to `long long\' if does not define. */ +m4trace:configure.in:757: -1- AC_DEFINE_TRACE_LITERAL([bits64_t]) +m4trace:configure.in:757: -1- AH_OUTPUT([bits64_t], [/* Define to `long long\' if does not define. */ #undef bits64_t]) -m4trace:configure.in:755: -1- AC_DEFINE_TRACE_LITERAL([bits64_t]) -m4trace:configure.in:755: -1- AH_OUTPUT([bits64_t], [/* Define to `long\' if does not define. */ +m4trace:configure.in:757: -1- AC_DEFINE_TRACE_LITERAL([bits64_t]) +m4trace:configure.in:757: -1- AH_OUTPUT([bits64_t], [/* Define to `long\' if does not define. */ #undef bits64_t]) -m4trace:configure.in:755: -1- AC_DEFINE_TRACE_LITERAL([bits64_t]) -m4trace:configure.in:755: -1- AH_OUTPUT([bits64_t], [/* Define to `double\' if does not define. */ +m4trace:configure.in:757: -1- AC_DEFINE_TRACE_LITERAL([bits64_t]) +m4trace:configure.in:757: -1- AH_OUTPUT([bits64_t], [/* Define to `double\' if does not define. */ #undef bits64_t]) -m4trace:configure.in:757: -1- AC_DEFINE_TRACE_LITERAL([ptrdiff_t]) -m4trace:configure.in:757: -1- AH_OUTPUT([ptrdiff_t], [/* Define to `int\' if does not define. */ +m4trace:configure.in:759: -1- AC_DEFINE_TRACE_LITERAL([ptrdiff_t]) +m4trace:configure.in:759: -1- AH_OUTPUT([ptrdiff_t], [/* Define to `int\' if does not define. */ #undef ptrdiff_t]) -m4trace:configure.in:757: -1- AC_DEFINE_TRACE_LITERAL([ptrdiff_t]) -m4trace:configure.in:757: -1- AH_OUTPUT([ptrdiff_t], [/* Define to `long\' if does not define. */ +m4trace:configure.in:759: -1- AC_DEFINE_TRACE_LITERAL([ptrdiff_t]) +m4trace:configure.in:759: -1- AH_OUTPUT([ptrdiff_t], [/* Define to `long\' if does not define. */ #undef ptrdiff_t]) -m4trace:configure.in:757: -1- AC_DEFINE_TRACE_LITERAL([ptrdiff_t]) -m4trace:configure.in:757: -1- AH_OUTPUT([ptrdiff_t], [/* Define to `long long\' if does not define. */ +m4trace:configure.in:759: -1- AC_DEFINE_TRACE_LITERAL([ptrdiff_t]) +m4trace:configure.in:759: -1- AH_OUTPUT([ptrdiff_t], [/* Define to `long long\' if does not define. */ #undef ptrdiff_t]) -m4trace:configure.in:757: -1- AC_DEFINE_TRACE_LITERAL([ptrdiff_t]) -m4trace:configure.in:757: -1- AH_OUTPUT([ptrdiff_t], [/* Define to `int\' if does not define. */ +m4trace:configure.in:759: -1- AC_DEFINE_TRACE_LITERAL([ptrdiff_t]) +m4trace:configure.in:759: -1- AH_OUTPUT([ptrdiff_t], [/* Define to `int\' if does not define. */ #undef ptrdiff_t]) -m4trace:configure.in:760: -1- AC_HEADER_STAT -m4trace:configure.in:760: -1- AC_DEFINE_TRACE_LITERAL([STAT_MACROS_BROKEN]) -m4trace:configure.in:760: -1- AH_OUTPUT([STAT_MACROS_BROKEN], [/* Define to 1 if the `S_IS*\' macros in do not work properly. */ +m4trace:configure.in:762: -1- AC_HEADER_STAT +m4trace:configure.in:762: -1- AC_DEFINE_TRACE_LITERAL([STAT_MACROS_BROKEN]) +m4trace:configure.in:762: -1- AH_OUTPUT([STAT_MACROS_BROKEN], [/* Define to 1 if the `S_IS*\' macros in do not work properly. */ #undef STAT_MACROS_BROKEN]) -m4trace:configure.in:765: -1- AC_DEFINE_TRACE_LITERAL([HAVE_HASH_BANG_EXEC]) -m4trace:configure.in:770: -1- AC_DEFINE_TRACE_LITERAL([HAVE_LSTAT]) -m4trace:configure.in:774: -1- AC_DEFINE_TRACE_LITERAL([CTYPE_NON_ASCII]) -m4trace:configure.in:775: -1- AC_DEFINE_TRACE_LITERAL([DUP2_BROKEN]) -m4trace:configure.in:776: -1- AC_DEFINE_TRACE_LITERAL([PGRP_PIPE]) -m4trace:configure.in:777: -1- AC_DEFINE_TRACE_LITERAL([HAVE_POSIX_SIGNALS]) -m4trace:configure.in:777: -1- AC_DEFINE_TRACE_LITERAL([HAVE_BSD_SIGNALS]) -m4trace:configure.in:777: -1- AC_DEFINE_TRACE_LITERAL([HAVE_USG_SIGHOLD]) -m4trace:configure.in:780: -1- AC_DEFINE_TRACE_LITERAL([HAVE_SYS_ERRLIST]) -m4trace:configure.in:781: -1- AC_DEFINE_TRACE_LITERAL([HAVE_SYS_SIGLIST]) -m4trace:configure.in:782: -1- AC_DEFINE_TRACE_LITERAL([UNDER_SYS_SIGLIST_DECLARED]) -m4trace:configure.in:782: -1- AC_DEFINE_TRACE_LITERAL([HAVE_UNDER_SYS_SIGLIST]) -m4trace:configure.in:785: -1- AC_DEFINE_TRACE_LITERAL([VOID_SIGHANDLER]) -m4trace:configure.in:786: -1- AC_DEFINE_TRACE_LITERAL([clock_t]) -m4trace:configure.in:787: -1- AC_DEFINE_TRACE_LITERAL([sigset_t]) -m4trace:configure.in:788: -1- AC_DEFINE_TRACE_LITERAL([HAVE_QUAD_T]) -m4trace:configure.in:788: -1- AC_DEFINE_TRACE_LITERAL([quad_t]) -m4trace:configure.in:789: -1- AC_DEFINE_TRACE_LITERAL([intmax_t]) -m4trace:configure.in:790: -1- AC_DEFINE_TRACE_LITERAL([uintmax_t]) -m4trace:configure.in:792: -1- AC_DEFINE_TRACE_LITERAL([HAVE_SOCKLEN_T]) -m4trace:configure.in:792: -1- AC_DEFINE_TRACE_LITERAL([socklen_t]) -m4trace:configure.in:794: -1- AC_DEFINE_TRACE_LITERAL([RLIMTYPE]) -m4trace:configure.in:794: -1- AC_DEFINE_TRACE_LITERAL([RLIMTYPE]) -m4trace:configure.in:797: -2- AC_DEFINE_TRACE_LITERAL([TERMIOS_LDISC]) -m4trace:configure.in:798: -2- AC_DEFINE_TRACE_LITERAL([TERMIO_LDISC]) -m4trace:configure.in:799: -1- AC_DEFINE_TRACE_LITERAL([STRUCT_DIRENT_HAS_D_INO]) -m4trace:configure.in:800: -1- AC_DEFINE_TRACE_LITERAL([STRUCT_DIRENT_HAS_D_FILENO]) -m4trace:configure.in:801: -1- AC_DEFINE_TRACE_LITERAL([STRUCT_WINSIZE_IN_SYS_IOCTL]) -m4trace:configure.in:801: -1- AC_DEFINE_TRACE_LITERAL([STRUCT_WINSIZE_IN_TERMIOS]) -m4trace:configure.in:802: -1- AC_DEFINE_TRACE_LITERAL([HAVE_TIMEVAL]) -m4trace:configure.in:803: -1- AC_CHECK_MEMBERS([struct stat.st_blocks]) -m4trace:configure.in:803: -1- AC_DEFINE_TRACE_LITERAL([HAVE_STRUCT_STAT_ST_BLOCKS]) -m4trace:configure.in:803: -1- AH_OUTPUT([HAVE_STRUCT_STAT_ST_BLOCKS], [/* Define to 1 if `st_blocks\' is member of `struct stat\'. */ +m4trace:configure.in:767: -1- AC_DEFINE_TRACE_LITERAL([HAVE_HASH_BANG_EXEC]) +m4trace:configure.in:772: -1- AC_DEFINE_TRACE_LITERAL([HAVE_LSTAT]) +m4trace:configure.in:776: -1- AC_DEFINE_TRACE_LITERAL([CTYPE_NON_ASCII]) +m4trace:configure.in:777: -1- AC_DEFINE_TRACE_LITERAL([DUP2_BROKEN]) +m4trace:configure.in:778: -1- AC_DEFINE_TRACE_LITERAL([PGRP_PIPE]) +m4trace:configure.in:779: -1- AC_DEFINE_TRACE_LITERAL([HAVE_POSIX_SIGNALS]) +m4trace:configure.in:779: -1- AC_DEFINE_TRACE_LITERAL([HAVE_BSD_SIGNALS]) +m4trace:configure.in:779: -1- AC_DEFINE_TRACE_LITERAL([HAVE_USG_SIGHOLD]) +m4trace:configure.in:782: -1- AC_DEFINE_TRACE_LITERAL([HAVE_SYS_ERRLIST]) +m4trace:configure.in:783: -1- AC_DEFINE_TRACE_LITERAL([HAVE_SYS_SIGLIST]) +m4trace:configure.in:784: -1- AC_DEFINE_TRACE_LITERAL([UNDER_SYS_SIGLIST_DECLARED]) +m4trace:configure.in:784: -1- AC_DEFINE_TRACE_LITERAL([HAVE_UNDER_SYS_SIGLIST]) +m4trace:configure.in:787: -1- AC_DEFINE_TRACE_LITERAL([VOID_SIGHANDLER]) +m4trace:configure.in:788: -1- AC_DEFINE_TRACE_LITERAL([clock_t]) +m4trace:configure.in:789: -1- AC_DEFINE_TRACE_LITERAL([sigset_t]) +m4trace:configure.in:790: -1- AC_DEFINE_TRACE_LITERAL([HAVE_QUAD_T]) +m4trace:configure.in:790: -1- AC_DEFINE_TRACE_LITERAL([quad_t]) +m4trace:configure.in:791: -1- AC_DEFINE_TRACE_LITERAL([intmax_t]) +m4trace:configure.in:792: -1- AC_DEFINE_TRACE_LITERAL([uintmax_t]) +m4trace:configure.in:794: -1- AC_DEFINE_TRACE_LITERAL([HAVE_SOCKLEN_T]) +m4trace:configure.in:794: -1- AC_DEFINE_TRACE_LITERAL([socklen_t]) +m4trace:configure.in:796: -1- AC_DEFINE_TRACE_LITERAL([RLIMTYPE]) +m4trace:configure.in:796: -1- AC_DEFINE_TRACE_LITERAL([RLIMTYPE]) +m4trace:configure.in:799: -2- AC_DEFINE_TRACE_LITERAL([TERMIOS_LDISC]) +m4trace:configure.in:800: -2- AC_DEFINE_TRACE_LITERAL([TERMIO_LDISC]) +m4trace:configure.in:801: -1- AC_DEFINE_TRACE_LITERAL([STRUCT_DIRENT_HAS_D_INO]) +m4trace:configure.in:802: -1- AC_DEFINE_TRACE_LITERAL([STRUCT_DIRENT_HAS_D_FILENO]) +m4trace:configure.in:803: -1- AC_DEFINE_TRACE_LITERAL([STRUCT_WINSIZE_IN_SYS_IOCTL]) +m4trace:configure.in:803: -1- AC_DEFINE_TRACE_LITERAL([STRUCT_WINSIZE_IN_TERMIOS]) +m4trace:configure.in:804: -1- AC_DEFINE_TRACE_LITERAL([HAVE_TIMEVAL]) +m4trace:configure.in:805: -1- AC_CHECK_MEMBERS([struct stat.st_blocks]) +m4trace:configure.in:805: -1- AC_DEFINE_TRACE_LITERAL([HAVE_STRUCT_STAT_ST_BLOCKS]) +m4trace:configure.in:805: -1- AH_OUTPUT([HAVE_STRUCT_STAT_ST_BLOCKS], [/* Define to 1 if `st_blocks\' is member of `struct stat\'. */ #undef HAVE_STRUCT_STAT_ST_BLOCKS]) -m4trace:configure.in:804: -1- AC_STRUCT_TM -m4trace:configure.in:804: -1- AC_DEFINE_TRACE_LITERAL([TM_IN_SYS_TIME]) -m4trace:configure.in:804: -1- AH_OUTPUT([TM_IN_SYS_TIME], [/* Define to 1 if your declares `struct tm\'. */ +m4trace:configure.in:806: -1- AC_STRUCT_TM +m4trace:configure.in:806: -1- AC_DEFINE_TRACE_LITERAL([TM_IN_SYS_TIME]) +m4trace:configure.in:806: -1- AH_OUTPUT([TM_IN_SYS_TIME], [/* Define to 1 if your declares `struct tm\'. */ #undef TM_IN_SYS_TIME]) -m4trace:configure.in:805: -1- AC_STRUCT_TIMEZONE -m4trace:configure.in:805: -1- AC_CHECK_MEMBERS([struct tm.tm_zone], [], [], [#include +m4trace:configure.in:807: -1- AC_STRUCT_TIMEZONE +m4trace:configure.in:807: -1- AC_CHECK_MEMBERS([struct tm.tm_zone], [], [], [#include #include <$ac_cv_struct_tm> ]) -m4trace:configure.in:805: -1- AC_DEFINE_TRACE_LITERAL([HAVE_STRUCT_TM_TM_ZONE]) -m4trace:configure.in:805: -1- AH_OUTPUT([HAVE_STRUCT_TM_TM_ZONE], [/* Define to 1 if `tm_zone\' is member of `struct tm\'. */ +m4trace:configure.in:807: -1- AC_DEFINE_TRACE_LITERAL([HAVE_STRUCT_TM_TM_ZONE]) +m4trace:configure.in:807: -1- AH_OUTPUT([HAVE_STRUCT_TM_TM_ZONE], [/* Define to 1 if `tm_zone\' is member of `struct tm\'. */ #undef HAVE_STRUCT_TM_TM_ZONE]) -m4trace:configure.in:805: -1- AC_DEFINE_TRACE_LITERAL([HAVE_TM_ZONE]) -m4trace:configure.in:805: -1- AH_OUTPUT([HAVE_TM_ZONE], [/* Define to 1 if your `struct tm\' has `tm_zone\'. Deprecated, use +m4trace:configure.in:807: -1- AC_DEFINE_TRACE_LITERAL([HAVE_TM_ZONE]) +m4trace:configure.in:807: -1- AH_OUTPUT([HAVE_TM_ZONE], [/* Define to 1 if your `struct tm\' has `tm_zone\'. Deprecated, use `HAVE_STRUCT_TM_TM_ZONE\' instead. */ #undef HAVE_TM_ZONE]) -m4trace:configure.in:805: -1- AC_DEFINE_TRACE_LITERAL([HAVE_TZNAME]) -m4trace:configure.in:805: -1- AH_OUTPUT([HAVE_TZNAME], [/* Define to 1 if you don\'t have `tm_zone\' but do have the external array +m4trace:configure.in:807: -1- AC_DEFINE_TRACE_LITERAL([HAVE_TZNAME]) +m4trace:configure.in:807: -1- AH_OUTPUT([HAVE_TZNAME], [/* Define to 1 if you don\'t have `tm_zone\' but do have the external array `tzname\'. */ #undef HAVE_TZNAME]) -m4trace:configure.in:806: -1- AC_DEFINE_TRACE_LITERAL([HAVE_STRUCT_TIMEZONE]) -m4trace:configure.in:809: -1- AC_DEFINE_TRACE_LITERAL([HAVE_STRSIGNAL]) -m4trace:configure.in:810: -1- AC_DEFINE_TRACE_LITERAL([OPENDIR_NOT_ROBUST]) -m4trace:configure.in:811: -1- AC_DEFINE_TRACE_LITERAL([ULIMIT_MAXFDS]) -m4trace:configure.in:812: -1- AC_DEFINE_TRACE_LITERAL([CAN_REDEFINE_GETENV]) -m4trace:configure.in:814: -1- AC_DEFINE_TRACE_LITERAL([GETCWD_BROKEN]) -m4trace:configure.in:814: -1- AC_LIBSOURCE([getcwd.c]) -m4trace:configure.in:814: -1- AC_SUBST([LIB@&t@OBJS]) -m4trace:configure.in:816: -1- AC_DEFINE_TRACE_LITERAL([HAVE_POSIX_SIGSETJMP]) -m4trace:configure.in:817: -1- AC_DEFINE_TRACE_LITERAL([STRCOLL_BROKEN]) -m4trace:configure.in:823: -1- AC_DEFINE_TRACE_LITERAL([HAVE_STD_PUTENV]) +m4trace:configure.in:808: -1- AC_DEFINE_TRACE_LITERAL([HAVE_STRUCT_TIMEZONE]) +m4trace:configure.in:811: -1- AC_DEFINE_TRACE_LITERAL([HAVE_STRSIGNAL]) +m4trace:configure.in:812: -1- AC_DEFINE_TRACE_LITERAL([OPENDIR_NOT_ROBUST]) +m4trace:configure.in:813: -1- AC_DEFINE_TRACE_LITERAL([ULIMIT_MAXFDS]) +m4trace:configure.in:814: -1- AC_DEFINE_TRACE_LITERAL([CAN_REDEFINE_GETENV]) +m4trace:configure.in:816: -1- AC_DEFINE_TRACE_LITERAL([GETCWD_BROKEN]) +m4trace:configure.in:816: -1- AC_LIBSOURCE([getcwd.c]) +m4trace:configure.in:816: -1- AC_SUBST([LIB@&t@OBJS]) +m4trace:configure.in:818: -1- AC_DEFINE_TRACE_LITERAL([HAVE_POSIX_SIGSETJMP]) +m4trace:configure.in:819: -1- AC_DEFINE_TRACE_LITERAL([STRCOLL_BROKEN]) m4trace:configure.in:825: -1- AC_DEFINE_TRACE_LITERAL([HAVE_STD_PUTENV]) -m4trace:configure.in:828: -1- AC_DEFINE_TRACE_LITERAL([HAVE_STD_UNSETENV]) +m4trace:configure.in:827: -1- AC_DEFINE_TRACE_LITERAL([HAVE_STD_PUTENV]) m4trace:configure.in:830: -1- AC_DEFINE_TRACE_LITERAL([HAVE_STD_UNSETENV]) -m4trace:configure.in:845: -1- AC_DEFINE_TRACE_LITERAL([HAVE_PRINTF_A_FORMAT]) -m4trace:configure.in:848: -1- AC_DEFINE_TRACE_LITERAL([MUST_REINSTALL_SIGHANDLERS]) -m4trace:configure.in:849: -1- AC_DEFINE_TRACE_LITERAL([JOB_CONTROL_MISSING]) -m4trace:configure.in:850: -1- AC_DEFINE_TRACE_LITERAL([NAMED_PIPES_MISSING]) -m4trace:configure.in:853: -1- AC_DEFINE_TRACE_LITERAL([GWINSZ_IN_SYS_IOCTL]) -m4trace:configure.in:853: -1- AH_OUTPUT([GWINSZ_IN_SYS_IOCTL], [/* Define to 1 if `TIOCGWINSZ\' requires . */ +m4trace:configure.in:832: -1- AC_DEFINE_TRACE_LITERAL([HAVE_STD_UNSETENV]) +m4trace:configure.in:847: -1- AC_DEFINE_TRACE_LITERAL([HAVE_PRINTF_A_FORMAT]) +m4trace:configure.in:850: -1- AC_DEFINE_TRACE_LITERAL([MUST_REINSTALL_SIGHANDLERS]) +m4trace:configure.in:851: -1- AC_DEFINE_TRACE_LITERAL([JOB_CONTROL_MISSING]) +m4trace:configure.in:852: -1- AC_DEFINE_TRACE_LITERAL([NAMED_PIPES_MISSING]) +m4trace:configure.in:855: -1- AC_DEFINE_TRACE_LITERAL([GWINSZ_IN_SYS_IOCTL]) +m4trace:configure.in:855: -1- AH_OUTPUT([GWINSZ_IN_SYS_IOCTL], [/* Define to 1 if `TIOCGWINSZ\' requires . */ #undef GWINSZ_IN_SYS_IOCTL]) -m4trace:configure.in:854: -1- AC_DEFINE_TRACE_LITERAL([TIOCSTAT_IN_SYS_IOCTL]) -m4trace:configure.in:855: -1- AC_DEFINE_TRACE_LITERAL([FIONREAD_IN_SYS_IOCTL]) -m4trace:configure.in:858: -1- AC_DEFINE_TRACE_LITERAL([SPEED_T_IN_SYS_TYPES]) -m4trace:configure.in:859: -1- AC_DEFINE_TRACE_LITERAL([HAVE_GETPW_DECLS]) -m4trace:configure.in:860: -1- AC_DEFINE_TRACE_LITERAL([UNUSABLE_RT_SIGNALS]) -m4trace:configure.in:861: -1- AC_SUBST([SIGLIST_O]) -m4trace:configure.in:865: -1- AC_DEFINE_TRACE_LITERAL([RLIMIT_NEEDS_KERNEL]) -m4trace:configure.in:873: -1- AC_CHECK_LIB([termcap], [tgetent], [bash_cv_termcap_lib=libtermcap], [AC_CHECK_LIB(tinfo, tgetent, bash_cv_termcap_lib=libtinfo, +m4trace:configure.in:856: -1- AC_DEFINE_TRACE_LITERAL([TIOCSTAT_IN_SYS_IOCTL]) +m4trace:configure.in:857: -1- AC_DEFINE_TRACE_LITERAL([FIONREAD_IN_SYS_IOCTL]) +m4trace:configure.in:860: -1- AC_DEFINE_TRACE_LITERAL([SPEED_T_IN_SYS_TYPES]) +m4trace:configure.in:861: -1- AC_DEFINE_TRACE_LITERAL([HAVE_GETPW_DECLS]) +m4trace:configure.in:862: -1- AC_DEFINE_TRACE_LITERAL([UNUSABLE_RT_SIGNALS]) +m4trace:configure.in:863: -1- AC_SUBST([SIGLIST_O]) +m4trace:configure.in:867: -1- AC_DEFINE_TRACE_LITERAL([RLIMIT_NEEDS_KERNEL]) +m4trace:configure.in:875: -1- AC_CHECK_LIB([termcap], [tgetent], [bash_cv_termcap_lib=libtermcap], [AC_CHECK_LIB(tinfo, tgetent, bash_cv_termcap_lib=libtinfo, [AC_CHECK_LIB(curses, tgetent, bash_cv_termcap_lib=libcurses, [AC_CHECK_LIB(ncurses, tgetent, bash_cv_termcap_lib=libncurses, bash_cv_termcap_lib=gnutermcap)])])]) -m4trace:configure.in:873: -1- AC_CHECK_LIB([tinfo], [tgetent], [bash_cv_termcap_lib=libtinfo], [AC_CHECK_LIB(curses, tgetent, bash_cv_termcap_lib=libcurses, +m4trace:configure.in:875: -1- AC_CHECK_LIB([tinfo], [tgetent], [bash_cv_termcap_lib=libtinfo], [AC_CHECK_LIB(curses, tgetent, bash_cv_termcap_lib=libcurses, [AC_CHECK_LIB(ncurses, tgetent, bash_cv_termcap_lib=libncurses, bash_cv_termcap_lib=gnutermcap)])]) -m4trace:configure.in:873: -1- AC_CHECK_LIB([curses], [tgetent], [bash_cv_termcap_lib=libcurses], [AC_CHECK_LIB(ncurses, tgetent, bash_cv_termcap_lib=libncurses, +m4trace:configure.in:875: -1- AC_CHECK_LIB([curses], [tgetent], [bash_cv_termcap_lib=libcurses], [AC_CHECK_LIB(ncurses, tgetent, bash_cv_termcap_lib=libncurses, bash_cv_termcap_lib=gnutermcap)]) -m4trace:configure.in:873: -1- AC_CHECK_LIB([ncurses], [tgetent], [bash_cv_termcap_lib=libncurses], [bash_cv_termcap_lib=gnutermcap]) -m4trace:configure.in:875: -1- AC_SUBST([TERMCAP_LIB]) -m4trace:configure.in:876: -1- AC_SUBST([TERMCAP_DEP]) -m4trace:configure.in:878: -1- AC_DEFINE_TRACE_LITERAL([HAVE_DEV_FD]) -m4trace:configure.in:878: -1- AC_DEFINE_TRACE_LITERAL([DEV_FD_PREFIX]) -m4trace:configure.in:878: -1- AC_DEFINE_TRACE_LITERAL([HAVE_DEV_FD]) -m4trace:configure.in:878: -1- AC_DEFINE_TRACE_LITERAL([DEV_FD_PREFIX]) -m4trace:configure.in:879: -1- AC_DEFINE_TRACE_LITERAL([HAVE_DEV_STDIN]) -m4trace:configure.in:880: -1- AC_DEFINE_TRACE_LITERAL([DEFAULT_MAIL_DIRECTORY]) -m4trace:configure.in:887: -1- AC_DEFINE_TRACE_LITERAL([JOB_CONTROL]) -m4trace:configure.in:893: -1- AC_SUBST([JOBS_O]) -m4trace:configure.in:906: -1- AC_DEFINE_TRACE_LITERAL([SVR4_2]) -m4trace:configure.in:907: -1- AC_DEFINE_TRACE_LITERAL([SVR4]) -m4trace:configure.in:908: -1- AC_DEFINE_TRACE_LITERAL([SVR4]) -m4trace:configure.in:909: -1- AC_DEFINE_TRACE_LITERAL([SVR5]) -m4trace:configure.in:966: -1- AC_SUBST([SHOBJ_CC]) -m4trace:configure.in:967: -1- AC_SUBST([SHOBJ_CFLAGS]) -m4trace:configure.in:968: -1- AC_SUBST([SHOBJ_LD]) -m4trace:configure.in:969: -1- AC_SUBST([SHOBJ_LDFLAGS]) -m4trace:configure.in:970: -1- AC_SUBST([SHOBJ_XLDFLAGS]) -m4trace:configure.in:971: -1- AC_SUBST([SHOBJ_LIBS]) -m4trace:configure.in:972: -1- AC_SUBST([SHOBJ_STATUS]) -m4trace:configure.in:993: -1- AC_SUBST([PROFILE_FLAGS]) -m4trace:configure.in:995: -1- AC_SUBST([incdir]) -m4trace:configure.in:996: -1- AC_SUBST([BUILD_DIR]) -m4trace:configure.in:998: -1- AC_SUBST([YACC]) -m4trace:configure.in:999: -1- AC_SUBST([AR]) -m4trace:configure.in:1000: -1- AC_SUBST([ARFLAGS]) -m4trace:configure.in:1002: -1- AC_SUBST([BASHVERS]) -m4trace:configure.in:1003: -1- AC_SUBST([RELSTATUS]) -m4trace:configure.in:1004: -1- AC_SUBST([DEBUG]) -m4trace:configure.in:1005: -1- AC_SUBST([MALLOC_DEBUG]) -m4trace:configure.in:1007: -1- AC_SUBST([host_cpu]) -m4trace:configure.in:1008: -1- AC_SUBST([host_vendor]) -m4trace:configure.in:1009: -1- AC_SUBST([host_os]) -m4trace:configure.in:1011: -1- AC_SUBST([LOCAL_LIBS]) -m4trace:configure.in:1012: -1- AC_SUBST([LOCAL_CFLAGS]) -m4trace:configure.in:1013: -1- AC_SUBST([LOCAL_LDFLAGS]) -m4trace:configure.in:1014: -1- AC_SUBST([LOCAL_DEFS]) -m4trace:configure.in:1028: -1- AC_CONFIG_FILES([Makefile builtins/Makefile lib/readline/Makefile lib/glob/Makefile \ +m4trace:configure.in:875: -1- AC_CHECK_LIB([ncurses], [tgetent], [bash_cv_termcap_lib=libncurses], [bash_cv_termcap_lib=gnutermcap]) +m4trace:configure.in:877: -1- AC_SUBST([TERMCAP_LIB]) +m4trace:configure.in:878: -1- AC_SUBST([TERMCAP_DEP]) +m4trace:configure.in:880: -1- AC_DEFINE_TRACE_LITERAL([HAVE_DEV_FD]) +m4trace:configure.in:880: -1- AC_DEFINE_TRACE_LITERAL([DEV_FD_PREFIX]) +m4trace:configure.in:880: -1- AC_DEFINE_TRACE_LITERAL([HAVE_DEV_FD]) +m4trace:configure.in:880: -1- AC_DEFINE_TRACE_LITERAL([DEV_FD_PREFIX]) +m4trace:configure.in:881: -1- AC_DEFINE_TRACE_LITERAL([HAVE_DEV_STDIN]) +m4trace:configure.in:882: -1- AC_DEFINE_TRACE_LITERAL([DEFAULT_MAIL_DIRECTORY]) +m4trace:configure.in:889: -1- AC_DEFINE_TRACE_LITERAL([JOB_CONTROL]) +m4trace:configure.in:895: -1- AC_SUBST([JOBS_O]) +m4trace:configure.in:908: -1- AC_DEFINE_TRACE_LITERAL([SVR4_2]) +m4trace:configure.in:909: -1- AC_DEFINE_TRACE_LITERAL([SVR4]) +m4trace:configure.in:910: -1- AC_DEFINE_TRACE_LITERAL([SVR4]) +m4trace:configure.in:911: -1- AC_DEFINE_TRACE_LITERAL([SVR5]) +m4trace:configure.in:968: -1- AC_SUBST([SHOBJ_CC]) +m4trace:configure.in:969: -1- AC_SUBST([SHOBJ_CFLAGS]) +m4trace:configure.in:970: -1- AC_SUBST([SHOBJ_LD]) +m4trace:configure.in:971: -1- AC_SUBST([SHOBJ_LDFLAGS]) +m4trace:configure.in:972: -1- AC_SUBST([SHOBJ_XLDFLAGS]) +m4trace:configure.in:973: -1- AC_SUBST([SHOBJ_LIBS]) +m4trace:configure.in:974: -1- AC_SUBST([SHOBJ_STATUS]) +m4trace:configure.in:995: -1- AC_SUBST([PROFILE_FLAGS]) +m4trace:configure.in:997: -1- AC_SUBST([incdir]) +m4trace:configure.in:998: -1- AC_SUBST([BUILD_DIR]) +m4trace:configure.in:1000: -1- AC_SUBST([YACC]) +m4trace:configure.in:1001: -1- AC_SUBST([AR]) +m4trace:configure.in:1002: -1- AC_SUBST([ARFLAGS]) +m4trace:configure.in:1004: -1- AC_SUBST([BASHVERS]) +m4trace:configure.in:1005: -1- AC_SUBST([RELSTATUS]) +m4trace:configure.in:1006: -1- AC_SUBST([DEBUG]) +m4trace:configure.in:1007: -1- AC_SUBST([MALLOC_DEBUG]) +m4trace:configure.in:1009: -1- AC_SUBST([host_cpu]) +m4trace:configure.in:1010: -1- AC_SUBST([host_vendor]) +m4trace:configure.in:1011: -1- AC_SUBST([host_os]) +m4trace:configure.in:1013: -1- AC_SUBST([LOCAL_LIBS]) +m4trace:configure.in:1014: -1- AC_SUBST([LOCAL_CFLAGS]) +m4trace:configure.in:1015: -1- AC_SUBST([LOCAL_LDFLAGS]) +m4trace:configure.in:1016: -1- AC_SUBST([LOCAL_DEFS]) +m4trace:configure.in:1030: -1- AC_CONFIG_FILES([Makefile builtins/Makefile lib/readline/Makefile lib/glob/Makefile \ lib/intl/Makefile \ lib/malloc/Makefile lib/sh/Makefile lib/termcap/Makefile \ lib/tilde/Makefile doc/Makefile support/Makefile po/Makefile.in \ examples/loadables/Makefile examples/loadables/perl/Makefile \ pathnames.h]) -m4trace:configure.in:1028: -1- AC_SUBST([LIB@&t@OBJS], [$ac_libobjs]) -m4trace:configure.in:1028: -1- AC_SUBST([LTLIBOBJS], [$ac_ltlibobjs]) +m4trace:configure.in:1030: -1- AC_SUBST([LIB@&t@OBJS], [$ac_libobjs]) +m4trace:configure.in:1030: -1- AC_SUBST([LTLIBOBJS], [$ac_ltlibobjs]) diff --git a/bashline.c b/bashline.c index af0897fc8..84679694e 100644 --- a/bashline.c +++ b/bashline.c @@ -324,6 +324,9 @@ enable_hostname_completion (on_or_off) void initialize_readline () { + rl_command_func_t *func; + char kseq[2]; + if (bash_readline_initialized) return; @@ -395,8 +398,15 @@ initialize_readline () /* In Bash, the user can switch editing modes with "set -o [vi emacs]", so it is not necessary to allow C-M-j for context switching. Turn off this occasionally confusing behaviour. */ - rl_unbind_key_in_map (CTRL('J'), emacs_meta_keymap); - rl_unbind_key_in_map (CTRL('M'), emacs_meta_keymap); + kseq[0] = CTRL('J'); + kseq[1] = '\0'; + func = rl_function_of_keyseq (kseq, emacs_meta_keymap, (int *)NULL); + if (func == rl_vi_editing_mode) + rl_unbind_key_in_map (CTRL('J'), emacs_meta_keymap); + kseq[0] = CTRL('M'); + func = rl_function_of_keyseq (kseq, emacs_meta_keymap, (int *)NULL); + if (func == rl_vi_editing_mode) + rl_unbind_key_in_map (CTRL('M'), emacs_meta_keymap); #if defined (VI_MODE) rl_unbind_key_in_map (CTRL('E'), vi_movement_keymap); #endif diff --git a/builtins/Makefile.in b/builtins/Makefile.in index 676dbb610..4bb4ea5ea 100644 --- a/builtins/Makefile.in +++ b/builtins/Makefile.in @@ -50,6 +50,8 @@ INSTALL = @INSTALL@ INSTALL_DATA = @INSTALL_DATA@ BUILD_DIR = @BUILD_DIR@ +LIBBUILD = ${BUILD_DIR}/lib + PROFILE_FLAGS = @PROFILE_FLAGS@ CFLAGS = @CFLAGS@ CFLAGS_FOR_BUILD = @CFLAGS_FOR_BUILD@ @@ -70,10 +72,15 @@ BASHINCDIR = ${topdir}/include RL_INCLUDEDIR = @RL_INCLUDEDIR@ +INTL_LIBSRC = ${topdir}/lib/intl +INTL_BUILDDIR = ${LIBBUILD}/intl +INTL_INC = @INTL_INC@ +LIBINTL_H = @LIBINTL_H@ + HELPDIR = @HELPDIR@ MKDIRS = ${topdir}/support/mkdirs -INCLUDES = -I. -I.. @RL_INCLUDE@ -I$(topdir) -I$(BASHINCDIR) -I$(topdir)/lib -I$(srcdir) +INCLUDES = -I. -I.. @RL_INCLUDE@ -I$(topdir) -I$(BASHINCDIR) -I$(topdir)/lib -I$(srcdir) ${INTL_INC} BASE_CCFLAGS = ${PROFILE_FLAGS} $(DEFS) $(LOCAL_DEFS) $(SYSTEM_FLAGS) \ ${INCLUDES} $(LOCAL_CFLAGS) @@ -577,38 +584,38 @@ complete.o: ${srcdir}/common.h ${srcdir}/bashgetopt.h #bind.o: $(RL_LIBSRC)chardefs.h $(RL_LIBSRC)readline.h $(RL_LIBSRC)keymaps.h # libintl dependencies -bind.o: ${topdir}/bashintl.h $(BASHINCDIR)/gettext.h -break.o: ${topdir}/bashintl.h $(BASHINCDIR)/gettext.h -caller.o: ${topdir}/bashintl.h $(BASHINCDIR)/gettext.h -cd.o: ${topdir}/bashintl.h $(BASHINCDIR)/gettext.h -common.c: ${topdir}/bashintl.h $(BASHINCDIR)/gettext.h -complete.o: ${topdir}/bashintl.h $(BASHINCDIR)/gettext.h -declare.o: ${topdir}/bashintl.h $(BASHINCDIR)/gettext.h -enable.o: ${topdir}/bashintl.h $(BASHINCDIR)/gettext.h -evalfile.c: ${topdir}/bashintl.h $(BASHINCDIR)/gettext.h -exec.o: ${topdir}/bashintl.h $(BASHINCDIR)/gettext.h -exit.o: ${topdir}/bashintl.h $(BASHINCDIR)/gettext.h -fc.o: ${topdir}/bashintl.h $(BASHINCDIR)/gettext.h -fg_bg.o: ${topdir}/bashintl.h $(BASHINCDIR)/gettext.h -getopt.c: ${topdir}/bashintl.h $(BASHINCDIR)/gettext.h -hash.o: ${topdir}/bashintl.h $(BASHINCDIR)/gettext.h -help.o: ${topdir}/bashintl.h $(BASHINCDIR)/gettext.h -history.o: ${topdir}/bashintl.h $(BASHINCDIR)/gettext.h -inlib.o: ${topdir}/bashintl.h $(BASHINCDIR)/gettext.h -jobs.o: ${topdir}/bashintl.h $(BASHINCDIR)/gettext.h -kill.o: ${topdir}/bashintl.h $(BASHINCDIR)/gettext.h -let.o: ${topdir}/bashintl.h $(BASHINCDIR)/gettext.h -mkbuiltins.c: ${topdir}/bashintl.h $(BASHINCDIR)/gettext.h -printf.o: ${topdir}/bashintl.h $(BASHINCDIR)/gettext.h -pushd.o: ${topdir}/bashintl.h $(BASHINCDIR)/gettext.h -read.o: ${topdir}/bashintl.h $(BASHINCDIR)/gettext.h -return.o: ${topdir}/bashintl.h $(BASHINCDIR)/gettext.h -set.o: ${topdir}/bashintl.h $(BASHINCDIR)/gettext.h -setattr.o: ${topdir}/bashintl.h $(BASHINCDIR)/gettext.h -shift.o: ${topdir}/bashintl.h $(BASHINCDIR)/gettext.h -shopt.o: ${topdir}/bashintl.h $(BASHINCDIR)/gettext.h -source.o: ${topdir}/bashintl.h $(BASHINCDIR)/gettext.h -suspend.o: ${topdir}/bashintl.h $(BASHINCDIR)/gettext.h -type.o: ${topdir}/bashintl.h $(BASHINCDIR)/gettext.h -ulimit.o: ${topdir}/bashintl.h $(BASHINCDIR)/gettext.h -umask.o: ${topdir}/bashintl.h $(BASHINCDIR)/gettext.h +bind.o: ${topdir}/bashintl.h ${LIBINTL_H} $(BASHINCDIR)/gettext.h +break.o: ${topdir}/bashintl.h ${LIBINTL_H} $(BASHINCDIR)/gettext.h +caller.o: ${topdir}/bashintl.h ${LIBINTL_H} $(BASHINCDIR)/gettext.h +cd.o: ${topdir}/bashintl.h ${LIBINTL_H} $(BASHINCDIR)/gettext.h +common.c: ${topdir}/bashintl.h ${LIBINTL_H} $(BASHINCDIR)/gettext.h +complete.o: ${topdir}/bashintl.h ${LIBINTL_H} $(BASHINCDIR)/gettext.h +declare.o: ${topdir}/bashintl.h ${LIBINTL_H} $(BASHINCDIR)/gettext.h +enable.o: ${topdir}/bashintl.h ${LIBINTL_H} $(BASHINCDIR)/gettext.h +evalfile.c: ${topdir}/bashintl.h ${LIBINTL_H} $(BASHINCDIR)/gettext.h +exec.o: ${topdir}/bashintl.h ${LIBINTL_H} $(BASHINCDIR)/gettext.h +exit.o: ${topdir}/bashintl.h ${LIBINTL_H} $(BASHINCDIR)/gettext.h +fc.o: ${topdir}/bashintl.h ${LIBINTL_H} $(BASHINCDIR)/gettext.h +fg_bg.o: ${topdir}/bashintl.h ${LIBINTL_H} $(BASHINCDIR)/gettext.h +getopt.c: ${topdir}/bashintl.h ${LIBINTL_H} $(BASHINCDIR)/gettext.h +hash.o: ${topdir}/bashintl.h ${LIBINTL_H} $(BASHINCDIR)/gettext.h +help.o: ${topdir}/bashintl.h ${LIBINTL_H} $(BASHINCDIR)/gettext.h +history.o: ${topdir}/bashintl.h ${LIBINTL_H} $(BASHINCDIR)/gettext.h +inlib.o: ${topdir}/bashintl.h ${LIBINTL_H} $(BASHINCDIR)/gettext.h +jobs.o: ${topdir}/bashintl.h ${LIBINTL_H} $(BASHINCDIR)/gettext.h +kill.o: ${topdir}/bashintl.h ${LIBINTL_H} $(BASHINCDIR)/gettext.h +let.o: ${topdir}/bashintl.h ${LIBINTL_H} $(BASHINCDIR)/gettext.h +mkbuiltins.c: ${topdir}/bashintl.h ${LIBINTL_H} $(BASHINCDIR)/gettext.h +printf.o: ${topdir}/bashintl.h ${LIBINTL_H} $(BASHINCDIR)/gettext.h +pushd.o: ${topdir}/bashintl.h ${LIBINTL_H} $(BASHINCDIR)/gettext.h +read.o: ${topdir}/bashintl.h ${LIBINTL_H} $(BASHINCDIR)/gettext.h +return.o: ${topdir}/bashintl.h ${LIBINTL_H} $(BASHINCDIR)/gettext.h +set.o: ${topdir}/bashintl.h ${LIBINTL_H} $(BASHINCDIR)/gettext.h +setattr.o: ${topdir}/bashintl.h ${LIBINTL_H} $(BASHINCDIR)/gettext.h +shift.o: ${topdir}/bashintl.h ${LIBINTL_H} $(BASHINCDIR)/gettext.h +shopt.o: ${topdir}/bashintl.h ${LIBINTL_H} $(BASHINCDIR)/gettext.h +source.o: ${topdir}/bashintl.h ${LIBINTL_H} $(BASHINCDIR)/gettext.h +suspend.o: ${topdir}/bashintl.h ${LIBINTL_H} $(BASHINCDIR)/gettext.h +type.o: ${topdir}/bashintl.h ${LIBINTL_H} $(BASHINCDIR)/gettext.h +ulimit.o: ${topdir}/bashintl.h ${LIBINTL_H} $(BASHINCDIR)/gettext.h +umask.o: ${topdir}/bashintl.h ${LIBINTL_H} $(BASHINCDIR)/gettext.h diff --git a/builtins/common.c b/builtins/common.c index 0e0787b0b..7fd9155e4 100644 --- a/builtins/common.c +++ b/builtins/common.c @@ -573,7 +573,11 @@ get_job_spec (list) word = list->word->word; if (*word == '\0') +#if 0 return (current_job); +#else + return (NO_JOB); +#endif if (*word == '%') word++; @@ -581,17 +585,14 @@ get_job_spec (list) if (DIGIT (*word) && all_digits (word)) { job = atoi (word); -#if 0 - return (job >= job_slots ? NO_JOB : job - 1); -#else return (job > job_slots ? NO_JOB : job - 1); -#endif } jflags = 0; switch (*word) { case 0: + return NO_JOB; case '%': case '+': return (current_job); diff --git a/builtins/common.c~ b/builtins/common.c~ new file mode 100644 index 000000000..4a5648099 --- /dev/null +++ b/builtins/common.c~ @@ -0,0 +1,818 @@ +/* Copyright (C) 1987-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 2, 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; see the file COPYING. If not, write to the Free Software + Foundation, 59 Temple Place, Suite 330, Boston, MA 02111 USA. */ + +#include + +#if defined (HAVE_UNISTD_H) +# ifdef _MINIX +# include +# endif +# include +#endif + +#include +#include +#include "../bashtypes.h" +#include "posixstat.h" +#include + +#include + +#if defined (PREFER_STDARG) +# include +#else +# include +#endif + +#include "../bashansi.h" +#include "../bashintl.h" + +#include "../shell.h" +#include "maxpath.h" +#include "../flags.h" +#include "../jobs.h" +#include "../builtins.h" +#include "../input.h" +#include "../execute_cmd.h" +#include "../trap.h" +#include "bashgetopt.h" +#include "common.h" +#include "builtext.h" +#include + +#if defined (HISTORY) +# include "../bashhist.h" +#endif + +#if !defined (errno) +extern int errno; +#endif /* !errno */ + +extern int indirection_level, subshell_environment; +extern int line_number; +extern int last_command_exit_value; +extern int running_trap; +extern int posixly_correct; +extern char *this_command_name, *shell_name; +extern char *bash_getcwd_errstr; + +/* Used by some builtins and the mainline code. */ +sh_builtin_func_t *last_shell_builtin = (sh_builtin_func_t *)NULL; +sh_builtin_func_t *this_shell_builtin = (sh_builtin_func_t *)NULL; + +/* **************************************************************** */ +/* */ +/* Error reporting, usage, and option processing */ +/* */ +/* **************************************************************** */ + +/* This is a lot like report_error (), but it is for shell builtins + instead of shell control structures, and it won't ever exit the + shell. */ +void +#if defined (PREFER_STDARG) +builtin_error (const char *format, ...) +#else +builtin_error (format, va_alist) + const char *format; + va_dcl +#endif +{ + va_list args; + char *name; + + name = get_name_for_error (); + fprintf (stderr, "%s: ", name); + + if (interactive_shell == 0) + fprintf (stderr, "line %d: ", executing_line_number ()); + + if (this_command_name && *this_command_name) + fprintf (stderr, "%s: ", this_command_name); + + SH_VA_START (args, format); + + vfprintf (stderr, format, args); + va_end (args); + fprintf (stderr, "\n"); +} + +/* Print a usage summary for the currently-executing builtin command. */ +void +builtin_usage () +{ + if (this_command_name && *this_command_name) + fprintf (stderr, "%s: usage: ", this_command_name); + fprintf (stderr, "%s\n", current_builtin->short_doc); + fflush (stderr); +} + +/* Return if LIST is NULL else barf and jump to top_level. Used by some + builtins that do not accept arguments. */ +void +no_args (list) + WORD_LIST *list; +{ + if (list) + { + builtin_error (_("too many arguments")); + jump_to_top_level (DISCARD); + } +} + +/* Check that no options were given to the currently-executing builtin, + and return 0 if there were options. */ +int +no_options (list) + WORD_LIST *list; +{ + reset_internal_getopt (); + if (internal_getopt (list, "") != -1) + { + builtin_usage (); + return (1); + } + return (0); +} + +void +sh_needarg (s) + char *s; +{ + builtin_error (_("%s: option requires an argument"), s); +} + +void +sh_neednumarg (s) + char *s; +{ + builtin_error (_("%s: numeric argument required"), s); +} + +void +sh_notfound (s) + char *s; +{ + builtin_error (_("%s: not found"), s); +} + +/* Function called when one of the builtin commands detects an invalid + option. */ +void +sh_invalidopt (s) + char *s; +{ + builtin_error (_("%s: invalid option"), s); +} + +void +sh_invalidoptname (s) + char *s; +{ + builtin_error (_("%s: invalid option name"), s); +} + +void +sh_invalidid (s) + char *s; +{ + builtin_error (_("`%s': not a valid identifier"), s); +} + +void +sh_invalidnum (s) + char *s; +{ + builtin_error (_("%s: invalid number"), s); +} + +void +sh_invalidsig (s) + char *s; +{ + builtin_error (_("%s: invalid signal specification"), s); +} + +void +sh_badpid (s) + char *s; +{ + builtin_error (_("`%s': not a pid or valid job spec"), s); +} + +void +sh_readonly (s) + const char *s; +{ + builtin_error (_("%s: readonly variable"), s); +} + +void +sh_erange (s, desc) + char *s, *desc; +{ + if (s) + builtin_error (_("%s: %s out of range"), s, desc ? desc : _("argument")); + else + builtin_error (_("%s out of range"), desc ? desc : _("argument")); +} + +#if defined (JOB_CONTROL) +void +sh_badjob (s) + char *s; +{ + builtin_error (_("%s: no such job"), s); +} + +void +sh_nojobs (s) + char *s; +{ + if (s) + builtin_error (_("%s: no job control"), s); + else + builtin_error (_("no job control")); +} +#endif + +#if defined (RESTRICTED_SHELL) +void +sh_restricted (s) + char *s; +{ + if (s) + builtin_error (_("%s: restricted"), s); + else + builtin_error (_("restricted")); +} +#endif + +void +sh_notbuiltin (s) + char *s; +{ + builtin_error (_("%s: not a shell builtin"), s); +} + +/* **************************************************************** */ +/* */ +/* Shell positional parameter manipulation */ +/* */ +/* **************************************************************** */ + +/* Convert a WORD_LIST into a C-style argv. Return the number of elements + in the list in *IP, if IP is non-null. A convenience function for + loadable builtins; also used by `test'. */ +char ** +make_builtin_argv (list, ip) + WORD_LIST *list; + int *ip; +{ + char **argv; + + argv = strvec_from_word_list (list, 0, 1, ip); + argv[0] = this_command_name; + return argv; +} + +/* Remember LIST in $0 ... $9, and REST_OF_ARGS. If DESTRUCTIVE is + non-zero, then discard whatever the existing arguments are, else + only discard the ones that are to be replaced. */ +void +remember_args (list, destructive) + WORD_LIST *list; + int destructive; +{ + register int i; + + for (i = 1; i < 10; i++) + { + if ((destructive || list) && dollar_vars[i]) + { + free (dollar_vars[i]); + dollar_vars[i] = (char *)NULL; + } + + if (list) + { + dollar_vars[i] = savestring (list->word->word); + list = list->next; + } + } + + /* If arguments remain, assign them to REST_OF_ARGS. + Note that copy_word_list (NULL) returns NULL, and + that dispose_words (NULL) does nothing. */ + if (destructive || list) + { + dispose_words (rest_of_args); + rest_of_args = copy_word_list (list); + } + + if (destructive) + set_dollar_vars_changed (); +} + +static int changed_dollar_vars; + +/* Have the dollar variables been reset to new values since we last + checked? */ +int +dollar_vars_changed () +{ + return (changed_dollar_vars); +} + +void +set_dollar_vars_unchanged () +{ + changed_dollar_vars = 0; +} + +void +set_dollar_vars_changed () +{ + if (variable_context) + changed_dollar_vars |= ARGS_FUNC; + else if (this_shell_builtin == set_builtin) + changed_dollar_vars |= ARGS_SETBLTIN; + else + changed_dollar_vars |= ARGS_INVOC; +} + +/* **************************************************************** */ +/* */ +/* Validating numeric input and arguments */ +/* */ +/* **************************************************************** */ + +/* Read a numeric arg for this_command_name, the name of the shell builtin + that wants it. LIST is the word list that the arg is to come from. + Accept only the numeric argument; report an error if other arguments + follow. If FATAL is true, call throw_to_top_level, which exits the + shell; if not, call jump_to_top_level (DISCARD), which aborts the + current command. */ +intmax_t +get_numeric_arg (list, fatal) + WORD_LIST *list; + int fatal; +{ + intmax_t count = 1; + + if (list && list->word && ISOPTION (list->word->word, '-')) + list = list->next; + + if (list) + { + register char *arg; + + arg = list->word->word; + if (arg == 0 || (legal_number (arg, &count) == 0)) + { + sh_neednumarg (list->word->word); + if (fatal) + throw_to_top_level (); + else + jump_to_top_level (DISCARD); + } + no_args (list->next); + } + + return (count); +} + +/* Get an eight-bit status value from LIST */ +int +get_exitstat (list) + WORD_LIST *list; +{ + int status; + intmax_t sval; + char *arg; + + if (list && list->word && ISOPTION (list->word->word, '-')) + list = list->next; + + if (list == 0) + return (last_command_exit_value); + + arg = list->word->word; + if (arg == 0 || legal_number (arg, &sval) == 0) + { + sh_neednumarg (list->word->word ? list->word->word : "`'"); + return 255; + } + no_args (list->next); + + status = sval & 255; + return status; +} + +/* Return the octal number parsed from STRING, or -1 to indicate + that the string contained a bad number. */ +int +read_octal (string) + char *string; +{ + int result, digits; + + result = digits = 0; + while (*string && ISOCTAL (*string)) + { + digits++; + result = (result * 8) + (*string++ - '0'); + if (result > 0777) + return -1; + } + + if (digits == 0 || *string) + result = -1; + + return (result); +} + +/* **************************************************************** */ +/* */ +/* Manipulating the current working directory */ +/* */ +/* **************************************************************** */ + +/* Return a consed string which is the current working directory. + FOR_WHOM is the name of the caller for error printing. */ +char *the_current_working_directory = (char *)NULL; + +char * +get_working_directory (for_whom) + char *for_whom; +{ + char *directory; + + if (no_symbolic_links) + { + if (the_current_working_directory) + free (the_current_working_directory); + + the_current_working_directory = (char *)NULL; + } + + if (the_current_working_directory == 0) + { + the_current_working_directory = (char *)xmalloc (PATH_MAX); + the_current_working_directory[0] = '\0'; + directory = getcwd (the_current_working_directory, PATH_MAX); + if (directory == 0) + { + fprintf (stderr, _("%s: could not get current directory: %s: %s\n"), + (for_whom && *for_whom) ? for_whom : get_name_for_error (), + _(bash_getcwd_errstr), strerror (errno)); + + free (the_current_working_directory); + the_current_working_directory = (char *)NULL; + return (char *)NULL; + } + } + + return (savestring (the_current_working_directory)); +} + +/* Make NAME our internal idea of the current working directory. */ +void +set_working_directory (name) + char *name; +{ + FREE (the_current_working_directory); + the_current_working_directory = savestring (name); +} + +/* **************************************************************** */ +/* */ +/* Job control support functions */ +/* */ +/* **************************************************************** */ + +#if defined (JOB_CONTROL) +int +get_job_by_name (name, flags) + const char *name; + int flags; +{ + register int i, wl, cl, match, job; + register PROCESS *p; + + job = NO_JOB; + wl = strlen (name); + for (i = job_slots - 1; i >= 0; i--) + { + if (jobs[i] == 0 || ((flags & JM_STOPPED) && JOBSTATE(i) != JSTOPPED)) + continue; + + p = jobs[i]->pipe; + do + { + if (flags & JM_EXACT) + { + cl = strlen (p->command); + match = STREQN (p->command, name, cl); + } + else if (flags & JM_SUBSTRING) + match = strindex (p->command, name) != (char *)0; + else + match = STREQN (p->command, name, wl); + + if (match == 0) + { + p = p->next; + continue; + } + else if (flags & JM_FIRSTMATCH) + return i; /* return first match */ + else if (job != NO_JOB) + { + if (this_shell_builtin) + builtin_error (_("%s: ambiguous job spec"), name); + else + report_error (_("%s: ambiguous job spec"), name); + return (DUP_JOB); + } + else + job = i; + } + while (p != jobs[i]->pipe); + } + + return (job); +} + +/* Return the job spec found in LIST. */ +int +get_job_spec (list) + WORD_LIST *list; +{ + register char *word; + int job, jflags; + + if (list == 0) + return (current_job); + + word = list->word->word; + + if (*word == '\0') +#if 0 + return (current_job); +#else + return (NO_JOB); +#endif + + if (*word == '%') + word++; + + if (DIGIT (*word) && all_digits (word)) + { + job = atoi (word); +#if 0 + return (job >= job_slots ? NO_JOB : job - 1); +#else + return (job > job_slots ? NO_JOB : job - 1); +#endif + } + + jflags = 0; + switch (*word) + { + case 0: + return NO_JOB; + case '%': + case '+': + return (current_job); + + case '-': + return (previous_job); + + case '?': /* Substring search requested. */ + jflags |= JM_SUBSTRING; + word++; + /* FALLTHROUGH */ + + default: + return get_job_by_name (word, jflags); + } +} +#endif /* JOB_CONTROL */ + +/* + * NOTE: `kill' calls this function with forcecols == 0 + */ +int +display_signal_list (list, forcecols) + WORD_LIST *list; + int forcecols; +{ + register int i, column; + char *name; + int result, signum, dflags; + intmax_t lsignum; + + result = EXECUTION_SUCCESS; + if (!list) + { + for (i = 1, column = 0; i < NSIG; i++) + { + name = signal_name (i); + if (STREQN (name, "SIGJUNK", 7) || STREQN (name, "Unknown", 7)) + continue; + + if (posixly_correct && !forcecols) + { + /* This is for the kill builtin. POSIX.2 says the signal names + are displayed without the `SIG' prefix. */ + if (STREQN (name, "SIG", 3)) + name += 3; + printf ("%s%s", name, (i == NSIG - 1) ? "" : " "); + } + else + { + printf ("%2d) %s", i, name); + + if (++column < 4) + printf ("\t"); + else + { + printf ("\n"); + column = 0; + } + } + } + + if ((posixly_correct && !forcecols) || column != 0) + printf ("\n"); + return result; + } + + /* List individual signal names or numbers. */ + while (list) + { + if (legal_number (list->word->word, &lsignum)) + { + /* This is specified by Posix.2 so that exit statuses can be + mapped into signal numbers. */ + if (lsignum > 128) + lsignum -= 128; + if (lsignum < 0 || lsignum >= NSIG) + { + sh_invalidsig (list->word->word); + result = EXECUTION_FAILURE; + list = list->next; + continue; + } + + signum = lsignum; + name = signal_name (signum); + if (STREQN (name, "SIGJUNK", 7) || STREQN (name, "Unknown", 7)) + { + list = list->next; + continue; + } +#if defined (JOB_CONTROL) + /* POSIX.2 says that `kill -l signum' prints the signal name without + the `SIG' prefix. */ + printf ("%s\n", (this_shell_builtin == kill_builtin) ? name + 3 : name); +#else + printf ("%s\n", name); +#endif + } + else + { + dflags = DSIG_NOCASE; + if (posixly_correct == 0 || this_shell_builtin != kill_builtin) + dflags |= DSIG_SIGPREFIX; + signum = decode_signal (list->word->word, dflags); + if (signum == NO_SIG) + { + sh_invalidsig (list->word->word); + result = EXECUTION_FAILURE; + list = list->next; + continue; + } + printf ("%d\n", signum); + } + list = list->next; + } + return (result); +} + +/* **************************************************************** */ +/* */ +/* Finding builtin commands and their functions */ +/* */ +/* **************************************************************** */ + +/* Perform a binary search and return the address of the builtin function + whose name is NAME. If the function couldn't be found, or the builtin + is disabled or has no function associated with it, return NULL. + Return the address of the builtin. + DISABLED_OKAY means find it even if the builtin is disabled. */ +struct builtin * +builtin_address_internal (name, disabled_okay) + char *name; + int disabled_okay; +{ + int hi, lo, mid, j; + + hi = num_shell_builtins - 1; + lo = 0; + + while (lo <= hi) + { + mid = (lo + hi) / 2; + + j = shell_builtins[mid].name[0] - name[0]; + + if (j == 0) + j = strcmp (shell_builtins[mid].name, name); + + if (j == 0) + { + /* It must have a function pointer. It must be enabled, or we + must have explicitly allowed disabled functions to be found, + and it must not have been deleted. */ + if (shell_builtins[mid].function && + ((shell_builtins[mid].flags & BUILTIN_DELETED) == 0) && + ((shell_builtins[mid].flags & BUILTIN_ENABLED) || disabled_okay)) + return (&shell_builtins[mid]); + else + return ((struct builtin *)NULL); + } + if (j > 0) + hi = mid - 1; + else + lo = mid + 1; + } + return ((struct builtin *)NULL); +} + +/* Return the pointer to the function implementing builtin command NAME. */ +sh_builtin_func_t * +find_shell_builtin (name) + char *name; +{ + current_builtin = builtin_address_internal (name, 0); + return (current_builtin ? current_builtin->function : (sh_builtin_func_t *)NULL); +} + +/* Return the address of builtin with NAME, whether it is enabled or not. */ +sh_builtin_func_t * +builtin_address (name) + char *name; +{ + current_builtin = builtin_address_internal (name, 1); + return (current_builtin ? current_builtin->function : (sh_builtin_func_t *)NULL); +} + +/* Return the function implementing the builtin NAME, but only if it is a + POSIX.2 special builtin. */ +sh_builtin_func_t * +find_special_builtin (name) + char *name; +{ + current_builtin = builtin_address_internal (name, 0); + return ((current_builtin && (current_builtin->flags & SPECIAL_BUILTIN)) ? + current_builtin->function : + (sh_builtin_func_t *)NULL); +} + +static int +shell_builtin_compare (sbp1, sbp2) + struct builtin *sbp1, *sbp2; +{ + int result; + + if ((result = sbp1->name[0] - sbp2->name[0]) == 0) + result = strcmp (sbp1->name, sbp2->name); + + return (result); +} + +/* Sort the table of shell builtins so that the binary search will work + in find_shell_builtin. */ +void +initialize_shell_builtins () +{ + qsort (shell_builtins, num_shell_builtins, sizeof (struct builtin), + (QSFUNC *)shell_builtin_compare); +} diff --git a/builtins/read.def b/builtins/read.def index ccbea8435..cdac9c4b1 100644 --- a/builtins/read.def +++ b/builtins/read.def @@ -1,7 +1,7 @@ This file is read.def, from which is created read.c. It implements the builtin "read" in Bash. -Copyright (C) 1987-2003 Free Software Foundation, Inc. +Copyright (C) 1987-2004 Free Software Foundation, Inc. This file is part of GNU Bash, the Bourne Again SHell. @@ -499,6 +499,13 @@ read_builtin (list) an assign them to `arrayname' in turn. */ if (arrayname) { + if (legal_identifier (arrayname) == 0) + { + sh_invalidid (arrayname); + xfree (input_string); + return (EXECUTION_FAILURE); + } + var = find_or_make_array_variable (arrayname, 1); if (var == 0) return EXECUTION_FAILURE; /* readonly or noassign */ diff --git a/builtins/read.def~ b/builtins/read.def~ new file mode 100644 index 000000000..30c893aec --- /dev/null +++ b/builtins/read.def~ @@ -0,0 +1,736 @@ +This file is read.def, from which is created read.c. +It implements the builtin "read" in Bash. + +Copyright (C) 1987-2003 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 2, 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; see the file COPYING. If not, write to the Free Software +Foundation, 59 Temple Place, Suite 330, Boston, MA 02111 USA. + +$PRODUCES read.c + +$BUILTIN read +$FUNCTION read_builtin +$SHORT_DOC read [-ers] [-u fd] [-t timeout] [-p prompt] [-a array] [-n nchars] [-d delim] [name ...] +One line is read from the standard input, or from file descriptor FD if the +-u option is supplied, and the first word is assigned to the first NAME, +the second word to the second NAME, and so on, with leftover words assigned +to the last NAME. Only the characters found in $IFS are recognized as word +delimiters. If no NAMEs are supplied, the line read is stored in the REPLY +variable. If the -r option is given, this signifies `raw' input, and +backslash escaping is disabled. The -d option causes read to continue +until the first character of DELIM is read, rather than newline. If the -p +option is supplied, the string PROMPT is output without a trailing newline +before attempting to read. If -a is supplied, the words read are assigned +to sequential indices of ARRAY, starting at zero. If -e is supplied and +the shell is interactive, readline is used to obtain the line. If -n is +supplied with a non-zero NCHARS argument, read returns after NCHARS +characters have been read. The -s option causes input coming from a +terminal to not be echoed. + +The -t option causes read to time out and return failure if a complete line +of input is not read within TIMEOUT seconds. If the TMOUT variable is set, +its value is the default timeout. The return code is zero, unless end-of-file +is encountered, read times out, or an invalid file descriptor is supplied as +the argument to -u. +$END + +#include + +#include "bashtypes.h" +#include "posixstat.h" + +#include + +#if defined (HAVE_UNISTD_H) +# include +#endif + +#include +#include + +#ifdef __CYGWIN__ +# include +# include +#endif + +#include "../bashintl.h" + +#include "../shell.h" +#include "common.h" +#include "bashgetopt.h" + +#include + +#if defined (READLINE) +#include "../bashline.h" +#include +#endif + +#if !defined(errno) +extern int errno; +#endif + +extern int interrupt_immediately; + +#if defined (READLINE) +static char *edit_line __P((char *)); +static void set_eol_delim __P((int)); +static void reset_eol_delim __P((char *)); +#endif +static SHELL_VAR *bind_read_variable __P((char *, char *)); + +static sighandler sigalrm __P((int)); +static void reset_alarm __P((void)); + +static procenv_t alrmbuf; +static SigHandler *old_alrm; +static unsigned char delim; + +static sighandler +sigalrm (s) + int s; +{ + longjmp (alrmbuf, 1); +} + +static void +reset_alarm () +{ + set_signal_handler (SIGALRM, old_alrm); + alarm (0); +} + +/* Read the value of the shell variables whose names follow. + The reading is done from the current input stream, whatever + that may be. Successive words of the input line are assigned + to the variables mentioned in LIST. The last variable in LIST + gets the remainder of the words on the line. If no variables + are mentioned in LIST, then the default variable is $REPLY. */ +int +read_builtin (list) + WORD_LIST *list; +{ + register char *varname; + int size, i, pass_next, saw_escape, eof, opt, retval, code; + int input_is_tty, input_is_pipe, unbuffered_read; + int raw, edit, nchars, silent, have_timeout, fd; + unsigned int tmout; + intmax_t intval; + char c; + char *input_string, *orig_input_string, *ifs_chars, *prompt, *arrayname; + char *e, *t, *t1; + struct stat tsb; + SHELL_VAR *var; +#if defined (ARRAY_VARS) + WORD_LIST *alist; +#endif +#if defined (READLINE) + char *rlbuf; + int rlind; +#endif + + USE_VAR(size); + USE_VAR(i); + USE_VAR(pass_next); + USE_VAR(saw_escape); + USE_VAR(input_is_pipe); +/* USE_VAR(raw); */ + USE_VAR(edit); + USE_VAR(tmout); + USE_VAR(nchars); + USE_VAR(silent); + USE_VAR(ifs_chars); + USE_VAR(prompt); + USE_VAR(arrayname); +#if defined (READLINE) + USE_VAR(rlbuf); + USE_VAR(rlind); +#endif + USE_VAR(list); + + i = 0; /* Index into the string that we are reading. */ + raw = edit = 0; /* Not reading raw input by default. */ + silent = 0; + arrayname = prompt = (char *)NULL; + fd = 0; /* file descriptor to read from */ + +#if defined (READLINE) + rlbuf = (char *)0; + rlind = 0; +#endif + + tmout = 0; /* no timeout */ + nchars = input_is_tty = input_is_pipe = unbuffered_read = have_timeout = 0; + delim = '\n'; /* read until newline */ + + reset_internal_getopt (); + while ((opt = internal_getopt (list, "ersa:d:n:p:t:u:")) != -1) + { + switch (opt) + { + case 'r': + raw = 1; + break; + case 'p': + prompt = list_optarg; + break; + case 's': + silent = 1; + break; + case 'e': +#if defined (READLINE) + edit = 1; +#endif + break; +#if defined (ARRAY_VARS) + case 'a': + arrayname = list_optarg; + break; +#endif + case 't': + code = legal_number (list_optarg, &intval); + if (code == 0 || intval < 0 || intval != (unsigned int)intval) + { + builtin_error (_("%s: invalid timeout specification"), list_optarg); + return (EXECUTION_FAILURE); + } + else + { + have_timeout = 1; + tmout = intval; + } + break; + case 'n': + code = legal_number (list_optarg, &intval); + if (code == 0 || intval < 0 || intval != (int)intval) + { + sh_invalidnum (list_optarg); + return (EXECUTION_FAILURE); + } + else + nchars = intval; + break; + case 'u': + code = legal_number (list_optarg, &intval); + if (code == 0 || intval < 0 || intval != (int)intval) + { + builtin_error (_("%s: invalid file descriptor specification"), list_optarg); + return (EXECUTION_FAILURE); + } + else + fd = intval; + if (sh_validfd (fd) == 0) + { + builtin_error (_("%d: invalid file descriptor: %s"), fd, strerror (errno)); + return (EXECUTION_FAILURE); + } + break; + case 'd': + delim = *list_optarg; + break; + default: + builtin_usage (); + return (EX_USAGE); + } + } + list = loptend; + + /* `read -t 0 var' returns failure immediately. XXX - should it test + whether input is available with select/FIONREAD, and fail if those + are unavailable? */ + if (have_timeout && tmout == 0) + return (EXECUTION_FAILURE); + + /* IF IFS is unset, we use the default of " \t\n". */ + ifs_chars = getifs (); + if (ifs_chars == 0) /* XXX - shouldn't happen */ + ifs_chars = ""; + + input_string = (char *)xmalloc (size = 112); /* XXX was 128 */ + + /* $TMOUT, if set, is the default timeout for read. */ + if (have_timeout == 0 && (e = get_string_value ("TMOUT"))) + { + code = legal_number (e, &intval); + if (code == 0 || intval < 0 || intval != (unsigned int)intval) + tmout = 0; + else + tmout = intval; + } + + begin_unwind_frame ("read_builtin"); + + input_is_tty = isatty (fd); + if (input_is_tty == 0) +#ifndef __CYGWIN__ + input_is_pipe = (lseek (0, 0L, SEEK_CUR) < 0) && (errno == ESPIPE); +#else + input_is_pipe = 1; +#endif + + /* If the -p, -e or -s flags were given, but input is not coming from the + terminal, turn them off. */ + if ((prompt || edit || silent) && input_is_tty == 0) + { + prompt = (char *)NULL; + edit = silent = 0; + } + +#if defined (READLINE) + if (edit) + add_unwind_protect (xfree, rlbuf); +#endif + + if (prompt && edit == 0) + { + fprintf (stderr, "%s", prompt); + fflush (stderr); + } + + pass_next = 0; /* Non-zero signifies last char was backslash. */ + saw_escape = 0; /* Non-zero signifies that we saw an escape char */ + + if (tmout > 0) + { + /* Turn off the timeout if stdin is a regular file (e.g. from + input redirection). */ + if ((fstat (fd, &tsb) < 0) || S_ISREG (tsb.st_mode)) + tmout = 0; + } + + if (tmout > 0) + { + code = setjmp (alrmbuf); + if (code) + { + run_unwind_frame ("read_builtin"); + return (EXECUTION_FAILURE); + } + old_alrm = set_signal_handler (SIGALRM, sigalrm); + add_unwind_protect (reset_alarm, (char *)NULL); + alarm (tmout); + } + + /* If we've been asked to read only NCHARS chars, or we're using some + character other than newline to terminate the line, do the right + thing to readline or the tty. */ + if (nchars > 0 || delim != '\n') + { +#if defined (READLINE) + if (edit) + { + if (nchars > 0) + { + unwind_protect_int (rl_num_chars_to_read); + rl_num_chars_to_read = nchars; + } + if (delim != '\n') + { + set_eol_delim (delim); + add_unwind_protect (reset_eol_delim, (char *)NULL); + } + } + else +#endif + if (input_is_tty) + { + ttsave (); + if (silent) + ttcbreak (); + else + ttonechar (); + add_unwind_protect ((Function *)ttrestore, (char *)NULL); + } + } + else if (silent) /* turn off echo but leave term in canonical mode */ + { + ttsave (); + ttnoecho (); + add_unwind_protect ((Function *)ttrestore, (char *)NULL); + } + + /* This *must* be the top unwind-protect on the stack, so the manipulation + of the unwind-protect stack after the realloc() works right. */ + add_unwind_protect (xfree, input_string); + interrupt_immediately++; + + unbuffered_read = (nchars > 0) || (delim != '\n') || input_is_pipe; + +#if defined (__CYGWIN__) && defined (O_TEXT) + setmode (0, O_TEXT); +#endif + + for (eof = retval = 0;;) + { +#if defined (READLINE) + if (edit) + { + if (rlbuf && rlbuf[rlind] == '\0') + { + xfree (rlbuf); + rlbuf = (char *)0; + } + if (rlbuf == 0) + { + rlbuf = edit_line (prompt ? prompt : ""); + rlind = 0; + } + if (rlbuf == 0) + { + eof = 1; + break; + } + c = rlbuf[rlind++]; + } + else + { +#endif + + if (unbuffered_read) + retval = zread (fd, &c, 1); + else + retval = zreadc (fd, &c); + + if (retval <= 0) + { + eof = 1; + break; + } + +#if defined (READLINE) + } +#endif + + if (i + 2 >= size) + { + input_string = (char *)xrealloc (input_string, size += 128); + remove_unwind_protect (); + add_unwind_protect (xfree, input_string); + } + + /* If the next character is to be accepted verbatim, a backslash + newline pair still disappears from the input. */ + if (pass_next) + { + if (c == '\n') + i--; /* back up over the CTLESC */ + else + input_string[i++] = c; + pass_next = 0; + continue; + } + + if (c == '\\' && raw == 0) + { + pass_next++; + saw_escape++; + input_string[i++] = CTLESC; + continue; + } + + if ((unsigned char)c == delim) + break; + + if (c == CTLESC || c == CTLNUL) + { + saw_escape++; + input_string[i++] = CTLESC; + } + + input_string[i++] = c; + + if (nchars > 0 && i >= nchars) + break; + } + input_string[i] = '\0'; + +#if 1 + if (retval < 0) + { + builtin_error (_("read error: %d: %s"), fd, strerror (errno)); + return (EXECUTION_FAILURE); + } +#endif + + if (tmout > 0) + reset_alarm (); + + if (nchars > 0 || delim != '\n') + { +#if defined (READLINE) + if (edit) + { + if (nchars > 0) + rl_num_chars_to_read = 0; + if (delim != '\n') + reset_eol_delim ((char *)NULL); + } + else +#endif + if (input_is_tty) + ttrestore (); + } + else if (silent) + ttrestore (); + + if (unbuffered_read == 0) + zsyncfd (fd); + + interrupt_immediately--; + discard_unwind_frame ("read_builtin"); + + retval = eof ? EXECUTION_FAILURE : EXECUTION_SUCCESS; + +#if defined (ARRAY_VARS) + /* If -a was given, take the string read, break it into a list of words, + an assign them to `arrayname' in turn. */ + if (arrayname) + { + if (legal_identifier (arrayname) == 0) + { + sh_invalidid (arrayname); + xfree (input_string); + return (EXECUTION_FAILURE); + } + + var = find_or_make_array_variable (arrayname, 1); + if (var == 0) + return EXECUTION_FAILURE; /* readonly or noassign */ + array_flush (array_cell (var)); + + alist = list_string (input_string, ifs_chars, 0); + if (alist) + { + word_list_remove_quoted_nulls (alist); + assign_array_var_from_word_list (var, alist); + dispose_words (alist); + } + xfree (input_string); + return (retval); + } +#endif /* ARRAY_VARS */ + + /* If there are no variables, save the text of the line read to the + variable $REPLY. ksh93 strips leading and trailing IFS whitespace, + so that `read x ; echo "$x"' and `read ; echo "$REPLY"' behave the + same way, but I believe that the difference in behaviors is useful + enough to not do it. Without the bash behavior, there is no way + to read a line completely without interpretation or modification + unless you mess with $IFS (e.g., setting it to the empty string). + If you disagree, change the occurrences of `#if 0' to `#if 1' below. */ + if (list == 0) + { +#if 0 + orig_input_string = input_string; + for (t = input_string; ifs_chars && *ifs_chars && spctabnl(*t) && isifs(*t); t++) + ; + input_string = t; + input_string = strip_trailing_ifs_whitespace (input_string, ifs_chars, saw_escape); +#endif + + if (saw_escape) + { + t = dequote_string (input_string); + var = bind_variable ("REPLY", t); + free (t); + } + else + var = bind_variable ("REPLY", input_string); + VUNSETATTR (var, att_invisible); + + free (input_string); + return (retval); + } + + /* This code implements the Posix.2 spec for splitting the words + read and assigning them to variables. */ + orig_input_string = input_string; + + /* Remove IFS white space at the beginning of the input string. If + $IFS is null, no field splitting is performed. */ + for (t = input_string; ifs_chars && *ifs_chars && spctabnl(*t) && isifs(*t); t++) + ; + input_string = t; + + for (; list->next; list = list->next) + { + varname = list->word->word; +#if defined (ARRAY_VARS) + if (legal_identifier (varname) == 0 && valid_array_reference (varname) == 0) +#else + if (legal_identifier (varname) == 0) +#endif + { + sh_invalidid (varname); + xfree (orig_input_string); + return (EXECUTION_FAILURE); + } + + /* If there are more variables than words read from the input, + the remaining variables are set to the empty string. */ + if (*input_string) + { + /* This call updates INPUT_STRING. */ + t = get_word_from_string (&input_string, ifs_chars, &e); + if (t) + *e = '\0'; + /* Don't bother to remove the CTLESC unless we added one + somewhere while reading the string. */ + if (t && saw_escape) + { + t1 = dequote_string (t); + var = bind_read_variable (varname, t1); + xfree (t1); + } + else + var = bind_read_variable (varname, t); + } + else + { + t = (char *)0; + var = bind_read_variable (varname, ""); + } + + FREE (t); + if (var == 0) + { + xfree (orig_input_string); + return (EXECUTION_FAILURE); + } + + stupidly_hack_special_variables (varname); + VUNSETATTR (var, att_invisible); + } + + /* Now assign the rest of the line to the last variable argument. */ +#if defined (ARRAY_VARS) + if (legal_identifier (list->word->word) == 0 && valid_array_reference (list->word->word) == 0) +#else + if (legal_identifier (list->word->word) == 0) +#endif + { + sh_invalidid (list->word->word); + xfree (orig_input_string); + return (EXECUTION_FAILURE); + } + + /* This has to be done this way rather than using string_list + and list_string because Posix.2 says that the last variable gets the + remaining words and their intervening separators. */ + input_string = strip_trailing_ifs_whitespace (input_string, ifs_chars, saw_escape); + + if (saw_escape) + { + t = dequote_string (input_string); + var = bind_read_variable (list->word->word, t); + xfree (t); + } + else + var = bind_read_variable (list->word->word, input_string); + stupidly_hack_special_variables (list->word->word); + if (var) + VUNSETATTR (var, att_invisible); + xfree (orig_input_string); + + return (retval); +} + +static SHELL_VAR * +bind_read_variable (name, value) + char *name, *value; +{ +#if defined (ARRAY_VARS) + if (valid_array_reference (name) == 0) + return (bind_variable (name, value)); + else + return (assign_array_element (name, value)); +#else /* !ARRAY_VARS */ + return bind_variable (name, value); +#endif /* !ARRAY_VARS */ +} + +#if defined (READLINE) +static rl_completion_func_t *old_attempted_completion_function; + +static char * +edit_line (p) + char *p; +{ + char *ret; + int len; + + if (!bash_readline_initialized) + initialize_readline (); + old_attempted_completion_function = rl_attempted_completion_function; + rl_attempted_completion_function = (rl_completion_func_t *)NULL; + ret = readline (p); + rl_attempted_completion_function = old_attempted_completion_function; + if (ret == 0) + return ret; + len = strlen (ret); + ret = (char *)xrealloc (ret, len + 2); + ret[len++] = delim; + ret[len] = '\0'; + return ret; +} + +static int old_delim_ctype; +static rl_command_func_t *old_delim_func; +static int old_newline_ctype; +static rl_command_func_t *old_newline_func; + +static unsigned char delim_char; + +static void +set_eol_delim (c) + int c; +{ + Keymap cmap; + + if (bash_readline_initialized == 0) + initialize_readline (); + cmap = rl_get_keymap (); + + /* Change newline to self-insert */ + old_newline_ctype = cmap[RETURN].type; + old_newline_func = cmap[RETURN].function; + cmap[RETURN].type = ISFUNC; + cmap[RETURN].function = rl_insert; + + /* Bind the delimiter character to accept-line. */ + old_delim_ctype = cmap[c].type; + old_delim_func = cmap[c].function; + cmap[c].type = ISFUNC; + cmap[c].function = rl_newline; + + delim_char = c; +} + +static void +reset_eol_delim (cp) + char *cp; +{ + Keymap cmap; + + cmap = rl_get_keymap (); + + cmap[RETURN].type = old_newline_ctype; + cmap[RETURN].function = old_newline_func; + + cmap[delim_char].type = old_delim_ctype; + cmap[delim_char].function = old_delim_func; +} +#endif diff --git a/configure b/configure index 8952c20ca..153f7b6f9 100755 --- a/configure +++ b/configure @@ -1,5 +1,5 @@ #! /bin/sh -# From configure.in for Bash 3.0, version 3.159, from autoconf version AC_ACVERSION. +# From configure.in for Bash 3.0, version 3.160, from autoconf version AC_ACVERSION. # Guess values for system-dependent variables and create Makefiles. # Generated by GNU Autoconf 2.57 for bash 3.0-beta1. # @@ -311,7 +311,7 @@ ac_includes_default="\ # include #endif" -ac_subst_vars='SHELL PATH_SEPARATOR PACKAGE_NAME PACKAGE_TARNAME PACKAGE_VERSION PACKAGE_STRING PACKAGE_BUGREPORT exec_prefix prefix program_transform_name bindir sbindir libexecdir datadir sysconfdir sharedstatedir localstatedir libdir includedir oldincludedir infodir mandir build_alias host_alias target_alias DEFS ECHO_C ECHO_N ECHO_T LIBS build build_cpu build_vendor build_os host host_cpu host_vendor host_os EMACS lispdir DEBUGGER_START_FILE TESTSCRIPT PURIFY MALLOC_TARGET MALLOC_SRC MALLOC_LIB MALLOC_LIBRARY MALLOC_LDFLAGS MALLOC_DEP htmldir HELPDIR HELPDIRDEFINE HELPINSTALL CC CFLAGS LDFLAGS CPPFLAGS ac_ct_CC EXEEXT OBJEXT CPP EGREP SIGNAMES_H CC_FOR_BUILD STATIC_LD CFLAGS_FOR_BUILD CPPFLAGS_FOR_BUILD LDFLAGS_FOR_BUILD RL_VERSION RL_MAJOR RL_MINOR READLINE_LIB READLINE_DEP RL_LIBDIR RL_INCLUDEDIR RL_INCLUDE HISTORY_LIB HISTORY_DEP HIST_LIBDIR INSTALL_PROGRAM INSTALL_SCRIPT INSTALL_DATA AR RANLIB ac_ct_RANLIB YACC SET_MAKE MAKE_SHELL MKINSTALLDIRS USE_NLS MSGFMT GMSGFMT XGETTEXT MSGMERGE ALLOCA GLIBC21 LIBICONV LTLIBICONV INTLBISON BUILD_INCLUDED_LIBINTL USE_INCLUDED_LIBINTL CATOBJEXT DATADIRNAME INSTOBJEXT GENCAT INTLOBJS INTL_LIBTOOL_SUFFIX_PREFIX INTLLIBS LIBINTL LTLIBINTL POSUB LIBOBJS INTL_DEP INTL_INC SIGLIST_O TERMCAP_LIB TERMCAP_DEP JOBS_O SHOBJ_CC SHOBJ_CFLAGS SHOBJ_LD SHOBJ_LDFLAGS SHOBJ_XLDFLAGS SHOBJ_LIBS SHOBJ_STATUS PROFILE_FLAGS incdir BUILD_DIR ARFLAGS BASHVERS RELSTATUS DEBUG MALLOC_DEBUG LOCAL_LIBS LOCAL_CFLAGS LOCAL_LDFLAGS LOCAL_DEFS LTLIBOBJS' +ac_subst_vars='SHELL PATH_SEPARATOR PACKAGE_NAME PACKAGE_TARNAME PACKAGE_VERSION PACKAGE_STRING PACKAGE_BUGREPORT exec_prefix prefix program_transform_name bindir sbindir libexecdir datadir sysconfdir sharedstatedir localstatedir libdir includedir oldincludedir infodir mandir build_alias host_alias target_alias DEFS ECHO_C ECHO_N ECHO_T LIBS build build_cpu build_vendor build_os host host_cpu host_vendor host_os EMACS lispdir DEBUGGER_START_FILE TESTSCRIPT PURIFY MALLOC_TARGET MALLOC_SRC MALLOC_LIB MALLOC_LIBRARY MALLOC_LDFLAGS MALLOC_DEP htmldir HELPDIR HELPDIRDEFINE HELPINSTALL CC CFLAGS LDFLAGS CPPFLAGS ac_ct_CC EXEEXT OBJEXT CPP EGREP SIGNAMES_H CC_FOR_BUILD STATIC_LD CFLAGS_FOR_BUILD CPPFLAGS_FOR_BUILD LDFLAGS_FOR_BUILD RL_VERSION RL_MAJOR RL_MINOR READLINE_LIB READLINE_DEP RL_LIBDIR RL_INCLUDEDIR RL_INCLUDE HISTORY_LIB HISTORY_DEP HIST_LIBDIR INSTALL_PROGRAM INSTALL_SCRIPT INSTALL_DATA AR RANLIB ac_ct_RANLIB YACC SET_MAKE MAKE_SHELL MKINSTALLDIRS USE_NLS MSGFMT GMSGFMT XGETTEXT MSGMERGE ALLOCA GLIBC21 LIBICONV LTLIBICONV INTLBISON BUILD_INCLUDED_LIBINTL USE_INCLUDED_LIBINTL CATOBJEXT DATADIRNAME INSTOBJEXT GENCAT INTLOBJS INTL_LIBTOOL_SUFFIX_PREFIX INTLLIBS LIBINTL LTLIBINTL POSUB LIBOBJS INTL_DEP INTL_INC LIBINTL_H SIGLIST_O TERMCAP_LIB TERMCAP_DEP JOBS_O SHOBJ_CC SHOBJ_CFLAGS SHOBJ_LD SHOBJ_LDFLAGS SHOBJ_XLDFLAGS SHOBJ_LIBS SHOBJ_STATUS PROFILE_FLAGS incdir BUILD_DIR ARFLAGS BASHVERS RELSTATUS DEBUG MALLOC_DEBUG LOCAL_LIBS LOCAL_CFLAGS LOCAL_LDFLAGS LOCAL_DEFS LTLIBOBJS' ac_subst_files='' # Initialize some variables set by options. @@ -13780,10 +13780,11 @@ fi done -INTL_DEP= INTL_INC= +INTL_DEP= INTL_INC= LIBINTL_H= if test "x$USE_INCLUDED_LIBINTL" = "xyes"; then INTL_DEP='${INTL_LIBDIR}/libintl.a' - INTL_INC='-I${INTL_LIBSRC}' + INTL_INC='-I${INTL_LIBSRC} -I${INTL_BUILDDIR}' + LIBINTL_H='${INTL_BUILDDIR}/libintl.h' fi @@ -13791,6 +13792,7 @@ fi + for ac_header in wctype.h do as_ac_Header=`echo "ac_cv_header_$ac_header" | $as_tr_sh` @@ -24854,6 +24856,7 @@ s,@POSUB@,$POSUB,;t t s,@LIBOBJS@,$LIBOBJS,;t t s,@INTL_DEP@,$INTL_DEP,;t t s,@INTL_INC@,$INTL_INC,;t t +s,@LIBINTL_H@,$LIBINTL_H,;t t s,@SIGLIST_O@,$SIGLIST_O,;t t s,@TERMCAP_LIB@,$TERMCAP_LIB,;t t s,@TERMCAP_DEP@,$TERMCAP_DEP,;t t diff --git a/configure.in b/configure.in index 89aa6c3d8..41241c9fd 100644 --- a/configure.in +++ b/configure.in @@ -5,7 +5,7 @@ dnl report bugs to chet@po.cwru.edu dnl dnl Process this file with autoconf to produce a configure script. -# Copyright (C) 1987-2003 Free Software Foundation, Inc. +# Copyright (C) 1987-2004 Free Software Foundation, Inc. # This program is free software; you can redistribute it and/or modify # it under the terms of the GNU General Public License as published by @@ -22,7 +22,7 @@ dnl Process this file with autoconf to produce a configure script. # Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA # 02111-1307, USA. -AC_REVISION([for Bash 3.0, version 3.159, from autoconf version] AC_ACVERSION)dnl +AC_REVISION([for Bash 3.0, version 3.160, from autoconf version] AC_ACVERSION)dnl define(bashvers, 3.0) define(relstatus, beta1) @@ -679,13 +679,15 @@ AC_FUNC_MMAP AC_CHECK_FUNCS([__argz_count __argz_next __argz_stringify dcgettext mempcpy \ munmap stpcpy strcspn strdup]) -INTL_DEP= INTL_INC= +INTL_DEP= INTL_INC= LIBINTL_H= if test "x$USE_INCLUDED_LIBINTL" = "xyes"; then INTL_DEP='${INTL_LIBDIR}/libintl.a' - INTL_INC='-I${INTL_LIBSRC}' + INTL_INC='-I${INTL_LIBSRC} -I${INTL_BUILDDIR}' + LIBINTL_H='${INTL_BUILDDIR}/libintl.h' fi AC_SUBST(INTL_DEP) AC_SUBST(INTL_INC) +AC_SUBST(LIBINTL_H) dnl dnl End of checks needed by files in lib/intl diff --git a/doc/Makefile b/doc/Makefile index cdc927f6b..15c972610 120000 --- a/doc/Makefile +++ b/doc/Makefile @@ -1 +1 @@ -/usr/local/build/chet/bash/bash-current/doc/Makefile \ No newline at end of file +/usr/local/build/bash/bash-current/doc/Makefile \ No newline at end of file diff --git a/doc/bash.0 b/doc/bash.0 index 8a402dd17..901d146fd 100644 --- a/doc/bash.0 +++ b/doc/bash.0 @@ -9,7 +9,7 @@ SSYYNNOOPPSSIISS bbaasshh [options] [file] CCOOPPYYRRIIGGHHTT - Bash is Copyright (C) 1989-2003 by the Free Software Foundation, Inc. + Bash is Copyright (C) 1989-2004 by the Free Software Foundation, Inc. DDEESSCCRRIIPPTTIIOONN BBaasshh is an sshh-compatible command language interpreter that executes @@ -2293,8 +2293,10 @@ PPRROOMMPPTTIINNGG \\uu the username of the current user \\vv the version of bbaasshh (e.g., 2.00) \\VV the release of bbaasshh, version + patchelvel (e.g., 2.00.0) - \\ww the current working directory - \\WW the basename of the current working directory + \\ww the current working directory, with $$HHOOMMEE abbreviated + with a tilde + \\WW the basename of the current working directory, with $$HHOOMMEE + abbreviated with a tilde \\!! the history number of this command \\## the command number of this command \\$$ if the effective UID is 0, a ##, otherwise a $$ @@ -3133,8 +3135,8 @@ HHIISSTTOORRYY are appended to the history file, otherwise the history file is over- written. If HHIISSTTFFIILLEE is unset, or if the history file is unwritable, the history is not saved. After saving the history, the history file - is truncated to contain no more than HHIISSTTFFIILLEESSIIZZEE lines. If - HHIISSTTFFIILLEESSIIZZEE is not set, no truncation is performed. + is truncated to contain no more than HHIISSTTFFIILLEESSIIZZEE lines. If HHIISSTTFFIILLEE-- + SSIIZZEE is not set, no truncation is performed. The builtin command ffcc (see SSHHEELLLL BBUUIILLTTIINN CCOOMMMMAANNDDSS below) may be used to list or edit and re-execute a portion of the history list. The hhiiss-- @@ -4515,8 +4517,8 @@ SSHHEELLLL BBUUIILLTTIINN CCOOMMMMAANNDDSS given, ttrraapp prints the list of commands associated with each signal number. The --ll option causes the shell to print a list of signal names and their corresponding numbers. Each _s_i_g_s_p_e_c - is either a signal name defined in <_s_i_g_n_a_l_._h>, or a signal - number. If a _s_i_g_s_p_e_c is EEXXIITT (0) the command _a_r_g is executed on + is either a signal name defined in <_s_i_g_n_a_l_._h>, or a signal num- + ber. If a _s_i_g_s_p_e_c is EEXXIITT (0) the command _a_r_g is executed on exit from the shell. If a _s_i_g_s_p_e_c is DDEEBBUUGG, the command _a_r_g is executed before every _s_i_m_p_l_e _c_o_m_m_a_n_d, _f_o_r command, _c_a_s_e command, _s_e_l_e_c_t command, every arithmetic _f_o_r command, and before the @@ -4767,4 +4769,4 @@ BBUUGGSS -GNU Bash-3.0 2003 Nov 13 BASH(1) +GNU Bash-3.0 2004 Jan 24 BASH(1) diff --git a/doc/bash.1 b/doc/bash.1 index 18b44f9bf..6691167ce 100644 --- a/doc/bash.1 +++ b/doc/bash.1 @@ -6,12 +6,12 @@ .\" Case Western Reserve University .\" chet@po.CWRU.Edu .\" -.\" Last Change: Thu Nov 13 09:47:27 EST 2003 +.\" Last Change: Sat Jan 24 13:18:08 EST 2004 .\" .\" bash_builtins, strip all but Built-Ins section .if \n(zZ=1 .ig zZ .if \n(zY=1 .ig zY -.TH BASH 1 "2003 Nov 13" "GNU Bash-3.0" +.TH BASH 1 "2004 Jan 24" "GNU Bash-3.0" .\" .\" There's some problem with having a `@' .\" in a tagged paragraph with the BSD man macros. @@ -51,8 +51,8 @@ bash \- GNU Bourne-Again SHell [options] [file] .SH COPYRIGHT -.if n Bash is Copyright (C) 1989-2003 by the Free Software Foundation, Inc. -.if t Bash is Copyright \(co 1989-2003 by the Free Software Foundation, Inc. +.if n Bash is Copyright (C) 1989-2004 by the Free Software Foundation, Inc. +.if t Bash is Copyright \(co 1989-2004 by the Free Software Foundation, Inc. .SH DESCRIPTION .B Bash is an \fBsh\fR-compatible command language interpreter that @@ -4157,10 +4157,11 @@ the version of \fBbash\fP (e.g., 2.00) the release of \fBbash\fP, version + patchelvel (e.g., 2.00.0) .TP .B \ew -the current working directory +the current working directory, with \fB$HOME\fP abbreviated with a tilde .TP .B \eW -the basename of the current working directory +the basename of the current working directory, with \fB$HOME\fP +abbreviated with a tilde .TP .B \e! the history number of this command diff --git a/doc/bash.1~ b/doc/bash.1~ new file mode 100644 index 000000000..16bdcc649 --- /dev/null +++ b/doc/bash.1~ @@ -0,0 +1,8722 @@ +.\" +.\" MAN PAGE COMMENTS to +.\" +.\" Chet Ramey +.\" Information Network Services +.\" Case Western Reserve University +.\" chet@po.CWRU.Edu +.\" +.\" Last Change: Thu Nov 13 09:47:27 EST 2003 +.\" +.\" bash_builtins, strip all but Built-Ins section +.if \n(zZ=1 .ig zZ +.if \n(zY=1 .ig zY +.TH BASH 1 "2004 Jan 24" "GNU Bash-3.0" +.\" +.\" 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\\*(]Xu-3p \{\\*(]X +.br\} +.el \\*(]X\h|\\n()Iu+\\n()Ru\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-2004 by the Free Software Foundation, Inc. +.if t Bash is Copyright \(co 1989-2004 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 IEEE +POSIX Shell and Tools specification (IEEE Working Group 1003\.2). +.SH OPTIONS +In addition to the single-character shell options documented in the +description of the \fBset\fR builtin command, \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 ouput. +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) and shell function tracing (see the description of the +\fB\-o functrace\fP option to the +.B set +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 1003.2 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 output 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 by the remote shell +daemon, usually \fIrshd\fP. +If +.B bash +determines it is being run by \fIrshd\fP, 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 +.B SHELLOPTS +variable, if it appears in the environment, is 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\(bv\(bv & && ; ;; ( ) | \fP +.if n \fB|| & && ; ;; ( ) | \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 +.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 +the character +.BR | . +The format for a pipeline is: +.RS +.PP +[\fBtime\fP [\fB\-p\fP]] [ ! ] \fIcommand\fP [ \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). +.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. +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 +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 \(bv\(bv , +and optionally terminated by one of +.BR ; , +.BR & , +or +.BR . +.PP +Of these list operators, +.B && +and +.B \(bv\(bv +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 +The control operators +.B && +and +.B \(bv\(bv +denote AND lists and OR lists, respectively. +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\(bv\(bv\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: +.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. +.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 the \fB==\fP and \fB!=\fP operators are used, the string to the +right of the operator is considered a pattern and matched according +to the rules described below under \fBPattern Matching\fP. +The return value is 0 if the string matches or does not match +the pattern, respectively, and 1 otherwise. +Any part of the pattern may be quoted to force it 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 nocaseglob +is enabled, the match is performed without regard to the case +of alphabetic characters. +Substrings matched by parenthesized subexpressions within the regular +expression are saved in the array variable \fBBASH_REMATCH\fP. +The element of \fBBASH_REMATCH\fP with index 0 is the portion of the string +matching the entire regular expression. +The element of \fBBASH_REMATCH\fP 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 +.if t \fIexpression1\fP \fB\(bv\(bv\fP \fIexpression2\fP +.if n \fIexpression1\fP \fB||\fP \fIexpression2\fP +True if either +.I expression1 +or +.I expression2 +is true. +.PD +.LP +The \fB&&\fP and +.if t \fB\(bv\(bv\fP +.if n \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 +.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 +.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). When a match is found, the +corresponding \fIlist\fP is executed. After the first match, no +subsequent matches are attempted. 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\fP; \fBdo\fP \fIlist\fP; \fBdone\fP +.PD 0 +.TP +\fBuntil\fP \fIlist\fP; \fBdo\fP \fIlist\fP; \fBdone\fP +.PD +The \fBwhile\fP command continuously executes the \fBdo\fP +\fIlist\fP as long as the last command in \fIlist\fP returns +an exit status of zero. The \fBuntil\fP command is identical +to the \fBwhile\fP command, except that the test is negated; +the +.B do +.I list +is executed as long as the last command in +.I list +returns a non-zero exit status. +The exit status of the \fBwhile\fP and \fBuntil\fP commands +is the exit status +of the last \fBdo\fP \fIlist\fP command executed, or zero if +none was executed. +.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 +[ \fBfunction\fP ] \fIname\fP () \fIcompound\-command\fP [\fIredirection\fP] +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, 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 . If a \fB\e\fP pair +appears, and the backslash is not itself quoted, the \fB\e\fP +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 ` , +and +.BR \e . +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 . +A double quote may be quoted within double quotes by preceding it with +a backslash. +When command history is being used, the double quote may not be used to +quote the history expansion character. +.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'\fIstring\fP' are treated specially. The +word expands to \fIstring\fP, with backslash-escaped characters replaced +as specifed 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 +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' +single 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 \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) 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. +.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" ... +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 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 file name of the shell or shell +script being executed as passed in the argument list. +Subsequently, expands to the last argument to the previous command, +after expansion. +Also set to the full file name of 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 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 \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 +\fBBASH_ARGC\fP. +.TP +.B 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 \fBBASH_ARGV\fP. +.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 +corresponding to each member of @var{FUNCNAME}. +\fB${BASH_LINENO[\fP\fI$i\fP\fB]}\fP is the line number in the source +file where \fB${FUNCNAME[\fP\fI$i + 1\fP\fB]}\fP was called. +The corresponding source file name is \fB${BASH_SOURCE[\fP\fI$i + 1\fP\fB]}\fB. +Use \fBLINENO\fP 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 corresponding +to the elements in the \fBFUNCNAME\fP array variable. +.TP +.B BASH_SUBSHELL +Incremented by one each time a subshell or subshell environment is spawned. +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 +.PD 0 +.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 \fBMACHTYPE\fP. +.PD +.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_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_WORDBREAKS +The set of characters that the Readline 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. +This variable is available only in shell functions invoked by the +programmable completion facilities (see \fBProgrammable Completion\fP +below). +.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 is "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. +.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 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 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 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 builtin command to determine the terminal width +when printing selection lists. Automatically set upon receipt of a 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 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 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 \fBHISTCONTROL\fP 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 +.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 +.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, 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 +.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 +.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. +.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, \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 +``''. +.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 \fBLANG\fP 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 builtin command to determine the column length +for printing selection lists. Automatically set upon receipt of a SIGWINCH. +.TP +.B MAIL +If this parameter is set to a file name and the +.SM +.B MAILPATH +variable is not set, +.B bash +informs the user of the arrival of mail in the specified file. +.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='/var/mail/bfox?"You have mail":~/shell\-mail?"$_ has mail!"' +.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 \fBPATH\fP 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/gnu/bin:/usr/local/bin:/usr/ucb:/bin:/usr/bin\fP. +.if n ``/usr/gnu/bin:/usr/local/bin:/usr/ucb:/bin:/usr/bin''. +.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 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 +.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 +.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 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$'\enreal\et%3lR\enuser\et%3lU\ensys\t%3lS'\fP. +If the value is null, no timing information is displayed. +A trailing newline is added when the format string is displayed. +.TP +.B TMOUT +If set to a value greater than zero, \fBTMOUT\fP is treated as the +default timeout for the \fBread\fP builtin. +The \fBselect\fP command terminates if input does not arrive +after \fBTMOUT\fP 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 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 +.B % +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 array variables. Any variable may be used as +an 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. Arrays are indexed using +integers and are zero-based. +.PP +An 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 +greater than or equal to zero. To explicitly declare an 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. 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. Only +\fIstring\fP is required. 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. +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. 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 element zero. +.PP +The +.B unset +builtin is used to destroy arrays. \fBunset\fP \fIname\fP[\fIsubscript\fP] +destroys the array element at index \fIsubscript\fP. +\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 array. 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, +where \fIx\fP and \fIy\fP are either integers or single characters. +When integers are supplied, the expression expands to each number between +\fIx\fP and \fIy\fP, inclusive. +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. +.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 +.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 paramter +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, +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 ${!\fIprefix\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. +When not performing substring expansion, \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). +\fIlength\fP must evaluate to a number greater than or equal to zero. +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 \fIparameter\fP is \fB@\fP, the result is \fIlength\fP positional +parameters beginning at \fIoffset\fP. +If \fIparameter\fP is an array name indexed by @ or *, +the result is the \fIlength\fP +members of the array beginning with ${\fIparameter\fP[\fIoffset\fP]}. +Substring indexing is zero-based unless the positional parameters +are used, in which case the indexing starts at 1. +.TP +${\fB!\fP\fIprefix\fP\fB*\fP} +.PD 0 +.TP +${\fB!\fP\fIprefix\fP\fB@\fP} +.PD +Expands to the names of variables whose names begin with \fIprefix\fP, +separated by the first character of the +.SM +.B IFS +special variable. +.TP +${\fB!\fP\fIname\fP[\fI@\fP]} +.PD 0 +.TP +${\fB!\fP\fIname\fP[\fI*\fP]} +.PD +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} +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 +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 +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} +.PD 0 +.TP +${\fIparameter\fP\fB//\fP\fIpattern\fP\fB/\fP\fIstring\fP} +.PD +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. +In the first form, only the first match is replaced. +The second form causes all matches of \fIpattern\fP to be +replaced with \fIstring\fP. +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. +.SS Command Substitution +.PP +\fICommand substitution\fP allows the output of a command to replace +the command name. There are two forms: +.PP +.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 , +the default, then +any sequence of +.SM +.B IFS +characters 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'\^'\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. +If no matching file names are found, +and the shell option +.B nullglob +is disabled, 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 +.TP +.B * +Matches any string, including the null string. +.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 value of the \fBLC_COLLATE\fP shell variable, +if set. +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.2 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 +.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 exactly 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 ' , +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 +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 as 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. +.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 +.B Bash +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 +.I word +with this construct. +.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 +.SS Here Documents +.PP +This type of redirection instructs the shell to read input from the +current source until a line containing only +.I 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. +.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 +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 and supplied 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 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 alias name and the replacement text may contain any valid +shell input, including the +.I metacharacters +listed above, with the exception that the alias name may not +contain \fI=\fP. 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. Positional parameter 0 +is unchanged. +The first element of the +.SM +.B 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 the exception that the +.SM +.B DEBUG +trap (see the description of the +.B trap +builtin under +.SM +.B SHELL BUILTIN COMMANDS +below) is 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 trap). +.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 +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. +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. 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 integer 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 \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 interchangably 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. +.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 \-O \fIfile\fP +True if \fIfile\fP exists and is owned by the effective user id. +.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 \-S \fIfile\fP +True if \fIfile\fP exists and is a socket. +.TP +.B \-N \fIfile\fP +True if \fIfile\fP exists and has been modified since it was last read. +.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 +\fIfile1\fP \fB\-ef\fP \fIfile2\fP +True if \fIfile1\fP and \fIfile2\fP refer to the same device and +inode numbers. +.TP +.B \-o \fIoptname\fP +True if 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 \-z \fIstring\fP +True if the length of \fIstring\fP is zero. +.TP +.B \-n \fIstring\fP +.TP +\fIstring\fP +True if the length of +.I string +is non-zero. +.TP +\fIstring1\fP \fB==\fP \fIstring2\fP +True if the strings are equal. \fB=\fP may be used in place of +\fB==\fP for strict POSIX compliance. +.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 +in the current locale. +.TP +\fIstring1\fP \fB>\fP \fIstring2\fP +True if \fIstring1\fP sorts after \fIstring2\fP lexicographically +in the current locale. +.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 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: +.sp 1 +.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 \fB$PPID\fP +.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. +.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 +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" +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 \Bbash\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 system'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 write to the +terminal. Background processes which attempt to read from (write to) the +terminal are sent a +.SM +.B SIGTTIN (SIGTTOU) +signal by the 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 name. 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 %\- . +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 \- . +.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, the shell prints a warning message. 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 the 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 + patchelvel (e.g., 2.00.0) +.TP +.B \ew +the current working directory, with \fB$HOME\fP abbreviated with a tilde +.TP +.B \eW +the basename of the current working directory, with \fB$HOME\fP +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. +By default, the line editing commands are similar to those of emacs. +A vi-style line editing interface is also available. +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 (see +.SM +.B SHELL BUILTIN COMMANDS +below). +.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' +literal ' +.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 '. +.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 +.BR Off . +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 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\-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 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 expand\-tilde (Off) +If set to \fBon\fP, tilde expansion is performed when readline +attempts word completion. +.TP +.B history-preserve-point +If set to \fBon\fP, the history code attempts to place point at the +same location on each history line retrived with \fBprevious-history\fP +or \fBnext-history\fP. +.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, unless the leading `.' is +supplied by the user in the filename to be completed. +.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 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 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 Bash: +.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 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. +.TP +.B +yank\-last\-arg (M\-.\^, M\-_\^) +Insert the last argument to the previous command (the last word of +the previous history entry). With an argument, +behave exactly like \fByank\-nth\-arg\fP. +Successive calls to \fByank\-last\-arg\fP move back through the history +list, inserting the last argument of each line in turn. +.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 $FCEDIT , +.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 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 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 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 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\-) +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 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 ouput. 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 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. +.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 filename 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, arithmetic expansion, and pathname 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 +.B COMP_LINE +and +.SM +.B COMP_POINT +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. +.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 \fBHISTSIZE\fP 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 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. 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), 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" ). +.SS Event Designators +.PP +An event designator is a reference to a command line entry 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 line 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 starting with +.IR string . +.TP +.B !?\fIstring\fR\fB[?]\fR +Refer to the most recent command 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 last 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. +.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 the suspended job \fIjobspec\fP in the background, as if it +had been started with +.BR & . +If \fIjobspec\fP 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, if \fIjobspec\fP was not found or 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 \-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 \-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 \-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. +.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 the shell is not executing +a loop when +.B break +is executed. +.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 +\fBcd\fP [\fB\-L|-P\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. An argument of +.B \- +is equivalent to +.SM +.BR $OLDPWD . +If a non-empty directory name from \fBCDPATH\fP 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 +\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 +\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 +.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\-A\fP \fIaction\fP] [\fB\-G\fP \fIglobpat\fP] [\fB\-W\fP \fIwordlist\fP] [\fB\-P\fP \fIprefix\fP] [\fB\-S\fP \fIsuffix\fP] +.br +[\fB\-X\fP \fIfilterpat\fP] [\fB\-F\fP \fIfunction\fP] [\fB\-C\fP \fIcommand\fP] \fIname\fP [\fIname ...\fP] +.PD 0 +.TP +\fBcomplete\fP \fB\-pr\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. +.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 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. +.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\-G\fP \fIglobpat\fP +The filename expansion pattern \fIglobpat\fP is expanded to generate +the possible completions. +.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\-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\-X\fP \fIfilterpat\fP +\fIfilterpat\fP is a pattern as used for filename 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. +.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. +.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 +\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 the +shell is not executing a loop when +.B continue +is executed. +.TP +\fBdeclare\fP [\fB\-afFirtx\fP] [\fB\-p\fP] [\fIname\fP[=\fIvalue\fP] ...] +.PD 0 +.TP +\fBtypeset\fP [\fB\-afFirtx\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, additional options are ignored. +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 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 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" ") " +is performed when the variable is assigned a value. +.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 trap from the calling shell. +The trace attribute has no special meaning for variables. +.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 exception that \fB+a\fP +may not be used to destroy an array variable. When used in a function, +makes each +\fIname\fP local, as with the +.B local +command. +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 [\fB\-clpv\fP] [+\fIn\fP] [\-\fIn\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 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 always 0. +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 +.B \-\- +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 trailing newline +.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 \e\fInnn\fP +the eight-bit character whose value is the octal value \fInnn\fP +(one 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) +.PD +.RE +.TP +\fBenable\fP [\fB\-adnps\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 arg 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\-nlr\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. +\fBOPTIND\fP is set to the index of the first non-option argument, +and \fBname\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] +For each +.IR name , +the full file name of the command is determined by searching +the directories in +.B $PATH +and remembered. +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\-s\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. +The \fB\-s\fP option restricts the information displayed to a short +usage synopsis. +The return status is 0 unless no command matches +.IR pattern . +.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 \fBHISTTIMEFORMAT\fP 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 \fBHISTTIMEFORMAT\fP is set, the time stamp information +associated with each history entry is written to the history file. +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 \-p +List only the process ID of the job's process group +leader. +.TP +.B \-n +Display information only about jobs that have changed status since +the user was last notified of their status. +.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 signal name such as +.SM +.B SIGKILL +or a signal number; +.I signum +is a signal number. If +.I sigspec +is a signal name, the name may be +given with or without the +.SM +.B SIG +prefix. +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 +.BR "ARITHMETIC EVALUATION" ). +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 +\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 +\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. +.TP +.B \-n +Suppresses the normal change of directory when removing directories +from the stack, so that only the stack is manipulated. +.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 \fIformat\fP [\fIarguments\fP] +Write the formatted \fIarguments\fP to the standard output under the +control of the \fIformat\fP. +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) formats, \fB%b\fP causes +\fBprintf\fP to expand backslash escape sequences in the corresponding +\fIargument\fP (except that \fB\ec\fP terminates output, backslashes in +\fB\e'\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), +and \fB%q\fP causes \fBprintf\fP to output the corresponding +\fIargument\fP in a format that can be reused as shell input. +.sp 1 +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. +.TP +\fBpushd\fP [\fB\-n\fP] [\fIdir\fP] +.PD 0 +.TP +\fBpushd\fP [\fB\-n\fP] [+\fIn\fP] [\-\fIn\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 +\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 +.B \-n +Suppresses the normal change of directory when adding directories +to the stack, so that only the stack is manipulated. +.TP +.I dir +Adds +.I dir +to the directory stack at the top, making it the +new current working directory. +.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\-u\fP \fIfd\fP] [\fB\-t\fP \fItimeout\fP] [\fB\-a\fP \fIaname\fP] [\fB\-p\fP \fIprompt\fP] [\fB\-n\fP \fInchars\fP] [\fB\-d\fP \fIdelim\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. +.TP +.B \-n \fInchars\fP +\fBread\fP returns after reading \fInchars\fP characters rather than +waiting for a complete line of input. +.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. +This option has no effect if \fBread\fP is not reading input from the +terminal or a pipe. +.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, or an invalid file descriptor is supplied as the argument to +\fB\-u\fP. +.RE +.TP +\fBreadonly\fP [\fB\-apf\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 arrays. +If no +.I name +arguments are given, or if the +.B \-p +option is supplied, a list of all readonly names is printed. +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\-\-abefhkmnptuvxBCHP\fP] [\fB\-o\fP \fIoption\fP] [\fIarg\fP ...] +Without options, the name and value of each shell variable are displayed +in a format that can be reused as input. +The output is sorted according to the current locale. +When options are specified, they set or unset shell attributes. +Any arguments remaining after the options are processed 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 \fIsimple command\fP (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 in an +.I if +statement, part of a +.B && +or +.B \(bv\(bv +list, or if the command's return value is +being inverted via +.BR ! . +A trap on \fBERR\fP, if set, is executed before the shell exits. +.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). Background processes run in a separate process +group and a line containing their exit status is printed +upon their completion. +.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. +.TP 8 +.B errtrace +Same as +.BR \-E . +.TP 8 +.B functrace +Same as +.BR \-T . +.TP 8 +.B errexit +Same as +.BR \-e . +.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 . +.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 1003.2 standard to match the standard (\fI`posix 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. +.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 +.B SHELLOPTS +variable, if it appears in the environment, is 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 as an error when performing +parameter expansion. If expansion is attempted on an +unset variable, 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 trap on \fBDEBUG\fP is inherited by shell functions, command +substitutions, and commands executed in a subshell environment. +The \fBDEBUG\fP trap is 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 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 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 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. +.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'\fIstring\fP' 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 \fBFIGNORE\fP 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 \fBFIGNORE\fP. +This option is enabled by default. +.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 +.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 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 \fBPATH\fP 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 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 +.TP +\fBsuspend\fP [\fB\-f\fP] +Suspend the execution of this shell until it receives a +.SM +.B SIGCONT +signal. The +.B \-f +option says not to complain if this is +a login shell; just suspend anyway. 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" . +.if t .sp 0.5 +.if n .sp 1 +Expressions may be combined using the following operators, listed +in decreasing order of precedence. +.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 +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. +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. +The \fB\-a\fP and \fB\-o\fP operators are considered binary operators +in this case. +.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. +.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 or +.BR \- , +all specified signals are +reset to their original values (the values they 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 number. +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. +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 \fBextglob\fP option to the +\fBshopt\fP builtin for details of its effect on the \fBDEBUG\fP trap. +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 +.B && +or +.B \(bv\(bv +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 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. +Signals ignored upon entry to the shell cannot be trapped or reset. +Trapped signals are reset to their original values in a child +process when it 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 any of the arguments are found, false if +none are found. +.TP +\fBulimit\fP [\fB\-SHacdflmnpstuv\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 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 \-c +The maximum size of core files created +.TP +.B \-d +The maximum size of a process's data segment +.TP +.B \-f +The maximum size of files created by the shell +.TP +.B \-l +The maximum size that may be locked into memory +.TP +.B \-m +The maximum resident set size +.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 \-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 +.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 +.B \-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 no options are supplied, or the +.B \-v +option is given, each +.I name +refers to a shell variable. +Read-only variables may not be unset. +If +.B \-f +is specifed, +each +.I name +refers to a shell function, and the function definition +is removed. +Each unset variable or function is removed from the environment +passed to subsequent commands. +If any of +.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 the specified process and return its termination +status. +.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 +.BR SHELL , +.BR PATH , +.BR ENV , +or +.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 \fBSHELLOPTS\fP 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 +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@po.CWRU.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/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@po.CWRU.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 +Commands inside of \fB$(\fP...\fB)\fP command substitution are not +parsed until substitution is attempted. This will delay error +reporting until some time after the command is entered. +.PP +Array variables may not (yet) be exported. +.zZ +.zY diff --git a/doc/bash.ps b/doc/bash.ps index 29e3e8764..10e7b0349 100644 --- a/doc/bash.ps +++ b/doc/bash.ps @@ -1,6 +1,6 @@ %!PS-Adobe-3.0 %%Creator: groff version 1.18.1 -%%CreationDate: Thu Nov 13 09:47:38 2003 +%%CreationDate: Sun Jan 25 21:10:35 2004 %%DocumentNeededResources: font Times-Roman %%+ font Times-Bold %%+ font Times-Italic @@ -189,11 +189,11 @@ setpacking %%IncludeResource: font Palatino-Italic %%IncludeResource: font Palatino-Bold grops begin/DEFS 1 dict def DEFS begin/u{.001 mul}bind def end/RES 72 -def/PL 792 def/LS false def/ENC0[/asciicircum/asciitilde/Scaron/Zcaron -/scaron/zcaron/Ydieresis/trademark/quotesingle/Euro/.notdef/.notdef +def/PL 841.89 def/LS false def/ENC0[/asciicircum/asciitilde/Scaron +/Zcaron/scaron/zcaron/Ydieresis/trademark/quotesingle/Euro/.notdef /.notdef/.notdef/.notdef/.notdef/.notdef/.notdef/.notdef/.notdef/.notdef /.notdef/.notdef/.notdef/.notdef/.notdef/.notdef/.notdef/.notdef/.notdef -/.notdef/.notdef/space/exclam/quotedbl/numbersign/dollar/percent +/.notdef/.notdef/.notdef/space/exclam/quotedbl/numbersign/dollar/percent /ampersand/quoteright/parenleft/parenright/asterisk/plus/comma/hyphen /period/slash/zero/one/two/three/four/five/six/seven/eight/nine/colon /semicolon/less/equal/greater/question/at/A/B/C/D/E/F/G/H/I/J/K/L/M/N/O @@ -230,7 +230,7 @@ BP (bash \255 GNU Bourne-Ag)108 96 Q(ain SHell)-.05 E F1(SYNOPSIS)72 112.8 Q/F2 10/Times-Bold@0 SF(bash)108 124.8 Q F0([options] [\214le])2.5 E F1 (COPYRIGHT)72 141.6 Q F0(Bash is Cop)108 153.6 Q -(yright \251 1989-2003 by the Free Softw)-.1 E(are F)-.1 E +(yright \251 1989-2004 by the Free Softw)-.1 E(are F)-.1 E (oundation, Inc.)-.15 E F1(DESCRIPTION)72 170.4 Q F2(Bash)108 182.4 Q F0 .973(is an)3.474 F F2(sh)3.473 E F0 .973 (-compatible command language interpreter that e)B -.15(xe)-.15 G .973 @@ -321,8 +321,7 @@ E F2(po)2.5 E F0(\(portable object\) \214le format.)2.5 E F2 144 686.4 Q .3 -.15(ve \()-.25 H(see).15 E F4(INV)2.5 E(OCA)-.405 E (TION)-.855 E F0(belo)2.25 E(w\).)-.25 E F2(\255\255login)108 703.2 Q F0 (Equi)144 715.2 Q -.25(va)-.25 G(lent to).25 E F22.5 E F0(.)A -(GNU Bash-3.0)72 768 Q(2003 No)147.975 E 2.5(v1)-.15 G 202.965(31)-2.5 G -0 Cg EP +(GNU Bash-3.0)72 768 Q(2004 Jan 24)149.845 E(1)204.835 E 0 Cg EP %%Page: 2 2 %%BeginPageSetup BP @@ -445,7 +444,7 @@ F(ariable)-.25 E F3 -.27(BA)108 679.2 S(SH_ENV).27 E F0 1.01(in the en) 108 727.2 S 2.5(tt).2 G(he v)-2.5 E(alue of the)-.25 E F3 -.666(PA)2.5 G (TH)-.189 E F0 -.25(va)2.25 G (riable is not used to search for the \214le name.).25 E(GNU Bash-3.0)72 -768 Q(2003 No)147.975 E 2.5(v1)-.15 G 202.965(32)-2.5 G 0 Cg EP +768 Q(2004 Jan 24)149.845 E(2)204.835 E 0 Cg EP %%Page: 3 3 %%BeginPageSetup BP @@ -570,8 +569,7 @@ F1(Pipelines)87 679.2 Q F0(A)108 691.2 Q F2(pipeline)2.919 E F0 .419 F F1(|)2.92 E F0 5.42(.T)C .42(he format for a pipeline)-5.42 F(is:)108 703.2 Q([)144 720 Q F1(time)A F0([)2.5 E F1A F0(]] [ ! ])A F2 (command)2.5 E F0([)2.5 E F1(|)2.5 E F2(command2)2.5 E F0(... ])2.5 E -(GNU Bash-3.0)72 768 Q(2003 No)147.975 E 2.5(v1)-.15 G 202.965(33)-2.5 G -0 Cg EP +(GNU Bash-3.0)72 768 Q(2004 Jan 24)149.845 E(3)204.835 E 0 Cg EP %%Page: 4 4 %%BeginPageSetup BP @@ -691,8 +689,8 @@ A({)108 573.6 Q F1(list)2.5 E F0 2.5(;})C F1(list)3.89 E F0 .402 F(SIONS)144 727.2 Q F5(.)A F0 -.8(Wo)5.633 G 1.133 (rd splitting and pathname e).8 F 1.133 (xpansion are not performed on the w)-.15 F 1.133(ords between the)-.1 F -F3([[)3.632 E F0(GNU Bash-3.0)72 768 Q(2003 No)147.975 E 2.5(v1)-.15 G -202.965(34)-2.5 G 0 Cg EP +F3([[)3.632 E F0(GNU Bash-3.0)72 768 Q(2004 Jan 24)149.845 E(4)204.835 E +0 Cg EP %%Page: 5 5 %%BeginPageSetup BP @@ -831,8 +829,8 @@ F F2(name)144 727.2 Q F0 .759(to be set to null.)3.439 F .759 (The line read is sa)5.759 F -.15(ve)-.2 G 3.26(di).15 G 3.26(nt)-3.26 G .76(he v)-3.26 F(ariable)-.25 E F1(REPL)3.26 E(Y)-.92 E F0 5.76(.T)C(he) -5.76 E F2(list)3.35 E F0 .76(is e)3.94 F -.15(xe)-.15 G .76 -(cuted after).15 F(GNU Bash-3.0)72 768 Q(2003 No)147.975 E 2.5(v1)-.15 G -202.965(35)-2.5 G 0 Cg EP +(cuted after).15 F(GNU Bash-3.0)72 768 Q(2004 Jan 24)149.845 E(5)204.835 +E 0 Cg EP %%Page: 6 6 %%BeginPageSetup BP @@ -967,7 +965,7 @@ E(xpansion.)-.15 E(There are three quoting mechanisms: the)108 708 Q F2 G(he)-2.974 E F2 .474(escape c)2.974 F(har)-.15 E(acter)-.15 E F0 5.474 (.I).73 G 2.974(tp)-5.474 G(reserv)-2.974 E .474(es the literal v)-.15 F .474(alue of the ne)-.25 F .474(xt character that)-.15 F(GNU Bash-3.0)72 -768 Q(2003 No)147.975 E 2.5(v1)-.15 G 202.965(36)-2.5 G 0 Cg EP +768 Q(2004 Jan 24)149.845 E(6)204.835 E 0 Cg EP %%Page: 7 7 %%BeginPageSetup BP @@ -1084,7 +1082,7 @@ d by one or more digits, other than the single digit 0.)3.935 F(Posi-) 5.706 E .445(tional parameters are assigned from the shell')108 729.6 R 2.944(sa)-.55 G -.18(rg)-2.944 G .444(uments when it is in).18 F -.2(vo) -.4 G -.1(ke).2 G .444(d, and may be reassigned using).1 F(GNU Bash-3.0) -72 768 Q(2003 No)147.975 E 2.5(v1)-.15 G 202.965(37)-2.5 G 0 Cg EP +72 768 Q(2004 Jan 24)149.845 E(7)204.835 E 0 Cg EP %%Page: 8 8 %%BeginPageSetup BP @@ -1202,7 +1200,7 @@ F F1 -.3(BA)144 619.2 S(SH_ARGV).3 E F0(.)A F1 -.3(BA)108 631.2 S F F1(${FUNCN)144 727.2 Q(AME[)-.2 E F3 8.951($i + 1)B F1(]})A F0 -.1(wa) 11.451 G 11.451(sc).1 G 11.451(alled. The)-11.451 F 8.951 (corresponding source \214le name is)11.451 F(GNU Bash-3.0)72 768 Q -(2003 No)147.975 E 2.5(v1)-.15 G 202.965(38)-2.5 G 0 Cg EP +(2004 Jan 24)149.845 E(8)204.835 E 0 Cg EP %%Page: 9 9 %%BeginPageSetup BP @@ -1303,7 +1301,7 @@ F(ariable)-.25 E .351(will not change the current directory)144 711.6 R 5.35(.I)-.65 G(f)-5.35 E F3(DIRST)2.85 E -.495(AC)-.81 G(K).495 E F0 .35 (is unset, it loses its special properties, e)2.6 F -.15(ve)-.25 G 2.85 (ni).15 G(f)-2.85 E(it is subsequently reset.)144 723.6 Q(GNU Bash-3.0) -72 768 Q(2003 No)147.975 E 2.5(v1)-.15 G 202.965(39)-2.5 G 0 Cg EP +72 768 Q(2004 Jan 24)149.845 E(9)204.835 E 0 Cg EP %%Page: 10 10 %%BeginPageSetup BP @@ -1392,8 +1390,7 @@ R .01(alue to)-.25 F F2(RANDOM)2.51 E/F4 9/Times-Roman@0 SF(.)A F0(If) 4.51 E F2(RANDOM)2.51 E F0(is)2.26 E (unset, it loses its special properties, e)144 720 Q -.15(ve)-.25 G 2.5 (ni).15 G 2.5(fi)-2.5 G 2.5(ti)-2.5 G 2.5(ss)-2.5 G(ubsequently reset.) --2.5 E(GNU Bash-3.0)72 768 Q(2003 No)147.975 E 2.5(v1)-.15 G 197.965(31) --2.5 G(0)-197.965 E 0 Cg EP +-2.5 E(GNU Bash-3.0)72 768 Q(2004 Jan 24)149.845 E(10)199.835 E 0 Cg EP %%Page: 11 11 %%BeginPageSetup BP @@ -1502,8 +1499,7 @@ me e)-3.118 F(xpan-)-.15 E 3.131(sion. If)144 640.8 R 3.132<618c>3.131 G (all pre)144 724.8 R .698 (vious lines matching the current line to be remo)-.25 F -.15(ve)-.15 G 3.198(df).15 G .698(rom the history list before that line is)-3.198 F -(GNU Bash-3.0)72 768 Q(2003 No)147.975 E 2.5(v1)-.15 G 197.965(31)-2.5 G -(1)-197.965 E 0 Cg EP +(GNU Bash-3.0)72 768 Q(2004 Jan 24)149.845 E(11)199.835 E 0 Cg EP %%Page: 12 12 %%BeginPageSetup BP @@ -1616,8 +1612,7 @@ E F1(LANG)108 648 Q F0 1.24(Used to determine the locale cate)7.11 F (rrides the v).15 F .764(alue of)-.25 F F1(LANG)3.264 E F0 .764(and an) 3.264 F 3.264(yo)-.15 G(ther)-3.264 E F1(LC_)3.264 E F0 -.25(va)3.264 G .764(riable specifying a locale cate-).25 F(gory)144 696 Q(.)-.65 E -(GNU Bash-3.0)72 768 Q(2003 No)147.975 E 2.5(v1)-.15 G 197.965(31)-2.5 G -(2)-197.965 E 0 Cg EP +(GNU Bash-3.0)72 768 Q(2004 Jan 24)149.845 E(12)199.835 E 0 Cg EP %%Page: 13 13 %%BeginPageSetup BP @@ -1721,8 +1716,8 @@ F0 1.225(displays during an e)3.725 F -.15(xe)-.15 G 1.225 E F0 1.226(is replicated multiple)3.476 F(times, as necessary)144 696 Q 2.5(,t)-.65 G 2.5(oi)-2.5 G(ndicate multiple le)-2.5 E -.15(ve)-.25 G (ls of indirection.).15 E(The def)5 E(ault is `)-.1 E(`)-.74 E F1(+)A F0 --.74('')2.5 G(.).74 E(GNU Bash-3.0)72 768 Q(2003 No)147.975 E 2.5(v1) --.15 G 197.965(31)-2.5 G(3)-197.965 E 0 Cg EP +-.74('')2.5 G(.).74 E(GNU Bash-3.0)72 768 Q(2004 Jan 24)149.845 E(13) +199.835 E 0 Cg EP %%Page: 14 14 %%BeginPageSetup BP @@ -1840,7 +1835,7 @@ G .961(or an)-3.461 F 3.461(yr)-.15 G(equirement)-3.461 E 1.302(An array is created automatically if an)108 728.4 R 3.801(yv)-.15 G 1.301(ariable is assigned to using the syntax)-4.051 F F2(name)3.801 E F0([)A F2(subscript)A F0(]=)A F2(value)A F0(.)A(GNU Bash-3.0)72 768 Q -(2003 No)147.975 E 2.5(v1)-.15 G 197.965(31)-2.5 G(4)-197.965 E 0 Cg EP +(2004 Jan 24)149.845 E(14)199.835 E 0 Cg EP %%Page: 15 15 %%BeginPageSetup BP @@ -1992,8 +1987,7 @@ F0(must be of the same type.)2.5 E .582(Brace e)108 705.6 R .582 (does not apply an)2.516 F 2.516(ys)-.15 G .016 (yntactic interpretation to the con-)-2.516 F(te)108 729.6 Q (xt of the e)-.15 E(xpansion or the te)-.15 E(xt between the braces.) --.15 E(GNU Bash-3.0)72 768 Q(2003 No)147.975 E 2.5(v1)-.15 G 197.965(31) --2.5 G(5)-197.965 E 0 Cg EP +-.15 E(GNU Bash-3.0)72 768 Q(2004 Jan 24)149.845 E(15)199.835 E 0 Cg EP %%Page: 16 16 %%BeginPageSetup BP @@ -2120,8 +2114,8 @@ E .351(able is then e)108 700.8 R .351(xpanded and that v)-.15 F .352 (e\214x)-.37 E F0 .019(*} and)B(${)108 724.8 Q F1(!)A F2(name)A F0([)A F2(@)A F0 .762(]} described belo)B 4.563 -.65(w. T)-.25 H .763(he e).65 F .763(xclamation point must immediately follo)-.15 F 3.263(wt)-.25 G -.763(he left brace in order to)-3.263 F(GNU Bash-3.0)72 768 Q(2003 No) -147.975 E 2.5(v1)-.15 G 197.965(31)-2.5 G(6)-197.965 E 0 Cg EP +.763(he left brace in order to)-3.263 F(GNU Bash-3.0)72 768 Q +(2004 Jan 24)149.845 E(16)199.835 E 0 Cg EP %%Page: 17 17 %%BeginPageSetup BP @@ -2244,8 +2238,7 @@ F1(par)145.25 664.8 Q(ameter)-.15 E F0 .607 3.151(,t)C .651(he pattern remo)-3.151 F -.25(va)-.15 G 3.151(lo).25 G .65(peration is applied to each member of the array in)-3.151 F (turn, and the e)144 712.8 Q(xpansion is the resultant list.)-.15 E -(GNU Bash-3.0)72 768 Q(2003 No)147.975 E 2.5(v1)-.15 G 197.965(31)-2.5 G -(7)-197.965 E 0 Cg EP +(GNU Bash-3.0)72 768 Q(2004 Jan 24)149.845 E(17)199.835 E 0 Cg EP %%Page: 18 18 %%BeginPageSetup BP @@ -2358,8 +2351,7 @@ F1 -.2(ex)2.666 G(pr).2 E(ession)-.37 E F0 .165 A F0(If)5.878 E F1 -.2(ex)108 705.6 S(pr).2 E(ession)-.37 E F0(is in) 2.74 E -.25(va)-.4 G(lid,).25 E F2(bash)2.5 E F0 (prints a message indicating f)2.5 E(ailure and no substitution occurs.) --.1 E(GNU Bash-3.0)72 768 Q(2003 No)147.975 E 2.5(v1)-.15 G 197.965(31) --2.5 G(8)-197.965 E 0 Cg EP +-.1 E(GNU Bash-3.0)72 768 Q(2004 Jan 24)149.845 E(18)199.835 E 0 Cg EP %%Page: 19 19 %%BeginPageSetup BP @@ -2496,8 +2488,8 @@ R 1.12(NUL character may not occur in a pattern.)3.62 F 3.62(Ab)6.12 G (The special pattern characters must be quoted if the)5.576 F 3.076(ya) -.15 G(re)-3.076 E(to be matched literally)108 691.2 Q(.)-.65 E (The special pattern characters ha)108 708 Q .3 -.15(ve t)-.2 H -(he follo).15 E(wing meanings:)-.25 E(GNU Bash-3.0)72 768 Q(2003 No) -147.975 E 2.5(v1)-.15 G 197.965(31)-2.5 G(9)-197.965 E 0 Cg EP +(he follo).15 E(wing meanings:)-.25 E(GNU Bash-3.0)72 768 Q(2004 Jan 24) +149.845 E(19)199.835 E 0 Cg EP %%Page: 20 20 %%BeginPageSetup BP @@ -2607,8 +2599,7 @@ ted, and the \214rst character of the redirec-)-.25 F .365 E F0(dirlist 2)2.5 E F1(>&)A F0(1)A (directs both standard output and standard error to the \214le)108 728.4 Q F2(dirlist)2.5 E F0 2.5(,w).68 G(hile the command)-2.5 E(GNU Bash-3.0) -72 768 Q(2003 No)147.975 E 2.5(v1)-.15 G 197.965(32)-2.5 G(0)-197.965 E -0 Cg EP +72 768 Q(2004 Jan 24)149.845 E(20)199.835 E 0 Cg EP %%Page: 21 21 %%BeginPageSetup BP @@ -2697,7 +2688,7 @@ Q F0(allo)3.141 E .642(ws both the standard output \(\214le descriptor \ E(There are tw)108 693.6 Q 2.5(of)-.1 G (ormats for redirecting standard output and standard error:)-2.5 E F1 (&>)144 710.4 Q F2(wor)A(d)-.37 E F0(and)108 722.4 Q(GNU Bash-3.0)72 768 -Q(2003 No)147.975 E 2.5(v1)-.15 G 197.965(32)-2.5 G(1)-197.965 E 0 Cg EP +Q(2004 Jan 24)149.845 E(21)199.835 E 0 Cg EP %%Page: 22 22 %%BeginPageSetup BP @@ -2784,7 +2775,7 @@ E F0(is closed after being duplicated to)2.5 E F2(n)2.5 E F0(.)A .24 G 2.786(rt)-2.786 G .285 (he standard output \(\214le descriptor 1\) if)-2.786 F F2(n)2.785 E F0 .285(is not speci-)2.785 F(\214ed.)108 705.6 Q(GNU Bash-3.0)72 768 Q -(2003 No)147.975 E 2.5(v1)-.15 G 197.965(32)-2.5 G(2)-197.965 E 0 Cg EP +(2004 Jan 24)149.845 E(22)199.835 E 0 Cg EP %%Page: 23 23 %%BeginPageSetup BP @@ -2924,8 +2915,8 @@ F F1 .616(\255o functrace)3.115 F F0 .616 (alues of the positional parameters and the spe-)-.25 F(cial parameter) 108 724.8 Q F1(#)2.5 E F0(are restored to the v)2.5 E(alues the)-.25 E 2.5(yh)-.15 G(ad prior to the function')-2.5 E 2.5(se)-.55 G -.15(xe) --2.65 G(cution.).15 E(GNU Bash-3.0)72 768 Q(2003 No)147.975 E 2.5(v1) --.15 G 197.965(32)-2.5 G(3)-197.965 E 0 Cg EP +-2.65 G(cution.).15 E(GNU Bash-3.0)72 768 Q(2004 Jan 24)149.845 E(23) +199.835 E 0 Cg EP %%Page: 24 24 %%BeginPageSetup BP @@ -3027,8 +3018,7 @@ H .343(ts inte).15 F .343(ger attrib)-.15 F .343(ute turned on)-.2 F (xpressions in parentheses are e)-.15 F -.25(va)-.25 G .234 (luated \214rst and may).25 F -.15(ove)108 724.8 S (rride the precedence rules abo).15 E -.15(ve)-.15 G(.).15 E -(GNU Bash-3.0)72 768 Q(2003 No)147.975 E 2.5(v1)-.15 G 197.965(32)-2.5 G -(4)-197.965 E 0 Cg EP +(GNU Bash-3.0)72 768 Q(2004 Jan 24)149.845 E(24)199.835 E 0 Cg EP %%Page: 25 25 %%BeginPageSetup BP @@ -3138,8 +3128,7 @@ qual to, greater than, or greater than or equal to)144 696 R F3(ar)144 -.65 E F3(Ar)6.01 E(g1)-.37 E F0(and)2.5 E F3(ar)2.83 E(g2)-.37 E F0 (may be positi)2.52 E .3 -.15(ve o)-.25 H 2.5(rn).15 G -2.25 -.15(eg a) -2.5 H(ti).15 E .3 -.15(ve i)-.25 H(nte).15 E(gers.)-.15 E(GNU Bash-3.0) -72 768 Q(2003 No)147.975 E 2.5(v1)-.15 G 197.965(32)-2.5 G(5)-197.965 E -0 Cg EP +72 768 Q(2004 Jan 24)149.845 E(25)199.835 E 0 Cg EP %%Page: 26 26 %%BeginPageSetup BP @@ -3255,8 +3244,7 @@ e remainder of the \214rst line speci\214es an interpreter for the pro-) (COMMAND EXECUTION ENVIR)72 703.2 Q(ONMENT)-.329 E F0(The shell has an) 108 715.2 Q F5 -.2(ex)2.5 G(ecution en).2 E(vir)-.4 E(onment)-.45 E F0 2.5(,w)C(hich consists of the follo)-2.5 E(wing:)-.25 E(GNU Bash-3.0)72 -768 Q(2003 No)147.975 E 2.5(v1)-.15 G 197.965(32)-2.5 G(6)-197.965 E 0 -Cg EP +768 Q(2004 Jan 24)149.845 E(26)199.835 E 0 Cg EP %%Page: 27 27 %%BeginPageSetup BP @@ -3366,8 +3354,8 @@ t for)-.4 F F2 -.2(ex)2.643 G(port).2 E F0 .143(to child pro-)3.323 F .202(parameter assignments, as described abo)108 724.8 R .502 -.15(ve i) -.15 H(n).15 E/F4 9/Times-Bold@0 SF -.666(PA)2.702 G(RAMETERS).666 E/F5 9/Times-Roman@0 SF(.)A F0 .202(These assignment statements af)4.702 F -.203(fect only the)-.25 F(GNU Bash-3.0)72 768 Q(2003 No)147.975 E 2.5 -(v1)-.15 G 197.965(32)-2.5 G(7)-197.965 E 0 Cg EP +.203(fect only the)-.25 F(GNU Bash-3.0)72 768 Q(2004 Jan 24)149.845 E +(27)199.835 E 0 Cg EP %%Page: 28 28 %%BeginPageSetup BP @@ -3491,8 +3479,7 @@ iated)108 676.8 R .732(with this job is 25647.)108 688.8 R .733 .87(notion of a)108 729.6 R F2(curr)3.37 E .87(ent terminal pr)-.37 F .871(ocess gr)-.45 F .871(oup ID)-.45 F F0 5.871(.M)C .871 (embers of this process group \(processes whose process)-5.871 F -(GNU Bash-3.0)72 768 Q(2003 No)147.975 E 2.5(v1)-.15 G 197.965(32)-2.5 G -(8)-197.965 E 0 Cg EP +(GNU Bash-3.0)72 768 Q(2004 Jan 24)149.845 E(28)199.835 E 0 Cg EP %%Page: 29 29 %%BeginPageSetup BP @@ -3619,8 +3606,7 @@ ized by inserting a number of backslash-escaped special characters that\ (\\r)144 700.8 Q F0(carriage return)28.78 E F4(\\s)144 712.8 Q F0 (the name of the shell, the basename of)29.33 E F4($0)2.5 E F0 (\(the portion follo)2.5 E(wing the \214nal slash\))-.25 E(GNU Bash-3.0) -72 768 Q(2003 No)147.975 E 2.5(v1)-.15 G 197.965(32)-2.5 G(9)-197.965 E -0 Cg EP +72 768 Q(2004 Jan 24)149.845 E(29)199.835 E 0 Cg EP %%Page: 30 30 %%BeginPageSetup BP @@ -3635,12 +3621,14 @@ BP 28.22 E(ersion of)-.15 E F1(bash)2.5 E F0(\(e.g., 2.00\))2.5 E F1(\\V) 144 156 Q F0(the release of)26 E F1(bash)2.5 E F0 2.5(,v)C (ersion + patchelv)-2.65 E(el \(e.g., 2.00.0\))-.15 E F1(\\w)144 168 Q -F0(the current w)26 E(orking directory)-.1 E F1(\\W)144 180 Q F0 -(the basename of the current w)23.22 E(orking directory)-.1 E F1(\\!)144 -192 Q F0(the history number of this command)29.89 E F1(\\#)144 204 Q F0 -(the command number of this command)28.22 E F1(\\$)144 216 Q F0 -(if the ef)28.22 E(fecti)-.25 E .3 -.15(ve U)-.25 H(ID is 0, a).15 E F1 -(#)2.5 E F0 2.5(,o)C(therwise a)-2.5 E F1($)2.5 E(\\)144 228 Q/F2 10 +F0(the current w)26 E(orking directory)-.1 E 2.5(,w)-.65 G(ith)-2.5 E F1 +($HOME)2.5 E F0(abbre)2.5 E(viated with a tilde)-.25 E F1(\\W)144 180 Q +F0(the basename of the current w)23.22 E(orking directory)-.1 E 2.5(,w) +-.65 G(ith)-2.5 E F1($HOME)2.5 E F0(abbre)2.5 E(viated with a tilde)-.25 +E F1(\\!)144 192 Q F0(the history number of this command)29.89 E F1(\\#) +144 204 Q F0(the command number of this command)28.22 E F1(\\$)144 216 Q +F0(if the ef)28.22 E(fecti)-.25 E .3 -.15(ve U)-.25 H(ID is 0, a).15 E +F1(#)2.5 E F0 2.5(,o)C(therwise a)-2.5 E F1($)2.5 E(\\)144 228 Q/F2 10 /Times-Italic@0 SF(nnn)A F0 (the character corresponding to the octal number)18.22 E F2(nnn)2.5 E F1 (\\\\)144 240 Q F0 2.5(ab)30.44 G(ackslash)-2.5 E F1(\\[)144 252 Q F0 @@ -3739,8 +3727,8 @@ nd the k)108 652.8 R 1.334 -.15(ey b)-.1 H 1.034(indings and).15 F -.25 -.15(ey)-.1 G .987(-bindings may be changed with an).15 F F2(inputr) 3.497 E(c)-.37 E F0 3.487(\214le. Other)3.797 F .987 (programs that use this library may)3.487 F(add their o)108 717.6 Q -(wn commands and bindings.)-.25 E(GNU Bash-3.0)72 768 Q(2003 No)147.975 -E 2.5(v1)-.15 G 197.965(33)-2.5 G(0)-197.965 E 0 Cg EP +(wn commands and bindings.)-.25 E(GNU Bash-3.0)72 768 Q(2004 Jan 24) +149.845 E(30)199.835 E 0 Cg EP %%Page: 31 31 %%BeginPageSetup BP @@ -3822,8 +3810,8 @@ pes is a)108 612 Q -.25(va)-.2 G(ilable:).25 E F2(\\a)144 624 Q F0 648 Q F0(delete)27.66 E F2(\\f)144 660 Q F0(form feed)29.89 E F2(\\n)144 672 Q F0(ne)27.66 E(wline)-.25 E F2(\\r)144 684 Q F0(carriage return) 28.78 E F2(\\t)144 696 Q F0(horizontal tab)29.89 E F2(\\v)144 708 Q F0 --.15(ve)28.22 G(rtical tab).15 E(GNU Bash-3.0)72 768 Q(2003 No)147.975 E -2.5(v1)-.15 G 197.965(33)-2.5 G(1)-197.965 E 0 Cg EP +-.15(ve)28.22 G(rtical tab).15 E(GNU Bash-3.0)72 768 Q(2004 Jan 24) +149.845 E(31)199.835 E 0 Cg EP %%Page: 32 32 %%BeginPageSetup BP @@ -3922,7 +3910,7 @@ F0 .448(When set to)144 688.8 R F1(On)2.948 E F0 2.948(,m)C(ak)-2.948 E .449(crolling the input horizontally on a)-2.948 F 1.194(single screen \ line when it becomes longer than the screen width rather than wrapping \ to a ne)144 700.8 R(w)-.25 E(line.)144 712.8 Q(GNU Bash-3.0)72 768 Q -(2003 No)147.975 E 2.5(v1)-.15 G 197.965(33)-2.5 G(2)-197.965 E 0 Cg EP +(2004 Jan 24)149.845 E(32)199.835 E 0 Cg EP %%Page: 33 33 %%BeginPageSetup BP @@ -4020,8 +4008,8 @@ F0 .463(construct allo)2.963 F .462(ws bindings to be made based on the\ (or the application using readline.)144 693.6 R .477(The te)5.477 F .477 (xt of the test e)-.15 F .477 (xtends to the end of the line; no characters)-.15 F -(are required to isolate it.)144 705.6 Q(GNU Bash-3.0)72 768 Q(2003 No) -147.975 E 2.5(v1)-.15 G 197.965(33)-2.5 G(3)-197.965 E 0 Cg EP +(are required to isolate it.)144 705.6 Q(GNU Bash-3.0)72 768 Q +(2004 Jan 24)149.845 E(33)199.835 E 0 Cg EP %%Page: 34 34 %%BeginPageSetup BP @@ -4129,8 +4117,8 @@ E F0 .911(refers to the current cursor position, and)3.411 F F2(mark) (db).15 G 3.41(yt)-3.41 G(he)-3.41 E F1(set\255mark)108 724.8 Q F0 2.5 (command. The)2.5 F(te)2.5 E (xt between the point and mark is referred to as the)-.15 E F2 -.37(re) -2.5 G(gion)-.03 E F0(.)A(GNU Bash-3.0)72 768 Q(2003 No)147.975 E 2.5(v1) --.15 G 197.965(33)-2.5 G(4)-197.965 E 0 Cg EP +2.5 G(gion)-.03 E F0(.)A(GNU Bash-3.0)72 768 Q(2004 Jan 24)149.845 E(34) +199.835 E 0 Cg EP %%Page: 35 35 %%BeginPageSetup BP @@ -4209,8 +4197,8 @@ etween the start of the current)-.1 F(line and the point.)144 688.8 Q (th an ar).4 F(gument)-.18 E/F3 10/Times-Italic@0 SF(n)3.294 E F0 3.294 (,i).24 G .794(nsert the)-3.294 F F3(n)3.294 E F0 .794(th w)B .794 (ord from the pre)-.1 F .794(vious command \(the w)-.25 F .795 -(ords in the)-.1 F(GNU Bash-3.0)72 768 Q(2003 No)147.975 E 2.5(v1)-.15 G -197.965(33)-2.5 G(5)-197.965 E 0 Cg EP +(ords in the)-.1 F(GNU Bash-3.0)72 768 Q(2004 Jan 24)149.845 E(35) +199.835 E 0 Cg EP %%Page: 36 36 %%BeginPageSetup BP @@ -4306,8 +4294,8 @@ G .779(nsert characters lik)-3.279 F(e)-.1 E F2(C\255q)3.278 E F0 3.278 -.1 F .023(ving point o)-.15 F -.15(ve)-.15 G 2.524(rt).15 G .024(hat w) -2.524 F .024(ord as well.)-.1 F .024(If point)5.024 F (is at the end of the line, this transposes the last tw)144 700.8 Q 2.5 -(ow)-.1 G(ords on the line.)-2.6 E(GNU Bash-3.0)72 768 Q(2003 No)147.975 -E 2.5(v1)-.15 G 197.965(33)-2.5 G(6)-197.965 E 0 Cg EP +(ow)-.1 G(ords on the line.)-2.6 E(GNU Bash-3.0)72 768 Q(2004 Jan 24) +149.845 E(36)199.835 E 0 Cg EP %%Page: 37 37 %%BeginPageSetup BP @@ -4397,8 +4385,7 @@ F0(or)2.5 E F1(yank\255pop)2.5 E F0(.)A F1(Numeric Ar)87 681.6 Q (gument already accumulating, or start a ne)-.18 F 3.141(wa)-.25 G -.18 (rg)-3.141 G 3.141(ument. M\255\255).18 F .641(starts a ne)3.141 F(g-) -.15 E(ati)144 717.6 Q .3 -.15(ve a)-.25 H -.18(rg).15 G(ument.).18 E -(GNU Bash-3.0)72 768 Q(2003 No)147.975 E 2.5(v1)-.15 G 197.965(33)-2.5 G -(7)-197.965 E 0 Cg EP +(GNU Bash-3.0)72 768 Q(2004 Jan 24)149.845 E(37)199.835 E 0 Cg EP %%Page: 38 38 %%BeginPageSetup BP @@ -4498,8 +4485,7 @@ F0(List the possible completions of the te)144 580.8 Q (possible\255command\255completions \(C\255x !\))108 688.8 Q F0 (List the possible completions of the te)144 700.8 Q (xt before point, treating it as a command name.)-.15 E(GNU Bash-3.0)72 -768 Q(2003 No)147.975 E 2.5(v1)-.15 G 197.965(33)-2.5 G(8)-197.965 E 0 -Cg EP +768 Q(2004 Jan 24)149.845 E(38)199.835 E 0 Cg EP %%Page: 39 39 %%BeginPageSetup BP @@ -4591,8 +4577,8 @@ F0 1.095(command enough times to)3.595 F (he current line a shell comment.)-3.339 F .84(If a numeric ar)5.84 F (gu-)-.18 E(ment causes the comment character to be remo)144 705.6 Q -.15(ve)-.15 G(d, the line will be e).15 E -.15(xe)-.15 G -(cuted by the shell.).15 E(GNU Bash-3.0)72 768 Q(2003 No)147.975 E 2.5 -(v1)-.15 G 197.965(33)-2.5 G(9)-197.965 E 0 Cg EP +(cuted by the shell.).15 E(GNU Bash-3.0)72 768 Q(2004 Jan 24)149.845 E +(39)199.835 E 0 Cg EP %%Page: 40 40 %%BeginPageSetup BP @@ -4712,8 +4698,8 @@ F .404(gument is the name of the command whose ar)-.18 F .404 (guments are being completed, the second)-.18 F(ar)108 729.6 Q 1.994 (gument is the w)-.18 F 1.993(ord being completed, and the third ar)-.1 F 1.993(gument is the w)-.18 F 1.993(ord preceding the w)-.1 F 1.993 -(ord being)-.1 F(GNU Bash-3.0)72 768 Q(2003 No)147.975 E 2.5(v1)-.15 G -197.965(34)-2.5 G(0)-197.965 E 0 Cg EP +(ord being)-.1 F(GNU Bash-3.0)72 768 Q(2004 Jan 24)149.845 E(40)199.835 +E 0 Cg EP %%Page: 41 41 %%BeginPageSetup BP @@ -4858,8 +4844,7 @@ R 1.486(ws control o)-.25 F -.15(ve)-.15 G 3.986(rw).15 G 1.486 E(OL)-.27 E F0(and)3.735 E F2(HISTIGNORE)108 729.6 Q F0 -.25(va)2.707 G .457(riables may be set to cause the shell to sa).25 F .758 -.15(ve o) -.2 H .458(nly a subset of the commands entered.).15 F(The)5.458 E -(GNU Bash-3.0)72 768 Q(2003 No)147.975 E 2.5(v1)-.15 G 197.965(34)-2.5 G -(1)-197.965 E 0 Cg EP +(GNU Bash-3.0)72 768 Q(2004 Jan 24)149.845 E(41)199.835 E 0 Cg EP %%Page: 42 42 %%BeginPageSetup BP @@ -4982,8 +4967,7 @@ SF(^)108 667.4 Q F4(string1)-5 I F5(^)5 I F4(string2)-5 I F5(^)5 I F0 F4(string2)A F0(/')A 2.5('\()-.74 G(see)-2.5 E F1(Modi\214ers)2.5 E F0 (belo)2.5 E(w\).)-.25 E F1(!#)108 698.4 Q F0 (The entire command line typed so f)27.67 E(ar)-.1 E(.)-.55 E -(GNU Bash-3.0)72 768 Q(2003 No)147.975 E 2.5(v1)-.15 G 197.965(34)-2.5 G -(2)-197.965 E 0 Cg EP +(GNU Bash-3.0)72 768 Q(2004 Jan 24)149.845 E(42)199.835 E 0 Cg EP %%Page: 43 43 %%BeginPageSetup BP @@ -5099,7 +5083,7 @@ R -.15(xe)-.15 G 3.333(cutable. When).15 F F1(bash)3.333 E F0 .832 /Times-Roman@0 SF(.)A F0 .981(If the)5.481 F F1(sour)3.481 E(cepath)-.18 E F0 .981(option to the)3.481 F F1(shopt)3.481 E F0 -.2(bu)3.481 G .981 (iltin command is turned of).2 F .982(f, the)-.25 F(GNU Bash-3.0)72 768 -Q(2003 No)147.975 E 2.5(v1)-.15 G 197.965(34)-2.5 G(3)-197.965 E 0 Cg EP +Q(2004 Jan 24)149.845 E(43)199.835 E 0 Cg EP %%Page: 44 44 %%BeginPageSetup BP @@ -5211,8 +5195,7 @@ F2 -.1(ke)2.5 G(yseq)-.2 E F0(Remo)180 650.4 Q .3 -.15(ve a)-.15 H .3 F2 -.1(ke)2.5 G(yseq)-.2 E F0(is entered.)2.5 E(The return v)144 691.2 Q (alue is 0 unless an unrecognized option is gi)-.25 E -.15(ve)-.25 G 2.5 (no).15 G 2.5(ra)-2.5 G 2.5(ne)-2.5 G(rror occurred.)-2.5 E -(GNU Bash-3.0)72 768 Q(2003 No)147.975 E 2.5(v1)-.15 G 197.965(34)-2.5 G -(4)-197.965 E 0 Cg EP +(GNU Bash-3.0)72 768 Q(2004 Jan 24)149.845 E(44)199.835 E 0 Cg EP %%Page: 45 45 %%BeginPageSetup BP @@ -5348,8 +5331,8 @@ F2(action)2.786 E F0 2.786(][)C F1-2.786 E F2(globpat)2.786 E F0 E F2(suf-)2.787 E<8c78>108 712.8 Q F0(])A([)144 724.8 Q F1A F2 (\214lterpat)2.5 E F0 2.5(][)C F1-2.5 E F2(function)2.5 E F0 2.5 (][)C F1-2.5 E F2(command)2.5 E F0(])A F2(name)2.5 E F0([)2.5 E F2 -(name ...)A F0(])A(GNU Bash-3.0)72 768 Q(2003 No)147.975 E 2.5(v1)-.15 G -197.965(34)-2.5 G(5)-197.965 E 0 Cg EP +(name ...)A F0(])A(GNU Bash-3.0)72 768 Q(2004 Jan 24)149.845 E(45) +199.835 E 0 Cg EP %%Page: 46 46 %%BeginPageSetup BP @@ -5424,7 +5407,7 @@ Q(en from the \214le speci\214ed by the)-.1 E/F3 9/Times-Bold@0 SF (HOSTFILE)2.5 E F0(shell v)2.25 E(ariable.)-.25 E F1(job)184 696 Q F0 (Job names, if job control is acti)26.11 E -.15(ve)-.25 G 5(.M).15 G (ay also be speci\214ed as)-5 E F12.5 E F0(.)A(GNU Bash-3.0)72 768 -Q(2003 No)147.975 E 2.5(v1)-.15 G 197.965(34)-2.5 G(6)-197.965 E 0 Cg EP +Q(2004 Jan 24)149.845 E(46)199.835 E 0 Cg EP %%Page: 47 47 %%BeginPageSetup BP @@ -5531,8 +5514,7 @@ n is de\214ned are displayed as well.)144 662.4 R(The)6.308 E F1 698.4 Q F0(Each)25.3 E F2(name)2.5 E F0(is an array v)2.5 E (ariable \(see)-.25 E F1(Arrays)2.5 E F0(abo)2.5 E -.15(ve)-.15 G(\).) .15 E F1144 710.4 Q F0(Use function names only)26.97 E(.)-.65 E -(GNU Bash-3.0)72 768 Q(2003 No)147.975 E 2.5(v1)-.15 G 197.965(34)-2.5 G -(7)-197.965 E 0 Cg EP +(GNU Bash-3.0)72 768 Q(2004 Jan 24)149.845 E(47)199.835 E 0 Cg EP %%Page: 48 48 %%BeginPageSetup BP @@ -5652,7 +5634,7 @@ E F0(shell)4.002 E .009 (\\a)144 672 Q F0(alert \(bell\))28.22 E F1(\\b)144 684 Q F0(backspace) 27.66 E F1(\\c)144 696 Q F0(suppress trailing ne)28.78 E(wline)-.25 E F1 (\\e)144 708 Q F0(an escape character)28.78 E(GNU Bash-3.0)72 768 Q -(2003 No)147.975 E 2.5(v1)-.15 G 197.965(34)-2.5 G(8)-197.965 E 0 Cg EP +(2004 Jan 24)149.845 E(48)199.835 E 0 Cg EP %%Page: 49 49 %%BeginPageSetup BP @@ -5786,8 +5768,8 @@ Q F0(that is not a function.)2.68 E F1(fc)108 688.8 Q F0([)2.5 E F1 (is selected from the his-)3.658 F .881(tory list.)144 724.8 R F2 -.45 (Fi)5.881 G -.1(rs).45 G(t).1 E F0(and)4.061 E F2(last)3.471 E F0 .882 (may be speci\214ed as a string \(to locate the last command be)4.062 F -.882(ginning with)-.15 F(GNU Bash-3.0)72 768 Q(2003 No)147.975 E 2.5(v1) --.15 G 197.965(34)-2.5 G(9)-197.965 E 0 Cg EP +.882(ginning with)-.15 F(GNU Bash-3.0)72 768 Q(2004 Jan 24)149.845 E(49) +199.835 E 0 Cg EP %%Page: 50 50 %%BeginPageSetup BP @@ -5917,8 +5899,7 @@ E F0 .399(is silent, the option character found is placed in)2.899 F F4 729.6 R 1.242(gument is not found, and)-.18 F F3(getopts)3.741 E F0 1.241(is not silent, a question mark \()3.741 F F3(?).833 E F0 3.741 (\)i).833 G 3.741(sp)-3.741 G 1.241(laced in)-3.741 F(GNU Bash-3.0)72 -768 Q(2003 No)147.975 E 2.5(v1)-.15 G 197.965(35)-2.5 G(0)-197.965 E 0 -Cg EP +768 Q(2004 Jan 24)149.845 E(50)199.835 E 0 Cg EP %%Page: 51 51 %%BeginPageSetup BP @@ -6033,8 +6014,7 @@ E F0 .28 (is supplied as an ar)2.922 F .422(gument to)-.18 F F32.922 E F0 (,)A(or the history e)144 703.2 Q(xpansion supplied as an ar)-.15 E (gument to)-.18 E F32.5 E F0 -.1(fa)2.5 G(ils.).1 E(GNU Bash-3.0) -72 768 Q(2003 No)147.975 E 2.5(v1)-.15 G 197.965(35)-2.5 G(1)-197.965 E -0 Cg EP +72 768 Q(2004 Jan 24)149.845 E(51)199.835 E 0 Cg EP %%Page: 52 52 %%BeginPageSetup BP @@ -6161,8 +6141,7 @@ tring which contains three types of objects: plain characters, which ar\ e simply)144 715.2 R 1.858 (copied to standard output, character escape sequences, which are con) 144 727.2 R -.15(ve)-.4 G 1.859(rted and copied to the).15 F -(GNU Bash-3.0)72 768 Q(2003 No)147.975 E 2.5(v1)-.15 G 197.965(35)-2.5 G -(2)-197.965 E 0 Cg EP +(GNU Bash-3.0)72 768 Q(2004 Jan 24)149.845 E(52)199.835 E 0 Cg EP %%Page: 53 53 %%BeginPageSetup BP @@ -6280,8 +6259,8 @@ F2144 655.2 Q F0 .372 -.15 E(s)-.1 E F2 -.18(re)180 691.2 S(ad).18 E F0 1.395 (returns after reading)3.895 F F1(nc)3.895 E(har)-.15 E(s)-.1 E F0 1.395 (characters rather than w)3.895 F 1.394(aiting for a complete line of) --.1 F(input.)180 703.2 Q(GNU Bash-3.0)72 768 Q(2003 No)147.975 E 2.5(v1) --.15 G 197.965(35)-2.5 G(3)-197.965 E 0 Cg EP +-.1 F(input.)180 703.2 Q(GNU Bash-3.0)72 768 Q(2004 Jan 24)149.845 E(53) +199.835 E 0 Cg EP %%Page: 54 54 %%BeginPageSetup BP @@ -6405,8 +6384,7 @@ F3(or)3.196 E F7(until)3.196 E F3(keywor)3.196 E .696 .711(This option is on by default for interac-)5.711 F 1.164 (tive shells on systems that support it \(see)184 727.2 R F5 1.165 (JOB CONTROL)3.665 F F3 3.665(above\). Backgr)3.415 F(ound)-.18 E F0 -(GNU Bash-3.0)72 768 Q(2003 No)147.975 E 2.5(v1)-.15 G 197.965(35)-2.5 G -(4)-197.965 E 0 Cg EP +(GNU Bash-3.0)72 768 Q(2004 Jan 24)149.845 E(54)199.835 E 0 Cg EP %%Page: 55 55 %%BeginPageSetup BP @@ -6468,8 +6446,8 @@ F24.63 E F1 2.131(is supplied with no)4.63 F F3(option\255name) (ent options ar)-.18 F(e)-.18 E 4.412(printed. If)184 726 R F2(+o)4.412 E F1 1.912(is supplied with no)4.412 F F3(option\255name)4.412 E F1 4.411(,as)C 1.911(eries of)-4.411 F F2(set)4.411 E F1 1.911(commands to) -4.411 F F0(GNU Bash-3.0)72 768 Q(2003 No)147.975 E 2.5(v1)-.15 G 197.965 -(35)-2.5 G(5)-197.965 E 0 Cg EP +4.411 F F0(GNU Bash-3.0)72 768 Q(2004 Jan 24)149.845 E(55)199.835 E 0 Cg +EP %%Page: 56 56 %%BeginPageSetup BP @@ -6590,8 +6568,8 @@ G(f)-2.5 E F3(n)2.76 E F1(is gr)2.58 E(eater than)-.18 E F2($#)2.5 E F1 (olling optional shell behavior)-.18 F 6.522(.W)-.74 G 1.522 (ith no options, or)-7.072 F 2.531(with the)144 722.4 R F25.031 E F1 2.531(option, a list of all settable options is displayed, with an i\ -ndication of)5.031 F F0(GNU Bash-3.0)72 768 Q(2003 No)147.975 E 2.5(v1) --.15 G 197.965(35)-2.5 G(6)-197.965 E 0 Cg EP +ndication of)5.031 F F0(GNU Bash-3.0)72 768 Q(2004 Jan 24)149.845 E(56) +199.835 E 0 Cg EP %%Page: 57 57 %%BeginPageSetup BP @@ -6685,8 +6663,7 @@ F1 1.106(trap r)3.606 F 1.106(eturns a value of 2, and the)-.18 F .87 (outine \(a shell function or a shell script exe-)-.18 F(cuted by the) 220 728.4 Q F2(.)2.5 E F1(or)2.5 E F2(source)2.5 E F1 (builtins\), a call to)2.5 E F2(return)2.5 E F1(is simulated.)2.5 E F0 -(GNU Bash-3.0)72 768 Q(2003 No)147.975 E 2.5(v1)-.15 G 197.965(35)-2.5 G -(7)-197.965 E 0 Cg EP +(GNU Bash-3.0)72 768 Q(2004 Jan 24)149.845 E(57)199.835 E 0 Cg EP %%Page: 58 58 %%BeginPageSetup BP @@ -6765,8 +6742,8 @@ F3(mail\214le)4.147 E F2 1.647(has been r)4.147 F(ead')-.18 E 4.148('i) F2 1.548 (matches \214lenames in a case\255insensitive fashion when performing) 4.048 F(pathname expansion \(see)184 696 Q F1(Pathname Expansion)2.5 E -F2(above\).)2.5 E F0(GNU Bash-3.0)72 768 Q(2003 No)147.975 E 2.5(v1)-.15 -G 197.965(35)-2.5 G(8)-197.965 E 0 Cg EP +F2(above\).)2.5 E F0(GNU Bash-3.0)72 768 Q(2004 Jan 24)149.845 E(58) +199.835 E 0 Cg EP %%Page: 59 59 %%BeginPageSetup BP @@ -6852,8 +6829,7 @@ F2 1.401(the expr)3.651 F 1.401(ession is tr)-.18 F 1.401 1.356(the \214rst ar)3.855 F 1.356 (gument is not a valid unary conditional operator)-.18 F 3.856(,t)-.74 G (he)-3.856 E(expr)180 712.8 Q(ession is false.)-.18 E F0(GNU Bash-3.0)72 -768 Q(2003 No)147.975 E 2.5(v1)-.15 G 197.965(35)-2.5 G(9)-197.965 E 0 -Cg EP +768 Q(2004 Jan 24)149.845 E(59)199.835 E 0 Cg EP %%Page: 60 60 %%BeginPageSetup BP @@ -6994,8 +6970,8 @@ E F1 2.516(,e)C .016(ven if)-2.516 F F7 .016(type -t)2.516 F(name)144 .411(option is used,)2.911 F F4(type)2.911 E F1 .411(prints all)2.911 F .164(of the places that contain an executable named)144 722.4 R F5(name) 2.664 E F1 5.164(.T).35 G .164(his includes aliases and functions,) --5.164 F F0(GNU Bash-3.0)72 768 Q(2003 No)147.975 E 2.5(v1)-.15 G -197.965(36)-2.5 G(0)-197.965 E 0 Cg EP +-5.164 F F0(GNU Bash-3.0)72 768 Q(2004 Jan 24)149.845 E(60)199.835 E 0 +Cg EP %%Page: 61 61 %%BeginPageSetup BP @@ -7116,8 +7092,7 @@ E F5(,)A F4(HISTCMD)3.725 E F5(,)A F4(FUNCNAME)144 708 Q F5(,)A F4 .553(operties, even if)-.18 F(they ar)144 720 Q 2.5(es)-.18 G (ubsequently r)-2.5 E 2.5(eset. The)-.18 F(exit status is tr)2.5 E (ue unless a)-.08 E F3(name)2.76 E F1(is r)2.85 E(eadonly)-.18 E(.)-1.11 -E F0(GNU Bash-3.0)72 768 Q(2003 No)147.975 E 2.5(v1)-.15 G 197.965(36) --2.5 G(1)-197.965 E 0 Cg EP +E F0(GNU Bash-3.0)72 768 Q(2004 Jan 24)149.845 E(61)199.835 E 0 Cg EP %%Page: 62 62 %%BeginPageSetup BP @@ -7201,7 +7176,7 @@ F2 2.5(,B)C(rian Fox and Chet Ramey)-2.5 E F3(Portable Operating System\ (The personal initialization \214le, executed for login shells)144 686.4 Q F3(~/.bashr)109.666 698.4 Q(c)-.18 E F2(The individual per)144 710.4 Q (-interactive-shell startup \214le)-.18 E F0(GNU Bash-3.0)72 768 Q -(2003 No)147.975 E 2.5(v1)-.15 G 197.965(36)-2.5 G(2)-197.965 E 0 Cg EP +(2004 Jan 24)149.845 E(62)199.835 E 0 Cg EP %%Page: 63 63 %%BeginPageSetup BP @@ -7264,8 +7239,7 @@ F1(bashbug)108.13 393.6 Q F2 1.316(inserts the \214rst thr)4.296 F 1.316 (This will delay err)108 607.2 Q(or r)-.18 E (eporting until some time after the command is enter)-.18 E(ed.)-.18 E (Array variables may not \(yet\) be exported.)108 624 Q F0(GNU Bash-3.0) -72 768 Q(2003 No)147.975 E 2.5(v1)-.15 G 197.965(36)-2.5 G(3)-197.965 E -0 Cg EP +72 768 Q(2004 Jan 24)149.845 E(63)199.835 E 0 Cg EP %%Trailer end %%EOF diff --git a/doc/bashref.fns b/doc/bashref.fns index 15a957a23..3fb6cb68f 100644 --- a/doc/bashref.fns +++ b/doc/bashref.fns @@ -1,115 +1,4 @@ \initial {A} \entry {\code {abort (C-g)}}{101} \entry {\code {accept-line (Newline or Return)}}{95} -\entry {\code {alias-expand-line ()}}{102} -\initial {B} -\entry {\code {backward-char (C-b)}}{95} -\entry {\code {backward-delete-char (Rubout)}}{97} -\entry {\code {backward-kill-line (C-x Rubout)}}{98} -\entry {\code {backward-kill-word (M-\key {DEL})}}{98} -\entry {\code {backward-word (M-b)}}{95} -\entry {\code {beginning-of-history (M-<)}}{96} -\entry {\code {beginning-of-line (C-a)}}{95} -\initial {C} -\entry {\code {call-last-kbd-macro (C-x e)}}{101} -\entry {\code {capitalize-word (M-c)}}{97} -\entry {\code {character-search (C-])}}{101} -\entry {\code {character-search-backward (M-C-])}}{101} -\entry {\code {clear-screen (C-l)}}{95} -\entry {\code {complete (\key {TAB})}}{99} -\entry {\code {complete-command (M-!)}}{100} -\entry {\code {complete-filename (M-/)}}{99} -\entry {\code {complete-hostname (M-@)}}{100} -\entry {\code {complete-into-braces (M-{\tt \char 123})}}{100} -\entry {\code {complete-username (M-~)}}{100} -\entry {\code {complete-variable (M-$)}}{100} -\entry {\code {copy-backward-word ()}}{98} -\entry {\code {copy-forward-word ()}}{98} -\entry {\code {copy-region-as-kill ()}}{98} -\initial {D} -\entry {\code {delete-char (C-d)}}{97} -\entry {\code {delete-char-or-list ()}}{99} -\entry {\code {delete-horizontal-space ()}}{98} -\entry {\code {digit-argument (\kbd {M-0}, \kbd {M-1}, \dots {} \kbd {M--})}}{99} -\entry {\code {display-shell-version (C-x C-v)}}{102} -\entry {\code {do-uppercase-version (M-a, M-b, M-\var {x}, \dots {})}}{101} -\entry {\code {downcase-word (M-l)}}{97} -\entry {\code {dump-functions ()}}{102} -\entry {\code {dump-macros ()}}{102} -\entry {\code {dump-variables ()}}{102} -\entry {\code {dynamic-complete-history (M-\key {TAB})}}{100} -\initial {E} -\entry {\code {edit-and-execute-command (C-xC-e)}}{103} -\entry {\code {end-kbd-macro (C-x ))}}{100} -\entry {\code {end-of-history (M->)}}{96} -\entry {\code {end-of-line (C-e)}}{95} -\entry {\code {exchange-point-and-mark (C-x C-x)}}{101} -\initial {F} -\entry {\code {forward-backward-delete-char ()}}{97} -\entry {\code {forward-char (C-f)}}{95} -\entry {\code {forward-search-history (C-s)}}{96} -\entry {\code {forward-word (M-f)}}{95} -\initial {G} -\entry {\code {glob-complete-word (M-g)}}{102} -\entry {\code {glob-expand-word (C-x *)}}{102} -\entry {\code {glob-list-expansions (C-x g)}}{102} -\initial {H} -\entry {\code {history-and-alias-expand-line ()}}{103} -\entry {\code {history-expand-line (M-^)}}{102} -\entry {\code {history-search-backward ()}}{96} -\entry {\code {history-search-forward ()}}{96} -\initial {I} -\entry {\code {insert-comment (M-#)}}{101} -\entry {\code {insert-completions (M-*)}}{99} -\entry {\code {insert-last-argument (M-. or M-_)}}{103} -\initial {K} -\entry {\code {kill-line (C-k)}}{98} -\entry {\code {kill-region ()}}{98} -\entry {\code {kill-whole-line ()}}{98} -\entry {\code {kill-word (M-d)}}{98} -\initial {M} -\entry {\code {magic-space ()}}{102} -\entry {\code {menu-complete ()}}{99} -\initial {N} -\entry {\code {next-history (C-n)}}{96} -\entry {\code {non-incremental-forward-search-history (M-n)}}{96} -\entry {\code {non-incremental-reverse-search-history (M-p)}}{96} -\initial {O} -\entry {\code {operate-and-get-next (C-o)}}{103} -\entry {\code {overwrite-mode ()}}{97} -\initial {P} -\entry {\code {possible-command-completions (C-x !)}}{100} -\entry {\code {possible-completions (M-?)}}{99} -\entry {\code {possible-filename-completions (C-x /)}}{100} -\entry {\code {possible-hostname-completions (C-x @)}}{100} -\entry {\code {possible-username-completions (C-x ~)}}{100} -\entry {\code {possible-variable-completions (C-x $)}}{100} -\entry {\code {prefix-meta (\key {ESC})}}{101} -\entry {\code {previous-history (C-p)}}{96} -\initial {Q} -\entry {\code {quoted-insert (C-q or C-v)}}{97} -\initial {R} -\entry {\code {re-read-init-file (C-x C-r)}}{101} -\entry {\code {redraw-current-line ()}}{95} -\entry {\code {reverse-search-history (C-r)}}{96} -\entry {\code {revert-line (M-r)}}{101} -\initial {S} -\entry {\code {self-insert (a, b, A, 1, !, \dots {})}}{97} -\entry {\code {set-mark (C-@)}}{101} -\entry {\code {shell-expand-line (M-C-e)}}{102} -\entry {\code {start-kbd-macro (C-x ()}}{100} -\initial {T} -\entry {\code {tilde-expand (M-&)}}{101} -\entry {\code {transpose-chars (C-t)}}{97} -\entry {\code {transpose-words (M-t)}}{97} -\initial {U} -\entry {\code {undo (C-_ or C-x C-u)}}{101} -\entry {\code {universal-argument ()}}{99} -\entry {\code {unix-line-discard (C-u)}}{98} -\entry {\code {unix-word-rubout (C-w)}}{98} -\entry {\code {upcase-word (M-u)}}{97} -\initial {Y} -\entry {\code {yank (C-y)}}{98} -\entry {\code {yank-last-arg (M-. or M-_)}}{96} -\entry {\code {yank-nth-arg (M-C-y)}}{96} -\entry {\code {yank-pop (M-y)}}{98} +\entry {\code {alias-expand-line ()}}{102 \ No newline at end of file diff --git a/doc/bashref.info b/doc/bashref.info index 5bf45bcc4..4a96a6105 100644 --- a/doc/bashref.info +++ b/doc/bashref.info @@ -1,11 +1,11 @@ -This is bashref.info, produced by makeinfo version 4.5 from -/usr/homes/chet/src/bash/src/doc/bashref.texi. +This is bashref.info, produced by makeinfo version 4.2 from +/usr/src/local/bash/bash-20040121/doc/bashref.texi. This text is a brief description of the features that are present in -the Bash shell (version 3.0-alpha, 13 November 2003). +the Bash shell (version 3.0-beta1, 24 January 2004). - This is Edition 3.0, last updated 13 November 2003, of `The GNU Bash -Reference Manual', for `Bash', Version 3.0-alpha. + This is Edition 3.0, last updated 24 January 2004, of `The GNU Bash +Reference Manual', for `Bash', Version 3.0-beta1. Copyright (C) 1988-2003 Free Software Foundation, Inc. @@ -37,10 +37,10 @@ Bash Features ************* This text is a brief description of the features that are present in -the Bash shell (version 3.0-alpha, 13 November 2003).. +the Bash shell (version 3.0-beta1, 24 January 2004).. - This is Edition 3.0, last updated 13 November 2003, of `The GNU Bash -Reference Manual', for `Bash', Version 3.0-alpha. + This is Edition 3.0, last updated 24 January 2004, of `The GNU Bash +Reference Manual', for `Bash', Version 3.0-beta1. Bash contains features that appear in other popular shells, and some features that only appear in Bash. Some of the shells that Bash has @@ -731,7 +731,6 @@ syntax, it may be replaced with one or more newlines. command in LIST that is executed, or false if any of the expressions is invalid. - The `break' and `continue' builtins (*note Bourne Shell Builtins::) may be used to control loop execution. @@ -896,7 +895,6 @@ Conditional Constructs value of EXPRESSION1 is sufficient to determine the return value of the entire conditional expression. -  File: bashref.info, Node: Command Grouping, Prev: Conditional Constructs, Up: Compound Commands @@ -1301,7 +1299,6 @@ the expanded value. `~-N' The string that would be displayed by `dirs -N' -  File: bashref.info, Node: Shell Parameter Expansion, Next: Command Substitution, Prev: Tilde Expansion, Up: Shell Expansions @@ -1448,7 +1445,6 @@ if the colon is omitted, the operator tests only for existence. member of the array in turn, and the expansion is the resultant list. -  File: bashref.info, Node: Command Substitution, Next: Arithmetic Expansion, Prev: Shell Parameter Expansion, Up: Shell Expansions @@ -1756,7 +1752,6 @@ redirections, as described in the following table: integer port number or service name, Bash attempts to open a UDP connection to the corresponding socket. - A failure to open or create a file causes the redirection to fail. Redirecting Input @@ -2715,7 +2710,6 @@ POSIX 1003.2 standard. `-x KEYSEQ:SHELL-COMMAND' Cause SHELL-COMMAND to be executed whenever KEYSEQ is entered. - The return status is zero unless an invalid option is supplied or an error occurs. @@ -3011,7 +3005,6 @@ POSIX 1003.2 standard. `-u FD' Read input from file descriptor FD. - `shopt' shopt [-pqsu] [-o] [OPTNAME ...] Toggle the values of variables controlling optional shell behavior. @@ -3221,7 +3214,6 @@ POSIX 1003.2 standard. If set, the `echo' builtin expands backslash-escape sequences by default. - The return status when listing options is zero if all OPTNAMES are enabled, non-zero otherwise. When setting or unsetting options, the return status is zero unless an OPTNAME is not a valid shell @@ -3315,7 +3307,6 @@ POSIX 1003.2 standard. `-v' The maximum amount of virtual memory available to the process. - If LIMIT is given, it is the new value of the specified resource; the special LIMIT values `hard', `soft', and `unlimited' stand for the current hard limit, the current soft limit, and no limit, @@ -3336,7 +3327,6 @@ POSIX 1003.2 standard. Remove each NAME from the list of aliases. If `-a' is supplied, all aliases are removed. Aliases are described in *Note Aliases::. -  File: bashref.info, Node: The Set Builtin, Next: Special Builtins, Prev: Bash Builtins, Up: Shell Builtin Commands @@ -3683,7 +3673,6 @@ shell. In some cases, Bash assigns a default value to the variable. `PS2' The secondary prompt string. The default value is `> '. -  File: bashref.info, Node: Bash Variables, Prev: Bourne Shell Variables, Up: Shell Variables @@ -3776,7 +3765,6 @@ Variables::). `BASH_VERSINFO[5]' The value of `MACHTYPE'. - `BASH_VERSION' The version number of the current instance of Bash. @@ -4157,7 +4145,6 @@ Variables::). The numeric real user id of the current user. This variable is readonly. -  File: bashref.info, Node: Bash Features, Next: Job Control, Prev: Shell Variables, Up: Top @@ -4255,7 +4242,6 @@ the single-character options to be recognized. Show version information for this instance of Bash on the standard output and exit successfully. - There are several single-character options that may be supplied at invocation which are not available with the `set' builtin. @@ -4307,7 +4293,6 @@ invocation which are not available with the `set' builtin. processing. Any arguments after the `--' are treated as filenames and arguments. - A _login_ shell is one whose first character of argument zero is `-', or one invoked with the `--login' option. @@ -4699,7 +4684,6 @@ checked. If the FILE argument to one of the primaries is one of greater than or equal to ARG2, respectively. ARG1 and ARG2 may be positive or negative integers. -  File: bashref.info, Node: Shell Arithmetic, Next: Aliases, Prev: Bash Conditional Expressions, Up: Bash Features @@ -5016,7 +5000,6 @@ Directory Stack Builtins Makes the current working directory be the top of the stack, and then executes the equivalent of ``cd' DIR'. `cd's to DIR. -  File: bashref.info, Node: Printing a Prompt, Next: The Restricted Shell, Prev: The Directory Stack, Up: Bash Features @@ -5089,10 +5072,11 @@ which can appear in the prompt variables: The release of Bash, version + patchlevel (e.g., 2.00.0) `\w' - The current working directory. + The current working directory, with `$HOME' abbreviated with a + tilde. `\W' - The basename of `$PWD'. + The basename of `$PWD', with `$HOME' abbreviated with a tilde. `\!' The history number of this command. @@ -5532,7 +5516,6 @@ Job Control Builtins signal. The `-f' option means to suspend even if the shell is a login shell. - When job control is not active, the `kill' and `wait' builtins do not accept JOBSPEC arguments. They must be supplied process IDs. @@ -5559,7 +5542,6 @@ Job Control Variables a prefix of a stopped job's name; this provides functionality analogous to the `%' job ID. -  File: bashref.info, Node: Command Line Editing, Next: Installing Bash, Prev: Using History Interactively, Up: Top @@ -5766,7 +5748,6 @@ available to be yanked back later, when you are typing another line. Kill from the cursor to the previous whitespace. This is different than `M-' because the word boundaries differ. - Here is how to "yank" the text back into the line. Yanking means to copy the most-recently-killed text from the kill buffer. @@ -6044,7 +6025,6 @@ Variable Settings appended to the filename when listing possible completions. The default is `off'. - Key Bindings The syntax for controlling key bindings in the init file is simple. First you need to find the name of the command that you @@ -6099,7 +6079,6 @@ Key Bindings ` <[> <1> <1> <~>' is bound to insert the text `Function Key 1'. - The following GNU Emacs style escape sequences are available when specifying key sequences: @@ -6165,7 +6144,6 @@ Key Bindings the line: "\C-x\\": "\\" -  File: bashref.info, Node: Conditional Init Constructs, Next: Sample Init File, Prev: Readline Init File Syntax, Up: Readline Init File @@ -6397,7 +6375,6 @@ Commands For Moving `redraw-current-line ()' Refresh the current line. By default, this is unbound. -  File: bashref.info, Node: Commands For History, Next: Commands For Text, Prev: Commands For Moving, Up: Bindable Readline Commands @@ -6468,7 +6445,6 @@ Commands For Manipulating The History through the history list, inserting the last argument of each line in turn. -  File: bashref.info, Node: Commands For Text, Next: Commands For Killing, Prev: Commands For History, Up: Bindable Readline Commands @@ -6533,7 +6509,6 @@ Commands For Changing Text By default, this command is unbound. -  File: bashref.info, Node: Commands For Killing, Next: Numeric Arguments, Prev: Commands For Text, Up: Bindable Readline Commands @@ -6709,7 +6684,6 @@ Letting Readline Type For You completions enclosed within braces so the list is available to the shell (*note Brace Expansion::). -  File: bashref.info, Node: Keyboard Macros, Next: Miscellaneous Commands, Prev: Commands For Completion, Up: Bindable Readline Commands @@ -6727,7 +6701,6 @@ Keyboard Macros Re-execute the last keyboard macro defined, by making the characters in the macro appear as if typed at the keyboard. -  File: bashref.info, Node: Miscellaneous Commands, Prev: Keyboard Macros, Up: Bindable Readline Commands @@ -6862,7 +6835,6 @@ Some Miscellaneous Commands result as shell commands. Bash attempts to invoke `$FCEDIT', `$EDITOR', and `emacs' as the editor, in that order. -  File: bashref.info, Node: Readline vi Mode, Next: Programmable Completion, Prev: Bindable Readline Commands, Up: Command Line Editing @@ -7195,7 +7167,6 @@ completion facilities. for a NAME for which no specification exists, or an error occurs adding a completion specification. -  File: bashref.info, Node: Using History Interactively, Next: Command Line Editing, Prev: Job Control, Up: Top @@ -7354,12 +7325,10 @@ and history file. The ARGs are added to the end of the history list as a single entry. - When any of the `-w', `-r', `-a', or `-n' options is used, if FILENAME is given, then it is used as the history file. If not, then the value of the `HISTFILE' variable is used. -  File: bashref.info, Node: History Interaction, Prev: Bash History Builtins, Up: Using History Interactively @@ -7449,7 +7418,6 @@ history list. `!#' The entire command line typed so far. -  File: bashref.info, Node: Word Designators, Next: Modifiers, Prev: Event Designators, Up: History Interaction @@ -7508,7 +7476,6 @@ line separated by single spaces. `X-' Abbreviates `X-$' like `X*', but omits the last word. - If a word designator is supplied without an event specification, the previous command is used as the event. @@ -7563,7 +7530,6 @@ more of the following modifiers, each preceded by a `:'. `G' Apply the following `s' modifier once to each word in the event. -  File: bashref.info, Node: Installing Bash, Next: Reporting Bugs, Prev: Command Line Editing, Up: Top @@ -7997,7 +7963,6 @@ does not provide the necessary support. Specification, version 2. *Note Bash Builtins::, for a description of the escape sequences that `echo' recognizes. - The file `config-top.h' contains C Preprocessor `#define' statements for options which are not settable from `configure'. Some of these are not meant to be changed; beware of the consequences if you do. Read @@ -9249,129 +9214,129 @@ Concept Index  Tag Table: -Node: Top1373 -Node: Introduction3532 -Node: What is Bash?3757 -Node: What is a shell?4845 -Node: Definitions7381 -Node: Basic Shell Features10121 -Node: Shell Syntax11339 -Node: Shell Operation12363 -Node: Quoting13648 -Node: Escape Character14910 -Node: Single Quotes15382 -Node: Double Quotes15717 -Node: ANSI-C Quoting16730 -Node: Locale Translation17673 -Node: Comments18556 -Node: Shell Commands19161 -Node: Simple Commands19922 -Node: Pipelines20543 -Node: Lists22409 -Node: Compound Commands24031 -Node: Looping Constructs24803 +Node: Top1376 +Node: Introduction3533 +Node: What is Bash?3758 +Node: What is a shell?4846 +Node: Definitions7382 +Node: Basic Shell Features10122 +Node: Shell Syntax11340 +Node: Shell Operation12364 +Node: Quoting13649 +Node: Escape Character14911 +Node: Single Quotes15383 +Node: Double Quotes15718 +Node: ANSI-C Quoting16731 +Node: Locale Translation17674 +Node: Comments18557 +Node: Shell Commands19162 +Node: Simple Commands19923 +Node: Pipelines20544 +Node: Lists22410 +Node: Compound Commands24032 +Node: Looping Constructs24804 Node: Conditional Constructs27237 -Node: Command Grouping34290 -Node: Shell Functions35726 -Node: Shell Parameters39991 -Node: Positional Parameters41562 -Node: Special Parameters42453 -Node: Shell Expansions45111 -Node: Brace Expansion47031 -Node: Tilde Expansion49347 -Node: Shell Parameter Expansion51679 -Node: Command Substitution58933 -Node: Arithmetic Expansion60255 -Node: Process Substitution61096 -Node: Word Splitting62133 -Node: Filename Expansion63585 -Node: Pattern Matching65709 -Node: Quote Removal69030 -Node: Redirections69316 -Node: Executing Commands76791 -Node: Simple Command Expansion77458 -Node: Command Search and Execution79379 -Node: Command Execution Environment81376 -Node: Environment84138 -Node: Exit Status85789 -Node: Signals86984 -Node: Shell Scripts88939 -Node: Shell Builtin Commands91450 -Node: Bourne Shell Builtins92880 -Node: Bash Builtins109763 -Node: The Set Builtin137885 -Node: Special Builtins146103 -Node: Shell Variables147075 -Node: Bourne Shell Variables147511 -Node: Bash Variables149488 -Node: Bash Features168993 -Node: Invoking Bash169875 -Node: Bash Startup Files175686 -Node: Interactive Shells180556 -Node: What is an Interactive Shell?180958 -Node: Is this Shell Interactive?181593 -Node: Interactive Shell Behavior182399 -Node: Bash Conditional Expressions185666 -Node: Shell Arithmetic189086 -Node: Aliases191826 -Node: Arrays194329 -Node: The Directory Stack197349 -Node: Directory Stack Builtins198055 -Node: Printing a Prompt200934 -Node: The Restricted Shell203560 -Node: Bash POSIX Mode205385 -Node: Job Control212031 -Node: Job Control Basics212497 -Node: Job Control Builtins216777 -Node: Job Control Variables221073 -Node: Command Line Editing222223 -Node: Introduction and Notation223221 -Node: Readline Interaction224838 -Node: Readline Bare Essentials226024 -Node: Readline Movement Commands227804 -Node: Readline Killing Commands228760 -Node: Readline Arguments230669 -Node: Searching231704 -Node: Readline Init File233881 -Node: Readline Init File Syntax234935 -Node: Conditional Init Constructs246579 -Node: Sample Init File249103 -Node: Bindable Readline Commands252286 -Node: Commands For Moving253485 -Node: Commands For History254334 -Node: Commands For Text257223 -Node: Commands For Killing259884 -Node: Numeric Arguments261834 -Node: Commands For Completion262961 -Node: Keyboard Macros266542 -Node: Miscellaneous Commands267101 -Node: Readline vi Mode272400 -Node: Programmable Completion273309 -Node: Programmable Completion Builtins279116 -Node: Using History Interactively286478 -Node: Bash History Facilities287157 -Node: Bash History Builtins289847 -Node: History Interaction293699 -Node: Event Designators296250 -Node: Word Designators297254 -Node: Modifiers298884 -Node: Installing Bash300281 -Node: Basic Installation301415 -Node: Compilers and Options304100 -Node: Compiling For Multiple Architectures304834 -Node: Installation Names306491 -Node: Specifying the System Type307302 -Node: Sharing Defaults308011 -Node: Operation Controls308676 -Node: Optional Features309627 -Node: Reporting Bugs317899 -Node: Major Differences From The Bourne Shell319074 -Node: Copying This Manual334822 -Node: GNU Free Documentation License335076 -Node: Builtin Index357469 -Node: Reserved Word Index361096 -Node: Variable Index362572 -Node: Function Index369565 -Node: Concept Index374115 +Node: Command Grouping34289 +Node: Shell Functions35725 +Node: Shell Parameters39990 +Node: Positional Parameters41561 +Node: Special Parameters42452 +Node: Shell Expansions45110 +Node: Brace Expansion47030 +Node: Tilde Expansion49346 +Node: Shell Parameter Expansion51677 +Node: Command Substitution58930 +Node: Arithmetic Expansion60252 +Node: Process Substitution61093 +Node: Word Splitting62130 +Node: Filename Expansion63582 +Node: Pattern Matching65706 +Node: Quote Removal69027 +Node: Redirections69313 +Node: Executing Commands76787 +Node: Simple Command Expansion77454 +Node: Command Search and Execution79375 +Node: Command Execution Environment81372 +Node: Environment84134 +Node: Exit Status85785 +Node: Signals86980 +Node: Shell Scripts88935 +Node: Shell Builtin Commands91446 +Node: Bourne Shell Builtins92876 +Node: Bash Builtins109759 +Node: The Set Builtin137876 +Node: Special Builtins146094 +Node: Shell Variables147066 +Node: Bourne Shell Variables147502 +Node: Bash Variables149478 +Node: Bash Features168981 +Node: Invoking Bash169863 +Node: Bash Startup Files175672 +Node: Interactive Shells180542 +Node: What is an Interactive Shell?180944 +Node: Is this Shell Interactive?181579 +Node: Interactive Shell Behavior182385 +Node: Bash Conditional Expressions185652 +Node: Shell Arithmetic189071 +Node: Aliases191811 +Node: Arrays194314 +Node: The Directory Stack197334 +Node: Directory Stack Builtins198040 +Node: Printing a Prompt200918 +Node: The Restricted Shell203627 +Node: Bash POSIX Mode205452 +Node: Job Control212098 +Node: Job Control Basics212564 +Node: Job Control Builtins216844 +Node: Job Control Variables221139 +Node: Command Line Editing222288 +Node: Introduction and Notation223286 +Node: Readline Interaction224903 +Node: Readline Bare Essentials226089 +Node: Readline Movement Commands227869 +Node: Readline Killing Commands228825 +Node: Readline Arguments230733 +Node: Searching231768 +Node: Readline Init File233945 +Node: Readline Init File Syntax234999 +Node: Conditional Init Constructs246640 +Node: Sample Init File249164 +Node: Bindable Readline Commands252347 +Node: Commands For Moving253546 +Node: Commands For History254394 +Node: Commands For Text257282 +Node: Commands For Killing259942 +Node: Numeric Arguments261892 +Node: Commands For Completion263019 +Node: Keyboard Macros266599 +Node: Miscellaneous Commands267157 +Node: Readline vi Mode272455 +Node: Programmable Completion273364 +Node: Programmable Completion Builtins279171 +Node: Using History Interactively286532 +Node: Bash History Facilities287211 +Node: Bash History Builtins289901 +Node: History Interaction293751 +Node: Event Designators296302 +Node: Word Designators297305 +Node: Modifiers298934 +Node: Installing Bash300330 +Node: Basic Installation301464 +Node: Compilers and Options304149 +Node: Compiling For Multiple Architectures304883 +Node: Installation Names306540 +Node: Specifying the System Type307351 +Node: Sharing Defaults308060 +Node: Operation Controls308725 +Node: Optional Features309676 +Node: Reporting Bugs317947 +Node: Major Differences From The Bourne Shell319122 +Node: Copying This Manual334870 +Node: GNU Free Documentation License335124 +Node: Builtin Index357517 +Node: Reserved Word Index361144 +Node: Variable Index362620 +Node: Function Index369613 +Node: Concept Index374163  End Tag Table diff --git a/doc/bashref.texi b/doc/bashref.texi index 98e6f2f63..74974a57f 100644 --- a/doc/bashref.texi +++ b/doc/bashref.texi @@ -5716,9 +5716,9 @@ 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. +The current working directory, with @env{$HOME} abbreviated with a tilde. @item \W -The basename of @env{$PWD}. +The basename of @env{$PWD}, with @env{$HOME} abbreviated with a tilde. @item \! The history number of this command. @item \# diff --git a/doc/bashref.texi~ b/doc/bashref.texi~ new file mode 100644 index 000000000..511887a40 --- /dev/null +++ b/doc/bashref.texi~ @@ -0,0 +1,7255 @@ +\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-2003 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.1 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 have freedom to copy and modify +this GNU Manual, like GNU software. Copies published by the Free +Software Foundation raise funds for GNU development.'' +@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:: A chapter describing what job control is + and how Bash allows you to use it. + +* Using History Interactively:: Chapter dealing with history expansion + rules. + +* Command Line Editing:: Chapter describing the command line + editing features. + +* 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. + +* Copying This Manual:: Copying this manual. + +* 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 +@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 specification (@sc{ieee} Working Group 1003.2). +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 utilitites 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 concerned with @sc{posix} 1003.2, the Shell and Tools 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{word} that performs a control function. It is a @code{newline} +or one of the following: +@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. + +@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 identifer 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} 1003.2 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 @code{token} that is not an @code{operator}. +@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, 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{`}, and @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. +When command history is being used, the double quote may not be used to +quote the history expansion character. + +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 +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 \@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 \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{Bash Builtins}), +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. +@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 +@samp{|}. + +@rwindex time +@rwindex ! +@cindex command timing +The format for a pipeline is +@example +[@code{time} [@code{-p}]] [@code{!}] @var{command1} [@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. + +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}. +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. + +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. + +The control operators @samp{&&} and @samp{||} +denote @sc{and} lists and @sc{or} lists, respectively. +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. + +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{list} +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}. +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{;;}. +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{;;}. 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 +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 specifed. +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 the @samp{==} and @samp{!=} operators are used, the string to the +right of the operator is considered a pattern and matched according +to the rules described below in @ref{Pattern Matching}. +The return value is 0 if the string matches or does not match +the pattern, respectively, and 1 otherwise. +Any part of the pattern may be quoted to force it 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{nocaseglob} +(see the description of @code{shopt} in @ref{Bash Builtins}) +is enabled, the match is performed without regard to the case +of alphabetic characters. +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. 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 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 +[ @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. + +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 by whitespace. +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. +Positional 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 the exception that the @env{DEBUG} trap +below) is 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 @code{DEBUG} trap). +@xref{Bourne Shell Builtins}, for the description of the +@code{trap} builtin. + +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. 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. + +@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{}}. +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 filename of the shell or shell +script being executed as passed in the argument list. +Subsequently, expands to the last argument to the previous command, +after expansion. +Also set to the full pathname of 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 sequnce 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}@}}, +where @var{x} and @var{y} are either integers or single characters. +When integers are supplied, the expression expands to each number between +@var{x} and @var{y}, inclusive. +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. + +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 @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, 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 existence and that the 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. + +@var{length} must evaluate to a number greater than or equal to zero. +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{parameter} is @samp{@@}, the result is @var{length} positional +parameters beginning at @var{offset}. +If @var{parameter} is an array name indexed by @samp{@@} or @samp{*}, +the result is the @var{length} +members of the array beginning with @code{$@{@var{parameter}[@var{offset}]@}}. +Substring indexing is zero-based unless the positional parameters +are used, in which case the indexing starts at 1. + +@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. + +@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}@} +@itemx $@{@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}. +In the first form, only the first match is replaced. +The second form causes all matches of @var{pattern} to be +replaced with @var{string}. +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. + +@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{}, +the default, then any sequence of @env{IFS} +characters 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. 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 generation, 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{Bash Builtins}, +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. +@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 value of the @env{LC_COLLATE} shell variable, +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}. + +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} 1003.2 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 exactly 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. + +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 duplicated as 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. + +@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 +Bash 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} with this construct. + +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 + +@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 and supplied 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 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} + +@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. + +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 + +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{Bash Builtins}), 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. +* The Set Builtin:: This builtin is so overloaded it + deserves its own section. +* Special Builtins:: Builtin commands classified specially by + POSIX.2. +@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 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. + +@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} 1003.2 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] [@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 @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 arg 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 @code{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 +Remember the full pathnames of 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}. +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 [-apf] [@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 array variable. +If no @var{name} arguments are given, or if the @option{-p} +option is supplied, a list of all readonly names is printed. +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}+1. +Parameters represented by the numbers @code{$#} to @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}. + +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. + +@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 +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. +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. +The @samp{-a} and @samp{-o} operators are considered binary operators +in this case. + +@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 + +@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 or +equal to @samp{-}, all specified signals are reset to the values +they 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 such as @code{SIGINT} (with +or without the @code{SIG} prefix) or a signal number. +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{extglob} option to the +@code{shopt} builtin (@pxref{Bash Builtins}) for details of its +effect on the @code{DEBUG} trap. +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 in an @code{if} statement, +part of 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. +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. + +Signals ignored upon entry to the shell cannot be trapped or reset. +Trapped signals are reset to their original values in a child +process when it 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 no options are supplied, or the @option{-v} option is given, each +@var{name} refers to a shell variable. +If the @option{-f} option is given, the @var{name}s refer to shell +functions, and the function definition is removed. +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} 1003.2 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 +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. + +@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 [-afFirtx] [-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, additional options are ignored. +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{Bash Builtins}), the source file name and line number where +the function is defined are displayed as well. +@option{-F} implies @option{-f}. +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 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 -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} trap from the calling shell. +The trace attribute has no special meaning for variables. + +@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. +When used in a function, @code{declare} makes each @var{name} local, +as with the @code{local} command. 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 always 0. +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} interprets the following escape sequences: +@table @code +@item \a +alert (bell) +@item \b +backspace +@item \c +suppress trailing newline +@item \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 \@var{nnn} +the eight-bit character whose value is the octal value @var{nnn} +(one 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) +@end table + +@item enable +@btindex enable +@example +enable [-n] [-p] [-f @var{filename}] [-ads] [@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 [-s] [@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. +The @option{-s} option restricts the information displayed to a short +usage synopsis. +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 printf +@btindex printf +@example +@code{printf} @var{format} [@var{arguments}] +@end example +Write the formatted @var{arguments} to the standard output under the +control of the @var{format}. +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, @samp{%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), +and @samp{%q} causes @code{printf} to output the +corresponding @var{argument} in a format that can be reused as shell input. + +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}] [-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, 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. + +@item -n @var{nchars} +@code{read} returns after reading @var{nchars} characters rather than +waiting for a complete line of input. + +@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. +This option has no effect if @code{read} is not reading input from the +terminal or a pipe. + +@item -u @var{fd} +Read input from file descriptor @var{fd}. + +@end table + +@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 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 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 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. +@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 pathname 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 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 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 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. + +@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 any of the @var{names} are found, non-zero +if none are 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 [-acdflmnpstuvSH] [@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 -c +The maximum size of core files created. + +@item -d +The maximum size of a process's data segment. + +@item -f +The maximum size of files created by the shell. + +@item -l +The maximum size that may be locked into memory. + +@item -m +The maximum resident set size. + +@item -n +The maximum number of open file descriptors. + +@item -p +The pipe buffer size. + +@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 process. + +@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. +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 The Set Builtin +@section The Set Builtin + +This builtin is so complicated that it deserves its own section. + +@table @code +@item set +@btindex set +@example +set [--abefhkmnptuvxBCHP] [-o @var{option}] [@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. + +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 simple command (@pxref{Simple Commands}) exits +with a non-zero status, unless 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 a @code{&&} or @code{||} list, or if the command's return +status is being inverted using @code{!}. +A trap on @code{ERR}, if set, is executed before the shell exits. + +@item -f +Disable file name generation (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}). + +@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}). + +@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} 1003.2 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. + +@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} variable, if it appears in the environment, +is 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 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, \fBfor\fP commands, \fBcase\fP +commands, \fBselect\fP commands, and arithmetic \fBfor\fP 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} is inherited by shell functions, command +substitutions, and commands executed in a subshell environment. +The @code{DEBUG} trap is 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 Special Builtins +@section Special Builtins +@cindex special builtin + +For historical reasons, the @sc{posix} 1003.2 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 and the @env{MAILPATH} variable +is not set, Bash informs the user of the arrival of mail in +the specified file. + +@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 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}. + +@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}. + +@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 +corresponding to each member of @var{FUNCNAME}. +@code{$@{BASH_LINENO[$i]@}} is the line number in the source file where +@code{$@{FUNCNAME[$i + 1]@}} was called. +The corresponding source file name is @code{$@{BASH_SOURCE[$i + 1]@}}. +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 corresponding +to the elements in the @code{FUNCNAME} array variable. + +@item BASH_SUBSHELL +Incremented by one each time a subshell or subshell environment is spawned. +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 COLUMNS +Used by the @code{select} builtin command to determine the terminal width +when printing selection lists. Automatically set 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_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. +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 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 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 is "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. + +@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, 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. + +@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, 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} builtin command to determine the column length +for printing selection lists. Automatically set 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 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 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 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 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 interative 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 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 + +In addition to the single-character shell command-line options +(@pxref{The Set Builtin}), 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{Bash Builtins} +for a description of the @code{extdebug} option to the @code{shopt} +builtin) and shell function tracing +(see @ref{The Set Builtin} for a description of the @code{-o functrace} +option). + +@item --dump-po-strings +A list of all double-quoted strings preceded by @samp{$} +is printed on the standard ouput +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 sucessfully. + +@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} 1003.2 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 ouput. +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{Shell Builtin Commands}). +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 describs 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 by the remote shell +daemon, usually @code{rshd}. If Bash determines it is being run by +rshd, 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} variable, if it appears in the environment, is 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 specifiying 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. + +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{hupoxexit} 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{Bash Builtins}). + +@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. + +@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 -O @var{file} +True if @var{file} exists and is owned by the effective user id. + +@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 -S @var{file} +True if @var{file} exists and is a socket. + +@item -N @var{file} +True if @var{file} exists and has been modified since it was last read. + +@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 @var{file1} -ef @var{file2} +True if @var{file1} and @var{file2} refer to the same device and +inode numbers. + +@item -o @var{optname} +True if 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 -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} +True if the strings are equal. +@samp{=} may be used in place of @samp{==} for strict @sc{posix} compliance. + +@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 +in the current locale. + +@item @var{string1} > @var{string2} +True if @var{string1} sorts after @var{string2} lexicographically +in the current locale. + +@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 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 @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 interchangably 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 alias name and the replacement text may contain any valid +shell input, including shell metacharacters, with the exception +that the alias name may not contain @samp{=}. +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{Bash Builtins}). + +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 array variables. Any variable may be used as +an 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. Arrays are zero-based. + +An 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 +greater than or equal to zero. 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. 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}. 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. +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. 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 element zero. + +The @code{unset} builtin is used to destroy arrays. +@code{unset} @var{name}[@var{subscript}] +destroys the array element at index @var{subscript}. +@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 array. 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 [@var{dir} | @var{+N} | @var{-N}] [-n] +@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 +@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 -n +Suppresses the normal change of directory when adding directories +to the stack, so that only the stack is manipulated. +@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. +@item \W +The basename of @env{$PWD}. +@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} 1003.2 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 +Reserved words may not be aliased. + +@item +The @sc{posix} 1003.2 @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} 1003.2 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 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 +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} 1003.2 `special' builtins are found before shell functions +during command lookup. + +@item +If a @sc{posix} 1003.2 special builtin returns an error status, a +non-interactive shell exits. The fatal errors are those listed in +the POSIX.2 standard, and include things like passing incorrect options, +redirection errors, variable assignment errors for assignments preceding +the command name, and so on. + +@item +If the @code{cd} builtin finds a directory to change to +using @env{$CDPATH}, the +value it assigns to the @env{PWD} variable does not contain any +symbolic links, as if @samp{cd -P} had been executed. + +@item +If @env{CDPATH} is set, the @code{cd} builtin will not implicitly +append the current directory to it. This means that @code{cd} will +fail if no valid directory name can be constructed from +any of the entries in @env{$CDPATH}, even if the a directory with +the same name as the name given as an argument to @code{cd} exists +in the current directory. + +@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 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 +Assignment statements preceding @sc{posix} 1003.2 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} 1003.2. + +@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. 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. +@end enumerate + +There is other @sc{posix} 1003.2 behavior that Bash does not implement. +Specifically: + +@enumerate +@item +Assignment statements affect the execution environment of all +builtins, not just special ones. + +@item +When a subshell is created to execute a shell script with execute permission, +but without a leading @samp{#!}, Bash sets @code{$0} to the full pathname of +the script as found by searching @code{$PATH}, rather than the command as +typed by the user. + +@item +When using @samp{.} to source a shell script found in @code{$PATH}, bash +checks execute permission bits rather than read permission bits, just as +if it were searching for a command. + +@end enumerate + +@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 system'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 +write to the terminal. Background processes which attempt to +read from (write to) the terminal are sent a @code{SIGTTIN} +(@code{SIGTTOU}) signal by the 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 name. + +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. The +previous job may be referenced using @samp{%-}. 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 while jobs are stopped, the +shell prints a message warning that there are stopped jobs. +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 the stopped jobs are terminated. + +@node Job Control Builtins +@section Job Control Builtins + +@table @code + +@item bg +@btindex bg +@example +bg [@var{jobspec}] +@end example +Resume the 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, if @var{jobspec} was +not found or @var{jobspec} 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 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 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. The @option{-f} option means to suspend +even if the shell is a login shell. + +@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 @file{lib/malloc/malloc.c}. This is not the same +@code{malloc} that appears in @sc{gnu} libc, but an older version +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 4.3 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-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 POSIX regular expressions using the +@samp{=~} binary operator in the @code{[[} conditional command. +(@pxref{Conditional Constructs}). + +@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-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-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-progcomp +Enable the programmable completion facilities +(@pxref{Programmable Completion}). +If Readline is not enabled, this option has no effect. + +@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} builtin, which allows the generation of simple +menus (@pxref{Conditional Constructs}). + +@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 2. +@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/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@@po.CWRU.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} 1003.2 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 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 two builtin commands, +@code{complete} and @code{compgen}, 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. + +@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}). + +@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 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} 1003.2 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 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{Bash Builtins}), 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. + +@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 +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} 1003.2 special builtins fails, and +only for certain failures, as enumerated in the @sc{posix} 1003.2 standard. + +@item +The SVR4.2 shell behaves differently when invoked as @code{jsh} +(it turns on job control). +@end itemize + +@node Copying This Manual +@appendix Copying This Manual + +@menu +* GNU Free Documentation License:: License for copying this manual. +@end menu + +@include fdl.texi + +@node Builtin Index +@unnumbered Index of Shell Builtin Commands +@printindex bt + +@node Reserved Word Index +@unnumbered Index of Shell Reserved Words +@printindex rw + +@node Variable Index +@unnumbered Parameter and Variable Index +@printindex vr + +@node Function Index +@unnumbered Function Index +@printindex fn + +@node Concept Index +@unnumbered Concept Index +@printindex cp + +@bye diff --git a/doc/builtins.ps b/doc/builtins.ps index a6875075a..16c03581f 100644 --- a/doc/builtins.ps +++ b/doc/builtins.ps @@ -1,6 +1,6 @@ %!PS-Adobe-3.0 %%Creator: groff version 1.18.1 -%%CreationDate: Thu Nov 13 09:47:38 2003 +%%CreationDate: Sun Jan 25 21:10:35 2004 %%DocumentNeededResources: font Times-Roman %%+ font Times-Bold %%+ font Times-Italic @@ -189,11 +189,11 @@ setpacking %%IncludeResource: font Palatino-Italic %%IncludeResource: font Palatino-Bold grops begin/DEFS 1 dict def DEFS begin/u{.001 mul}bind def end/RES 72 -def/PL 792 def/LS false def/ENC0[/asciicircum/asciitilde/Scaron/Zcaron -/scaron/zcaron/Ydieresis/trademark/quotesingle/Euro/.notdef/.notdef +def/PL 841.89 def/LS false def/ENC0[/asciicircum/asciitilde/Scaron +/Zcaron/scaron/zcaron/Ydieresis/trademark/quotesingle/Euro/.notdef /.notdef/.notdef/.notdef/.notdef/.notdef/.notdef/.notdef/.notdef/.notdef /.notdef/.notdef/.notdef/.notdef/.notdef/.notdef/.notdef/.notdef/.notdef -/.notdef/.notdef/space/exclam/quotedbl/numbersign/dollar/percent +/.notdef/.notdef/.notdef/space/exclam/quotedbl/numbersign/dollar/percent /ampersand/quoteright/parenleft/parenright/asterisk/plus/comma/hyphen /period/slash/zero/one/two/three/four/five/six/seven/eight/nine/colon /semicolon/less/equal/greater/question/at/A/B/C/D/E/F/G/H/I/J/K/L/M/N/O diff --git a/doc/rbash.ps b/doc/rbash.ps index 861e9db1f..1610e591c 100644 --- a/doc/rbash.ps +++ b/doc/rbash.ps @@ -1,6 +1,6 @@ %!PS-Adobe-3.0 %%Creator: groff version 1.18.1 -%%CreationDate: Thu Nov 13 09:47:38 2003 +%%CreationDate: Sun Jan 25 21:10:36 2004 %%DocumentNeededResources: font Times-Roman %%+ font Times-Bold %%DocumentSuppliedResources: procset grops 1.18 1 @@ -177,11 +177,11 @@ setpacking %%IncludeResource: font Times-Roman %%IncludeResource: font Times-Bold grops begin/DEFS 1 dict def DEFS begin/u{.001 mul}bind def end/RES 72 -def/PL 792 def/LS false def/ENC0[/asciicircum/asciitilde/Scaron/Zcaron -/scaron/zcaron/Ydieresis/trademark/quotesingle/Euro/.notdef/.notdef +def/PL 841.89 def/LS false def/ENC0[/asciicircum/asciitilde/Scaron +/Zcaron/scaron/zcaron/Ydieresis/trademark/quotesingle/Euro/.notdef /.notdef/.notdef/.notdef/.notdef/.notdef/.notdef/.notdef/.notdef/.notdef /.notdef/.notdef/.notdef/.notdef/.notdef/.notdef/.notdef/.notdef/.notdef -/.notdef/.notdef/space/exclam/quotedbl/numbersign/dollar/percent +/.notdef/.notdef/.notdef/space/exclam/quotedbl/numbersign/dollar/percent /ampersand/quoteright/parenleft/parenright/asterisk/plus/comma/hyphen /period/slash/zero/one/two/three/four/five/six/seven/eight/nine/colon /semicolon/less/equal/greater/question/at/A/B/C/D/E/F/G/H/I/J/K/L/M/N/O diff --git a/doc/version.texi b/doc/version.texi index 31a1d6804..9bdd14cd2 100644 --- a/doc/version.texi +++ b/doc/version.texi @@ -1,10 +1,10 @@ @ignore -Copyright (C) 1988-2003 Free Software Foundation, Inc. +Copyright (C) 1988-2004 Free Software Foundation, Inc. @end ignore @set EDITION 3.0 -@set VERSION 3.0-alpha -@set UPDATED 13 November 2003 -@set UPDATED-MONTH November 2003 +@set VERSION 3.0-beta1 +@set UPDATED 24 January 2004 +@set UPDATED-MONTH January 2004 -@set LASTCHANGE Thu Nov 13 09:47:04 EST 2003 +@set LASTCHANGE Sat Jan 24 13:17:53 EST 2004 diff --git a/doc/version.texi~ b/doc/version.texi~ new file mode 100644 index 000000000..31a1d6804 --- /dev/null +++ b/doc/version.texi~ @@ -0,0 +1,10 @@ +@ignore +Copyright (C) 1988-2003 Free Software Foundation, Inc. +@end ignore + +@set EDITION 3.0 +@set VERSION 3.0-alpha +@set UPDATED 13 November 2003 +@set UPDATED-MONTH November 2003 + +@set LASTCHANGE Thu Nov 13 09:47:04 EST 2003 diff --git a/jobs.h b/jobs.h index 1e21f8cb7..10c975b28 100644 --- a/jobs.h +++ b/jobs.h @@ -95,6 +95,7 @@ typedef struct job { #define NO_JOB -1 /* An impossible job array index. */ #define DUP_JOB -2 /* A possible return value for get_job_spec (). */ +#define BAD_JOBSPEC -3 /* Bad syntax for job spec. */ /* A value which cannot be a process ID. */ #define NO_PID (pid_t)-1 diff --git a/jobs.h~ b/jobs.h~ new file mode 100644 index 000000000..1e21f8cb7 --- /dev/null +++ b/jobs.h~ @@ -0,0 +1,182 @@ +/* jobs.h -- structures and stuff used by the jobs.c file. */ + +/* Copyright (C) 1993 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 2, 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; see the file COPYING. If not, write to the Free Software + Foundation, 59 Temple Place, Suite 330, Boston, MA 02111 USA. */ + +#if !defined (_JOBS_H_) +# define _JOBS_H_ + +#include "quit.h" +#include "siglist.h" + +#include "stdc.h" + +#include "posixwait.h" + +/* Defines controlling the fashion in which jobs are listed. */ +#define JLIST_STANDARD 0 +#define JLIST_LONG 1 +#define JLIST_PID_ONLY 2 +#define JLIST_CHANGED_ONLY 3 +#define JLIST_NONINTERACTIVE 4 + +/* I looked it up. For pretty_print_job (). The real answer is 24. */ +#define LONGEST_SIGNAL_DESC 24 + +/* We keep an array of jobs. Each entry in the array is a linked list + of processes that are piped together. The first process encountered is + the group leader. */ + +/* Values for the `running' field of a struct process. */ +#define PS_DONE 0 +#define PS_RUNNING 1 +#define PS_STOPPED 2 + +/* Each child of the shell is remembered in a STRUCT PROCESS. A chain of + such structures is a pipeline. The chain is circular. */ +typedef struct process { + struct process *next; /* Next process in the pipeline. A circular chain. */ + pid_t pid; /* Process ID. */ + WAIT status; /* The status of this command as returned by wait. */ + int running; /* Non-zero if this process is running. */ + char *command; /* The particular program that is running. */ +} PROCESS; + +/* PRUNNING really means `not exited' */ +#define PRUNNING(p) ((p)->running || WIFSTOPPED((p)->status)) +#define PSTOPPED(p) (WIFSTOPPED((p)->status)) +#define PDEADPROC(p) ((p)->running == PS_DONE) + +/* A description of a pipeline's state. */ +typedef enum { JRUNNING, JSTOPPED, JDEAD, JMIXED } JOB_STATE; +#define JOBSTATE(job) (jobs[(job)]->state) + +#define STOPPED(j) (jobs[(j)]->state == JSTOPPED) +#define RUNNING(j) (jobs[(j)]->state == JRUNNING) +#define DEADJOB(j) (jobs[(j)]->state == JDEAD) + +/* Values for the FLAGS field in the JOB struct below. */ +#define J_FOREGROUND 0x01 /* Non-zero if this is running in the foreground. */ +#define J_NOTIFIED 0x02 /* Non-zero if already notified about job state. */ +#define J_JOBCONTROL 0x04 /* Non-zero if this job started under job control. */ +#define J_NOHUP 0x08 /* Don't send SIGHUP to job if shell gets SIGHUP. */ + +#define IS_FOREGROUND(j) ((jobs[j]->flags & J_FOREGROUND) != 0) +#define IS_NOTIFIED(j) ((jobs[j]->flags & J_NOTIFIED) != 0) +#define IS_JOBCONTROL(j) ((jobs[j]->flags & J_JOBCONTROL) != 0) + +typedef struct job { + char *wd; /* The working directory at time of invocation. */ + PROCESS *pipe; /* The pipeline of processes that make up this job. */ + pid_t pgrp; /* The process ID of the process group (necessary). */ + JOB_STATE state; /* The state that this job is in. */ + int flags; /* Flags word: J_NOTIFIED, J_FOREGROUND, or J_JOBCONTROL. */ +#if defined (JOB_CONTROL) + COMMAND *deferred; /* Commands that will execute when this job is done. */ + sh_vptrfunc_t *j_cleanup; /* Cleanup function to call when job marked JDEAD */ + PTR_T cleanarg; /* Argument passed to (*j_cleanup)() */ +#endif /* JOB_CONTROL */ +} JOB; + +#define NO_JOB -1 /* An impossible job array index. */ +#define DUP_JOB -2 /* A possible return value for get_job_spec (). */ + +/* A value which cannot be a process ID. */ +#define NO_PID (pid_t)-1 + +/* System calls. */ +#if !defined (HAVE_UNISTD_H) +extern pid_t fork (), getpid (), getpgrp (); +#endif /* !HAVE_UNISTD_H */ + +/* Stuff from the jobs.c file. */ +extern pid_t original_pgrp, shell_pgrp, pipeline_pgrp; +extern pid_t last_made_pid, last_asynchronous_pid; +extern int current_job, previous_job; +extern int asynchronous_notification; +extern JOB **jobs; +extern int job_slots; + +extern void making_children __P((void)); +extern void stop_making_children __P((void)); +extern void cleanup_the_pipeline __P((void)); +extern void save_pipeline __P((int)); +extern void restore_pipeline __P((int)); +extern void start_pipeline __P((void)); +extern int stop_pipeline __P((int, COMMAND *)); + +extern void delete_job __P((int, int)); +extern void nohup_job __P((int)); +extern void delete_all_jobs __P((int)); +extern void nohup_all_jobs __P((int)); + +extern int count_all_jobs __P((void)); + +extern void terminate_current_pipeline __P((void)); +extern void terminate_stopped_jobs __P((void)); +extern void hangup_all_jobs __P((void)); +extern void kill_current_pipeline __P((void)); + +#if defined (__STDC__) && defined (pid_t) +extern int get_job_by_pid __P((int, int)); +extern void describe_pid __P((int)); +#else +extern int get_job_by_pid __P((pid_t, int)); +extern void describe_pid __P((pid_t)); +#endif + +extern void list_one_job __P((JOB *, int, int, int)); +extern void list_all_jobs __P((int)); +extern void list_stopped_jobs __P((int)); +extern void list_running_jobs __P((int)); + +extern pid_t make_child __P((char *, int)); + +extern int get_tty_state __P((void)); +extern int set_tty_state __P((void)); + +extern int wait_for_single_pid __P((pid_t)); +extern void wait_for_background_pids __P((void)); +extern int wait_for __P((pid_t)); +extern int wait_for_job __P((int)); + +extern void notify_and_cleanup __P((void)); +extern void reap_dead_jobs __P((void)); +extern int start_job __P((int, int)); +extern int kill_pid __P((pid_t, int, int)); +extern int initialize_job_control __P((int)); +extern void initialize_job_signals __P((void)); +extern int give_terminal_to __P((pid_t, int)); + +extern void set_sigwinch_handler __P((void)); +extern void unset_sigwinch_handler __P((void)); + +extern void unfreeze_jobs_list __P((void)); +extern int set_job_control __P((int)); +extern void without_job_control __P((void)); +extern void end_job_control __P((void)); +extern void restart_job_control __P((void)); +extern void set_sigchld_handler __P((void)); +extern void ignore_tty_job_signals __P((void)); +extern void default_tty_job_signals __P((void)); + +#if defined (JOB_CONTROL) +extern int job_control; +#endif + +#endif /* _JOBS_H_ */ diff --git a/lib/malloc/Makefile.in b/lib/malloc/Makefile.in index 0fc3618ea..d013dc798 100644 --- a/lib/malloc/Makefile.in +++ b/lib/malloc/Makefile.in @@ -46,9 +46,16 @@ LDFLAGS = @LDFLAGS@ DEFS = @DEFS@ LOCAL_DEFS = @LOCAL_DEFS@ +LIBBUILD = ${BUILD_DIR}/lib + BASHINCDIR = ${topdir}/include -INCLUDES = -I. -I../.. -I$(topdir) -I$(BASHINCDIR) -I$(topdir)/lib +INTL_LIBSRC = ${topdir}/lib/intl +INTL_BUILDDIR = ${LIBBUILD}/intl +INTL_INC = @INTL_INC@ +LIBINTL_H = @LIBINTL_H@ + +INCLUDES = -I. -I../.. -I$(topdir) -I$(BASHINCDIR) -I$(topdir)/lib $(INTL_INC) CCFLAGS = ${PROFILE_FLAGS} ${INCLUDES} $(DEFS) $(LOCAL_DEFS) $(LOCAL_CFLAGS) \ $(CFLAGS) $(MALLOC_CFLAGS) $(CPPFLAGS) @@ -116,11 +123,11 @@ trace.o: ${srcdir}/imalloc.h table.o: ${srcdir}/imalloc.h ${srcdir}/table.h watch.o: ${srcdir}/imalloc.h ${srcdir}/watch.h -malloc.o: ${topdir}/bashintl.h ${BASHINCDIR}/gettext.h -stats.o: ${topdir}/bashintl.h ${BASHINCDIR}/gettext.h -trace.o: ${topdir}/bashintl.h ${BASHINCDIR}/gettext.h -table.o: ${topdir}/bashintl.h ${BASHINCDIR}/gettext.h -watch.o: ${topdir}/bashintl.h ${BASHINCDIR}/gettext.h +malloc.o: ${topdir}/bashintl.h ${LIBINTL_H} ${BASHINCDIR}/gettext.h +stats.o: ${topdir}/bashintl.h ${LIBINTL_H} ${BASHINCDIR}/gettext.h +trace.o: ${topdir}/bashintl.h ${LIBINTL_H} ${BASHINCDIR}/gettext.h +table.o: ${topdir}/bashintl.h ${LIBINTL_H} ${BASHINCDIR}/gettext.h +watch.o: ${topdir}/bashintl.h ${LIBINTL_H} ${BASHINCDIR}/gettext.h # Rules for deficient makes, like SunOS and Solaris stub.o: stub.c diff --git a/lib/readline/complete.c b/lib/readline/complete.c index a5aa84a9c..8e41d8b88 100644 --- a/lib/readline/complete.c +++ b/lib/readline/complete.c @@ -1,6 +1,6 @@ /* complete.c -- filename completion for readline. */ -/* Copyright (C) 1987, 1989, 1992 Free Software Foundation, Inc. +/* Copyright (C) 1987-2004 Free Software Foundation, Inc. This file is part of the GNU Readline Library, a library for reading lines of text with interactive input and history editing. diff --git a/lib/readline/display.c b/lib/readline/display.c index 28f69b5ef..ba8e30711 100644 --- a/lib/readline/display.c +++ b/lib/readline/display.c @@ -1,6 +1,6 @@ /* display.c -- readline redisplay facility. */ -/* Copyright (C) 1987, 1989, 1992 Free Software Foundation, Inc. +/* Copyright (C) 1987-2004 Free Software Foundation, Inc. This file is part of the GNU Readline Library, a library for reading lines of text with interactive input and history editing. diff --git a/lib/readline/doc/rltech.texi b/lib/readline/doc/rltech.texi index e2d62ea2f..510b1246d 100644 --- a/lib/readline/doc/rltech.texi +++ b/lib/readline/doc/rltech.texi @@ -933,6 +933,11 @@ expand the primary prompt if the @code{rl_on_new_line_with_prompt()} function or @code{rl_already_prompted} variable is used. It returns the number of visible characters on the last line of the (possibly multi-line) prompt. +Applications may indicate that the prompt contains characters that take +up no physical screen space when displayed by bracketing a sequence of +such characters with the special markers @code{RL_PROMPT_START_IGNORE} +and @code{RL_PROMPT_END_IGNORE} (declared in @file{readline.h}. This may +be used to embed terminal-specific escape sequences in prompts. @end deftypefun @deftypefun int rl_set_prompt (const char *prompt) diff --git a/lib/readline/doc/version.texi b/lib/readline/doc/version.texi index 64cb98e0a..cc78d84a4 100644 --- a/lib/readline/doc/version.texi +++ b/lib/readline/doc/version.texi @@ -4,7 +4,7 @@ Copyright (C) 1988-2004 Free Software Foundation, Inc. @set EDITION 5.0 @set VERSION 5.0 -@set UPDATED 8 January 2004 +@set UPDATED 15 January 2004 @set UPDATED-MONTH January 2003 -@set LASTCHANGE Thu Jan 8 10:34:23 EST 2004 +@set LASTCHANGE Thu Jan 15 09:05:10 EST 2004 diff --git a/lib/readline/mbutil.c b/lib/readline/mbutil.c index 597638bc9..9a8f17c0f 100644 --- a/lib/readline/mbutil.c +++ b/lib/readline/mbutil.c @@ -1,6 +1,6 @@ /* mbutil.c -- readline multibyte character utility functions */ -/* Copyright (C) 2001 Free Software Foundation, Inc. +/* Copyright (C) 2001-2004 Free Software Foundation, Inc. This file is part of the GNU Readline Library, a library for reading lines of text with interactive input and history editing. @@ -92,7 +92,7 @@ _rl_find_next_mbchar_internal (string, seed, count, find_non_zero) /* if this is true, means that seed was not pointed character started byte. So correct the point and consume count */ if (seed < point) - count --; + count--; while (count > 0) { diff --git a/lib/readline/readline.h b/lib/readline/readline.h index 82a7fe37e..f7994edbb 100644 --- a/lib/readline/readline.h +++ b/lib/readline/readline.h @@ -1,6 +1,6 @@ /* Readline.h -- the names of functions callable from within readline. */ -/* Copyright (C) 1987, 1989, 1992 Free Software Foundation, Inc. +/* Copyright (C) 1987-2004 Free Software Foundation, Inc. This file is part of the GNU Readline Library, a library for reading lines of text with interactive input and history editing. diff --git a/lib/sh/Makefile.in b/lib/sh/Makefile.in index 00b3c4293..c375c1de5 100644 --- a/lib/sh/Makefile.in +++ b/lib/sh/Makefile.in @@ -31,8 +31,15 @@ VPATH = .:@srcdir@ topdir = @top_srcdir@ BUILD_DIR = @BUILD_DIR@ +LIBBUILD = ${BUILD_DIR}/lib + BASHINCDIR = ${topdir}/include +INTL_LIBSRC = ${topdir}/lib/intl +INTL_BUILDDIR = ${LIBBUILD}/intl +INTL_INC = @INTL_INC@ +LIBINTL_H = @LIBINTL_H@ + INSTALL = @INSTALL@ INSTALL_PROGRAM = @INSTALL_PROGRAM@ INSTALL_DATA = @INSTALL_DATA@ @@ -57,7 +64,7 @@ PROFILE_FLAGS = @PROFILE_FLAGS@ DEFS = @DEFS@ LOCAL_DEFS = @LOCAL_DEFS@ -INCLUDES = -I. -I../.. -I$(topdir) -I$(topdir)/lib -I$(BASHINCDIR) -I$(srcdir) +INCLUDES = -I. -I../.. -I$(topdir) -I$(topdir)/lib -I$(BASHINCDIR) -I$(srcdir) $(INTL_INC) CCFLAGS = ${PROFILE_FLAGS} ${INCLUDES} $(DEFS) $(LOCAL_DEFS) $(LOCAL_CFLAGS) \ $(CFLAGS) $(CPPFLAGS) @@ -277,7 +284,7 @@ netopen.o: ${topdir}/array.h ${topdir}/hashlib.h ${topdir}/quit.h netopen.o: ${topdir}/unwind_prot.h ${topdir}/dispose_cmd.h netopen.o: ${topdir}/make_cmd.h ${topdir}/subst.h ${topdir}/sig.h netopen.o: ${BUILD_DIR}/pathnames.h ${topdir}/externs.h ${BUILD_DIR}/version.h -netopen.o: ${topdir}/bashintl.h $(BASHINCDIR)/gettext.h +netopen.o: ${topdir}/bashintl.h ${LIBINTL_H} $(BASHINCDIR)/gettext.h oslib.o: ${topdir}/bashtypes.h ${topdir}/bashansi.h ${BASHINCDIR}/maxpath.h oslib.o: ${topdir}/shell.h ${topdir}/syntax.h ${topdir}/bashjmp.h ${BASHINCDIR}/posixjmp.h @@ -423,21 +430,21 @@ fmtulong.o: ${BASHINCDIR}/ansi_stdlib.h fmtulong.o: ${BASHINCDIR}/chartypes.h fmtulong.o: ${BASHINCDIR}/stdc.h fmtulong.o: ${BASHINCDIR}/typemax.h -fmtulong.o: ${topdir}/bashintl.h ${BASHINCDIR}/gettext.h +fmtulong.o: ${topdir}/bashintl.h ${LIBINTL_H} ${BASHINCDIR}/gettext.h fmtullong.o: ${topdir}/bashansi.h fmtullong.o: ${BASHINCDIR}/ansi_stdlib.h fmtullong.o: ${BASHINCDIR}/chartypes.h fmtullong.o: ${BASHINCDIR}/stdc.h fmtullong.o: ${BASHINCDIR}/typemax.h -fmtullong.o: ${topdir}/bashintl.h ${BASHINCDIR}/gettext.h +fmtullong.o: ${topdir}/bashintl.h ${LIBINTL_H} ${BASHINCDIR}/gettext.h fmtumax.o: ${topdir}/bashansi.h fmtumax.o: ${BASHINCDIR}/ansi_stdlib.h fmtumax.o: ${BASHINCDIR}/chartypes.h fmtumax.o: ${BASHINCDIR}/stdc.h fmtumax.o: ${BASHINCDIR}/typemax.h -fmtumax.o: ${topdir}/bashintl.h ${BASHINCDIR}/gettext.h +fmtumax.o: ${topdir}/bashintl.h ${LIBINTL_H} ${BASHINCDIR}/gettext.h xstrchr.o: ${topdir}/bashansi.h xstrchr.o: ${BASHINCDIR}/ansi_stdlib.h diff --git a/parse.y b/parse.y index 7bd65ba5d..dc3612854 100644 --- a/parse.y +++ b/parse.y @@ -1,6 +1,6 @@ /* Yacc grammar for bash. */ -/* Copyright (C) 1989-2002 Free Software Foundation, Inc. +/* Copyright (C) 1989-2004 Free Software Foundation, Inc. This file is part of GNU Bash, the Bourne Again SHell. @@ -4070,7 +4070,7 @@ decode_prompt_string (string) case 'W': { /* Use the value of PWD because it is much more efficient. */ - char t_string[PATH_MAX]; + char t_string[PATH_MAX], *t; int tlen; temp = get_string_value ("PWD"); @@ -4094,7 +4094,8 @@ decode_prompt_string (string) #define ROOT_PATH(x) ((x)[0] == '/' && (x)[1] == 0) #define DOUBLE_SLASH_ROOT(x) ((x)[0] == '/' && (x)[1] == '/' && (x)[2] == 0) - if (c == 'W') + /* Abbreviate \W as ~ if $PWD == $HOME */ + if (c == 'W' && (((t = get_string_value ("HOME")) == 0) || STREQ (t, temp) == 0)) { if (ROOT_PATH (t_string) == 0 && DOUBLE_SLASH_ROOT (t_string) == 0) { diff --git a/parse.y~ b/parse.y~ new file mode 100644 index 000000000..03819993f --- /dev/null +++ b/parse.y~ @@ -0,0 +1,4851 @@ +/* Yacc grammar for bash. */ + +/* Copyright (C) 1989-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 2, 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; see the file LICENSE. If not, write to the Free Software + Foundation, 59 Temple Place, Suite 330, Boston, MA 02111 USA. */ + +%{ +#include "config.h" + +#include "bashtypes.h" +#include "bashansi.h" + +#include "filecntl.h" + +#if defined (HAVE_UNISTD_H) +# include +#endif + +#if defined (HAVE_LOCALE_H) +# include +#endif + +#include +#include "chartypes.h" +#include + +#include "memalloc.h" + +#include "bashintl.h" + +#define NEED_STRFTIME_DECL /* used in externs.h */ + +#include "shell.h" +#include "trap.h" +#include "flags.h" +#include "parser.h" +#include "mailcheck.h" +#include "test.h" +#include "builtins/common.h" +#include "builtins/builtext.h" + +#include "shmbutil.h" + +#if defined (READLINE) +# include "bashline.h" +# include +#endif /* READLINE */ + +#if defined (HISTORY) +# include "bashhist.h" +# include +#endif /* HISTORY */ + +#if defined (JOB_CONTROL) +# include "jobs.h" +#endif /* JOB_CONTROL */ + +#if defined (ALIAS) +# include "alias.h" +#else +typedef void *alias_t; +#endif /* ALIAS */ + +#if defined (PROMPT_STRING_DECODE) +# ifndef _MINIX +# include +# endif +# include +# if defined (TM_IN_SYS_TIME) +# include +# include +# endif /* TM_IN_SYS_TIME */ +# include "maxpath.h" +#endif /* PROMPT_STRING_DECODE */ + +#define RE_READ_TOKEN -99 +#define NO_EXPANSION -100 + +#ifdef DEBUG +# define YYDEBUG 1 +#else +# define YYDEBUG 0 +#endif + +#if defined (HANDLE_MULTIBYTE) +# define last_shell_getc_is_singlebyte \ + ((shell_input_line_index > 1) \ + ? shell_input_line_property[shell_input_line_index - 1] \ + : 1) +# define MBTEST(x) ((x) && last_shell_getc_is_singlebyte) +#else +# define last_shell_getc_is_singlebyte 1 +# define MBTEST(x) ((x)) +#endif + +#if defined (EXTENDED_GLOB) +extern int extended_glob; +#endif + +extern int eof_encountered; +extern int no_line_editing, running_under_emacs; +extern int current_command_number; +extern int sourcelevel; +extern int posixly_correct; +extern int last_command_exit_value; +extern int interrupt_immediately; +extern char *shell_name, *current_host_name; +extern char *dist_version; +extern int patch_level; +extern int dump_translatable_strings, dump_po_strings; +extern sh_builtin_func_t *last_shell_builtin, *this_shell_builtin; +#if defined (BUFFERED_INPUT) +extern int bash_input_fd_changed; +#endif + +extern int errno; +/* **************************************************************** */ +/* */ +/* "Forward" declarations */ +/* */ +/* **************************************************************** */ + +#ifdef DEBUG +static void debug_parser __P((int)); +#endif + +static int yy_getc __P((void)); +static int yy_ungetc __P((int)); + +#if defined (READLINE) +static int yy_readline_get __P((void)); +static int yy_readline_unget __P((int)); +#endif + +static int yy_string_get __P((void)); +static int yy_string_unget __P((int)); +static int yy_stream_get __P((void)); +static int yy_stream_unget __P((int)); + +static int shell_getc __P((int)); +static void shell_ungetc __P((int)); +static void discard_until __P((int)); + +#if defined (ALIAS) || defined (DPAREN_ARITHMETIC) +static void push_string __P((char *, int, alias_t *)); +static void pop_string __P((void)); +static void free_string_list __P((void)); +#endif + +static char *read_a_line __P((int)); + +static int reserved_word_acceptable __P((int)); +static int yylex __P((void)); +static int alias_expand_token __P((char *)); +static int time_command_acceptable __P((void)); +static int special_case_tokens __P((char *)); +static int read_token __P((int)); +static char *parse_matched_pair __P((int, int, int, int *, int)); +#if defined (ARRAY_VARS) +static char *parse_compound_assignment __P((int *)); +#endif +#if defined (DPAREN_ARITHMETIC) || defined (ARITH_FOR_COMMAND) +static int parse_dparen __P((int)); +static int parse_arith_cmd __P((char **, int)); +#endif +#if defined (COND_COMMAND) +static void cond_error __P((void)); +static COND_COM *cond_expr __P((void)); +static COND_COM *cond_or __P((void)); +static COND_COM *cond_and __P((void)); +static COND_COM *cond_term __P((void)); +static int cond_skip_newlines __P((void)); +static COMMAND *parse_cond_command __P((void)); +#endif +#if defined (ARRAY_VARS) +static int token_is_assignment __P((char *, int)); +static int token_is_ident __P((char *, int)); +#endif +static int read_token_word __P((int)); +static void discard_parser_constructs __P((int)); + +static char *error_token_from_token __P((int)); +static char *error_token_from_text __P((void)); +static void print_offending_line __P((void)); +static void report_syntax_error __P((char *)); + +static void handle_eof_input_unit __P((void)); +static void prompt_again __P((void)); +#if 0 +static void reset_readline_prompt __P((void)); +#endif +static void print_prompt __P((void)); + +#if defined (HISTORY) +char *history_delimiting_chars __P((void)); +#endif + +#if defined (HANDLE_MULTIBYTE) +static void set_line_mbstate __P((void)); +static char *shell_input_line_property = NULL; +#else +# define set_line_mbstate() +#endif + +extern int yyerror __P((const char *)); + +#ifdef DEBUG +extern int yydebug; +#endif + +/* Default prompt strings */ +char *primary_prompt = PPROMPT; +char *secondary_prompt = SPROMPT; + +/* PROMPT_STRING_POINTER points to one of these, never to an actual string. */ +char *ps1_prompt, *ps2_prompt; + +/* Handle on the current prompt string. Indirectly points through + ps1_ or ps2_prompt. */ +char **prompt_string_pointer = (char **)NULL; +char *current_prompt_string; + +/* Non-zero means we expand aliases in commands. */ +int expand_aliases = 0; + +/* If non-zero, the decoded prompt string undergoes parameter and + variable substitution, command substitution, arithmetic substitution, + string expansion, process substitution, and quote removal in + decode_prompt_string. */ +int promptvars = 1; + +/* If non-zero, $'...' and $"..." are expanded when they appear within + a ${...} expansion, even when the expansion appears within double + quotes. */ +int extended_quote = 1; + +/* The decoded prompt string. Used if READLINE is not defined or if + editing is turned off. Analogous to current_readline_prompt. */ +static char *current_decoded_prompt; + +/* The number of lines read from input while creating the current command. */ +int current_command_line_count; + +/* Variables to manage the task of reading here documents, because we need to + defer the reading until after a complete command has been collected. */ +static REDIRECT *redir_stack[10]; +int need_here_doc; + +/* Where shell input comes from. History expansion is performed on each + line when the shell is interactive. */ +static char *shell_input_line = (char *)NULL; +static int shell_input_line_index; +static int shell_input_line_size; /* Amount allocated for shell_input_line. */ +static int shell_input_line_len; /* strlen (shell_input_line) */ + +/* Either zero or EOF. */ +static int shell_input_line_terminator; + +/* The line number in a script on which a function definition starts. */ +static int function_dstart; + +/* The line number in a script on which a function body starts. */ +static int function_bstart; + +/* The line number in a script at which an arithmetic for command starts. */ +static int arith_for_lineno; + +/* The line number in a script where the word in a `case WORD', `select WORD' + or `for WORD' begins. This is a nested command maximum, since the array + index is decremented after a case, select, or for command is parsed. */ +#define MAX_CASE_NEST 128 +static int word_lineno[MAX_CASE_NEST]; +static int word_top = -1; + +/* If non-zero, it is the token that we want read_token to return + regardless of what text is (or isn't) present to be read. This + is reset by read_token. If token_to_read == WORD or + ASSIGNMENT_WORD, yylval.word should be set to word_desc_to_read. */ +static int token_to_read; +static WORD_DESC *word_desc_to_read; + +static REDIRECTEE redir; +%} + +%union { + WORD_DESC *word; /* the word that we read. */ + int number; /* the number that we read. */ + WORD_LIST *word_list; + COMMAND *command; + REDIRECT *redirect; + ELEMENT element; + PATTERN_LIST *pattern; +} + +/* Reserved words. Members of the first group are only recognized + in the case that they are preceded by a list_terminator. Members + of the second group are for [[...]] commands. Members of the + third group are recognized only under special circumstances. */ +%token IF THEN ELSE ELIF FI CASE ESAC FOR SELECT WHILE UNTIL DO DONE FUNCTION +%token COND_START COND_END COND_ERROR +%token IN BANG TIME TIMEOPT + +/* More general tokens. yylex () knows how to make these. */ +%token WORD ASSIGNMENT_WORD +%token NUMBER +%token ARITH_CMD ARITH_FOR_EXPRS +%token COND_CMD +%token AND_AND OR_OR GREATER_GREATER LESS_LESS LESS_AND LESS_LESS_LESS +%token GREATER_AND SEMI_SEMI LESS_LESS_MINUS AND_GREATER LESS_GREATER +%token GREATER_BAR + +/* The types that the various syntactical units return. */ + +%type inputunit command pipeline pipeline_command +%type list list0 list1 compound_list simple_list simple_list1 +%type simple_command shell_command +%type for_command select_command case_command group_command +%type arith_command +%type cond_command +%type arith_for_command +%type function_def function_body if_command elif_clause subshell +%type redirection redirection_list +%type simple_command_element +%type word_list pattern +%type pattern_list case_clause_sequence case_clause +%type timespec +%type list_terminator + +%start inputunit + +%left '&' ';' '\n' yacc_EOF +%left AND_AND OR_OR +%right '|' +%% + +inputunit: simple_list simple_list_terminator + { + /* Case of regular command. Discard the error + safety net,and return the command just parsed. */ + global_command = $1; + eof_encountered = 0; + /* discard_parser_constructs (0); */ + YYACCEPT; + } + | '\n' + { + /* Case of regular command, but not a very + interesting one. Return a NULL command. */ + global_command = (COMMAND *)NULL; + YYACCEPT; + } + | error '\n' + { + /* Error during parsing. Return NULL command. */ + global_command = (COMMAND *)NULL; + eof_encountered = 0; + /* discard_parser_constructs (1); */ + if (interactive) + { + YYACCEPT; + } + else + { + YYABORT; + } + } + | yacc_EOF + { + /* Case of EOF seen by itself. Do ignoreeof or + not. */ + global_command = (COMMAND *)NULL; + handle_eof_input_unit (); + YYACCEPT; + } + ; + +word_list: WORD + { $$ = make_word_list ($1, (WORD_LIST *)NULL); } + | word_list WORD + { $$ = make_word_list ($2, $1); } + ; + +redirection: '>' WORD + { + redir.filename = $2; + $$ = make_redirection (1, r_output_direction, redir); + } + | '<' WORD + { + redir.filename = $2; + $$ = make_redirection (0, r_input_direction, redir); + } + | NUMBER '>' WORD + { + redir.filename = $3; + $$ = make_redirection ($1, r_output_direction, redir); + } + | NUMBER '<' WORD + { + redir.filename = $3; + $$ = make_redirection ($1, r_input_direction, redir); + } + | GREATER_GREATER WORD + { + redir.filename = $2; + $$ = make_redirection (1, r_appending_to, redir); + } + | NUMBER GREATER_GREATER WORD + { + redir.filename = $3; + $$ = make_redirection ($1, r_appending_to, redir); + } + | LESS_LESS WORD + { + redir.filename = $2; + $$ = make_redirection (0, r_reading_until, redir); + redir_stack[need_here_doc++] = $$; + } + | NUMBER LESS_LESS WORD + { + redir.filename = $3; + $$ = make_redirection ($1, r_reading_until, redir); + redir_stack[need_here_doc++] = $$; + } + | LESS_LESS_LESS WORD + { + redir.filename = $2; + $$ = make_redirection (0, r_reading_string, redir); + } + | NUMBER LESS_LESS_LESS WORD + { + redir.filename = $3; + $$ = make_redirection ($1, r_reading_string, redir); + } + | LESS_AND NUMBER + { + redir.dest = $2; + $$ = make_redirection (0, r_duplicating_input, redir); + } + | NUMBER LESS_AND NUMBER + { + redir.dest = $3; + $$ = make_redirection ($1, r_duplicating_input, redir); + } + | GREATER_AND NUMBER + { + redir.dest = $2; + $$ = make_redirection (1, r_duplicating_output, redir); + } + | NUMBER GREATER_AND NUMBER + { + redir.dest = $3; + $$ = make_redirection ($1, r_duplicating_output, redir); + } + | LESS_AND WORD + { + redir.filename = $2; + $$ = make_redirection (0, r_duplicating_input_word, redir); + } + | NUMBER LESS_AND WORD + { + redir.filename = $3; + $$ = make_redirection ($1, r_duplicating_input_word, redir); + } + | GREATER_AND WORD + { + redir.filename = $2; + $$ = make_redirection (1, r_duplicating_output_word, redir); + } + | NUMBER GREATER_AND WORD + { + redir.filename = $3; + $$ = make_redirection ($1, r_duplicating_output_word, redir); + } + | LESS_LESS_MINUS WORD + { + redir.filename = $2; + $$ = make_redirection + (0, r_deblank_reading_until, redir); + redir_stack[need_here_doc++] = $$; + } + | NUMBER LESS_LESS_MINUS WORD + { + redir.filename = $3; + $$ = make_redirection + ($1, r_deblank_reading_until, redir); + redir_stack[need_here_doc++] = $$; + } + | GREATER_AND '-' + { + redir.dest = 0; + $$ = make_redirection (1, r_close_this, redir); + } + | NUMBER GREATER_AND '-' + { + redir.dest = 0; + $$ = make_redirection ($1, r_close_this, redir); + } + | LESS_AND '-' + { + redir.dest = 0; + $$ = make_redirection (0, r_close_this, redir); + } + | NUMBER LESS_AND '-' + { + redir.dest = 0; + $$ = make_redirection ($1, r_close_this, redir); + } + | AND_GREATER WORD + { + redir.filename = $2; + $$ = make_redirection (1, r_err_and_out, redir); + } + | NUMBER LESS_GREATER WORD + { + redir.filename = $3; + $$ = make_redirection ($1, r_input_output, redir); + } + | LESS_GREATER WORD + { + redir.filename = $2; + $$ = make_redirection (0, r_input_output, redir); + } + | GREATER_BAR WORD + { + redir.filename = $2; + $$ = make_redirection (1, r_output_force, redir); + } + | NUMBER GREATER_BAR WORD + { + redir.filename = $3; + $$ = make_redirection ($1, r_output_force, redir); + } + ; + +simple_command_element: WORD + { $$.word = $1; $$.redirect = 0; } + | ASSIGNMENT_WORD + { $$.word = $1; $$.redirect = 0; } + | redirection + { $$.redirect = $1; $$.word = 0; } + ; + +redirection_list: redirection + { + $$ = $1; + } + | redirection_list redirection + { + register REDIRECT *t; + + for (t = $1; t->next; t = t->next) + ; + t->next = $2; + $$ = $1; + } + ; + +simple_command: simple_command_element + { $$ = make_simple_command ($1, (COMMAND *)NULL); } + | simple_command simple_command_element + { $$ = make_simple_command ($2, $1); } + ; + +command: simple_command + { $$ = clean_simple_command ($1); } + | shell_command + { $$ = $1; } + | shell_command redirection_list + { + COMMAND *tc; + + tc = $1; + if (tc->redirects) + { + register REDIRECT *t; + for (t = tc->redirects; t->next; t = t->next) + ; + t->next = $2; + } + else + tc->redirects = $2; + $$ = $1; + } + | function_def + { $$ = $1; } + ; + +shell_command: for_command + { $$ = $1; } + | case_command + { $$ = $1; } + | WHILE compound_list DO compound_list DONE + { $$ = make_while_command ($2, $4); } + | UNTIL compound_list DO compound_list DONE + { $$ = make_until_command ($2, $4); } + | select_command + { $$ = $1; } + | if_command + { $$ = $1; } + | subshell + { $$ = $1; } + | group_command + { $$ = $1; } + | arith_command + { $$ = $1; } + | cond_command + { $$ = $1; } + | arith_for_command + { $$ = $1; } + ; + +for_command: FOR WORD newline_list DO compound_list DONE + { + $$ = make_for_command ($2, add_string_to_list ("\"$@\"", (WORD_LIST *)NULL), $5, word_lineno[word_top]); + if (word_top > 0) word_top--; + } + | FOR WORD newline_list '{' compound_list '}' + { + $$ = make_for_command ($2, add_string_to_list ("\"$@\"", (WORD_LIST *)NULL), $5, word_lineno[word_top]); + if (word_top > 0) word_top--; + } + | FOR WORD ';' newline_list DO compound_list DONE + { + $$ = make_for_command ($2, add_string_to_list ("\"$@\"", (WORD_LIST *)NULL), $6, word_lineno[word_top]); + if (word_top > 0) word_top--; + } + | FOR WORD ';' newline_list '{' compound_list '}' + { + $$ = make_for_command ($2, add_string_to_list ("\"$@\"", (WORD_LIST *)NULL), $6, word_lineno[word_top]); + if (word_top > 0) word_top--; + } + | FOR WORD newline_list IN word_list list_terminator newline_list DO compound_list DONE + { + $$ = make_for_command ($2, REVERSE_LIST ($5, WORD_LIST *), $9, word_lineno[word_top]); + if (word_top > 0) word_top--; + } + | FOR WORD newline_list IN word_list list_terminator newline_list '{' compound_list '}' + { + $$ = make_for_command ($2, REVERSE_LIST ($5, WORD_LIST *), $9, word_lineno[word_top]); + if (word_top > 0) word_top--; + } + | FOR WORD newline_list IN list_terminator newline_list DO compound_list DONE + { + $$ = make_for_command ($2, (WORD_LIST *)NULL, $8, word_lineno[word_top]); + if (word_top > 0) word_top--; + } + | FOR WORD newline_list IN list_terminator newline_list '{' compound_list '}' + { + $$ = make_for_command ($2, (WORD_LIST *)NULL, $8, word_lineno[word_top]); + if (word_top > 0) word_top--; + } + ; + +arith_for_command: FOR ARITH_FOR_EXPRS list_terminator newline_list DO compound_list DONE + { + $$ = make_arith_for_command ($2, $6, arith_for_lineno); + if (word_top > 0) word_top--; + } + | FOR ARITH_FOR_EXPRS list_terminator newline_list '{' compound_list '}' + { + $$ = make_arith_for_command ($2, $6, arith_for_lineno); + if (word_top > 0) word_top--; + } + | FOR ARITH_FOR_EXPRS DO compound_list DONE + { + $$ = make_arith_for_command ($2, $4, arith_for_lineno); + if (word_top > 0) word_top--; + } + | FOR ARITH_FOR_EXPRS '{' compound_list '}' + { + $$ = make_arith_for_command ($2, $4, arith_for_lineno); + if (word_top > 0) word_top--; + } + ; + +select_command: SELECT WORD newline_list DO list DONE + { + $$ = make_select_command ($2, add_string_to_list ("\"$@\"", (WORD_LIST *)NULL), $5, word_lineno[word_top]); + if (word_top > 0) word_top--; + } + | SELECT WORD newline_list '{' list '}' + { + $$ = make_select_command ($2, add_string_to_list ("\"$@\"", (WORD_LIST *)NULL), $5, word_lineno[word_top]); + if (word_top > 0) word_top--; + } + | SELECT WORD ';' newline_list DO list DONE + { + $$ = make_select_command ($2, add_string_to_list ("\"$@\"", (WORD_LIST *)NULL), $6, word_lineno[word_top]); + if (word_top > 0) word_top--; + } + | SELECT WORD ';' newline_list '{' list '}' + { + $$ = make_select_command ($2, add_string_to_list ("\"$@\"", (WORD_LIST *)NULL), $6, word_lineno[word_top]); + if (word_top > 0) word_top--; + } + | SELECT WORD newline_list IN word_list list_terminator newline_list DO list DONE + { + $$ = make_select_command ($2, REVERSE_LIST ($5, WORD_LIST *), $9, word_lineno[word_top]); + if (word_top > 0) word_top--; + } + | SELECT WORD newline_list IN word_list list_terminator newline_list '{' list '}' + { + $$ = make_select_command ($2, REVERSE_LIST ($5, WORD_LIST *), $9, word_lineno[word_top]); + if (word_top > 0) word_top--; + } + ; + +case_command: CASE WORD newline_list IN newline_list ESAC + { + $$ = make_case_command ($2, (PATTERN_LIST *)NULL, word_lineno[word_top]); + if (word_top > 0) word_top--; + } + | CASE WORD newline_list IN case_clause_sequence newline_list ESAC + { + $$ = make_case_command ($2, $5, word_lineno[word_top]); + if (word_top > 0) word_top--; + } + | CASE WORD newline_list IN case_clause ESAC + { + $$ = make_case_command ($2, $5, word_lineno[word_top]); + if (word_top > 0) word_top--; + } + ; + +function_def: WORD '(' ')' newline_list function_body + { $$ = make_function_def ($1, $5, function_dstart, function_bstart); } + + | FUNCTION WORD '(' ')' newline_list function_body + { $$ = make_function_def ($2, $6, function_dstart, function_bstart); } + + | FUNCTION WORD newline_list function_body + { $$ = make_function_def ($2, $4, function_dstart, function_bstart); } + ; + + +function_body: shell_command + { $$ = $1; } + | shell_command redirection_list + { + COMMAND *tc; + + tc = $1; + /* According to Posix.2 3.9.5, redirections + specified after the body of a function should + be attached to the function and performed when + the function is executed, not as part of the + function definition command. */ + /* XXX - I don't think it matters, but we might + want to change this in the future to avoid + problems differentiating between a function + definition with a redirection and a function + definition containing a single command with a + redirection. The two are semantically equivalent, + though -- the only difference is in how the + command printing code displays the redirections. */ + if (tc->redirects) + { + register REDIRECT *t; + for (t = tc->redirects; t->next; t = t->next) + ; + t->next = $2; + } + else + tc->redirects = $2; + $$ = $1; + } + ; + +subshell: '(' compound_list ')' + { + $$ = make_subshell_command ($2); + $$->flags |= CMD_WANT_SUBSHELL; + } + ; + +if_command: IF compound_list THEN compound_list FI + { $$ = make_if_command ($2, $4, (COMMAND *)NULL); } + | IF compound_list THEN compound_list ELSE compound_list FI + { $$ = make_if_command ($2, $4, $6); } + | IF compound_list THEN compound_list elif_clause FI + { $$ = make_if_command ($2, $4, $5); } + ; + + +group_command: '{' compound_list '}' + { $$ = make_group_command ($2); } + ; + +arith_command: ARITH_CMD + { $$ = make_arith_command ($1); } + ; + +cond_command: COND_START COND_CMD COND_END + { $$ = $2; } + ; + +elif_clause: ELIF compound_list THEN compound_list + { $$ = make_if_command ($2, $4, (COMMAND *)NULL); } + | ELIF compound_list THEN compound_list ELSE compound_list + { $$ = make_if_command ($2, $4, $6); } + | ELIF compound_list THEN compound_list elif_clause + { $$ = make_if_command ($2, $4, $5); } + ; + +case_clause: pattern_list + | case_clause_sequence pattern_list + { $2->next = $1; $$ = $2; } + ; + +pattern_list: newline_list pattern ')' compound_list + { $$ = make_pattern_list ($2, $4); } + | newline_list pattern ')' newline_list + { $$ = make_pattern_list ($2, (COMMAND *)NULL); } + | newline_list '(' pattern ')' compound_list + { $$ = make_pattern_list ($3, $5); } + | newline_list '(' pattern ')' newline_list + { $$ = make_pattern_list ($3, (COMMAND *)NULL); } + ; + +case_clause_sequence: pattern_list SEMI_SEMI + | case_clause_sequence pattern_list SEMI_SEMI + { $2->next = $1; $$ = $2; } + ; + +pattern: WORD + { $$ = make_word_list ($1, (WORD_LIST *)NULL); } + | pattern '|' WORD + { $$ = make_word_list ($3, $1); } + ; + +/* A list allows leading or trailing newlines and + newlines as operators (equivalent to semicolons). + It must end with a newline or semicolon. + Lists are used within commands such as if, for, while. */ + +list: newline_list list0 + { + $$ = $2; + if (need_here_doc) + gather_here_documents (); + } + ; + +compound_list: list + | newline_list list1 + { + $$ = $2; + } + ; + +list0: list1 '\n' newline_list + | list1 '&' newline_list + { + if ($1->type == cm_connection) + $$ = connect_async_list ($1, (COMMAND *)NULL, '&'); + else + $$ = command_connect ($1, (COMMAND *)NULL, '&'); + } + | list1 ';' newline_list + + ; + +list1: list1 AND_AND newline_list list1 + { $$ = command_connect ($1, $4, AND_AND); } + | list1 OR_OR newline_list list1 + { $$ = command_connect ($1, $4, OR_OR); } + | list1 '&' newline_list list1 + { + if ($1->type == cm_connection) + $$ = connect_async_list ($1, $4, '&'); + else + $$ = command_connect ($1, $4, '&'); + } + | list1 ';' newline_list list1 + { $$ = command_connect ($1, $4, ';'); } + | list1 '\n' newline_list list1 + { $$ = command_connect ($1, $4, ';'); } + | pipeline_command + { $$ = $1; } + ; + +simple_list_terminator: '\n' + | yacc_EOF + ; + +list_terminator:'\n' + { $$ = '\n'; } + | ';' + { $$ = ';'; } + | yacc_EOF + { $$ = yacc_EOF; } + ; + +newline_list: + | newline_list '\n' + ; + +/* A simple_list is a list that contains no significant newlines + and no leading or trailing newlines. Newlines are allowed + only following operators, where they are not significant. + + This is what an inputunit consists of. */ + +simple_list: simple_list1 + { + $$ = $1; + if (need_here_doc) + gather_here_documents (); + } + | simple_list1 '&' + { + if ($1->type == cm_connection) + $$ = connect_async_list ($1, (COMMAND *)NULL, '&'); + else + $$ = command_connect ($1, (COMMAND *)NULL, '&'); + if (need_here_doc) + gather_here_documents (); + } + | simple_list1 ';' + { + $$ = $1; + if (need_here_doc) + gather_here_documents (); + } + ; + +simple_list1: simple_list1 AND_AND newline_list simple_list1 + { $$ = command_connect ($1, $4, AND_AND); } + | simple_list1 OR_OR newline_list simple_list1 + { $$ = command_connect ($1, $4, OR_OR); } + | simple_list1 '&' simple_list1 + { + if ($1->type == cm_connection) + $$ = connect_async_list ($1, $3, '&'); + else + $$ = command_connect ($1, $3, '&'); + } + | simple_list1 ';' simple_list1 + { $$ = command_connect ($1, $3, ';'); } + + | pipeline_command + { $$ = $1; } + ; + +pipeline_command: pipeline + { $$ = $1; } + | BANG pipeline + { + $2->flags |= CMD_INVERT_RETURN; + $$ = $2; + } + | timespec pipeline + { + $2->flags |= $1; + $$ = $2; + } + | timespec BANG pipeline + { + $3->flags |= $1|CMD_INVERT_RETURN; + $$ = $3; + } + | BANG timespec pipeline + { + $3->flags |= $2|CMD_INVERT_RETURN; + $$ = $3; + } + | timespec list_terminator + { + ELEMENT x; + + /* Boy, this is unclean. `time' by itself can + time a null command. We cheat and push a + newline back if the list_terminator was a newline + to avoid the double-newline problem (one to + terminate this, one to terminate the command) */ + x.word = 0; + x.redirect = 0; + $$ = make_simple_command (x, (COMMAND *)NULL); + $$->flags |= $1; + /* XXX - let's cheat and push a newline back */ + if ($2 == '\n') + token_to_read = '\n'; + } + + ; + +pipeline: + pipeline '|' newline_list pipeline + { $$ = command_connect ($1, $4, '|'); } + | command + { $$ = $1; } + ; + +timespec: TIME + { $$ = CMD_TIME_PIPELINE; } + | TIME TIMEOPT + { $$ = CMD_TIME_PIPELINE|CMD_TIME_POSIX; } + ; +%% + +/* Possible states for the parser that require it to do special things. */ +#define PST_CASEPAT 0x0001 /* in a case pattern list */ +#define PST_ALEXPNEXT 0x0002 /* expand next word for aliases */ +#define PST_ALLOWOPNBRC 0x0004 /* allow open brace for function def */ +#define PST_NEEDCLOSBRC 0x0008 /* need close brace */ +#define PST_DBLPAREN 0x0010 /* double-paren parsing */ +#define PST_SUBSHELL 0x0020 /* ( ... ) subshell */ +#define PST_CMDSUBST 0x0040 /* $( ... ) command substitution */ +#define PST_CASESTMT 0x0080 /* parsing a case statement */ +#define PST_CONDCMD 0x0100 /* parsing a [[...]] command */ +#define PST_CONDEXPR 0x0200 /* parsing the guts of [[...]] */ +#define PST_ARITHFOR 0x0400 /* parsing an arithmetic for command */ +#define PST_ALEXPAND 0x0800 /* OK to expand aliases - unused */ +#define PST_CMDTOKEN 0x1000 /* command token OK - unused */ +#define PST_COMPASSIGN 0x2000 /* parsing x=(...) compound assignment */ + +/* Initial size to allocate for tokens, and the + amount to grow them by. */ +#define TOKEN_DEFAULT_INITIAL_SIZE 496 +#define TOKEN_DEFAULT_GROW_SIZE 512 + +/* Should we call prompt_again? */ +#define SHOULD_PROMPT() \ + (interactive && (bash_input.type == st_stdin || bash_input.type == st_stream)) + +#if defined (ALIAS) +# define expanding_alias() (pushed_string_list && pushed_string_list->expander) +#else +# define expanding_alias() 0 +#endif + +/* The token currently being read. */ +static int current_token; + +/* The last read token, or NULL. read_token () uses this for context + checking. */ +static int last_read_token; + +/* The token read prior to last_read_token. */ +static int token_before_that; + +/* The token read prior to token_before_that. */ +static int two_tokens_ago; + +/* The current parser state. */ +static int parser_state; + +/* Global var is non-zero when end of file has been reached. */ +int EOF_Reached = 0; + +#ifdef DEBUG +static void +debug_parser (i) + int i; +{ +#if YYDEBUG != 0 + yydebug = i; +#endif +} +#endif + +/* yy_getc () returns the next available character from input or EOF. + yy_ungetc (c) makes `c' the next character to read. + init_yy_io (get, unget, type, location) makes the function GET the + installed function for getting the next character, makes UNGET the + installed function for un-getting a character, sets the type of stream + (either string or file) from TYPE, and makes LOCATION point to where + the input is coming from. */ + +/* Unconditionally returns end-of-file. */ +int +return_EOF () +{ + return (EOF); +} + +/* Variable containing the current get and unget functions. + See ./input.h for a clearer description. */ +BASH_INPUT bash_input; + +/* Set all of the fields in BASH_INPUT to NULL. Free bash_input.name if it + is non-null, avoiding a memory leak. */ +void +initialize_bash_input () +{ + bash_input.type = st_none; + FREE (bash_input.name); + bash_input.name = (char *)NULL; + bash_input.location.file = (FILE *)NULL; + bash_input.location.string = (char *)NULL; + bash_input.getter = (sh_cget_func_t *)NULL; + bash_input.ungetter = (sh_cunget_func_t *)NULL; +} + +/* Set the contents of the current bash input stream from + GET, UNGET, TYPE, NAME, and LOCATION. */ +void +init_yy_io (get, unget, type, name, location) + sh_cget_func_t *get; + sh_cunget_func_t *unget; + enum stream_type type; + const char *name; + INPUT_STREAM location; +{ + bash_input.type = type; + FREE (bash_input.name); + bash_input.name = name ? savestring (name) : (char *)NULL; + + /* XXX */ +#if defined (CRAY) + memcpy((char *)&bash_input.location.string, (char *)&location.string, sizeof(location)); +#else + bash_input.location = location; +#endif + bash_input.getter = get; + bash_input.ungetter = unget; +} + +char * +yy_input_name () +{ + return (bash_input.name ? bash_input.name : "stdin"); +} + +/* Call this to get the next character of input. */ +static int +yy_getc () +{ + return (*(bash_input.getter)) (); +} + +/* Call this to unget C. That is, to make C the next character + to be read. */ +static int +yy_ungetc (c) + int c; +{ + return (*(bash_input.ungetter)) (c); +} + +#if defined (BUFFERED_INPUT) +#ifdef INCLUDE_UNUSED +int +input_file_descriptor () +{ + switch (bash_input.type) + { + case st_stream: + return (fileno (bash_input.location.file)); + case st_bstream: + return (bash_input.location.buffered_fd); + case st_stdin: + default: + return (fileno (stdin)); + } +} +#endif +#endif /* BUFFERED_INPUT */ + +/* **************************************************************** */ +/* */ +/* Let input be read from readline (). */ +/* */ +/* **************************************************************** */ + +#if defined (READLINE) +char *current_readline_prompt = (char *)NULL; +char *current_readline_line = (char *)NULL; +int current_readline_line_index = 0; + +static int +yy_readline_get () +{ + SigHandler *old_sigint; + int line_len; + unsigned char c; + + if (!current_readline_line) + { + if (!bash_readline_initialized) + initialize_readline (); + +#if defined (JOB_CONTROL) + if (job_control) + give_terminal_to (shell_pgrp, 0); +#endif /* JOB_CONTROL */ + + old_sigint = (SigHandler *)NULL; + if (signal_is_ignored (SIGINT) == 0) + { + old_sigint = (SigHandler *)set_signal_handler (SIGINT, sigint_sighandler); + interrupt_immediately++; + } + + current_readline_line = readline (current_readline_prompt ? + current_readline_prompt : ""); + + if (signal_is_ignored (SIGINT) == 0 && old_sigint) + { + interrupt_immediately--; + set_signal_handler (SIGINT, old_sigint); + } + +#if 0 + /* Reset the prompt to the decoded value of prompt_string_pointer. */ + reset_readline_prompt (); +#endif + + if (current_readline_line == 0) + return (EOF); + + current_readline_line_index = 0; + line_len = strlen (current_readline_line); + + current_readline_line = (char *)xrealloc (current_readline_line, 2 + line_len); + current_readline_line[line_len++] = '\n'; + current_readline_line[line_len] = '\0'; + } + + if (current_readline_line[current_readline_line_index] == 0) + { + free (current_readline_line); + current_readline_line = (char *)NULL; + return (yy_readline_get ()); + } + else + { + c = current_readline_line[current_readline_line_index++]; + return (c); + } +} + +static int +yy_readline_unget (c) + int c; +{ + if (current_readline_line_index && current_readline_line) + current_readline_line[--current_readline_line_index] = c; + return (c); +} + +void +with_input_from_stdin () +{ + INPUT_STREAM location; + + if (bash_input.type != st_stdin && stream_on_stack (st_stdin) == 0) + { + location.string = current_readline_line; + init_yy_io (yy_readline_get, yy_readline_unget, + st_stdin, "readline stdin", location); + } +} + +#else /* !READLINE */ + +void +with_input_from_stdin () +{ + with_input_from_stream (stdin, "stdin"); +} +#endif /* !READLINE */ + +/* **************************************************************** */ +/* */ +/* Let input come from STRING. STRING is zero terminated. */ +/* */ +/* **************************************************************** */ + +static int +yy_string_get () +{ + register char *string; + register unsigned char c; + + string = bash_input.location.string; + + /* If the string doesn't exist, or is empty, EOF found. */ + if (string && *string) + { + c = *string++; + bash_input.location.string = string; + return (c); + } + else + return (EOF); +} + +static int +yy_string_unget (c) + int c; +{ + *(--bash_input.location.string) = c; + return (c); +} + +void +with_input_from_string (string, name) + char *string; + const char *name; +{ + INPUT_STREAM location; + + location.string = string; + init_yy_io (yy_string_get, yy_string_unget, st_string, name, location); +} + +/* **************************************************************** */ +/* */ +/* Let input come from STREAM. */ +/* */ +/* **************************************************************** */ + +/* These two functions used to test the value of the HAVE_RESTARTABLE_SYSCALLS + define, and just use getc/ungetc if it was defined, but since bash + installs its signal handlers without the SA_RESTART flag, some signals + (like SIGCHLD, SIGWINCH, etc.) received during a read(2) will not cause + the read to be restarted. We need to restart it ourselves. */ + +static int +yy_stream_get () +{ + int result; + + result = EOF; + if (bash_input.location.file) + result = getc_with_restart (bash_input.location.file); + + return (result); +} + +static int +yy_stream_unget (c) + int c; +{ + return (ungetc_with_restart (c, bash_input.location.file)); +} + +void +with_input_from_stream (stream, name) + FILE *stream; + const char *name; +{ + INPUT_STREAM location; + + location.file = stream; + init_yy_io (yy_stream_get, yy_stream_unget, st_stream, name, location); +} + +typedef struct stream_saver { + struct stream_saver *next; + BASH_INPUT bash_input; + int line; +#if defined (BUFFERED_INPUT) + BUFFERED_STREAM *bstream; +#endif /* BUFFERED_INPUT */ +} STREAM_SAVER; + +/* The globally known line number. */ +int line_number = 0; + +#if defined (COND_COMMAND) +static int cond_lineno; +static int cond_token; +#endif + +STREAM_SAVER *stream_list = (STREAM_SAVER *)NULL; + +void +push_stream (reset_lineno) + int reset_lineno; +{ + STREAM_SAVER *saver = (STREAM_SAVER *)xmalloc (sizeof (STREAM_SAVER)); + + xbcopy ((char *)&bash_input, (char *)&(saver->bash_input), sizeof (BASH_INPUT)); + +#if defined (BUFFERED_INPUT) + saver->bstream = (BUFFERED_STREAM *)NULL; + /* If we have a buffered stream, clear out buffers[fd]. */ + if (bash_input.type == st_bstream && bash_input.location.buffered_fd >= 0) + saver->bstream = set_buffered_stream (bash_input.location.buffered_fd, + (BUFFERED_STREAM *)NULL); +#endif /* BUFFERED_INPUT */ + + saver->line = line_number; + bash_input.name = (char *)NULL; + saver->next = stream_list; + stream_list = saver; + EOF_Reached = 0; + if (reset_lineno) + line_number = 0; +} + +void +pop_stream () +{ + if (!stream_list) + EOF_Reached = 1; + else + { + STREAM_SAVER *saver = stream_list; + + EOF_Reached = 0; + stream_list = stream_list->next; + + init_yy_io (saver->bash_input.getter, + saver->bash_input.ungetter, + saver->bash_input.type, + saver->bash_input.name, + saver->bash_input.location); + +#if defined (BUFFERED_INPUT) + /* If we have a buffered stream, restore buffers[fd]. */ + /* If the input file descriptor was changed while this was on the + save stack, update the buffered fd to the new file descriptor and + re-establish the buffer <-> bash_input fd correspondence. */ + if (bash_input.type == st_bstream && bash_input.location.buffered_fd >= 0) + { + if (bash_input_fd_changed) + { + bash_input_fd_changed = 0; + if (default_buffered_input >= 0) + { + bash_input.location.buffered_fd = default_buffered_input; + saver->bstream->b_fd = default_buffered_input; + SET_CLOSE_ON_EXEC (default_buffered_input); + } + } + /* XXX could free buffered stream returned as result here. */ + set_buffered_stream (bash_input.location.buffered_fd, saver->bstream); + } +#endif /* BUFFERED_INPUT */ + + line_number = saver->line; + + FREE (saver->bash_input.name); + free (saver); + } +} + +/* Return 1 if a stream of type TYPE is saved on the stack. */ +int +stream_on_stack (type) + enum stream_type type; +{ + register STREAM_SAVER *s; + + for (s = stream_list; s; s = s->next) + if (s->bash_input.type == type) + return 1; + return 0; +} + +/* Save the current token state and return it in a malloced array. */ +int * +save_token_state () +{ + int *ret; + + ret = (int *)xmalloc (3 * sizeof (int)); + ret[0] = last_read_token; + ret[1] = token_before_that; + ret[2] = two_tokens_ago; + return ret; +} + +void +restore_token_state (ts) + int *ts; +{ + if (ts == 0) + return; + last_read_token = ts[0]; + token_before_that = ts[1]; + two_tokens_ago = ts[2]; +} + +/* + * This is used to inhibit alias expansion and reserved word recognition + * inside case statement pattern lists. A `case statement pattern list' is: + * + * everything between the `in' in a `case word in' and the next ')' + * or `esac' + * everything between a `;;' and the next `)' or `esac' + */ + +#if defined (ALIAS) || defined (DPAREN_ARITHMETIC) + +#define END_OF_ALIAS 0 + +/* + * Pseudo-global variables used in implementing token-wise alias expansion. + */ + +/* + * Pushing and popping strings. This works together with shell_getc to + * implement alias expansion on a per-token basis. + */ + +typedef struct string_saver { + struct string_saver *next; + int expand_alias; /* Value to set expand_alias to when string is popped. */ + char *saved_line; +#if defined (ALIAS) + alias_t *expander; /* alias that caused this line to be pushed. */ +#endif + int saved_line_size, saved_line_index, saved_line_terminator; +} STRING_SAVER; + +STRING_SAVER *pushed_string_list = (STRING_SAVER *)NULL; + +/* + * Push the current shell_input_line onto a stack of such lines and make S + * the current input. Used when expanding aliases. EXPAND is used to set + * the value of expand_next_token when the string is popped, so that the + * word after the alias in the original line is handled correctly when the + * alias expands to multiple words. TOKEN is the token that was expanded + * into S; it is saved and used to prevent infinite recursive expansion. + */ +static void +push_string (s, expand, ap) + char *s; + int expand; + alias_t *ap; +{ + STRING_SAVER *temp = (STRING_SAVER *)xmalloc (sizeof (STRING_SAVER)); + + temp->expand_alias = expand; + temp->saved_line = shell_input_line; + temp->saved_line_size = shell_input_line_size; + temp->saved_line_index = shell_input_line_index; + temp->saved_line_terminator = shell_input_line_terminator; +#if defined (ALIAS) + temp->expander = ap; +#endif + temp->next = pushed_string_list; + pushed_string_list = temp; + +#if defined (ALIAS) + if (ap) + ap->flags |= AL_BEINGEXPANDED; +#endif + + shell_input_line = s; + shell_input_line_size = strlen (s); + shell_input_line_index = 0; + shell_input_line_terminator = '\0'; +#if 0 + parser_state &= ~PST_ALEXPNEXT; /* XXX */ +#endif + + set_line_mbstate (); +} + +/* + * Make the top of the pushed_string stack be the current shell input. + * Only called when there is something on the stack. Called from shell_getc + * when it thinks it has consumed the string generated by an alias expansion + * and needs to return to the original input line. + */ +static void +pop_string () +{ + STRING_SAVER *t; + + FREE (shell_input_line); + shell_input_line = pushed_string_list->saved_line; + shell_input_line_index = pushed_string_list->saved_line_index; + shell_input_line_size = pushed_string_list->saved_line_size; + shell_input_line_terminator = pushed_string_list->saved_line_terminator; + + if (pushed_string_list->expand_alias) + parser_state |= PST_ALEXPNEXT; + else + parser_state &= ~PST_ALEXPNEXT; + + t = pushed_string_list; + pushed_string_list = pushed_string_list->next; + +#if defined (ALIAS) + if (t->expander) + t->expander->flags &= ~AL_BEINGEXPANDED; +#endif + + free ((char *)t); + + set_line_mbstate (); +} + +static void +free_string_list () +{ + register STRING_SAVER *t, *t1; + + for (t = pushed_string_list; t; ) + { + t1 = t->next; + FREE (t->saved_line); +#if defined (ALIAS) + if (t->expander) + t->expander->flags &= ~AL_BEINGEXPANDED; +#endif + free ((char *)t); + t = t1; + } + pushed_string_list = (STRING_SAVER *)NULL; +} + +#endif /* ALIAS || DPAREN_ARITHMETIC */ + +void +free_pushed_string_input () +{ +#if defined (ALIAS) || defined (DPAREN_ARITHMETIC) + free_string_list (); +#endif +} + +/* Return a line of text, taken from wherever yylex () reads input. + If there is no more input, then we return NULL. If REMOVE_QUOTED_NEWLINE + is non-zero, we remove unquoted \ pairs. This is used by + read_secondary_line to read here documents. */ +static char * +read_a_line (remove_quoted_newline) + int remove_quoted_newline; +{ + static char *line_buffer = (char *)NULL; + static int buffer_size = 0; + int indx = 0, c, peekc, pass_next; + +#if defined (READLINE) + if (no_line_editing && SHOULD_PROMPT ()) +#else + if (SHOULD_PROMPT ()) +#endif + print_prompt (); + + pass_next = 0; + while (1) + { + c = yy_getc (); + + /* Allow immediate exit if interrupted during input. */ + QUIT; + + /* Ignore null bytes in input. */ + if (c == 0) + { +#if 0 + internal_warning ("read_a_line: ignored null byte in input"); +#endif + continue; + } + + /* If there is no more input, then we return NULL. */ + if (c == EOF) + { + if (interactive && bash_input.type == st_stream) + clearerr (stdin); + if (indx == 0) + return ((char *)NULL); + c = '\n'; + } + + /* `+2' in case the final character in the buffer is a newline. */ + RESIZE_MALLOCED_BUFFER (line_buffer, indx, 2, buffer_size, 128); + + /* IF REMOVE_QUOTED_NEWLINES is non-zero, we are reading a + here document with an unquoted delimiter. In this case, + the line will be expanded as if it were in double quotes. + We allow a backslash to escape the next character, but we + need to treat the backslash specially only if a backslash + quoting a backslash-newline pair appears in the line. */ + if (pass_next) + { + line_buffer[indx++] = c; + pass_next = 0; + } + else if (c == '\\' && remove_quoted_newline) + { + peekc = yy_getc (); + if (peekc == '\n') + { + line_number++; + continue; /* Make the unquoted \ pair disappear. */ + } + else + { + yy_ungetc (peekc); + pass_next = 1; + line_buffer[indx++] = c; /* Preserve the backslash. */ + } + } + else + line_buffer[indx++] = c; + + if (c == '\n') + { + line_buffer[indx] = '\0'; + return (line_buffer); + } + } +} + +/* Return a line as in read_a_line (), but insure that the prompt is + the secondary prompt. This is used to read the lines of a here + document. REMOVE_QUOTED_NEWLINE is non-zero if we should remove + newlines quoted with backslashes while reading the line. It is + non-zero unless the delimiter of the here document was quoted. */ +char * +read_secondary_line (remove_quoted_newline) + int remove_quoted_newline; +{ + prompt_string_pointer = &ps2_prompt; + if (SHOULD_PROMPT()) + prompt_again (); + return (read_a_line (remove_quoted_newline)); +} + +/* **************************************************************** */ +/* */ +/* YYLEX () */ +/* */ +/* **************************************************************** */ + +/* Reserved words. These are only recognized as the first word of a + command. */ +STRING_INT_ALIST word_token_alist[] = { + { "if", IF }, + { "then", THEN }, + { "else", ELSE }, + { "elif", ELIF }, + { "fi", FI }, + { "case", CASE }, + { "esac", ESAC }, + { "for", FOR }, +#if defined (SELECT_COMMAND) + { "select", SELECT }, +#endif + { "while", WHILE }, + { "until", UNTIL }, + { "do", DO }, + { "done", DONE }, + { "in", IN }, + { "function", FUNCTION }, +#if defined (COMMAND_TIMING) + { "time", TIME }, +#endif + { "{", '{' }, + { "}", '}' }, + { "!", BANG }, +#if defined (COND_COMMAND) + { "[[", COND_START }, + { "]]", COND_END }, +#endif + { (char *)NULL, 0} +}; + +/* other tokens that can be returned by read_token() */ +STRING_INT_ALIST other_token_alist[] = { + /* Multiple-character tokens with special values */ + { "-p", TIMEOPT }, + { "&&", AND_AND }, + { "||", OR_OR }, + { ">>", GREATER_GREATER }, + { "<<", LESS_LESS }, + { "<&", LESS_AND }, + { ">&", GREATER_AND }, + { ";;", SEMI_SEMI }, + { "<<-", LESS_LESS_MINUS }, + { "<<<", LESS_LESS_LESS }, + { "&>", AND_GREATER }, + { "<>", LESS_GREATER }, + { ">|", GREATER_BAR }, + { "EOF", yacc_EOF }, + /* Tokens whose value is the character itself */ + { ">", '>' }, + { "<", '<' }, + { "-", '-' }, + { "{", '{' }, + { "}", '}' }, + { ";", ';' }, + { "(", '(' }, + { ")", ')' }, + { "|", '|' }, + { "&", '&' }, + { "newline", '\n' }, + { (char *)NULL, 0} +}; + +/* others not listed here: + WORD look at yylval.word + ASSIGNMENT_WORD look at yylval.word + NUMBER look at yylval.number + ARITH_CMD look at yylval.word_list + ARITH_FOR_EXPRS look at yylval.word_list + COND_CMD look at yylval.command +*/ + +/* These are used by read_token_word, but appear up here so that shell_getc + can use them to decide when to add otherwise blank lines to the history. */ + +/* The primary delimiter stack. */ +struct dstack dstack = { (char *)NULL, 0, 0 }; + +/* A temporary delimiter stack to be used when decoding prompt strings. + This is needed because command substitutions in prompt strings (e.g., PS2) + can screw up the parser's quoting state. */ +static struct dstack temp_dstack = { (char *)NULL, 0, 0 }; + +/* Macro for accessing the top delimiter on the stack. Returns the + delimiter or zero if none. */ +#define current_delimiter(ds) \ + (ds.delimiter_depth ? ds.delimiters[ds.delimiter_depth - 1] : 0) + +#define push_delimiter(ds, character) \ + do \ + { \ + if (ds.delimiter_depth + 2 > ds.delimiter_space) \ + ds.delimiters = (char *)xrealloc \ + (ds.delimiters, (ds.delimiter_space += 10) * sizeof (char)); \ + ds.delimiters[ds.delimiter_depth] = character; \ + ds.delimiter_depth++; \ + } \ + while (0) + +#define pop_delimiter(ds) ds.delimiter_depth-- + +/* Return the next shell input character. This always reads characters + from shell_input_line; when that line is exhausted, it is time to + read the next line. This is called by read_token when the shell is + processing normal command input. */ + +/* This implements one-character lookahead/lookbehind across physical input + lines, to avoid something being lost because it's pushed back with + shell_ungetc when we're at the start of a line. */ +static int eol_ungetc_lookahead = 0; + +static int +shell_getc (remove_quoted_newline) + int remove_quoted_newline; +{ + register int i; + int c; + unsigned char uc; + static int mustpop = 0; + + QUIT; + + if (eol_ungetc_lookahead) + { + c = eol_ungetc_lookahead; + eol_ungetc_lookahead = 0; + return (c); + } + +#if defined (ALIAS) || defined (DPAREN_ARITHMETIC) + /* If shell_input_line[shell_input_line_index] == 0, but there is + something on the pushed list of strings, then we don't want to go + off and get another line. We let the code down below handle it. */ + + if (!shell_input_line || ((!shell_input_line[shell_input_line_index]) && + (pushed_string_list == (STRING_SAVER *)NULL))) +#else /* !ALIAS && !DPAREN_ARITHMETIC */ + if (!shell_input_line || !shell_input_line[shell_input_line_index]) +#endif /* !ALIAS && !DPAREN_ARITHMETIC */ + { + line_number++; + + restart_read: + + /* Allow immediate exit if interrupted during input. */ + QUIT; + + i = 0; + shell_input_line_terminator = 0; + + /* If the shell is interatctive, but not currently printing a prompt + (interactive_shell && interactive == 0), we don't want to print + notifies or cleanup the jobs -- we want to defer it until we do + print the next prompt. */ + if (interactive_shell == 0 || SHOULD_PROMPT()) + { +#if defined (JOB_CONTROL) + /* This can cause a problem when reading a command as the result + of a trap, when the trap is called from flush_child. This call + had better not cause jobs to disappear from the job table in + that case, or we will have big trouble. */ + notify_and_cleanup (); +#else /* !JOB_CONTROL */ + cleanup_dead_jobs (); +#endif /* !JOB_CONTROL */ + } + +#if defined (READLINE) + if (no_line_editing && SHOULD_PROMPT()) +#else + if (SHOULD_PROMPT()) +#endif + print_prompt (); + + if (bash_input.type == st_stream) + clearerr (stdin); + + while (1) + { + c = yy_getc (); + + /* Allow immediate exit if interrupted during input. */ + QUIT; + + if (c == '\0') + { +#if 0 + internal_warning ("shell_getc: ignored null byte in input"); +#endif + continue; + } + + RESIZE_MALLOCED_BUFFER (shell_input_line, i, 2, shell_input_line_size, 256); + + if (c == EOF) + { + if (bash_input.type == st_stream) + clearerr (stdin); + + if (i == 0) + shell_input_line_terminator = EOF; + + shell_input_line[i] = '\0'; + break; + } + + shell_input_line[i++] = c; + + if (c == '\n') + { + shell_input_line[--i] = '\0'; + current_command_line_count++; + break; + } + } + + shell_input_line_index = 0; + shell_input_line_len = i; /* == strlen (shell_input_line) */ + + set_line_mbstate (); + +#if defined (HISTORY) + if (remember_on_history && shell_input_line && shell_input_line[0]) + { + char *expansions; +# if defined (BANG_HISTORY) + int old_hist; + + /* If the current delimiter is a single quote, we should not be + performing history expansion, even if we're on a different + line from the original single quote. */ + old_hist = history_expansion_inhibited; + if (current_delimiter (dstack) == '\'') + history_expansion_inhibited = 1; +# endif + expansions = pre_process_line (shell_input_line, 1, 1); +# if defined (BANG_HISTORY) + history_expansion_inhibited = old_hist; +# endif + if (expansions != shell_input_line) + { + free (shell_input_line); + shell_input_line = expansions; + shell_input_line_len = shell_input_line ? + strlen (shell_input_line) : 0; + if (!shell_input_line_len) + current_command_line_count--; + + /* We have to force the xrealloc below because we don't know + the true allocated size of shell_input_line anymore. */ + shell_input_line_size = shell_input_line_len; + + set_line_mbstate (); + } + } + /* Try to do something intelligent with blank lines encountered while + entering multi-line commands. XXX - this is grotesque */ + else if (remember_on_history && shell_input_line && + shell_input_line[0] == '\0' && + current_command_line_count > 1) + { + if (current_delimiter (dstack)) + /* We know shell_input_line[0] == 0 and we're reading some sort of + quoted string. This means we've got a line consisting of only + a newline in a quoted string. We want to make sure this line + gets added to the history. */ + maybe_add_history (shell_input_line); + else + { + char *hdcs; + hdcs = history_delimiting_chars (); + if (hdcs && hdcs[0] == ';') + maybe_add_history (shell_input_line); + } + } + +#endif /* HISTORY */ + + if (shell_input_line) + { + /* Lines that signify the end of the shell's input should not be + echoed. */ + if (echo_input_at_read && (shell_input_line[0] || + shell_input_line_terminator != EOF)) + fprintf (stderr, "%s\n", shell_input_line); + } + else + { + shell_input_line_size = 0; + prompt_string_pointer = ¤t_prompt_string; + if (SHOULD_PROMPT ()) + prompt_again (); + goto restart_read; + } + + /* Add the newline to the end of this string, iff the string does + not already end in an EOF character. */ + if (shell_input_line_terminator != EOF) + { + if (shell_input_line_len + 3 > shell_input_line_size) + shell_input_line = (char *)xrealloc (shell_input_line, + 1 + (shell_input_line_size += 2)); + + shell_input_line[shell_input_line_len] = '\n'; + shell_input_line[shell_input_line_len + 1] = '\0'; + + set_line_mbstate (); + } + } + + uc = shell_input_line[shell_input_line_index]; + + if (uc) + shell_input_line_index++; + + if MBTEST(uc == '\\' && remove_quoted_newline && shell_input_line[shell_input_line_index] == '\n') + { + if (SHOULD_PROMPT ()) + prompt_again (); + line_number++; + goto restart_read; + } + +#if defined (ALIAS) || defined (DPAREN_ARITHMETIC) + /* If UC is NULL, we have reached the end of the current input string. If + pushed_string_list is non-empty, it's time to pop to the previous string + because we have fully consumed the result of the last alias expansion. + Do it transparently; just return the next character of the string popped + to. */ + if (!uc && (pushed_string_list != (STRING_SAVER *)NULL)) + { + pop_string (); + uc = shell_input_line[shell_input_line_index]; + if (uc) + shell_input_line_index++; + } +#endif /* ALIAS || DPAREN_ARITHMETIC */ + + if (!uc && shell_input_line_terminator == EOF) + return ((shell_input_line_index != 0) ? '\n' : EOF); + + return (uc); +} + +/* Put C back into the input for the shell. This might need changes for + HANDLE_MULTIBYTE around EOLs. Since we (currently) never push back a + character different than we read, shell_input_line_property doesn't need + to change when manipulating shell_input_line. The define for + last_shell_getc_is_singlebyte should take care of it, though. */ +static void +shell_ungetc (c) + int c; +{ + if (shell_input_line && shell_input_line_index) + shell_input_line[--shell_input_line_index] = c; + else + eol_ungetc_lookahead = c; +} + +#ifdef INCLUDE_UNUSED +/* Back the input pointer up by one, effectively `ungetting' a character. */ +static void +shell_ungetchar () +{ + if (shell_input_line && shell_input_line_index) + shell_input_line_index--; +} +#endif + +/* Discard input until CHARACTER is seen, then push that character back + onto the input stream. */ +static void +discard_until (character) + int character; +{ + int c; + + while ((c = shell_getc (0)) != EOF && c != character) + ; + + if (c != EOF) + shell_ungetc (c); +} + +void +execute_prompt_command (command) + char *command; +{ + char *last_lastarg; + sh_parser_state_t ps; + + save_parser_state (&ps); + last_lastarg = get_string_value ("_"); + if (last_lastarg) + last_lastarg = savestring (last_lastarg); + + parse_and_execute (savestring (command), "PROMPT_COMMAND", SEVAL_NONINT|SEVAL_NOHIST); + + restore_parser_state (&ps); + bind_variable ("_", last_lastarg); + FREE (last_lastarg); + + if (token_to_read == '\n') /* reset_parser was called */ + token_to_read = 0; +} + +/* Place to remember the token. We try to keep the buffer + at a reasonable size, but it can grow. */ +static char *token = (char *)NULL; + +/* Current size of the token buffer. */ +static int token_buffer_size; + +/* Command to read_token () explaining what we want it to do. */ +#define READ 0 +#define RESET 1 +#define prompt_is_ps1 \ + (!prompt_string_pointer || prompt_string_pointer == &ps1_prompt) + +/* Function for yyparse to call. yylex keeps track of + the last two tokens read, and calls read_token. */ +static int +yylex () +{ + if (interactive && (current_token == 0 || current_token == '\n')) + { + /* Before we print a prompt, we might have to check mailboxes. + We do this only if it is time to do so. Notice that only here + is the mail alarm reset; nothing takes place in check_mail () + except the checking of mail. Please don't change this. */ + if (prompt_is_ps1 && time_to_check_mail ()) + { + check_mail (); + reset_mail_timer (); + } + + /* Avoid printing a prompt if we're not going to read anything, e.g. + after resetting the parser with read_token (RESET). */ + if (token_to_read == 0 && SHOULD_PROMPT ()) + prompt_again (); + } + + two_tokens_ago = token_before_that; + token_before_that = last_read_token; + last_read_token = current_token; + current_token = read_token (READ); + return (current_token); +} + +/* When non-zero, we have read the required tokens + which allow ESAC to be the next one read. */ +static int esacs_needed_count; + +void +gather_here_documents () +{ + int r = 0; + while (need_here_doc) + { + make_here_document (redir_stack[r++]); + need_here_doc--; + } +} + +/* When non-zero, an open-brace used to create a group is awaiting a close + brace partner. */ +static int open_brace_count; + +#define command_token_position(token) \ + (((token) == ASSIGNMENT_WORD) || \ + ((token) != SEMI_SEMI && reserved_word_acceptable(token))) + +#define assignment_acceptable(token) \ + (command_token_position(token) && ((parser_state & PST_CASEPAT) == 0)) + +/* Check to see if TOKEN is a reserved word and return the token + value if it is. */ +#define CHECK_FOR_RESERVED_WORD(tok) \ + do { \ + if (!dollar_present && !quoted && \ + reserved_word_acceptable (last_read_token)) \ + { \ + int i; \ + for (i = 0; word_token_alist[i].word != (char *)NULL; i++) \ + if (STREQ (tok, word_token_alist[i].word)) \ + { \ + if ((parser_state & PST_CASEPAT) && (word_token_alist[i].token != ESAC)) \ + break; \ + if (word_token_alist[i].token == TIME && time_command_acceptable () == 0) \ + break; \ + if (word_token_alist[i].token == ESAC) \ + parser_state &= ~(PST_CASEPAT|PST_CASESTMT); \ + else if (word_token_alist[i].token == CASE) \ + parser_state |= PST_CASESTMT; \ + else if (word_token_alist[i].token == COND_END) \ + parser_state &= ~(PST_CONDCMD|PST_CONDEXPR); \ + else if (word_token_alist[i].token == COND_START) \ + parser_state |= PST_CONDCMD; \ + else if (word_token_alist[i].token == '{') \ + open_brace_count++; \ + else if (word_token_alist[i].token == '}' && open_brace_count) \ + open_brace_count--; \ + return (word_token_alist[i].token); \ + } \ + } \ + } while (0) + +#if defined (ALIAS) + + /* OK, we have a token. Let's try to alias expand it, if (and only if) + it's eligible. + + It is eligible for expansion if EXPAND_ALIASES is set, and + the token is unquoted and the last token read was a command + separator (or expand_next_token is set), and we are currently + processing an alias (pushed_string_list is non-empty) and this + token is not the same as the current or any previously + processed alias. + + Special cases that disqualify: + In a pattern list in a case statement (parser_state & PST_CASEPAT). */ + +static char * +mk_alexpansion (s) + char *s; +{ + int l; + char *r; + + l = strlen (s); + r = xmalloc (l + 2); + strcpy (r, s); + if (r[l -1] != ' ') + r[l++] = ' '; + r[l] = '\0'; + return r; +} + +static int +alias_expand_token (tokstr) + char *tokstr; +{ + char *expanded; + alias_t *ap; + + if (((parser_state & PST_ALEXPNEXT) || command_token_position (last_read_token)) && + (parser_state & PST_CASEPAT) == 0) + { + ap = find_alias (tokstr); + + /* Currently expanding this token. */ + if (ap && (ap->flags & AL_BEINGEXPANDED)) + return (NO_EXPANSION); + + /* mk_alexpansion puts an extra space on the end of the alias expansion, + so the lookahead by the parser works right. If this gets changed, + make sure the code in shell_getc that deals with reaching the end of + an expanded alias is changed with it. */ + expanded = ap ? mk_alexpansion (ap->value) : (char *)NULL; + + if (expanded) + { + push_string (expanded, ap->flags & AL_EXPANDNEXT, ap); + return (RE_READ_TOKEN); + } + else + /* This is an eligible token that does not have an expansion. */ + return (NO_EXPANSION); + } + return (NO_EXPANSION); +} +#endif /* ALIAS */ + +static int +time_command_acceptable () +{ +#if defined (COMMAND_TIMING) + switch (last_read_token) + { + case 0: + case ';': + case '\n': + case AND_AND: + case OR_OR: + case '&': + case DO: + case THEN: + case ELSE: + case '{': /* } */ + case '(': /* ) */ + return 1; + default: + return 0; + } +#else + return 0; +#endif /* COMMAND_TIMING */ +} + +/* Handle special cases of token recognition: + IN is recognized if the last token was WORD and the token + before that was FOR or CASE or SELECT. + + DO is recognized if the last token was WORD and the token + before that was FOR or SELECT. + + ESAC is recognized if the last token caused `esacs_needed_count' + to be set + + `{' is recognized if the last token as WORD and the token + before that was FUNCTION, or if we just parsed an arithmetic + `for' command. + + `}' is recognized if there is an unclosed `{' present. + + `-p' is returned as TIMEOPT if the last read token was TIME. + + ']]' is returned as COND_END if the parser is currently parsing + a conditional expression ((parser_state & PST_CONDEXPR) != 0) + + `time' is returned as TIME if and only if it is immediately + preceded by one of `;', `\n', `||', `&&', or `&'. +*/ + +static int +special_case_tokens (tokstr) + char *tokstr; +{ + if ((last_read_token == WORD) && +#if defined (SELECT_COMMAND) + ((token_before_that == FOR) || (token_before_that == CASE) || (token_before_that == SELECT)) && +#else + ((token_before_that == FOR) || (token_before_that == CASE)) && +#endif + (tokstr[0] == 'i' && tokstr[1] == 'n' && tokstr[2] == 0)) + { + if (token_before_that == CASE) + { + parser_state |= PST_CASEPAT; + esacs_needed_count++; + } + return (IN); + } + + if (last_read_token == WORD && +#if defined (SELECT_COMMAND) + (token_before_that == FOR || token_before_that == SELECT) && +#else + (token_before_that == FOR) && +#endif + (tokstr[0] == 'd' && tokstr[1] == 'o' && tokstr[2] == '\0')) + return (DO); + + /* Ditto for ESAC in the CASE case. + Specifically, this handles "case word in esac", which is a legal + construct, certainly because someone will pass an empty arg to the + case construct, and we don't want it to barf. Of course, we should + insist that the case construct has at least one pattern in it, but + the designers disagree. */ + if (esacs_needed_count) + { + esacs_needed_count--; + if (STREQ (tokstr, "esac")) + { + parser_state &= ~PST_CASEPAT; + return (ESAC); + } + } + + /* The start of a shell function definition. */ + if (parser_state & PST_ALLOWOPNBRC) + { + parser_state &= ~PST_ALLOWOPNBRC; + if (tokstr[0] == '{' && tokstr[1] == '\0') /* } */ + { + open_brace_count++; + function_bstart = line_number; + return ('{'); /* } */ + } + } + + /* We allow a `do' after a for ((...)) without an intervening + list_terminator */ + if (last_read_token == ARITH_FOR_EXPRS && tokstr[0] == 'd' && tokstr[1] == 'o' && !tokstr[2]) + return (DO); + if (last_read_token == ARITH_FOR_EXPRS && tokstr[0] == '{' && tokstr[1] == '\0') /* } */ + { + open_brace_count++; + return ('{'); /* } */ + } + + if (open_brace_count && reserved_word_acceptable (last_read_token) && tokstr[0] == '}' && !tokstr[1]) + { + open_brace_count--; /* { */ + return ('}'); + } + +#if defined (COMMAND_TIMING) + /* Handle -p after `time'. */ + if (last_read_token == TIME && tokstr[0] == '-' && tokstr[1] == 'p' && !tokstr[2]) + return (TIMEOPT); +#endif + +#if 0 +#if defined (COMMAND_TIMING) + if (STREQ (token, "time") && ((parser_state & PST_CASEPAT) == 0) && time_command_acceptable ()) + return (TIME); +#endif /* COMMAND_TIMING */ +#endif + +#if defined (COND_COMMAND) /* [[ */ + if ((parser_state & PST_CONDEXPR) && tokstr[0] == ']' && tokstr[1] == ']' && tokstr[2] == '\0') + return (COND_END); +#endif + + return (-1); +} + +/* Called from shell.c when Control-C is typed at top level. Or + by the error rule at top level. */ +void +reset_parser () +{ + dstack.delimiter_depth = 0; /* No delimiters found so far. */ + open_brace_count = 0; + + parser_state = 0; + +#if defined (ALIAS) || defined (DPAREN_ARITHMETIC) + if (pushed_string_list) + free_string_list (); +#endif /* ALIAS || DPAREN_ARITHMETIC */ + + if (shell_input_line) + { + free (shell_input_line); + shell_input_line = (char *)NULL; + shell_input_line_size = shell_input_line_index = 0; + } + + FREE (word_desc_to_read); + word_desc_to_read = (WORD_DESC *)NULL; + + last_read_token = '\n'; + token_to_read = '\n'; +} + +/* Read the next token. Command can be READ (normal operation) or + RESET (to normalize state). */ +static int +read_token (command) + int command; +{ + int character; /* Current character. */ + int peek_char; /* Temporary look-ahead character. */ + int result; /* The thing to return. */ + + if (command == RESET) + { + reset_parser (); + return ('\n'); + } + + if (token_to_read) + { + result = token_to_read; + if (token_to_read == WORD || token_to_read == ASSIGNMENT_WORD) + { + yylval.word = word_desc_to_read; + word_desc_to_read = (WORD_DESC *)NULL; + } + token_to_read = 0; + return (result); + } + +#if defined (COND_COMMAND) + if ((parser_state & (PST_CONDCMD|PST_CONDEXPR)) == PST_CONDCMD) + { + cond_lineno = line_number; + parser_state |= PST_CONDEXPR; + yylval.command = parse_cond_command (); + if (cond_token != COND_END) + { + cond_error (); + return (-1); + } + token_to_read = COND_END; + parser_state &= ~(PST_CONDEXPR|PST_CONDCMD); + return (COND_CMD); + } +#endif + +#if defined (ALIAS) + /* This is a place to jump back to once we have successfully expanded a + token with an alias and pushed the string with push_string () */ + re_read_token: +#endif /* ALIAS */ + + /* Read a single word from input. Start by skipping blanks. */ + while ((character = shell_getc (1)) != EOF && whitespace (character)) + ; + + if (character == EOF) + { + EOF_Reached = 1; + return (yacc_EOF); + } + + if MBTEST(character == '#' && (!interactive || interactive_comments)) + { + /* A comment. Discard until EOL or EOF, and then return a newline. */ + discard_until ('\n'); + shell_getc (0); + character = '\n'; /* this will take the next if statement and return. */ + } + + if (character == '\n') + { + /* If we're about to return an unquoted newline, we can go and collect + the text of any pending here document. */ + if (need_here_doc) + gather_here_documents (); + +#if defined (ALIAS) + parser_state &= ~PST_ALEXPNEXT; +#endif /* ALIAS */ + + return (character); + } + + /* Shell meta-characters. */ + if MBTEST(shellmeta (character) && ((parser_state & PST_DBLPAREN) == 0)) + { +#if defined (ALIAS) + /* Turn off alias tokenization iff this character sequence would + not leave us ready to read a command. */ + if (character == '<' || character == '>') + parser_state &= ~PST_ALEXPNEXT; +#endif /* ALIAS */ + + peek_char = shell_getc (1); + if (character == peek_char) + { + switch (character) + { + case '<': + /* If '<' then we could be at "<<" or at "<<-". We have to + look ahead one more character. */ + peek_char = shell_getc (1); + if (peek_char == '-') + return (LESS_LESS_MINUS); + else if (peek_char == '<') + return (LESS_LESS_LESS); + else + { + shell_ungetc (peek_char); + return (LESS_LESS); + } + + case '>': + return (GREATER_GREATER); + + case ';': + parser_state |= PST_CASEPAT; +#if defined (ALIAS) + parser_state &= ~PST_ALEXPNEXT; +#endif /* ALIAS */ + return (SEMI_SEMI); + + case '&': + return (AND_AND); + + case '|': + return (OR_OR); + +#if defined (DPAREN_ARITHMETIC) || defined (ARITH_FOR_COMMAND) + case '(': /* ) */ + result = parse_dparen (character); + if (result == -2) + break; + else + return result; +#endif + } + } + else if MBTEST(character == '<' && peek_char == '&') + return (LESS_AND); + else if MBTEST(character == '>' && peek_char == '&') + return (GREATER_AND); + else if MBTEST(character == '<' && peek_char == '>') + return (LESS_GREATER); + else if MBTEST(character == '>' && peek_char == '|') + return (GREATER_BAR); + else if MBTEST(peek_char == '>' && character == '&') + return (AND_GREATER); + + shell_ungetc (peek_char); + + /* If we look like we are reading the start of a function + definition, then let the reader know about it so that + we will do the right thing with `{'. */ + if MBTEST(character == ')' && last_read_token == '(' && token_before_that == WORD) + { + parser_state |= PST_ALLOWOPNBRC; +#if defined (ALIAS) + parser_state &= ~PST_ALEXPNEXT; +#endif /* ALIAS */ + function_dstart = line_number; + } + + /* case pattern lists may be preceded by an optional left paren. If + we're not trying to parse a case pattern list, the left paren + indicates a subshell. */ + if MBTEST(character == '(' && (parser_state & PST_CASEPAT) == 0) /* ) */ + parser_state |= PST_SUBSHELL; + /*(*/ + else if MBTEST((parser_state & PST_CASEPAT) && character == ')') + parser_state &= ~PST_CASEPAT; + /*(*/ + else if MBTEST((parser_state & PST_SUBSHELL) && character == ')') + parser_state &= ~PST_SUBSHELL; + +#if defined (PROCESS_SUBSTITUTION) + /* Check for the constructs which introduce process substitution. + Shells running in `posix mode' don't do process substitution. */ + if MBTEST(posixly_correct || ((character != '>' && character != '<') || peek_char != '(')) /*)*/ +#endif /* PROCESS_SUBSTITUTION */ + return (character); + } + + /* Hack <&- (close stdin) case. Also <&N- (dup and close). */ + if MBTEST(character == '-' && (last_read_token == LESS_AND || last_read_token == GREATER_AND)) + return (character); + + /* Okay, if we got this far, we have to read a word. Read one, + and then check it against the known ones. */ + result = read_token_word (character); +#if defined (ALIAS) + if (result == RE_READ_TOKEN) + goto re_read_token; +#endif + return result; +} + +/* + * Match a $(...) or other grouping construct. This has to handle embedded + * quoted strings ('', ``, "") and nested constructs. It also must handle + * reprompting the user, if necessary, after reading a newline (unless the + * P_NONL flag is passed), and returning correct error values if it reads + * EOF. + */ +#define P_FIRSTCLOSE 0x01 +#define P_ALLOWESC 0x02 +#define P_DQUOTE 0x04 + +static char matched_pair_error; +static char * +parse_matched_pair (qc, open, close, lenp, flags) + int qc; /* `"' if this construct is within double quotes */ + int open, close; + int *lenp, flags; +{ + int count, ch, was_dollar; + int pass_next_character, nestlen, ttranslen, start_lineno; + char *ret, *nestret, *ttrans; + int retind, retsize, rflags; + + count = 1; + pass_next_character = was_dollar = 0; + + /* RFLAGS is the set of flags we want to pass to recursive calls. */ + rflags = (qc == '"') ? P_DQUOTE : (flags & P_DQUOTE); + + ret = (char *)xmalloc (retsize = 64); + retind = 0; + + start_lineno = line_number; + while (count) + { + ch = shell_getc ((qc != '\'' || (flags & P_ALLOWESC)) && pass_next_character == 0); + if (ch == EOF) + { + free (ret); + parser_error (start_lineno, _("unexpected EOF while looking for matching `%c'"), close); + EOF_Reached = 1; /* XXX */ + return (&matched_pair_error); + } + + /* Possible reprompting. */ + if (ch == '\n' && SHOULD_PROMPT ()) + prompt_again (); + + if (pass_next_character) /* last char was backslash */ + { + pass_next_character = 0; + if (qc != '\'' && ch == '\n') /* double-quoted \ disappears. */ + { + if (retind > 0) retind--; /* swallow previously-added backslash */ + continue; + } + + RESIZE_MALLOCED_BUFFER (ret, retind, 2, retsize, 64); + if MBTEST(ch == CTLESC || ch == CTLNUL) + ret[retind++] = CTLESC; + ret[retind++] = ch; + continue; + } + else if MBTEST(ch == CTLESC || ch == CTLNUL) /* special shell escapes */ + { + RESIZE_MALLOCED_BUFFER (ret, retind, 2, retsize, 64); + ret[retind++] = CTLESC; + ret[retind++] = ch; + continue; + } + else if MBTEST(ch == close) /* ending delimiter */ + count--; +#if 1 + /* handle nested ${...} specially. */ + else if MBTEST(open != close && was_dollar && open == '{' && ch == open) /* } */ + count++; +#endif + else if MBTEST(((flags & P_FIRSTCLOSE) == 0) && ch == open) /* nested begin */ + count++; + + /* Add this character. */ + RESIZE_MALLOCED_BUFFER (ret, retind, 1, retsize, 64); + ret[retind++] = ch; + + if (open == '\'') /* '' inside grouping construct */ + { + if MBTEST((flags & P_ALLOWESC) && ch == '\\') + pass_next_character++; + continue; + } + + if MBTEST(ch == '\\') /* backslashes */ + pass_next_character++; + + if (open != close) /* a grouping construct */ + { + if MBTEST(shellquote (ch)) + { + /* '', ``, or "" inside $(...) or other grouping construct. */ + push_delimiter (dstack, ch); + if MBTEST(was_dollar && ch == '\'') /* $'...' inside group */ + nestret = parse_matched_pair (ch, ch, ch, &nestlen, P_ALLOWESC|rflags); + else + nestret = parse_matched_pair (ch, ch, ch, &nestlen, rflags); + pop_delimiter (dstack); + if (nestret == &matched_pair_error) + { + free (ret); + return &matched_pair_error; + } + if MBTEST(was_dollar && ch == '\'' && (extended_quote || (rflags & P_DQUOTE) == 0)) + { + /* Translate $'...' here. */ + ttrans = ansiexpand (nestret, 0, nestlen - 1, &ttranslen); + xfree (nestret); + nestret = sh_single_quote (ttrans); + free (ttrans); + nestlen = strlen (nestret); + retind -= 2; /* back up before the $' */ + } + else if MBTEST(was_dollar && ch == '"' && (extended_quote || (rflags & P_DQUOTE) == 0)) + { + /* Locale expand $"..." here. */ + ttrans = localeexpand (nestret, 0, nestlen - 1, start_lineno, &ttranslen); + xfree (nestret); + nestret = (char *)xmalloc (ttranslen + 3); + nestret[0] = '"'; + strcpy (nestret + 1, ttrans); + nestret[ttranslen + 1] = '"'; + nestret[ttranslen += 2] = '\0'; + free (ttrans); + nestlen = ttranslen; + retind -= 2; /* back up before the $" */ + } + + if (nestlen) + { + RESIZE_MALLOCED_BUFFER (ret, retind, nestlen, retsize, 64); + strcpy (ret + retind, nestret); + retind += nestlen; + } + FREE (nestret); + } + } + /* Parse an old-style command substitution within double quotes as a + single word. */ + /* XXX - sh and ksh93 don't do this - XXX */ + else if MBTEST(open == '"' && ch == '`') + { + nestret = parse_matched_pair (0, '`', '`', &nestlen, rflags); + if (nestret == &matched_pair_error) + { + free (ret); + return &matched_pair_error; + } + if (nestlen) + { + RESIZE_MALLOCED_BUFFER (ret, retind, nestlen, retsize, 64); + strcpy (ret + retind, nestret); + retind += nestlen; + } + FREE (nestret); + } + else if MBTEST(was_dollar && (ch == '(' || ch == '{' || ch == '[')) /* ) } ] */ + /* check for $(), $[], or ${} inside quoted string. */ + { + if (open == ch) /* undo previous increment */ + count--; + if (ch == '(') /* ) */ + nestret = parse_matched_pair (0, '(', ')', &nestlen, rflags); + else if (ch == '{') /* } */ + nestret = parse_matched_pair (0, '{', '}', &nestlen, P_FIRSTCLOSE|rflags); + else if (ch == '[') /* ] */ + nestret = parse_matched_pair (0, '[', ']', &nestlen, rflags); + if (nestret == &matched_pair_error) + { + free (ret); + return &matched_pair_error; + } + if (nestlen) + { + RESIZE_MALLOCED_BUFFER (ret, retind, nestlen, retsize, 64); + strcpy (ret + retind, nestret); + retind += nestlen; + } + FREE (nestret); + } + was_dollar = MBTEST(ch == '$'); + } + + ret[retind] = '\0'; + if (lenp) + *lenp = retind; + return ret; +} + +#if defined (DPAREN_ARITHMETIC) || defined (ARITH_FOR_COMMAND) +/* Parse a double-paren construct. It can be either an arithmetic + command, an arithmetic `for' command, or a nested subshell. Returns + the parsed token, -1 on error, or -2 if we didn't do anything and + should just go on. */ +static int +parse_dparen (c) + int c; +{ + int cmdtyp, len, sline; + char *wval, *wv2; + WORD_DESC *wd; + +#if defined (ARITH_FOR_COMMAND) + if (last_read_token == FOR) + { + arith_for_lineno = line_number; + cmdtyp = parse_arith_cmd (&wval, 0); + if (cmdtyp == 1) + { + wd = make_word (wval); + yylval.word_list = make_word_list (wd, (WORD_LIST *)NULL); + free (wval); + return (ARITH_FOR_EXPRS); + } + else + return -1; /* ERROR */ + } +#endif + +#if defined (DPAREN_ARITHMETIC) + if (reserved_word_acceptable (last_read_token)) + { + sline = line_number; +#if 0 + cmdtyp = parse_arith_cmd (&wval, 1); +#else + cmdtyp = parse_arith_cmd (&wval, 0); +#endif + if (cmdtyp == 1) /* arithmetic command */ + { + wd = make_word (wval); +#if 0 + wd->flags = W_QUOTED; +#else + wd->flags = W_QUOTED|W_NOSPLIT|W_NOGLOB; +#endif + yylval.word_list = make_word_list (wd, (WORD_LIST *)NULL); + free (wval); /* make_word copies it */ + return (ARITH_CMD); + } + else if (cmdtyp == 0) /* nested subshell */ + { + push_string (wval, 0, (alias_t *)NULL); + if ((parser_state & PST_CASEPAT) == 0) + parser_state |= PST_SUBSHELL; + return (c); + } + else /* ERROR */ + return -1; + } +#endif + + return -2; /* XXX */ +} + +/* We've seen a `(('. Look for the matching `))'. If we get it, return 1. + If not, assume it's a nested subshell for backwards compatibility and + return 0. In any case, put the characters we've consumed into a locally- + allocated buffer and make *ep point to that buffer. Return -1 on an + error, for example EOF. */ +static int +parse_arith_cmd (ep, adddq) + char **ep; + int adddq; +{ + int exp_lineno, rval, c; + char *ttok, *tokstr; + int ttoklen; + + exp_lineno = line_number; + ttok = parse_matched_pair (0, '(', ')', &ttoklen, 0); + rval = 1; + if (ttok == &matched_pair_error) + return -1; + /* Check that the next character is the closing right paren. If + not, this is a syntax error. ( */ + c = shell_getc (0); + if MBTEST(c != ')') + rval = 0; + + tokstr = (char *)xmalloc (ttoklen + 4); + + /* if ADDDQ != 0 then (( ... )) -> "..." */ + if (rval == 1 && adddq) /* arith cmd, add double quotes */ + { + tokstr[0] = '"'; + strncpy (tokstr + 1, ttok, ttoklen - 1); + tokstr[ttoklen] = '"'; + tokstr[ttoklen+1] = '\0'; + } + else if (rval == 1) /* arith cmd, don't add double quotes */ + { + strncpy (tokstr, ttok, ttoklen - 1); + tokstr[ttoklen-1] = '\0'; + } + else /* nested subshell */ + { + tokstr[0] = '('; + strncpy (tokstr + 1, ttok, ttoklen - 1); + tokstr[ttoklen] = ')'; + tokstr[ttoklen+1] = c; + tokstr[ttoklen+2] = '\0'; + } + + *ep = tokstr; + FREE (ttok); + return rval; +} +#endif /* DPAREN_ARITHMETIC || ARITH_FOR_COMMAND */ + +#if defined (COND_COMMAND) +static void +cond_error () +{ + char *etext; + + if (EOF_Reached && cond_token != COND_ERROR) /* [[ */ + parser_error (cond_lineno, _("unexpected EOF while looking for `]]'")); + else if (cond_token != COND_ERROR) + { + if (etext = error_token_from_token (cond_token)) + { + parser_error (cond_lineno, _("syntax error in conditional expression: unexpected token `%s'"), etext); + free (etext); + } + else + parser_error (cond_lineno, _("syntax error in conditional expression")); + } +} + +static COND_COM * +cond_expr () +{ + return (cond_or ()); +} + +static COND_COM * +cond_or () +{ + COND_COM *l, *r; + + l = cond_and (); + if (cond_token == OR_OR) + { + r = cond_or (); + l = make_cond_node (COND_OR, (WORD_DESC *)NULL, l, r); + } + return l; +} + +static COND_COM * +cond_and () +{ + COND_COM *l, *r; + + l = cond_term (); + if (cond_token == AND_AND) + { + r = cond_and (); + l = make_cond_node (COND_AND, (WORD_DESC *)NULL, l, r); + } + return l; +} + +static int +cond_skip_newlines () +{ + while ((cond_token = read_token (READ)) == '\n') + { + if (SHOULD_PROMPT ()) + prompt_again (); + } + return (cond_token); +} + +#define COND_RETURN_ERROR() \ + do { cond_token = COND_ERROR; return ((COND_COM *)NULL); } while (0) + +static COND_COM * +cond_term () +{ + WORD_DESC *op; + COND_COM *term, *tleft, *tright; + int tok, lineno; + char *etext; + + /* Read a token. It can be a left paren, a `!', a unary operator, or a + word that should be the first argument of a binary operator. Start by + skipping newlines, since this is a compound command. */ + tok = cond_skip_newlines (); + lineno = line_number; + if (tok == COND_END) + { + COND_RETURN_ERROR (); + } + else if (tok == '(') + { + term = cond_expr (); + if (cond_token != ')') + { + if (term) + dispose_cond_node (term); /* ( */ + if (etext = error_token_from_token (cond_token)) + { + parser_error (lineno, _("unexpected token `%s', expected `)'"), etext); + free (etext); + } + else + parser_error (lineno, _("expected `)'")); + COND_RETURN_ERROR (); + } + term = make_cond_node (COND_EXPR, (WORD_DESC *)NULL, term, (COND_COM *)NULL); + (void)cond_skip_newlines (); + } + else if (tok == BANG || (tok == WORD && (yylval.word->word[0] == '!' && yylval.word->word[1] == '\0'))) + { + if (tok == WORD) + dispose_word (yylval.word); /* not needed */ + term = cond_term (); + if (term) + term->flags |= CMD_INVERT_RETURN; + } + else if (tok == WORD && test_unop (yylval.word->word)) + { + op = yylval.word; + tok = read_token (READ); + if (tok == WORD) + { + tleft = make_cond_node (COND_TERM, yylval.word, (COND_COM *)NULL, (COND_COM *)NULL); + term = make_cond_node (COND_UNARY, op, tleft, (COND_COM *)NULL); + } + else + { + dispose_word (op); + if (etext = error_token_from_token (tok)) + { + parser_error (line_number, _("unexpected argument `%s' to conditional unary operator"), etext); + free (etext); + } + else + parser_error (line_number, _("unexpected argument to conditional unary operator")); + COND_RETURN_ERROR (); + } + + (void)cond_skip_newlines (); + } + else if (tok == WORD) /* left argument to binary operator */ + { + /* lhs */ + tleft = make_cond_node (COND_TERM, yylval.word, (COND_COM *)NULL, (COND_COM *)NULL); + + /* binop */ + tok = read_token (READ); + if (tok == WORD && test_binop (yylval.word->word)) + op = yylval.word; +#if defined (COND_REGEXP) + else if (tok == WORD && STREQ (yylval.word->word,"=~")) + op = yylval.word; +#endif + else if (tok == '<' || tok == '>') + op = make_word_from_token (tok); /* ( */ + /* There should be a check before blindly accepting the `)' that we have + seen the opening `('. */ + else if (tok == COND_END || tok == AND_AND || tok == OR_OR || tok == ')') + { + /* Special case. [[ x ]] is equivalent to [[ -n x ]], just like + the test command. Similarly for [[ x && expr ]] or + [[ x || expr ]] or [[ (x) ]]. */ + op = make_word ("-n"); + term = make_cond_node (COND_UNARY, op, tleft, (COND_COM *)NULL); + cond_token = tok; + return (term); + } + else + { + if (etext = error_token_from_token (tok)) + { + parser_error (line_number, _("unexpected token `%s', conditional binary operator expected"), etext); + free (etext); + } + else + parser_error (line_number, _("conditional binary operator expected")); + dispose_cond_node (tleft); + COND_RETURN_ERROR (); + } + + /* rhs */ + tok = read_token (READ); + if (tok == WORD) + { + tright = make_cond_node (COND_TERM, yylval.word, (COND_COM *)NULL, (COND_COM *)NULL); + term = make_cond_node (COND_BINARY, op, tleft, tright); + } + else + { + if (etext = error_token_from_token (tok)) + { + parser_error (line_number, _("unexpected argument `%s' to conditional binary operator"), etext); + free (etext); + } + else + parser_error (line_number, _("unexpected argument to conditional binary operator")); + dispose_cond_node (tleft); + dispose_word (op); + COND_RETURN_ERROR (); + } + + (void)cond_skip_newlines (); + } + else + { + if (tok < 256) + parser_error (line_number, _("unexpected token `%c' in conditional command"), tok); + else if (etext = error_token_from_token (tok)) + { + parser_error (line_number, _("unexpected token `%s' in conditional command"), etext); + free (etext); + } + else + parser_error (line_number, _("unexpected token %d in conditional command"), tok); + COND_RETURN_ERROR (); + } + return (term); +} + +/* This is kind of bogus -- we slip a mini recursive-descent parser in + here to handle the conditional statement syntax. */ +static COMMAND * +parse_cond_command () +{ + COND_COM *cexp; + + cexp = cond_expr (); + return (make_cond_command (cexp)); +} +#endif + +#if defined (ARRAY_VARS) +/* When this is called, it's guaranteed that we don't care about anything + in t beyond i. We do save and restore the chars, though. */ +static int +token_is_assignment (t, i) + char *t; + int i; +{ + unsigned char c, c1; + int r; + + c = t[i]; c1 = t[i+1]; + t[i] = '='; t[i+1] = '\0'; + r = assignment (t, (parser_state & PST_COMPASSIGN) != 0); + t[i] = c; t[i+1] = c1; + return r; +} + +static int +token_is_ident (t, i) + char *t; + int i; +{ + unsigned char c; + int r; + + c = t[i]; + t[i] = '\0'; + r = legal_identifier (t); + t[i] = c; + return r; +} +#endif + +static int +read_token_word (character) + int character; +{ + /* The value for YYLVAL when a WORD is read. */ + WORD_DESC *the_word; + + /* Index into the token that we are building. */ + int token_index; + + /* ALL_DIGITS becomes zero when we see a non-digit. */ + int all_digit_token; + + /* DOLLAR_PRESENT becomes non-zero if we see a `$'. */ + int dollar_present; + + /* QUOTED becomes non-zero if we see one of ("), ('), (`), or (\). */ + int quoted; + + /* Non-zero means to ignore the value of the next character, and just + to add it no matter what. */ + int pass_next_character; + + /* The current delimiting character. */ + int cd; + int result, peek_char; + char *ttok, *ttrans; + int ttoklen, ttranslen; + intmax_t lvalue; + + if (token_buffer_size < TOKEN_DEFAULT_INITIAL_SIZE) + token = (char *)xrealloc (token, token_buffer_size = TOKEN_DEFAULT_INITIAL_SIZE); + + token_index = 0; + all_digit_token = DIGIT (character); + dollar_present = quoted = pass_next_character = 0; + + for (;;) + { + if (character == EOF) + goto got_token; + + if (pass_next_character) + { + pass_next_character = 0; + goto got_character; + } + + cd = current_delimiter (dstack); + + /* Handle backslashes. Quote lots of things when not inside of + double-quotes, quote some things inside of double-quotes. */ + if MBTEST(character == '\\') + { + peek_char = shell_getc (0); + + /* Backslash-newline is ignored in all cases except + when quoted with single quotes. */ + if (peek_char == '\n') + { + character = '\n'; + goto next_character; + } + else + { + shell_ungetc (peek_char); + + /* If the next character is to be quoted, note it now. */ + if (cd == 0 || cd == '`' || + (cd == '"' && peek_char >= 0 && (sh_syntaxtab[peek_char] & CBSDQUOTE))) + pass_next_character++; + + quoted = 1; + goto got_character; + } + } + + /* Parse a matched pair of quote characters. */ + if MBTEST(shellquote (character)) + { + push_delimiter (dstack, character); + ttok = parse_matched_pair (character, character, character, &ttoklen, 0); + pop_delimiter (dstack); + if (ttok == &matched_pair_error) + return -1; /* Bail immediately. */ + RESIZE_MALLOCED_BUFFER (token, token_index, ttoklen + 2, + token_buffer_size, TOKEN_DEFAULT_GROW_SIZE); + token[token_index++] = character; + strcpy (token + token_index, ttok); + token_index += ttoklen; + all_digit_token = 0; + quoted = 1; + dollar_present |= (character == '"' && strchr (ttok, '$') != 0); + FREE (ttok); + goto next_character; + } + +#ifdef EXTENDED_GLOB + /* Parse a ksh-style extended pattern matching specification. */ + if (extended_glob && PATTERN_CHAR (character)) + { + peek_char = shell_getc (1); + if MBTEST(peek_char == '(') /* ) */ + { + push_delimiter (dstack, peek_char); + ttok = parse_matched_pair (cd, '(', ')', &ttoklen, 0); + pop_delimiter (dstack); + if (ttok == &matched_pair_error) + return -1; /* Bail immediately. */ + RESIZE_MALLOCED_BUFFER (token, token_index, ttoklen + 2, + token_buffer_size, + TOKEN_DEFAULT_GROW_SIZE); + token[token_index++] = character; + token[token_index++] = peek_char; + strcpy (token + token_index, ttok); + token_index += ttoklen; + FREE (ttok); + dollar_present = all_digit_token = 0; + goto next_character; + } + else + shell_ungetc (peek_char); + } +#endif /* EXTENDED_GLOB */ + + /* If the delimiter character is not single quote, parse some of + the shell expansions that must be read as a single word. */ + if (shellexp (character)) + { + peek_char = shell_getc (1); + /* $(...), <(...), >(...), $((...)), ${...}, and $[...] constructs */ + if MBTEST(peek_char == '(' || \ + ((peek_char == '{' || peek_char == '[') && character == '$')) /* ) ] } */ + { + if (peek_char == '{') /* } */ + ttok = parse_matched_pair (cd, '{', '}', &ttoklen, P_FIRSTCLOSE); + else if (peek_char == '(') /* ) */ + { + /* XXX - push and pop the `(' as a delimiter for use by + the command-oriented-history code. This way newlines + appearing in the $(...) string get added to the + history literally rather than causing a possibly- + incorrect `;' to be added. ) */ + push_delimiter (dstack, peek_char); + ttok = parse_matched_pair (cd, '(', ')', &ttoklen, 0); + pop_delimiter (dstack); + } + else + ttok = parse_matched_pair (cd, '[', ']', &ttoklen, 0); + if (ttok == &matched_pair_error) + return -1; /* Bail immediately. */ + RESIZE_MALLOCED_BUFFER (token, token_index, ttoklen + 2, + token_buffer_size, + TOKEN_DEFAULT_GROW_SIZE); + token[token_index++] = character; + token[token_index++] = peek_char; + strcpy (token + token_index, ttok); + token_index += ttoklen; + FREE (ttok); + dollar_present = 1; + all_digit_token = 0; + goto next_character; + } + /* This handles $'...' and $"..." new-style quoted strings. */ + else if MBTEST(character == '$' && (peek_char == '\'' || peek_char == '"')) + { + int first_line; + + first_line = line_number; + push_delimiter (dstack, peek_char); + ttok = parse_matched_pair (peek_char, peek_char, peek_char, + &ttoklen, + (peek_char == '\'') ? P_ALLOWESC : 0); + pop_delimiter (dstack); + if (ttok == &matched_pair_error) + return -1; + if (peek_char == '\'') + { + ttrans = ansiexpand (ttok, 0, ttoklen - 1, &ttranslen); + free (ttok); + /* Insert the single quotes and correctly quote any + embedded single quotes (allowed because P_ALLOWESC was + passed to parse_matched_pair). */ + ttok = sh_single_quote (ttrans); + free (ttrans); + ttrans = ttok; + ttranslen = strlen (ttrans); + } + else + { + /* Try to locale-expand the converted string. */ + ttrans = localeexpand (ttok, 0, ttoklen - 1, first_line, &ttranslen); + free (ttok); + + /* Add the double quotes back */ + ttok = (char *)xmalloc (ttranslen + 3); + ttok[0] = '"'; + strcpy (ttok + 1, ttrans); + ttok[ttranslen + 1] = '"'; + ttok[ttranslen += 2] = '\0'; + free (ttrans); + ttrans = ttok; + } + + RESIZE_MALLOCED_BUFFER (token, token_index, ttranslen + 2, + token_buffer_size, + TOKEN_DEFAULT_GROW_SIZE); + strcpy (token + token_index, ttrans); + token_index += ttranslen; + FREE (ttrans); + quoted = 1; + all_digit_token = 0; + goto next_character; + } + /* This could eventually be extended to recognize all of the + shell's single-character parameter expansions, and set flags.*/ + else if MBTEST(character == '$' && peek_char == '$') + { + ttok = (char *)xmalloc (3); + ttok[0] = ttok[1] = '$'; + ttok[2] = '\0'; + RESIZE_MALLOCED_BUFFER (token, token_index, 3, + token_buffer_size, + TOKEN_DEFAULT_GROW_SIZE); + strcpy (token + token_index, ttok); + token_index += 2; + dollar_present = 1; + all_digit_token = 0; + FREE (ttok); + goto next_character; + } + else + shell_ungetc (peek_char); + } + +#if defined (ARRAY_VARS) + /* Identify possible array subscript assignment; match [...] */ + else if MBTEST(character == '[' && token_index > 0 && assignment_acceptable (last_read_token) && token_is_ident (token, token_index)) /* ] */ + { + ttok = parse_matched_pair (cd, '[', ']', &ttoklen, 0); + if (ttok == &matched_pair_error) + return -1; /* Bail immediately. */ + RESIZE_MALLOCED_BUFFER (token, token_index, ttoklen + 2, + token_buffer_size, + TOKEN_DEFAULT_GROW_SIZE); + token[token_index++] = character; + strcpy (token + token_index, ttok); + token_index += ttoklen; + FREE (ttok); + all_digit_token = 0; + goto next_character; + } + /* Identify possible compound array variable assignment. */ + else if MBTEST(character == '=' && token_index > 0 && token_is_assignment (token, token_index)) + { + peek_char = shell_getc (1); + if MBTEST(peek_char == '(') /* ) */ + { + ttok = parse_compound_assignment (&ttoklen); + + RESIZE_MALLOCED_BUFFER (token, token_index, ttoklen + 4, + token_buffer_size, + TOKEN_DEFAULT_GROW_SIZE); + + token[token_index++] = '='; + token[token_index++] = '('; + if (ttok) + { + strcpy (token + token_index, ttok); + token_index += ttoklen; + } + token[token_index++] = ')'; + FREE (ttok); + all_digit_token = 0; + goto next_character; + } + else + shell_ungetc (peek_char); + } +#endif + + /* When not parsing a multi-character word construct, shell meta- + characters break words. */ + if MBTEST(shellbreak (character)) + { + shell_ungetc (character); + goto got_token; + } + + got_character: + + all_digit_token &= DIGIT (character); + dollar_present |= character == '$'; + + if (character == CTLESC || character == CTLNUL) + token[token_index++] = CTLESC; + + token[token_index++] = character; + + RESIZE_MALLOCED_BUFFER (token, token_index, 1, token_buffer_size, + TOKEN_DEFAULT_GROW_SIZE); + + next_character: + if (character == '\n' && SHOULD_PROMPT ()) + prompt_again (); + + /* We want to remove quoted newlines (that is, a \ pair) + unless we are within single quotes or pass_next_character is + set (the shell equivalent of literal-next). */ + cd = current_delimiter (dstack); + character = shell_getc (cd != '\'' && pass_next_character == 0); + } /* end for (;;) */ + +got_token: + + token[token_index] = '\0'; + + /* Check to see what thing we should return. If the last_read_token + is a `<', or a `&', or the character which ended this token is + a '>' or '<', then, and ONLY then, is this input token a NUMBER. + Otherwise, it is just a word, and should be returned as such. */ + if MBTEST(all_digit_token && (character == '<' || character == '>' || \ + last_read_token == LESS_AND || \ + last_read_token == GREATER_AND)) + { + if (legal_number (token, &lvalue) && (int)lvalue == lvalue) + yylval.number = lvalue; + else + yylval.number = -1; + return (NUMBER); + } + + /* Check for special case tokens. */ + result = (last_shell_getc_is_singlebyte) ? special_case_tokens (token) : -1; + if (result >= 0) + return result; + +#if defined (ALIAS) + /* Posix.2 does not allow reserved words to be aliased, so check for all + of them, including special cases, before expanding the current token + as an alias. */ + if MBTEST(posixly_correct) + CHECK_FOR_RESERVED_WORD (token); + + /* Aliases are expanded iff EXPAND_ALIASES is non-zero, and quoting + inhibits alias expansion. */ + if (expand_aliases && quoted == 0) + { + result = alias_expand_token (token); + if (result == RE_READ_TOKEN) + return (RE_READ_TOKEN); + else if (result == NO_EXPANSION) + parser_state &= ~PST_ALEXPNEXT; + } + + /* If not in Posix.2 mode, check for reserved words after alias + expansion. */ + if MBTEST(posixly_correct == 0) +#endif + CHECK_FOR_RESERVED_WORD (token); + + the_word = (WORD_DESC *)xmalloc (sizeof (WORD_DESC)); + the_word->word = (char *)xmalloc (1 + token_index); + the_word->flags = 0; + strcpy (the_word->word, token); + if (dollar_present) + the_word->flags |= W_HASDOLLAR; + if (quoted) + the_word->flags |= W_QUOTED; + /* A word is an assignment if it appears at the beginning of a + simple command, or after another assignment word. This is + context-dependent, so it cannot be handled in the grammar. */ + if (assignment (token, (parser_state & PST_COMPASSIGN) != 0)) + { + the_word->flags |= W_ASSIGNMENT; + /* Don't perform word splitting on assignment statements. */ + if (assignment_acceptable (last_read_token) || (parser_state & PST_COMPASSIGN) != 0) + the_word->flags |= W_NOSPLIT; + } + + yylval.word = the_word; + + result = ((the_word->flags & (W_ASSIGNMENT|W_NOSPLIT)) == (W_ASSIGNMENT|W_NOSPLIT)) + ? ASSIGNMENT_WORD : WORD; + + switch (last_read_token) + { + case FUNCTION: + parser_state |= PST_ALLOWOPNBRC; + function_dstart = line_number; + break; + case CASE: + case SELECT: + case FOR: + if (word_top < MAX_CASE_NEST) + word_top++; + word_lineno[word_top] = line_number; + break; + } + + return (result); +} + +/* Return 1 if TOKSYM is a token that after being read would allow + a reserved word to be seen, else 0. */ +static int +reserved_word_acceptable (toksym) + int toksym; +{ + switch (toksym) + { + case '\n': + case ';': + case '(': + case ')': + case '|': + case '&': + case '{': + case '}': /* XXX */ + case AND_AND: + case BANG: + case DO: + case DONE: + case ELIF: + case ELSE: + case ESAC: + case FI: + case IF: + case OR_OR: + case SEMI_SEMI: + case THEN: + case TIME: + case TIMEOPT: + case UNTIL: + case WHILE: + case 0: + return 1; + default: + return 0; + } +} + +/* Return the index of TOKEN in the alist of reserved words, or -1 if + TOKEN is not a shell reserved word. */ +int +find_reserved_word (tokstr) + char *tokstr; +{ + int i; + for (i = 0; word_token_alist[i].word; i++) + if (STREQ (tokstr, word_token_alist[i].word)) + return i; + return -1; +} + +#if 0 +#if defined (READLINE) +/* Called after each time readline is called. This insures that whatever + the new prompt string is gets propagated to readline's local prompt + variable. */ +static void +reset_readline_prompt () +{ + char *temp_prompt; + + if (prompt_string_pointer) + { + temp_prompt = (*prompt_string_pointer) + ? decode_prompt_string (*prompt_string_pointer) + : (char *)NULL; + + if (temp_prompt == 0) + { + temp_prompt = (char *)xmalloc (1); + temp_prompt[0] = '\0'; + } + + FREE (current_readline_prompt); + current_readline_prompt = temp_prompt; + } +} +#endif /* READLINE */ +#endif /* 0 */ + +#if defined (HISTORY) +/* A list of tokens which can be followed by newlines, but not by + semi-colons. When concatenating multiple lines of history, the + newline separator for such tokens is replaced with a space. */ +static int no_semi_successors[] = { + '\n', '{', '(', ')', ';', '&', '|', + CASE, DO, ELSE, IF, SEMI_SEMI, THEN, UNTIL, WHILE, AND_AND, OR_OR, IN, + 0 +}; + +/* If we are not within a delimited expression, try to be smart + about which separators can be semi-colons and which must be + newlines. Returns the string that should be added into the + history entry. */ +char * +history_delimiting_chars () +{ + register int i; + + if (dstack.delimiter_depth != 0) + return ("\n"); + + /* First, handle some special cases. */ + /*(*/ + /* If we just read `()', assume it's a function definition, and don't + add a semicolon. If the token before the `)' was not `(', and we're + not in the midst of parsing a case statement, assume it's a + parenthesized command and add the semicolon. */ + /*)(*/ + if (token_before_that == ')') + { + if (two_tokens_ago == '(') /*)*/ /* function def */ + return " "; + /* This does not work for subshells inside case statement + command lists. It's a suboptimal solution. */ + else if (parser_state & PST_CASESTMT) /* case statement pattern */ + return " "; + else + return "; "; /* (...) subshell */ + } + else if (token_before_that == WORD && two_tokens_ago == FUNCTION) + return " "; /* function def using `function name' without `()' */ + + else if (token_before_that == WORD && two_tokens_ago == FOR) + { + /* Tricky. `for i\nin ...' should not have a semicolon, but + `for i\ndo ...' should. We do what we can. */ + for (i = shell_input_line_index; whitespace(shell_input_line[i]); i++) + ; + if (shell_input_line[i] && shell_input_line[i] == 'i' && shell_input_line[i+1] == 'n') + return " "; + return ";"; + } + + for (i = 0; no_semi_successors[i]; i++) + { + if (token_before_that == no_semi_successors[i]) + return (" "); + } + + return ("; "); +} +#endif /* HISTORY */ + +/* Issue a prompt, or prepare to issue a prompt when the next character + is read. */ +static void +prompt_again () +{ + char *temp_prompt; + + if (interactive == 0 || expanding_alias()) /* XXX */ + return; + + ps1_prompt = get_string_value ("PS1"); + ps2_prompt = get_string_value ("PS2"); + + if (!prompt_string_pointer) + prompt_string_pointer = &ps1_prompt; + + temp_prompt = *prompt_string_pointer + ? decode_prompt_string (*prompt_string_pointer) + : (char *)NULL; + + if (temp_prompt == 0) + { + temp_prompt = (char *)xmalloc (1); + temp_prompt[0] = '\0'; + } + + current_prompt_string = *prompt_string_pointer; + prompt_string_pointer = &ps2_prompt; + +#if defined (READLINE) + if (!no_line_editing) + { + FREE (current_readline_prompt); + current_readline_prompt = temp_prompt; + } + else +#endif /* READLINE */ + { + FREE (current_decoded_prompt); + current_decoded_prompt = temp_prompt; + } +} + +int +get_current_prompt_level () +{ + return ((current_prompt_string && current_prompt_string == ps2_prompt) ? 2 : 1); +} + +void +set_current_prompt_level (x) + int x; +{ + prompt_string_pointer = (x == 2) ? &ps2_prompt : &ps1_prompt; + current_prompt_string = *prompt_string_pointer; +} + +static void +print_prompt () +{ + fprintf (stderr, "%s", current_decoded_prompt); + fflush (stderr); +} + +/* Return a string which will be printed as a prompt. The string + may contain special characters which are decoded as follows: + + \a bell (ascii 07) + \d the date in Day Mon Date format + \e escape (ascii 033) + \h the hostname up to the first `.' + \H the hostname + \j the number of active jobs + \l the basename of the shell's tty device name + \n CRLF + \r CR + \s the name of the shell + \t the time in 24-hour hh:mm:ss format + \T the time in 12-hour hh:mm:ss format + \@ the time in 12-hour hh:mm am/pm format + \A the time in 24-hour hh:mm format + \D{fmt} the result of passing FMT to strftime(3) + \u your username + \v the version of bash (e.g., 2.00) + \V the release of bash, version + patchlevel (e.g., 2.00.0) + \w the current working directory + \W the last element of $PWD + \! the history number of this command + \# the command number of this command + \$ a $ or a # if you are root + \nnn character code nnn in octal + \\ a backslash + \[ begin a sequence of non-printing chars + \] end a sequence of non-printing chars +*/ +#define PROMPT_GROWTH 48 +char * +decode_prompt_string (string) + char *string; +{ + WORD_LIST *list; + char *result, *t; + struct dstack save_dstack; + int last_exit_value; +#if defined (PROMPT_STRING_DECODE) + int result_size, result_index; + int c, n; + char *temp, octal_string[4]; + struct tm *tm; + time_t the_time; + char timebuf[128]; + char *timefmt; + + result = (char *)xmalloc (result_size = PROMPT_GROWTH); + result[result_index = 0] = 0; + temp = (char *)NULL; + + while (c = *string++) + { + if (posixly_correct && c == '!') + { + if (*string == '!') + { + temp = savestring ("!"); + goto add_string; + } + else + { +#if !defined (HISTORY) + temp = savestring ("1"); +#else /* HISTORY */ + temp = itos (history_number ()); +#endif /* HISTORY */ + string--; /* add_string increments string again. */ + goto add_string; + } + } + if (c == '\\') + { + c = *string; + + switch (c) + { + case '0': + case '1': + case '2': + case '3': + case '4': + case '5': + case '6': + case '7': + strncpy (octal_string, string, 3); + octal_string[3] = '\0'; + + n = read_octal (octal_string); + temp = (char *)xmalloc (3); + + if (n == CTLESC || n == CTLNUL) + { + temp[0] = CTLESC; + temp[1] = n; + temp[2] = '\0'; + } + else if (n == -1) + { + temp[0] = '\\'; + temp[1] = '\0'; + } + else + { + temp[0] = n; + temp[1] = '\0'; + } + + for (c = 0; n != -1 && c < 3 && ISOCTAL (*string); c++) + string++; + + c = 0; /* tested at add_string: */ + goto add_string; + + case 'd': + case 't': + case 'T': + case '@': + case 'A': + /* Make the current time/date into a string. */ + (void) time (&the_time); + tm = localtime (&the_time); + + if (c == 'd') + n = strftime (timebuf, sizeof (timebuf), "%a %b %d", tm); + else if (c == 't') + n = strftime (timebuf, sizeof (timebuf), "%H:%M:%S", tm); + else if (c == 'T') + n = strftime (timebuf, sizeof (timebuf), "%I:%M:%S", tm); + else if (c == '@') + n = strftime (timebuf, sizeof (timebuf), "%I:%M %p", tm); + else if (c == 'A') + n = strftime (timebuf, sizeof (timebuf), "%H:%M", tm); + + timebuf[sizeof(timebuf) - 1] = '\0'; + temp = savestring (timebuf); + goto add_string; + + case 'D': /* strftime format */ + if (string[1] != '{') /* } */ + goto not_escape; + + (void) time (&the_time); + tm = localtime (&the_time); + string += 2; /* skip { */ + timefmt = xmalloc (strlen (string) + 3); + for (t = timefmt; *string && *string != '}'; ) + *t++ = *string++; + *t = '\0'; + c = *string; /* tested at add_string */ + if (timefmt[0] == '\0') + { + timefmt[0] = '%'; + timefmt[1] = 'X'; /* locale-specific current time */ + timefmt[2] = '\0'; + } + n = strftime (timebuf, sizeof (timebuf), timefmt, tm); + free (timefmt); + + timebuf[sizeof(timebuf) - 1] = '\0'; + if (promptvars || posixly_correct) + /* Make sure that expand_prompt_string is called with a + second argument of Q_DOUBLE_QUOTES if we use this + function here. */ + temp = sh_backslash_quote_for_double_quotes (timebuf); + else + temp = savestring (timebuf); + goto add_string; + + case 'n': + temp = (char *)xmalloc (3); + temp[0] = no_line_editing ? '\n' : '\r'; + temp[1] = no_line_editing ? '\0' : '\n'; + temp[2] = '\0'; + goto add_string; + + case 's': + temp = base_pathname (shell_name); + temp = savestring (temp); + goto add_string; + + case 'v': + case 'V': + temp = (char *)xmalloc (16); + if (c == 'v') + strcpy (temp, dist_version); + else + sprintf (temp, "%s.%d", dist_version, patch_level); + goto add_string; + + case 'w': + case 'W': + { + /* Use the value of PWD because it is much more efficient. */ + char t_string[PATH_MAX], *t; + int tlen; + + temp = get_string_value ("PWD"); + + if (temp == 0) + { + if (getcwd (t_string, sizeof(t_string)) == 0) + { + t_string[0] = '.'; + tlen = 1; + } + else + tlen = strlen (t_string); + } + else + { + tlen = sizeof (t_string) - 1; + strncpy (t_string, temp, tlen); + } + t_string[tlen] = '\0'; + +#define ROOT_PATH(x) ((x)[0] == '/' && (x)[1] == 0) +#define DOUBLE_SLASH_ROOT(x) ((x)[0] == '/' && (x)[1] == '/' && (x)[2] == 0) + /* Abbreviate \W as ~ if $PWD == $HOME */ + if (c == 'W' && (((t = get_string_value ("HOME")) == 0) || STREQ (t, temp) == 0)) + { + if (ROOT_PATH (t_string) == 0 && DOUBLE_SLASH_ROOT (t_string) == 0) + { + t = strrchr (t_string, '/'); + if (t) + strcpy (t_string, t + 1); + } + } +#undef ROOT_PATH +#undef DOUBLE_SLASH_ROOT + else + /* polite_directory_format is guaranteed to return a string + no longer than PATH_MAX - 1 characters. */ + strcpy (t_string, polite_directory_format (t_string)); + + /* If we're going to be expanding the prompt string later, + quote the directory name. */ + if (promptvars || posixly_correct) + /* Make sure that expand_prompt_string is called with a + second argument of Q_DOUBLE_QUOTES if we use this + function here. */ + temp = sh_backslash_quote_for_double_quotes (t_string); + else + temp = savestring (t_string); + + goto add_string; + } + + case 'u': + if (current_user.user_name == 0) + get_current_user_info (); + temp = savestring (current_user.user_name); + goto add_string; + + case 'h': + case 'H': + temp = savestring (current_host_name); + if (c == 'h' && (t = (char *)strchr (temp, '.'))) + *t = '\0'; + goto add_string; + + case '#': + temp = itos (current_command_number); + goto add_string; + + case '!': +#if !defined (HISTORY) + temp = savestring ("1"); +#else /* HISTORY */ + temp = itos (history_number ()); +#endif /* HISTORY */ + goto add_string; + + case '$': + t = temp = (char *)xmalloc (3); + if ((promptvars || posixly_correct) && (current_user.euid != 0)) + *t++ = '\\'; + *t++ = current_user.euid == 0 ? '#' : '$'; + *t = '\0'; + goto add_string; + + case 'j': + temp = itos (count_all_jobs ()); + goto add_string; + + case 'l': +#if defined (HAVE_TTYNAME) + temp = (char *)ttyname (fileno (stdin)); + t = temp ? base_pathname (temp) : "tty"; + temp = savestring (t); +#else + temp = savestring ("tty"); +#endif /* !HAVE_TTYNAME */ + goto add_string; + +#if defined (READLINE) + case '[': + case ']': + if (no_line_editing) + { + string++; + break; + } + temp = (char *)xmalloc (3); + temp[0] = '\001'; + temp[1] = (c == '[') ? RL_PROMPT_START_IGNORE : RL_PROMPT_END_IGNORE; + temp[2] = '\0'; + goto add_string; +#endif /* READLINE */ + + case '\\': + case 'a': + case 'e': + case 'r': + temp = (char *)xmalloc (2); + if (c == 'a') + temp[0] = '\07'; + else if (c == 'e') + temp[0] = '\033'; + else if (c == 'r') + temp[0] = '\r'; + else /* (c == '\\') */ + temp[0] = c; + temp[1] = '\0'; + goto add_string; + + default: +not_escape: + temp = (char *)xmalloc (3); + temp[0] = '\\'; + temp[1] = c; + temp[2] = '\0'; + + add_string: + if (c) + string++; + result = + sub_append_string (temp, result, &result_index, &result_size); + temp = (char *)NULL; /* Freed in sub_append_string (). */ + result[result_index] = '\0'; + break; + } + } + else + { + RESIZE_MALLOCED_BUFFER (result, result_index, 3, result_size, PROMPT_GROWTH); + result[result_index++] = c; + result[result_index] = '\0'; + } + } +#else /* !PROMPT_STRING_DECODE */ + result = savestring (string); +#endif /* !PROMPT_STRING_DECODE */ + + /* Save the delimiter stack and point `dstack' to temp space so any + command substitutions in the prompt string won't result in screwing + up the parser's quoting state. */ + save_dstack = dstack; + dstack = temp_dstack; + dstack.delimiter_depth = 0; + + /* Perform variable and parameter expansion and command substitution on + the prompt string. */ + if (promptvars || posixly_correct) + { + last_exit_value = last_command_exit_value; + list = expand_prompt_string (result, Q_DOUBLE_QUOTES); + free (result); + result = string_list (list); + dispose_words (list); + last_command_exit_value = last_exit_value; + } + else + { + t = dequote_string (result); + free (result); + result = t; + } + + dstack = save_dstack; + + return (result); +} + +/************************************************ + * * + * ERROR HANDLING * + * * + ************************************************/ + +/* Report a syntax error, and restart the parser. Call here for fatal + errors. */ +int +yyerror (msg) + const char *msg; +{ + report_syntax_error ((char *)NULL); + reset_parser (); + return (0); +} + +static char * +error_token_from_token (token) + int token; +{ + char *t; + + if (t = find_token_in_alist (token, word_token_alist, 0)) + return t; + + if (t = find_token_in_alist (token, other_token_alist, 0)) + return t; + + t = (char *)NULL; + /* This stuff is dicy and needs closer inspection */ + switch (current_token) + { + case WORD: + case ASSIGNMENT_WORD: + if (yylval.word) + t = savestring (yylval.word->word); + break; + case NUMBER: + t = itos (yylval.number); + break; + case ARITH_CMD: + if (yylval.word_list) + t = string_list (yylval.word_list); + break; + case ARITH_FOR_EXPRS: + if (yylval.word_list) + t = string_list_internal (yylval.word_list, " ; "); + break; + case COND_CMD: + t = (char *)NULL; /* punt */ + break; + } + + return t; +} + +static char * +error_token_from_text () +{ + char *msg, *t; + int token_end, i; + + t = shell_input_line; + i = shell_input_line_index; + token_end = 0; + msg = (char *)NULL; + + if (i && t[i] == '\0') + i--; + + while (i && (whitespace (t[i]) || t[i] == '\n')) + i--; + + if (i) + token_end = i + 1; + + while (i && (member (t[i], " \n\t;|&") == 0)) + i--; + + while (i != token_end && (whitespace (t[i]) || t[i] == '\n')) + i++; + + /* Return our idea of the offending token. */ + if (token_end || (i == 0 && token_end == 0)) + { + if (token_end) + msg = substring (t, i, token_end); + else /* one-character token */ + { + msg = (char *)xmalloc (2); + msg[0] = t[i]; + msg[1] = '\0'; + } + } + + return (msg); +} + +static void +print_offending_line () +{ + char *msg; + int token_end; + + msg = savestring (shell_input_line); + token_end = strlen (msg); + while (token_end && msg[token_end - 1] == '\n') + msg[--token_end] = '\0'; + + parser_error (line_number, "`%s'", msg); + free (msg); +} + +/* Report a syntax error with line numbers, etc. + Call here for recoverable errors. If you have a message to print, + then place it in MESSAGE, otherwise pass NULL and this will figure + out an appropriate message for you. */ +static void +report_syntax_error (message) + char *message; +{ + char *msg; + + if (message) + { + parser_error (line_number, "%s", message); + if (interactive && EOF_Reached) + EOF_Reached = 0; + last_command_exit_value = EX_USAGE; + return; + } + + /* If the line of input we're reading is not null, try to find the + objectionable token. First, try to figure out what token the + parser's complaining about by looking at current_token. */ + if (current_token != 0 && EOF_Reached == 0 && (msg = error_token_from_token (current_token))) + { + parser_error (line_number, _("syntax error near unexpected token `%s'"), msg); + free (msg); + + if (interactive == 0) + print_offending_line (); + + last_command_exit_value = EX_USAGE; + return; + } + + /* If looking at the current token doesn't prove fruitful, try to find the + offending token by analyzing the text of the input line near the current + input line index and report what we find. */ + if (shell_input_line && *shell_input_line) + { + msg = error_token_from_text (); + if (msg) + { + parser_error (line_number, _("syntax error near `%s'"), msg); + free (msg); + } + + /* If not interactive, print the line containing the error. */ + if (interactive == 0) + print_offending_line (); + } + else + { + msg = EOF_Reached ? _("syntax error: unexpected end of file") : _("syntax error"); + parser_error (line_number, "%s", msg); + /* When the shell is interactive, this file uses EOF_Reached + only for error reporting. Other mechanisms are used to + decide whether or not to exit. */ + if (interactive && EOF_Reached) + EOF_Reached = 0; + } + + last_command_exit_value = EX_USAGE; +} + +/* ??? Needed function. ??? We have to be able to discard the constructs + created during parsing. In the case of error, we want to return + allocated objects to the memory pool. In the case of no error, we want + to throw away the information about where the allocated objects live. + (dispose_command () will actually free the command.) */ +static void +discard_parser_constructs (error_p) + int error_p; +{ +} + +/************************************************ + * * + * EOF HANDLING * + * * + ************************************************/ + +/* Do that silly `type "bye" to exit' stuff. You know, "ignoreeof". */ + +/* A flag denoting whether or not ignoreeof is set. */ +int ignoreeof = 0; + +/* The number of times that we have encountered an EOF character without + another character intervening. When this gets above the limit, the + shell terminates. */ +int eof_encountered = 0; + +/* The limit for eof_encountered. */ +int eof_encountered_limit = 10; + +/* If we have EOF as the only input unit, this user wants to leave + the shell. If the shell is not interactive, then just leave. + Otherwise, if ignoreeof is set, and we haven't done this the + required number of times in a row, print a message. */ +static void +handle_eof_input_unit () +{ + if (interactive) + { + /* shell.c may use this to decide whether or not to write out the + history, among other things. We use it only for error reporting + in this file. */ + if (EOF_Reached) + EOF_Reached = 0; + + /* If the user wants to "ignore" eof, then let her do so, kind of. */ + if (ignoreeof) + { + if (eof_encountered < eof_encountered_limit) + { + fprintf (stderr, _("Use \"%s\" to leave the shell.\n"), + login_shell ? "logout" : "exit"); + eof_encountered++; + /* Reset the parsing state. */ + last_read_token = current_token = '\n'; + /* Reset the prompt string to be $PS1. */ + prompt_string_pointer = (char **)NULL; + prompt_again (); + return; + } + } + + /* In this case EOF should exit the shell. Do it now. */ + reset_parser (); + exit_builtin ((WORD_LIST *)NULL); + } + else + { + /* We don't write history files, etc., for non-interactive shells. */ + EOF_Reached = 1; + } +} + +/************************************************ + * * + * STRING PARSING FUNCTIONS * + * * + ************************************************/ + +/* It's very important that these two functions treat the characters + between ( and ) identically. */ + +static WORD_LIST parse_string_error; + +/* Take a string and run it through the shell parser, returning the + resultant word list. Used by compound array assignment. */ +WORD_LIST * +parse_string_to_word_list (s, flags, whom) + char *s; + int flags; + const char *whom; +{ + WORD_LIST *wl; + int tok, orig_current_token, orig_line_number, orig_input_terminator; + int orig_line_count; + int old_echo_input, old_expand_aliases; +#if defined (HISTORY) + int old_remember_on_history, old_history_expansion_inhibited; +#endif + +#if defined (HISTORY) + old_remember_on_history = remember_on_history; +# if defined (BANG_HISTORY) + old_history_expansion_inhibited = history_expansion_inhibited; +# endif + bash_history_disable (); +#endif + + orig_line_number = line_number; + orig_line_count = current_command_line_count; + orig_input_terminator = shell_input_line_terminator; + old_echo_input = echo_input_at_read; + old_expand_aliases = expand_aliases; + + push_stream (1); + last_read_token = WORD; /* WORD to allow reserved words here */ + current_command_line_count = 0; + echo_input_at_read = expand_aliases = 0; + + with_input_from_string (s, whom); + wl = (WORD_LIST *)NULL; + + if (flags & 1) + parser_state |= PST_COMPASSIGN; + + while ((tok = read_token (READ)) != yacc_EOF) + { + if (tok == '\n' && *bash_input.location.string == '\0') + break; + if (tok == '\n') /* Allow newlines in compound assignments */ + continue; + if (tok != WORD && tok != ASSIGNMENT_WORD) + { + line_number = orig_line_number + line_number - 1; + orig_current_token = current_token; + current_token = tok; + yyerror ((char *)NULL); /* does the right thing */ + current_token = orig_current_token; + if (wl) + dispose_words (wl); + wl = &parse_string_error; + break; + } + wl = make_word_list (yylval.word, wl); + } + + last_read_token = '\n'; + pop_stream (); + +#if defined (HISTORY) + remember_on_history = old_remember_on_history; +# if defined (BANG_HISTORY) + history_expansion_inhibited = old_history_expansion_inhibited; +# endif /* BANG_HISTORY */ +#endif /* HISTORY */ + + echo_input_at_read = old_echo_input; + expand_aliases = old_expand_aliases; + + current_command_line_count = orig_line_count; + shell_input_line_terminator = orig_input_terminator; + + if (flags & 1) + parser_state &= ~PST_COMPASSIGN; + + if (wl == &parse_string_error) + { + last_command_exit_value = EXECUTION_FAILURE; + if (interactive_shell == 0 && posixly_correct) + jump_to_top_level (FORCE_EOF); + else + jump_to_top_level (DISCARD); + } + + return (REVERSE_LIST (wl, WORD_LIST *)); +} + +static char * +parse_compound_assignment (retlenp) + int *retlenp; +{ + WORD_LIST *wl, *rl; + int tok, orig_line_number, orig_token_size; + char *saved_token, *ret; + + saved_token = token; + orig_token_size = token_buffer_size; + orig_line_number = line_number; + + last_read_token = WORD; /* WORD to allow reserved words here */ + + token = (char *)NULL; + token_buffer_size = 0; + + wl = (WORD_LIST *)NULL; /* ( */ + parser_state |= PST_COMPASSIGN; + + while ((tok = read_token (READ)) != ')') + { + if (tok == '\n') /* Allow newlines in compound assignments */ + { + if (SHOULD_PROMPT ()) + prompt_again (); + continue; + } + if (tok != WORD && tok != ASSIGNMENT_WORD) + { + current_token = tok; /* for error reporting */ + if (tok == yacc_EOF) /* ( */ + parser_error (orig_line_number, _("unexpected EOF while looking for matching `)'")); + else + yyerror ((char *)NULL); /* does the right thing */ + if (wl) + dispose_words (wl); + wl = &parse_string_error; + break; + } + wl = make_word_list (yylval.word, wl); + } + + FREE (token); + token = saved_token; + token_buffer_size = orig_token_size; + + parser_state &= ~PST_COMPASSIGN; + + if (wl == &parse_string_error) + { + last_command_exit_value = EXECUTION_FAILURE; + last_read_token = '\n'; /* XXX */ + if (interactive_shell == 0 && posixly_correct) + jump_to_top_level (FORCE_EOF); + else + jump_to_top_level (DISCARD); + } + + last_read_token = WORD; + if (wl) + { + rl = REVERSE_LIST (wl, WORD_LIST *); + ret = string_list (rl); + dispose_words (rl); + } + else + ret = (char *)NULL; + + if (retlenp) + *retlenp = (ret && *ret) ? strlen (ret) : 0; + return ret; +} + +/************************************************ + * * + * SAVING AND RESTORING PARTIAL PARSE STATE * + * * + ************************************************/ + +sh_parser_state_t * +save_parser_state (ps) + sh_parser_state_t *ps; +{ +#if defined (ARRAY_VARS) + SHELL_VAR *v; +#endif + + if (ps == 0) + ps = xmalloc (sizeof (sh_parser_state_t)); + if (ps == 0) + return ((sh_parser_state_t *)NULL); + + ps->parser_state = parser_state; + ps->token_state = save_token_state (); + + ps->input_line_terminator = shell_input_line_terminator; + ps->eof_encountered = eof_encountered; + + ps->current_command_line_count = current_command_line_count; + +#if defined (HISTORY) + ps->remember_on_history = remember_on_history; +# if defined (BANG_HISTORY) + ps->history_expansion_inhibited = history_expansion_inhibited; +# endif +#endif + + ps->last_command_exit_value = last_command_exit_value; +#if defined (ARRAY_VARS) + v = find_variable ("PIPESTATUS"); + if (v && array_p (v) && array_cell (v)) + ps->pipestatus = array_copy (array_cell (v)); + else + ps->pipestatus = (ARRAY *)NULL; +#endif + + ps->last_shell_builtin = last_shell_builtin; + ps->this_shell_builtin = this_shell_builtin; + + ps->expand_aliases = expand_aliases; + ps->echo_input_at_read = echo_input_at_read; + + return (ps); +} + +void +restore_parser_state (ps) + sh_parser_state_t *ps; +{ +#if defined (ARRAY_VARS) + SHELL_VAR *v; +#endif + + if (ps == 0) + return; + + parser_state = ps->parser_state; + if (ps->token_state) + { + restore_token_state (ps->token_state); + free (ps->token_state); + } + + shell_input_line_terminator = ps->input_line_terminator; + eof_encountered = ps->eof_encountered; + + current_command_line_count = ps->current_command_line_count; + +#if defined (HISTORY) + remember_on_history = ps->remember_on_history; +# if defined (BANG_HISTORY) + history_expansion_inhibited = ps->history_expansion_inhibited; +# endif +#endif + + last_command_exit_value = ps->last_command_exit_value; +#if defined (ARRAY_VARS) + v = find_variable ("PIPESTATUS"); + if (v && array_p (v) && array_cell (v)) + { + array_dispose (array_cell (v)); + var_setarray (v, ps->pipestatus); + } +#endif + + last_shell_builtin = ps->last_shell_builtin; + this_shell_builtin = ps->this_shell_builtin; + + expand_aliases = ps->expand_aliases; + echo_input_at_read = ps->echo_input_at_read; +} + +/************************************************ + * * + * MULTIBYTE CHARACTER HANDLING * + * * + ************************************************/ + +#if defined (HANDLE_MULTIBYTE) +static void +set_line_mbstate () +{ + int i, previ, len, c; + mbstate_t mbs, prevs; + size_t mbclen; + + if (shell_input_line == NULL) + return; + len = strlen (shell_input_line); /* XXX - shell_input_line_len ? */ + FREE (shell_input_line_property); + shell_input_line_property = (char *)xmalloc (len + 1); + + memset (&prevs, '\0', sizeof (mbstate_t)); + for (i = previ = 0; i < len; i++) + { + mbs = prevs; + + c = shell_input_line[i]; + if (c == EOF) + { + int j; + for (j = i; j < len; j++) + shell_input_line_property[j] = 1; + break; + } + + mbclen = mbrlen (shell_input_line + previ, i - previ + 1, &mbs); + if (mbclen == 1 || mbclen == (size_t)-1) + { + mbclen = 1; + previ = i + 1; + } + else if (mbclen == (size_t)-2) + mbclen = 0; + else if (mbclen > 1) + { + mbclen = 0; + previ = i + 1; + prevs = mbs; + } + else + { + /* XXX - what to do if mbrlen returns 0? (null wide character) */ + int j; + for (j = i; j < len; j++) + shell_input_line_property[j] = 1; + break; + } + + shell_input_line_property[i] = mbclen; + } +} +#endif /* HANDLE_MULTIBYTE */ diff --git a/shell.c b/shell.c index f6f78ba60..bce1f8e3b 100644 --- a/shell.c +++ b/shell.c @@ -1332,25 +1332,8 @@ open_shell_script (script_name) ARRAY *funcname_a, *bash_source_a, *bash_lineno_a; #endif - free (dollar_vars[0]); - dollar_vars[0] = savestring (script_name); filename = savestring (script_name); -#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); - - array_push (bash_source_a, filename); - if (bash_lineno_a) - { - t = itos (executing_line_number ()); - array_push (bash_lineno_a, t); - free (t); - } - array_push (funcname_a, "main"); -#endif - fd = open (filename, O_RDONLY); if ((fd < 0) && (errno == ENOENT) && (absolute_program (filename) == 0)) { @@ -1375,6 +1358,24 @@ open_shell_script (script_name) exit ((e == ENOENT) ? EX_NOTFOUND : EX_NOINPUT); } + free (dollar_vars[0]); + dollar_vars[0] = savestring (script_name); + +#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); + + array_push (bash_source_a, filename); + if (bash_lineno_a) + { + t = itos (executing_line_number ()); + array_push (bash_lineno_a, t); + free (t); + } + array_push (funcname_a, "main"); +#endif + #ifdef HAVE_DEV_FD fd_is_tty = isatty (fd); #else diff --git a/shell.c~ b/shell.c~ new file mode 100644 index 000000000..f6f78ba60 --- /dev/null +++ b/shell.c~ @@ -0,0 +1,1785 @@ +/* shell.c -- GNU's idea of the POSIX shell specification. */ + +/* Copyright (C) 1987-2003 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 2, 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; see the file COPYING. If not, write to the Free + Software Foundation, 59 Temple Place, Suite 330, Boston, MA 02111 USA. + + Birthdate: + Sunday, January 10th, 1988. + Initial author: Brian Fox +*/ +#define INSTALL_DEBUG_MODE + +#include "config.h" + +#include "bashtypes.h" +#if !defined (_MINIX) && defined (HAVE_SYS_FILE_H) +# include +#endif +#include "posixstat.h" +#include "posixtime.h" +#include "bashansi.h" +#include +#include +#include +#include "filecntl.h" +#include + +#if defined (HAVE_UNISTD_H) +# include +#endif + +#include "bashintl.h" + +#define NEED_SH_SETLINEBUF_DECL /* used in externs.h */ + +#include "shell.h" +#include "flags.h" +#include "trap.h" +#include "mailcheck.h" +#include "builtins.h" +#include "builtins/common.h" + +#if defined (JOB_CONTROL) +#include "jobs.h" +#endif /* JOB_CONTROL */ + +#include "input.h" +#include "execute_cmd.h" +#include "findcmd.h" + +#if defined (USING_BASH_MALLOC) && defined (DEBUG) && !defined (DISABLE_MALLOC_WRAPPERS) +# include +#endif + +#if defined (HISTORY) +# include "bashhist.h" +# include +#endif + +#include +#include + +#if defined (__OPENNT) +# include +#endif + +#if !defined (HAVE_GETPW_DECLS) +extern struct passwd *getpwuid (); +#endif /* !HAVE_GETPW_DECLS */ + +#if !defined (errno) +extern int errno; +#endif + +#if defined (NO_MAIN_ENV_ARG) +extern char **environ; /* used if no third argument to main() */ +#endif + +extern char *dist_version, *release_status; +extern int patch_level, build_version; +extern int shell_level; +extern int subshell_environment; +extern int last_command_exit_value; +extern int line_number; +extern char *primary_prompt, *secondary_prompt; +extern int expand_aliases; +extern char *this_command_name; +extern int array_needs_making; + +/* Non-zero means that this shell has already been run; i.e. you should + call shell_reinitialize () if you need to start afresh. */ +int shell_initialized = 0; + +COMMAND *global_command = (COMMAND *)NULL; + +/* Information about the current user. */ +struct user_info current_user = +{ + (uid_t)-1, (uid_t)-1, (gid_t)-1, (gid_t)-1, + (char *)NULL, (char *)NULL, (char *)NULL +}; + +/* The current host's name. */ +char *current_host_name = (char *)NULL; + +/* Non-zero means that this shell is a login shell. + Specifically: + 0 = not login shell. + 1 = login shell from getty (or equivalent fake out) + -1 = login shell from "--login" (or -l) flag. + -2 = both from getty, and from flag. + */ +int login_shell = 0; + +/* Non-zero means that at this moment, the shell is interactive. In + general, this means that the shell is at this moment reading input + from the keyboard. */ +int interactive = 0; + +/* Non-zero means that the shell was started as an interactive shell. */ +int interactive_shell = 0; + +/* Non-zero means to send a SIGHUP to all jobs when an interactive login + shell exits. */ +int hup_on_exit = 0; + +/* Tells what state the shell was in when it started: + 0 = non-interactive shell script + 1 = interactive + 2 = -c command + 3 = wordexp evaluation + This is a superset of the information provided by interactive_shell. +*/ +int startup_state = 0; + +/* Special debugging helper. */ +int debugging_login_shell = 0; + +/* The environment that the shell passes to other commands. */ +char **shell_environment; + +/* Non-zero when we are executing a top-level command. */ +int executing = 0; + +/* The number of commands executed so far. */ +int current_command_number = 1; + +/* Non-zero is the recursion depth for commands. */ +int indirection_level = 0; + +/* The name of this shell, as taken from argv[0]. */ +char *shell_name = (char *)NULL; + +/* time in seconds when the shell was started */ +time_t shell_start_time; + +/* Are we running in an emacs shell window? */ +int running_under_emacs; + +/* The name of the .(shell)rc file. */ +static char *bashrc_file = "~/.bashrc"; + +/* Non-zero means to act more like the Bourne shell on startup. */ +static int act_like_sh; + +/* Non-zero if this shell is being run by `su'. */ +static int su_shell; + +/* Non-zero if we have already expanded and sourced $ENV. */ +static int sourced_env; + +/* Is this shell running setuid? */ +static int running_setuid; + +/* Values for the long-winded argument names. */ +static int debugging; /* Do debugging things. */ +static int no_rc; /* Don't execute ~/.bashrc */ +static int no_profile; /* Don't execute .profile */ +static int do_version; /* Display interesting version info. */ +static int make_login_shell; /* Make this shell be a `-bash' shell. */ +static int want_initial_help; /* --help option */ + +int debugging_mode = 0; /* In debugging mode with --debugger */ +int no_line_editing = 0; /* Don't do fancy line editing. */ +int posixly_correct = 0; /* Non-zero means posix.2 superset. */ +int dump_translatable_strings; /* Dump strings in $"...", don't execute. */ +int dump_po_strings; /* Dump strings in $"..." in po format */ +int wordexp_only = 0; /* Do word expansion only */ +int protected_mode = 0; /* No command substitution with --wordexp */ + +/* Some long-winded argument names. These are obviously new. */ +#define Int 1 +#define Charp 2 +struct { + char *name; + int type; + int *int_value; + char **char_value; +} long_args[] = { + { "debug", Int, &debugging, (char **)0x0 }, +#if defined (DEBUGGER) + { "debugger", Int, &debugging_mode, (char **)0x0 }, +#endif + { "dump-po-strings", Int, &dump_po_strings, (char **)0x0 }, + { "dump-strings", Int, &dump_translatable_strings, (char **)0x0 }, + { "help", Int, &want_initial_help, (char **)0x0 }, + { "init-file", Charp, (int *)0x0, &bashrc_file }, + { "login", Int, &make_login_shell, (char **)0x0 }, + { "noediting", Int, &no_line_editing, (char **)0x0 }, + { "noprofile", Int, &no_profile, (char **)0x0 }, + { "norc", Int, &no_rc, (char **)0x0 }, + { "posix", Int, &posixly_correct, (char **)0x0 }, + { "protected", Int, &protected_mode, (char **)0x0 }, + { "rcfile", Charp, (int *)0x0, &bashrc_file }, +#if defined (RESTRICTED_SHELL) + { "restricted", Int, &restricted, (char **)0x0 }, +#endif + { "verbose", Int, &echo_input_at_read, (char **)0x0 }, + { "version", Int, &do_version, (char **)0x0 }, + { "wordexp", Int, &wordexp_only, (char **)0x0 }, + { (char *)0x0, Int, (int *)0x0, (char **)0x0 } +}; + +/* These are extern so execute_simple_command can set them, and then + longjmp back to main to execute a shell script, instead of calling + main () again and resulting in indefinite, possibly fatal, stack + growth. */ +procenv_t subshell_top_level; +int subshell_argc; +char **subshell_argv; +char **subshell_envp; + +#if defined (BUFFERED_INPUT) +/* The file descriptor from which the shell is reading input. */ +int default_buffered_input = -1; +#endif + +/* The following two variables are not static so they can show up in $-. */ +int read_from_stdin; /* -s flag supplied */ +int want_pending_command; /* -c flag supplied */ + +/* This variable is not static so it can be bound to $BASH_EXECUTION_STRING */ +char *command_execution_string; /* argument to -c option */ + +int malloc_trace_at_exit = 0; + +static int shell_reinitialized = 0; + +static FILE *default_input; + +static STRING_INT_ALIST *shopt_alist; +static int shopt_ind = 0, shopt_len = 0; + +static int parse_long_options __P((char **, int, int)); +static int parse_shell_options __P((char **, int, int)); +static int bind_args __P((char **, int, int, int)); + +static void start_debugger __P((void)); + +static void add_shopt_to_alist __P((char *, int)); +static void run_shopt_alist __P((void)); + +static void execute_env_file __P((char *)); +static void run_startup_files __P((void)); +static int open_shell_script __P((char *)); +static void set_bash_input __P((void)); +static int run_one_command __P((char *)); +static int run_wordexp __P((char *)); + +static int uidget __P((void)); + +static void init_interactive __P((void)); +static void init_noninteractive __P((void)); + +static void set_shell_name __P((char *)); +static void shell_initialize __P((void)); +static void shell_reinitialize __P((void)); + +static void show_shell_usage __P((FILE *, int)); + +#ifdef __CYGWIN__ +static void +_cygwin32_check_tmp () +{ + struct stat sb; + + if (stat ("/tmp", &sb) < 0) + internal_warning (_("could not find /tmp, please create!")); + else + { + if (S_ISDIR (sb.st_mode) == 0) + internal_warning (_("/tmp must be a valid directory name")); + } +} +#endif /* __CYGWIN__ */ + +#if defined (NO_MAIN_ENV_ARG) +/* systems without third argument to main() */ +int +main (argc, argv) + int argc; + char **argv; +#else /* !NO_MAIN_ENV_ARG */ +int +main (argc, argv, env) + int argc; + char **argv, **env; +#endif /* !NO_MAIN_ENV_ARG */ +{ + register int i; + int code, old_errexit_flag; +#if defined (RESTRICTED_SHELL) + int saverst; +#endif + volatile int locally_skip_execution; + volatile int arg_index, top_level_arg_index; +#ifdef __OPENNT + char **env; + + env = environ; +#endif /* __OPENNT */ + + USE_VAR(argc); + USE_VAR(argv); + USE_VAR(env); + USE_VAR(code); + USE_VAR(old_errexit_flag); +#if defined (RESTRICTED_SHELL) + USE_VAR(saverst); +#endif + + /* Catch early SIGINTs. */ + code = setjmp (top_level); + if (code) + exit (2); + +#if defined (USING_BASH_MALLOC) && defined (DEBUG) && !defined (DISABLE_MALLOC_WRAPPERS) +# if 1 + malloc_set_register (1); +# endif +#endif + + check_dev_tty (); + +#ifdef __CYGWIN__ + _cygwin32_check_tmp (); +#endif /* __CYGWIN__ */ + + /* Wait forever if we are debugging a login shell. */ + while (debugging_login_shell); + + set_default_locale (); + + running_setuid = uidget (); + + if (getenv ("POSIXLY_CORRECT") || getenv ("POSIX_PEDANTIC")) + posixly_correct = 1; + +#if defined (USE_GNU_MALLOC_LIBRARY) + mcheck (programming_error, (void (*) ())0); +#endif /* USE_GNU_MALLOC_LIBRARY */ + + if (setjmp (subshell_top_level)) + { + argc = subshell_argc; + argv = subshell_argv; + env = subshell_envp; + sourced_env = 0; + } + + shell_reinitialized = 0; + + /* Initialize `local' variables for all `invocations' of main (). */ + arg_index = 1; + command_execution_string = (char *)NULL; + want_pending_command = locally_skip_execution = read_from_stdin = 0; + default_input = stdin; +#if defined (BUFFERED_INPUT) + default_buffered_input = -1; +#endif + + /* Fix for the `infinite process creation' bug when running shell scripts + from startup files on System V. */ + login_shell = make_login_shell = 0; + + /* If this shell has already been run, then reinitialize it to a + vanilla state. */ + if (shell_initialized || shell_name) + { + /* Make sure that we do not infinitely recurse as a login shell. */ + if (*shell_name == '-') + shell_name++; + + shell_reinitialize (); + if (setjmp (top_level)) + exit (2); + } + + shell_environment = env; + set_shell_name (argv[0]); + shell_start_time = NOW; /* NOW now defined in general.h */ + + /* Parse argument flags from the input line. */ + + /* Find full word arguments first. */ + arg_index = parse_long_options (argv, arg_index, argc); + + if (want_initial_help) + { + show_shell_usage (stdout, 1); + exit (EXECUTION_SUCCESS); + } + + if (do_version) + { + show_shell_version (1); + exit (EXECUTION_SUCCESS); + } + + /* All done with full word options; do standard shell option parsing.*/ + this_command_name = shell_name; /* for error reporting */ + arg_index = parse_shell_options (argv, arg_index, argc); + + /* If user supplied the "--login" (or -l) flag, then set and invert + LOGIN_SHELL. */ + if (make_login_shell) + { + login_shell++; + login_shell = -login_shell; + } + + set_login_shell (login_shell != 0); + + if (dump_po_strings) + dump_translatable_strings = 1; + + if (dump_translatable_strings) + read_but_dont_execute = 1; + + if (running_setuid && privileged_mode == 0) + disable_priv_mode (); + + /* Need to get the argument to a -c option processed in the + above loop. The next arg is a command to execute, and the + following args are $0...$n respectively. */ + if (want_pending_command) + { + command_execution_string = argv[arg_index]; + if (command_execution_string == 0) + { + report_error (_("%s: option requires an argument"), "-c"); + exit (EX_BADUSAGE); + } + arg_index++; + } + this_command_name = (char *)NULL; + + cmd_init(); /* initialize the command object caches */ + + /* First, let the outside world know about our interactive status. + A shell is interactive if the `-i' flag was given, or if all of + the following conditions are met: + no -c command + no arguments remaining or the -s flag given + standard input is a terminal + standard output is a terminal + Refer to Posix.2, the description of the `sh' utility. */ + + if (forced_interactive || /* -i flag */ + (!command_execution_string && /* No -c command and ... */ + wordexp_only == 0 && /* No --wordexp and ... */ + ((arg_index == argc) || /* no remaining args or... */ + read_from_stdin) && /* -s flag with args, and */ + isatty (fileno (stdin)) && /* Input is a terminal and */ + isatty (fileno (stdout)))) /* output is a terminal. */ + init_interactive (); + else + init_noninteractive (); + +#define CLOSE_FDS_AT_LOGIN +#if defined (CLOSE_FDS_AT_LOGIN) + /* + * Some systems have the bad habit of starting login shells with lots of open + * file descriptors. For instance, most systems that have picked up the + * pre-4.0 Sun YP code leave a file descriptor open each time you call one + * of the getpw* functions, and it's set to be open across execs. That + * means one for login, one for xterm, one for shelltool, etc. + */ + if (login_shell && interactive_shell) + { + for (i = 3; i < 20; i++) + close (i); + } +#endif /* CLOSE_FDS_AT_LOGIN */ + + /* If we're in a strict Posix.2 mode, turn on interactive comments, + alias expansion in non-interactive shells, and other Posix.2 things. */ + if (posixly_correct) + { + bind_variable ("POSIXLY_CORRECT", "y"); + sv_strict_posix ("POSIXLY_CORRECT"); + } + + /* Now we run the shopt_alist and process the options. */ + if (shopt_alist) + run_shopt_alist (); + + /* From here on in, the shell must be a normal functioning shell. + Variables from the environment are expected to be set, etc. */ + shell_initialize (); + + set_default_locale_vars (); + + if (interactive_shell) + { + char *term, *emacs; + + term = get_string_value ("TERM"); + no_line_editing |= term && (STREQ (term, "emacs")); + emacs = get_string_value ("EMACS"); + running_under_emacs = emacs ? ((strmatch ("*term*", emacs, 0) == 0) ? 2 : 1) + : 0; +#if 0 + no_line_editing |= emacs && emacs[0] == 't' && emacs[1] == '\0'; +#else + no_line_editing |= emacs && emacs[0] == 't' && emacs[1] == '\0' && STREQ (term, "dumb"); +#endif + } + + top_level_arg_index = arg_index; + old_errexit_flag = exit_immediately_on_error; + + /* Give this shell a place to longjmp to before executing the + startup files. This allows users to press C-c to abort the + lengthy startup. */ + code = setjmp (top_level); + if (code) + { + if (code == EXITPROG || code == ERREXIT) + exit_shell (last_command_exit_value); + else + { +#if defined (JOB_CONTROL) + /* Reset job control, since run_startup_files turned it off. */ + set_job_control (interactive_shell); +#endif + /* Reset value of `set -e', since it's turned off before running + the startup files. */ + exit_immediately_on_error += old_errexit_flag; + locally_skip_execution++; + } + } + + arg_index = top_level_arg_index; + + /* Execute the start-up scripts. */ + + if (interactive_shell == 0) + { + unbind_variable ("PS1"); + unbind_variable ("PS2"); + interactive = 0; +#if 0 + /* This has already been done by init_noninteractive */ + expand_aliases = posixly_correct; +#endif + } + else + { + change_flag ('i', FLAG_ON); + interactive = 1; + } + +#if defined (RESTRICTED_SHELL) + /* Set restricted_shell based on whether the basename of $0 indicates that + the shell should be restricted or if the `-r' option was supplied at + startup. */ + restricted_shell = shell_is_restricted (shell_name); + + /* If the `-r' option is supplied at invocation, make sure that the shell + is not in restricted mode when running the startup files. */ + saverst = restricted; + restricted = 0; +#endif + + /* The startup files are run with `set -e' temporarily disabled. */ + if (locally_skip_execution == 0 && running_setuid == 0) + { + old_errexit_flag = exit_immediately_on_error; + exit_immediately_on_error = 0; + + run_startup_files (); + exit_immediately_on_error += old_errexit_flag; + } + + /* If we are invoked as `sh', turn on Posix mode. */ + if (act_like_sh) + { + bind_variable ("POSIXLY_CORRECT", "y"); + sv_strict_posix ("POSIXLY_CORRECT"); + } + +#if defined (RESTRICTED_SHELL) + /* Turn on the restrictions after executing the startup files. This + means that `bash -r' or `set -r' invoked from a startup file will + turn on the restrictions after the startup files are executed. */ + restricted = saverst || restricted; + if (shell_reinitialized == 0) + maybe_make_restricted (shell_name); +#endif /* RESTRICTED_SHELL */ + + if (wordexp_only) + { + startup_state = 3; + last_command_exit_value = run_wordexp (argv[arg_index]); + exit_shell (last_command_exit_value); + } + + if (command_execution_string) + { + arg_index = bind_args (argv, arg_index, argc, 0); + startup_state = 2; + + if (debugging_mode) + start_debugger (); + +#if defined (ONESHOT) + executing = 1; + run_one_command (command_execution_string); + exit_shell (last_command_exit_value); +#else /* ONESHOT */ + with_input_from_string (command_execution_string, "-c"); + goto read_and_execute; +#endif /* !ONESHOT */ + } + + /* Get possible input filename and set up default_buffered_input or + default_input as appropriate. */ + if (arg_index != argc && read_from_stdin == 0) + { + open_shell_script (argv[arg_index]); + arg_index++; + } + else if (interactive == 0) + /* In this mode, bash is reading a script from stdin, which is a + pipe or redirected file. */ +#if defined (BUFFERED_INPUT) + default_buffered_input = fileno (stdin); /* == 0 */ +#else + setbuf (default_input, (char *)NULL); +#endif /* !BUFFERED_INPUT */ + + set_bash_input (); + + /* Bind remaining args to $1 ... $n */ + arg_index = bind_args (argv, arg_index, argc, 1); + + if (debugging_mode && locally_skip_execution == 0 && running_setuid == 0) + start_debugger (); + + /* Do the things that should be done only for interactive shells. */ + if (interactive_shell) + { + /* Set up for checking for presence of mail. */ + remember_mail_dates (); + reset_mail_timer (); + +#if defined (HISTORY) + /* Initialize the interactive history stuff. */ + bash_initialize_history (); + /* Don't load the history from the history file if we've already + saved some lines in this session (e.g., by putting `history -s xx' + into one of the startup files). */ + if (shell_initialized == 0 && history_lines_this_session == 0) + load_history (); +#endif /* HISTORY */ + + /* Initialize terminal state for interactive shells after the + .bash_profile and .bashrc are interpreted. */ + get_tty_state (); + } + +#if !defined (ONESHOT) + read_and_execute: +#endif /* !ONESHOT */ + + shell_initialized = 1; + + /* Read commands until exit condition. */ + reader_loop (); + exit_shell (last_command_exit_value); +} + +static int +parse_long_options (argv, arg_start, arg_end) + char **argv; + int arg_start, arg_end; +{ + int arg_index, longarg, i; + char *arg_string; + + arg_index = arg_start; + while ((arg_index != arg_end) && (arg_string = argv[arg_index]) && + (*arg_string == '-')) + { + longarg = 0; + + /* Make --login equivalent to -login. */ + if (arg_string[1] == '-' && arg_string[2]) + { + longarg = 1; + arg_string++; + } + + for (i = 0; long_args[i].name; i++) + { + if (STREQ (arg_string + 1, long_args[i].name)) + { + if (long_args[i].type == Int) + *long_args[i].int_value = 1; + else if (argv[++arg_index] == 0) + { + report_error (_("%s: option requires an argument"), long_args[i].name); + exit (EX_BADUSAGE); + } + else + *long_args[i].char_value = argv[arg_index]; + + break; + } + } + if (long_args[i].name == 0) + { + if (longarg) + { + report_error (_("%s: invalid option"), argv[arg_index]); + show_shell_usage (stderr, 0); + exit (EX_BADUSAGE); + } + break; /* No such argument. Maybe flag arg. */ + } + + arg_index++; + } + + return (arg_index); +} + +static int +parse_shell_options (argv, arg_start, arg_end) + char **argv; + int arg_start, arg_end; +{ + int arg_index; + int arg_character, on_or_off, next_arg, i; + char *o_option, *arg_string; + + arg_index = arg_start; + while (arg_index != arg_end && (arg_string = argv[arg_index]) && + (*arg_string == '-' || *arg_string == '+')) + { + /* There are flag arguments, so parse them. */ + next_arg = arg_index + 1; + + /* A single `-' signals the end of options. From the 4.3 BSD sh. + An option `--' means the same thing; this is the standard + getopt(3) meaning. */ + if (arg_string[0] == '-' && + (arg_string[1] == '\0' || + (arg_string[1] == '-' && arg_string[2] == '\0'))) + return (next_arg); + + i = 1; + on_or_off = arg_string[0]; + while (arg_character = arg_string[i++]) + { + switch (arg_character) + { + case 'c': + want_pending_command = 1; + break; + + case 'l': + make_login_shell = 1; + break; + + case 's': + read_from_stdin = 1; + break; + + case 'o': + o_option = argv[next_arg]; + if (o_option == 0) + { + list_minus_o_opts (-1, (on_or_off == '-') ? 0 : 1); + break; + } + if (set_minus_o_option (on_or_off, o_option) != EXECUTION_SUCCESS) + exit (EX_BADUSAGE); + next_arg++; + break; + + case 'O': + /* Since some of these can be overridden by the normal + interactive/non-interactive shell initialization or + initializing posix mode, we save the options and process + them after initialization. */ + o_option = argv[next_arg]; + if (o_option == 0) + { + shopt_listopt (o_option, (on_or_off == '-') ? 0 : 1); + break; + } + add_shopt_to_alist (o_option, on_or_off); + next_arg++; + break; + + case 'D': + dump_translatable_strings = 1; + break; + + default: + if (change_flag (arg_character, on_or_off) == FLAG_ERROR) + { + report_error (_("%c%c: invalid option"), on_or_off, arg_character); + show_shell_usage (stderr, 0); + exit (EX_BADUSAGE); + } + } + } + /* Can't do just a simple increment anymore -- what about + "bash -abouo emacs ignoreeof -hP"? */ + arg_index = next_arg; + } + + return (arg_index); +} + +/* Exit the shell with status S. */ +void +exit_shell (s) + int s; +{ + /* Do trap[0] if defined. Allow it to override the exit status + passed to us. */ + if (signal_is_trapped (0)) + s = run_exit_trap (); + +#if defined (PROCESS_SUBSTITUTION) + unlink_fifo_list (); +#endif /* PROCESS_SUBSTITUTION */ + +#if defined (HISTORY) + if (interactive_shell) + maybe_save_shell_history (); +#endif /* HISTORY */ + +#if defined (JOB_CONTROL) + /* If the user has run `shopt -s huponexit', hangup all jobs when we exit + an interactive login shell. ksh does this unconditionally. */ + if (interactive_shell && login_shell && hup_on_exit) + hangup_all_jobs (); + + /* If this shell is interactive, terminate all stopped jobs and + restore the original terminal process group. Don't do this if we're + in a subshell and calling exit_shell after, for example, a failed + word expansion. */ + if (subshell_environment == 0) + end_job_control (); +#endif /* JOB_CONTROL */ + + /* Always return the exit status of the last command to our parent. */ + sh_exit (s); +} + +/* A wrapper for exit that (optionally) can do other things, like malloc + statistics tracing. */ +void +sh_exit (s) + int s; +{ +#if defined (MALLOC_DEBUG) && defined (USING_BASH_MALLOC) + if (malloc_trace_at_exit) + trace_malloc_stats (get_name_for_error (), (char *)NULL); +#endif + + exit (s); +} + +/* Source the bash startup files. If POSIXLY_CORRECT is non-zero, we obey + the Posix.2 startup file rules: $ENV is expanded, and if the file it + names exists, that file is sourced. The Posix.2 rules are in effect + for interactive shells only. (section 4.56.5.3) */ + +/* Execute ~/.bashrc for most shells. Never execute it if + ACT_LIKE_SH is set, or if NO_RC is set. + + If the executable file "/usr/gnu/src/bash/foo" contains: + + #!/usr/gnu/bin/bash + echo hello + + then: + + COMMAND EXECUTE BASHRC + -------------------------------- + bash -c foo NO + bash foo NO + foo NO + rsh machine ls YES (for rsh, which calls `bash -c') + rsh machine foo YES (for shell started by rsh) NO (for foo!) + echo ls | bash NO + login NO + bash YES +*/ + +static void +execute_env_file (env_file) + char *env_file; +{ + char *fn; + + if (env_file && *env_file) + { + fn = expand_string_unsplit_to_string (env_file, Q_DOUBLE_QUOTES); + if (fn && *fn) + maybe_execute_file (fn, 1); + FREE (fn); + } +} + +static void +run_startup_files () +{ +#if defined (JOB_CONTROL) + int old_job_control; +#endif + int sourced_login, run_by_ssh; + + /* get the rshd/sshd case out of the way first. */ + if (interactive_shell == 0 && no_rc == 0 && login_shell == 0 && + act_like_sh == 0 && command_execution_string) + { +#ifdef SSH_SOURCE_BASHRC + run_by_ssh = (find_variable ("SSH_CLIENT") != (SHELL_VAR *)0) || + (find_variable ("SSH2_CLIENT") != (SHELL_VAR *)0); +#else + run_by_ssh = 0; +#endif + + /* If we were run by sshd or we think we were run by rshd, execute + ~/.bashrc if we are a top-level shell. */ + if ((run_by_ssh || isnetconn (fileno (stdin))) && shell_level < 2) + { +#ifdef SYS_BASHRC +# if defined (__OPENNT) + maybe_execute_file (_prefixInstallPath(SYS_BASHRC, NULL, 0), 1); +# else + maybe_execute_file (SYS_BASHRC, 1); +# endif +#endif + maybe_execute_file (bashrc_file, 1); + return; + } + } + +#if defined (JOB_CONTROL) + /* Startup files should be run without job control enabled. */ + old_job_control = interactive_shell ? set_job_control (0) : 0; +#endif + + sourced_login = 0; + + /* A shell begun with the --login (or -l) flag that is not in posix mode + runs the login shell startup files, no matter whether or not it is + interactive. If NON_INTERACTIVE_LOGIN_SHELLS is defined, run the + startup files if argv[0][0] == '-' as well. */ +#if defined (NON_INTERACTIVE_LOGIN_SHELLS) + if (login_shell && posixly_correct == 0) +#else + if (login_shell < 0 && posixly_correct == 0) +#endif + { + /* We don't execute .bashrc for login shells. */ + no_rc++; + + /* Execute /etc/profile and one of the personal login shell + initialization files. */ + if (no_profile == 0) + { + maybe_execute_file (SYS_PROFILE, 1); + + if (act_like_sh) /* sh */ + maybe_execute_file ("~/.profile", 1); + else if ((maybe_execute_file ("~/.bash_profile", 1) == 0) && + (maybe_execute_file ("~/.bash_login", 1) == 0)) /* bash */ + maybe_execute_file ("~/.profile", 1); + } + + sourced_login = 1; + } + + /* A non-interactive shell not named `sh' and not in posix mode reads and + executes commands from $BASH_ENV. If `su' starts a shell with `-c cmd' + and `-su' as the name of the shell, we want to read the startup files. + No other non-interactive shells read any startup files. */ + if (interactive_shell == 0 && !(su_shell && login_shell)) + { + if (posixly_correct == 0 && act_like_sh == 0 && privileged_mode == 0 && + sourced_env++ == 0) + execute_env_file (get_string_value ("BASH_ENV")); + return; + } + + /* Interactive shell or `-su' shell. */ + if (posixly_correct == 0) /* bash, sh */ + { + if (login_shell && sourced_login++ == 0) + { + /* We don't execute .bashrc for login shells. */ + no_rc++; + + /* Execute /etc/profile and one of the personal login shell + initialization files. */ + if (no_profile == 0) + { + maybe_execute_file (SYS_PROFILE, 1); + + if (act_like_sh) /* sh */ + maybe_execute_file ("~/.profile", 1); + else if ((maybe_execute_file ("~/.bash_profile", 1) == 0) && + (maybe_execute_file ("~/.bash_login", 1) == 0)) /* bash */ + maybe_execute_file ("~/.profile", 1); + } + } + + /* bash */ + if (act_like_sh == 0 && no_rc == 0) + { +#ifdef SYS_BASHRC +# if defined (__OPENNT) + maybe_execute_file (_prefixInstallPath(SYS_BASHRC, NULL, 0), 1); +# else + maybe_execute_file (SYS_BASHRC, 1); +# endif +#endif + maybe_execute_file (bashrc_file, 1); + } + /* sh */ + else if (act_like_sh && privileged_mode == 0 && sourced_env++ == 0) + execute_env_file (get_string_value ("ENV")); + } + else /* bash --posix, sh --posix */ + { + /* bash and sh */ + if (interactive_shell && privileged_mode == 0 && sourced_env++ == 0) + execute_env_file (get_string_value ("ENV")); + } + +#if defined (JOB_CONTROL) + set_job_control (old_job_control); +#endif +} + +#if defined (RESTRICTED_SHELL) +/* Return 1 if the shell should be a restricted one based on NAME or the + value of `restricted'. Don't actually do anything, just return a + boolean value. */ +int +shell_is_restricted (name) + char *name; +{ + char *temp; + + if (restricted) + return 1; + temp = base_pathname (name); + return (STREQ (temp, RESTRICTED_SHELL_NAME)); +} + +/* Perhaps make this shell a `restricted' one, based on NAME. If the + basename of NAME is "rbash", then this shell is restricted. The + name of the restricted shell is a configurable option, see config.h. + In a restricted shell, PATH, SHELL, ENV, and BASH_ENV are read-only + and non-unsettable. + Do this also if `restricted' is already set to 1; maybe the shell was + started with -r. */ +int +maybe_make_restricted (name) + char *name; +{ + char *temp; + + temp = base_pathname (name); + if (*temp == '-') + temp++; + if (restricted || (STREQ (temp, RESTRICTED_SHELL_NAME))) + { + set_var_read_only ("PATH"); + set_var_read_only ("SHELL"); + set_var_read_only ("ENV"); + set_var_read_only ("BASH_ENV"); + restricted = 1; + } + return (restricted); +} +#endif /* RESTRICTED_SHELL */ + +/* Fetch the current set of uids and gids and return 1 if we're running + setuid or setgid. */ +static int +uidget () +{ + uid_t u; + + u = getuid (); + if (current_user.uid != u) + { + FREE (current_user.user_name); + FREE (current_user.shell); + FREE (current_user.home_dir); + current_user.user_name = current_user.shell = current_user.home_dir = (char *)NULL; + } + current_user.uid = u; + current_user.gid = getgid (); + current_user.euid = geteuid (); + current_user.egid = getegid (); + + /* See whether or not we are running setuid or setgid. */ + return (current_user.uid != current_user.euid) || + (current_user.gid != current_user.egid); +} + +void +disable_priv_mode () +{ + setuid (current_user.uid); + setgid (current_user.gid); + current_user.euid = current_user.uid; + current_user.egid = current_user.gid; +} + +static int +run_wordexp (words) + char *words; +{ + int code, nw, nb; + WORD_LIST *wl, *tl, *result; + + code = setjmp (top_level); + + if (code != NOT_JUMPED) + { + switch (code) + { + /* Some kind of throw to top_level has occured. */ + case FORCE_EOF: + return last_command_exit_value = 127; + case ERREXIT: + case EXITPROG: + return last_command_exit_value; + case DISCARD: + return last_command_exit_value = 1; + default: + command_error ("run_wordexp", CMDERR_BADJUMP, code, 0); + } + } + + /* Run it through the parser to get a list of words and expand them */ + if (words && *words) + { + with_input_from_string (words, "--wordexp"); + if (parse_command () != 0) + return (126); + if (global_command == 0) + { + printf ("0\n0\n"); + return (0); + } + if (global_command->type != cm_simple) + return (126); + wl = global_command->value.Simple->words; + if (protected_mode) + for (tl = wl; tl; tl = tl->next) + tl->word->flags |= W_NOCOMSUB; + result = wl ? expand_words_no_vars (wl) : (WORD_LIST *)0; + } + else + result = (WORD_LIST *)0; + + last_command_exit_value = 0; + + if (result == 0) + { + printf ("0\n0\n"); + return (0); + } + + /* Count up the number of words and bytes, and print them. Don't count + the trailing NUL byte. */ + for (nw = nb = 0, wl = result; wl; wl = wl->next) + { + nw++; + nb += strlen (wl->word->word); + } + printf ("%u\n%u\n", nw, nb); + /* Print each word on a separate line. This will have to be changed when + the interface to glibc is completed. */ + for (wl = result; wl; wl = wl->next) + printf ("%s\n", wl->word->word); + + return (0); +} + +#if defined (ONESHOT) +/* Run one command, given as the argument to the -c option. Tell + parse_and_execute not to fork for a simple command. */ +static int +run_one_command (command) + char *command; +{ + int code; + + code = setjmp (top_level); + + if (code != NOT_JUMPED) + { +#if defined (PROCESS_SUBSTITUTION) + unlink_fifo_list (); +#endif /* PROCESS_SUBSTITUTION */ + switch (code) + { + /* Some kind of throw to top_level has occured. */ + case FORCE_EOF: + return last_command_exit_value = 127; + case ERREXIT: + case EXITPROG: + return last_command_exit_value; + case DISCARD: + return last_command_exit_value = 1; + default: + command_error ("run_one_command", CMDERR_BADJUMP, code, 0); + } + } + return (parse_and_execute (savestring (command), "-c", SEVAL_NOHIST)); +} +#endif /* ONESHOT */ + +static int +bind_args (argv, arg_start, arg_end, start_index) + char **argv; + int arg_start, arg_end, start_index; +{ + register int i; + WORD_LIST *args; + + for (i = arg_start, args = (WORD_LIST *)NULL; i != arg_end; i++) + args = make_word_list (make_word (argv[i]), args); + if (args) + { + args = REVERSE_LIST (args, WORD_LIST *); + if (start_index == 0) /* bind to $0...$n for sh -c command */ + { + /* Posix.2 4.56.3 says that the first argument after sh -c command + becomes $0, and the rest of the arguments become $1...$n */ + shell_name = savestring (args->word->word); + FREE (dollar_vars[0]); + dollar_vars[0] = savestring (args->word->word); + remember_args (args->next, 1); + push_args (args->next); /* BASH_ARGV and BASH_ARGC */ + } + else /* bind to $1...$n for shell script */ + { + remember_args (args, 1); + push_args (args); /* BASH_ARGV and BASH_ARGC */ + } + + dispose_words (args); + } + + return (i); +} + +void +unbind_args () +{ + remember_args ((WORD_LIST *)NULL, 1); + pop_args (); /* Reset BASH_ARGV and BASH_ARGC */ +} + +static void +start_debugger () +{ +#if defined (DEBUGGER) && defined (DEBUGGER_START_FILE) + int old_errexit; + + old_errexit = exit_immediately_on_error; + exit_immediately_on_error = 0; + + maybe_execute_file (DEBUGGER_START_FILE, 1); + function_trace_mode = 1; + + exit_immediately_on_error += old_errexit; +#endif +} + +static int +open_shell_script (script_name) + char *script_name; +{ + int fd, e, fd_is_tty; + char *filename, *path_filename, *t; + char sample[80]; + int sample_len; + struct stat sb; +#if defined (ARRAY_VARS) + SHELL_VAR *funcname_v, *bash_source_v, *bash_lineno_v; + ARRAY *funcname_a, *bash_source_a, *bash_lineno_a; +#endif + + free (dollar_vars[0]); + dollar_vars[0] = savestring (script_name); + filename = savestring (script_name); + +#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); + + array_push (bash_source_a, filename); + if (bash_lineno_a) + { + t = itos (executing_line_number ()); + array_push (bash_lineno_a, t); + free (t); + } + array_push (funcname_a, "main"); +#endif + + fd = open (filename, O_RDONLY); + if ((fd < 0) && (errno == ENOENT) && (absolute_program (filename) == 0)) + { + e = errno; + /* If it's not in the current directory, try looking through PATH + for it. */ + path_filename = find_path_file (script_name); + if (path_filename) + { + free (filename); + filename = path_filename; + fd = open (filename, O_RDONLY); + } + else + errno = e; + } + + if (fd < 0) + { + e = errno; + file_error (filename); + exit ((e == ENOENT) ? EX_NOTFOUND : EX_NOINPUT); + } + +#ifdef HAVE_DEV_FD + fd_is_tty = isatty (fd); +#else + fd_is_tty = 0; +#endif + + /* Only do this with non-tty file descriptors we can seek on. */ + if (fd_is_tty == 0 && (lseek (fd, 0L, 1) != -1)) + { + /* Check to see if the `file' in `bash file' is a binary file + according to the same tests done by execute_simple_command (), + and report an error and exit if it is. */ + sample_len = read (fd, sample, sizeof (sample)); + if (sample_len < 0) + { + e = errno; + if ((fstat (fd, &sb) == 0) && S_ISDIR (sb.st_mode)) + internal_error (_("%s: is a directory"), filename); + else + { + errno = e; + file_error (filename); + } + exit (EX_NOEXEC); + } + else if (sample_len > 0 && (check_binary_file (sample, sample_len))) + { + internal_error ("%s: cannot execute binary file", filename); + exit (EX_BINARY_FILE); + } + /* Now rewind the file back to the beginning. */ + lseek (fd, 0L, 0); + } + + /* Open the script. But try to move the file descriptor to a randomly + large one, in the hopes that any descriptors used by the script will + not match with ours. */ + fd = move_to_high_fd (fd, 0, -1); + +#if defined (__CYGWIN__) && defined (O_TEXT) + setmode (fd, O_TEXT); +#endif + +#if defined (BUFFERED_INPUT) + default_buffered_input = fd; + SET_CLOSE_ON_EXEC (default_buffered_input); +#else /* !BUFFERED_INPUT */ + default_input = fdopen (fd, "r"); + + if (default_input == 0) + { + file_error (filename); + exit (EX_NOTFOUND); + } + + SET_CLOSE_ON_EXEC (fd); + if (fileno (default_input) != fd) + SET_CLOSE_ON_EXEC (fileno (default_input)); +#endif /* !BUFFERED_INPUT */ + + /* Just about the only way for this code to be executed is if something + like `bash -i /dev/stdin' is executed. */ + if (interactive_shell && fd_is_tty) + { + dup2 (fd, 0); + close (fd); + fd = 0; +#if defined (BUFFERED_INPUT) + default_buffered_input = 0; +#else + fclose (default_input); + default_input = stdin; +#endif + } + else if (forced_interactive && fd_is_tty == 0) + /* But if a script is called with something like `bash -i scriptname', + we need to do a non-interactive setup here, since we didn't do it + before. */ + init_noninteractive (); + + free (filename); + return (fd); +} + +/* Initialize the input routines for the parser. */ +static void +set_bash_input () +{ + /* Make sure the fd from which we are reading input is not in + no-delay mode. */ +#if defined (BUFFERED_INPUT) + if (interactive == 0) + sh_unset_nodelay_mode (default_buffered_input); + else +#endif /* !BUFFERED_INPUT */ + sh_unset_nodelay_mode (fileno (stdin)); + + /* with_input_from_stdin really means `with_input_from_readline' */ + if (interactive && no_line_editing == 0) + with_input_from_stdin (); + else +#if defined (BUFFERED_INPUT) + { + if (interactive == 0) + with_input_from_buffered_stream (default_buffered_input, dollar_vars[0]); + else + with_input_from_stream (default_input, dollar_vars[0]); + } +#else /* !BUFFERED_INPUT */ + with_input_from_stream (default_input, dollar_vars[0]); +#endif /* !BUFFERED_INPUT */ +} + +/* Close the current shell script input source and forget about it. This is + extern so execute_cmd.c:initialize_subshell() can call it. If CHECK_ZERO + is non-zero, we close default_buffered_input even if it's the standard + input (fd 0). */ +void +unset_bash_input (check_zero) + int check_zero; +{ +#if defined (BUFFERED_INPUT) + if ((check_zero && default_buffered_input >= 0) || + (check_zero == 0 && default_buffered_input > 0)) + { + close_buffered_fd (default_buffered_input); + default_buffered_input = bash_input.location.buffered_fd = -1; + } +#else /* !BUFFERED_INPUT */ + if (default_input) + { + fclose (default_input); + default_input = (FILE *)NULL; + } +#endif /* !BUFFERED_INPUT */ +} + + +#if !defined (PROGRAM) +# define PROGRAM "bash" +#endif + +static void +set_shell_name (argv0) + char *argv0; +{ + /* Here's a hack. If the name of this shell is "sh", then don't do + any startup files; just try to be more like /bin/sh. */ + shell_name = base_pathname (argv0); + + if (*shell_name == '-') + { + shell_name++; + login_shell++; + } + + if (shell_name[0] == 's' && shell_name[1] == 'h' && shell_name[2] == '\0') + act_like_sh++; + if (shell_name[0] == 's' && shell_name[1] == 'u' && shell_name[2] == '\0') + su_shell++; + + shell_name = argv0; + FREE (dollar_vars[0]); + dollar_vars[0] = savestring (shell_name); + + /* A program may start an interactive shell with + "execl ("/bin/bash", "-", NULL)". + If so, default the name of this shell to our name. */ + if (!shell_name || !*shell_name || (shell_name[0] == '-' && !shell_name[1])) + shell_name = PROGRAM; +} + +static void +init_interactive () +{ + interactive_shell = startup_state = interactive = 1; + expand_aliases = 1; +} + +static void +init_noninteractive () +{ +#if defined (HISTORY) + bash_history_reinit (0); +#endif /* HISTORY */ + interactive_shell = startup_state = interactive = 0; + expand_aliases = posixly_correct; /* XXX - was 0 not posixly_correct */ + no_line_editing = 1; +#if defined (JOB_CONTROL) + set_job_control (0); +#endif /* JOB_CONTROL */ +} + +void +get_current_user_info () +{ + struct passwd *entry; + + /* Don't fetch this more than once. */ + if (current_user.user_name == 0) + { + entry = getpwuid (current_user.uid); + if (entry) + { + current_user.user_name = savestring (entry->pw_name); + current_user.shell = (entry->pw_shell && entry->pw_shell[0]) + ? savestring (entry->pw_shell) + : savestring ("/bin/sh"); + current_user.home_dir = savestring (entry->pw_dir); + } + else + { + current_user.user_name = _("I have no name!"); + current_user.user_name = savestring (current_user.user_name); + current_user.shell = savestring ("/bin/sh"); + current_user.home_dir = savestring ("/"); + } + endpwent (); + } +} + +/* Do whatever is necessary to initialize the shell. + Put new initializations in here. */ +static void +shell_initialize () +{ + char hostname[256]; + + /* Line buffer output for stderr and stdout. */ + if (shell_initialized == 0) + { + sh_setlinebuf (stderr); + sh_setlinebuf (stdout); + } + + /* Sort the array of shell builtins so that the binary search in + find_shell_builtin () works correctly. */ + initialize_shell_builtins (); + + /* Initialize the trap signal handlers before installing our own + signal handlers. traps.c:restore_original_signals () is responsible + for restoring the original default signal handlers. That function + is called when we make a new child. */ + initialize_traps (); + initialize_signals (0); + + /* It's highly unlikely that this will change. */ + if (current_host_name == 0) + { + /* Initialize current_host_name. */ + if (gethostname (hostname, 255) < 0) + current_host_name = "??host??"; + else + current_host_name = savestring (hostname); + } + + /* Initialize the stuff in current_user that comes from the password + file. We don't need to do this right away if the shell is not + interactive. */ + if (interactive_shell) + get_current_user_info (); + + /* Initialize our interface to the tilde expander. */ + tilde_initialize (); + + /* Initialize internal and environment variables. Don't import shell + functions from the environment if we are running in privileged or + restricted mode or if the shell is running setuid. */ +#if defined (RESTRICTED_SHELL) + initialize_shell_variables (shell_environment, privileged_mode||restricted||running_setuid); +#else + initialize_shell_variables (shell_environment, privileged_mode||running_setuid); +#endif + + /* Initialize the data structures for storing and running jobs. */ + initialize_job_control (0); + + /* Initialize input streams to null. */ + initialize_bash_input (); + + initialize_flags (); + + /* Initialize the shell options. Don't import the shell options + from the environment variable $SHELLOPTS if we are running in + privileged or restricted mode or if the shell is running setuid. */ +#if defined (RESTRICTED_SHELL) + initialize_shell_options (privileged_mode||restricted||running_setuid); +#else + initialize_shell_options (privileged_mode||running_setuid); +#endif +} + +/* Function called by main () when it appears that the shell has already + had some initialization performed. This is supposed to reset the world + back to a pristine state, as if we had been exec'ed. */ +static void +shell_reinitialize () +{ + /* The default shell prompts. */ + primary_prompt = PPROMPT; + secondary_prompt = SPROMPT; + + /* Things that get 1. */ + current_command_number = 1; + + /* We have decided that the ~/.bashrc file should not be executed + for the invocation of each shell script. If the variable $ENV + (or $BASH_ENV) is set, its value is used as the name of a file + to source. */ + no_rc = no_profile = 1; + + /* Things that get 0. */ + login_shell = make_login_shell = interactive = executing = 0; + debugging = do_version = line_number = last_command_exit_value = 0; + forced_interactive = interactive_shell = subshell_environment = 0; + expand_aliases = 0; + +#if defined (HISTORY) + bash_history_reinit (0); +#endif /* HISTORY */ + +#if defined (RESTRICTED_SHELL) + restricted = 0; +#endif /* RESTRICTED_SHELL */ + + /* Ensure that the default startup file is used. (Except that we don't + execute this file for reinitialized shells). */ + bashrc_file = "~/.bashrc"; + + /* Delete all variables and functions. They will be reinitialized when + the environment is parsed. */ + delete_all_contexts (shell_variables); + delete_all_variables (shell_functions); + + shell_reinitialized = 1; +} + +static void +show_shell_usage (fp, extra) + FILE *fp; + int extra; +{ + int i; + char *set_opts, *s, *t; + + if (extra) + fprintf (fp, "GNU bash, version %s-(%s)\n", shell_version_string (), MACHTYPE); + fprintf (fp, _("Usage:\t%s [GNU long option] [option] ...\n\t%s [GNU long option] [option] script-file ...\n"), + shell_name, shell_name); + fputs (_("GNU long options:\n"), fp); + for (i = 0; long_args[i].name; i++) + fprintf (fp, "\t--%s\n", long_args[i].name); + + fputs (_("Shell options:\n"), fp); + fputs (_("\t-irsD or -c command or -O shopt_option\t\t(invocation only)\n"), fp); + + for (i = 0, set_opts = 0; shell_builtins[i].name; i++) + if (STREQ (shell_builtins[i].name, "set")) + set_opts = savestring (shell_builtins[i].short_doc); + if (set_opts) + { + s = xstrchr (set_opts, '['); + if (s == 0) + s = set_opts; + while (*++s == '-') + ; + t = xstrchr (s, ']'); + if (t) + *t = '\0'; + fprintf (fp, _("\t-%s or -o option\n"), s); + free (set_opts); + } + + if (extra) + { + fprintf (fp, _("Type `%s -c \"help set\"' for more information about shell options.\n"), shell_name); + fprintf (fp, _("Type `%s -c help' for more information about shell builtin commands.\n"), shell_name); + fprintf (fp, _("Use the `bashbug' command to report bugs.\n")); + } +} + +static void +add_shopt_to_alist (opt, on_or_off) + char *opt; + int on_or_off; +{ + if (shopt_ind >= shopt_len) + { + shopt_len += 8; + shopt_alist = (STRING_INT_ALIST *)xrealloc (shopt_alist, shopt_len * sizeof (shopt_alist[0])); + } + shopt_alist[shopt_ind].word = opt; + shopt_alist[shopt_ind].token = on_or_off; + shopt_ind++; +} + +static void +run_shopt_alist () +{ + register int i; + + for (i = 0; i < shopt_ind; i++) + if (shopt_setopt (shopt_alist[i].word, (shopt_alist[i].token == '-')) != EXECUTION_SUCCESS) + exit (EX_BADUSAGE); + free (shopt_alist); + shopt_alist = 0; + shopt_ind = shopt_len = 0; +} diff --git a/subst.c b/subst.c index a43a72f27..17d93a434 100644 --- a/subst.c +++ b/subst.c @@ -1565,6 +1565,10 @@ string_list_internal (list, sep) if (list == 0) return ((char *)NULL); + /* Short-circuit quickly if we don't need to separate anything. */ + if (list->next == 0) + return (savestring (list->word->word)); + /* This is nearly always called with either sep[0] == 0 or sep[1] == 0. */ sep_len = STRLEN (sep); result_size = 0; @@ -4356,11 +4360,16 @@ parameter_brace_expand_rhs (name, value, c, quoted, qdollaratp, hasdollarat) if (l) { /* The expansion of TEMP returned something. We need to treat things - slightly differently if HASDOL is non-zero. */ - temp = string_list (l); + slightly differently if HASDOL is non-zero. If we have "$@", the + individual words have already been quoted. We need to turn them + into a string with the words separated by the first character of + $IFS without any additional quoting, so string_list_dollar_at won't + do the right thing. We use string_list_dollar_star instead. */ + temp = (hasdol || l->next) ? string_list_dollar_star (l) : string_list (l); + /* If l->next is not null, we know that TEMP contained "$@", since that is the only expansion that creates more than one word. */ - if ((hasdol && quoted) || l->next) + if (qdollaratp && ((hasdol && quoted) || l->next)) *qdollaratp = 1; dispose_words (l); } diff --git a/subst.c~ b/subst.c~ index ee40d8e64..f59a7d467 100644 --- a/subst.c~ +++ b/subst.c~ @@ -3107,6 +3107,8 @@ match_pattern (string, pat, mtype, sp, ep) else p++; } + + FREE (mblen); return (0); case MATCH_BEG: @@ -3136,6 +3138,8 @@ match_pattern (string, pat, mtype, sp, ep) else p--; } + + FREE (mblen); return (0); case MATCH_END: @@ -3161,6 +3165,7 @@ match_pattern (string, pat, mtype, sp, ep) return (0); } + FREE (mblen); return (0); } @@ -4351,11 +4356,16 @@ parameter_brace_expand_rhs (name, value, c, quoted, qdollaratp, hasdollarat) if (l) { /* The expansion of TEMP returned something. We need to treat things - slightly differently if HASDOL is non-zero. */ - temp = string_list (l); + slightly differently if HASDOL is non-zero. If we have "$@", the + individual words have already been quoted. We need to turn them + into a string with the words separated by the first character of + $IFS without any additional quoting, so string_list_dollar_at won't + do the right thing. We use string_list_dollar_star instead. */ + temp = (hasdol || l->next) ? string_list_dollar_star (l) : string_list (l); + /* If l->next is not null, we know that TEMP contained "$@", since that is the only expansion that creates more than one word. */ - if ((hasdol && quoted) || l->next) + if (qdollaratp && ((hasdol && quoted) || l->next)) *qdollaratp = 1; dispose_words (l); } diff --git a/tests/RUN-ONE-TEST b/tests/RUN-ONE-TEST index 3efcf32d6..72ec06a2c 100755 --- a/tests/RUN-ONE-TEST +++ b/tests/RUN-ONE-TEST @@ -1,4 +1,4 @@ -BUILD_DIR=/usr/local/build/chet/bash/bash-current +BUILD_DIR=/usr/local/build/bash/bash-current THIS_SH=$BUILD_DIR/bash PATH=$PATH:$BUILD_DIR diff --git a/tests/dollar-at-star b/tests/dollar-at-star index ade9c1f9c..7b6d75ae0 100755 --- a/tests/dollar-at-star +++ b/tests/dollar-at-star @@ -211,4 +211,8 @@ esac # expansions -- bugs through bash-2.05b ${THIS_SH} ./dollar-star1.sub +# tests for expansion of "$@" on rhs of things like ${param:+word}. Bugs +# though bash-2.05b +${THIS_SH} ./dollar-at1.sub + exit 0 diff --git a/tests/dollar-at-star~ b/tests/dollar-at-star~ new file mode 100755 index 000000000..ade9c1f9c --- /dev/null +++ b/tests/dollar-at-star~ @@ -0,0 +1,214 @@ +# first, let's start with the basics + +recho "$@" +recho "$*" + +recho $@ +recho $* + +set a b + +recho "$*" + +# If IFS is null, the parameters are joined without separators +IFS='' +recho "$*" + +# If IFS is unset, the parameters are separated by spaces +unset IFS +recho "${*}" + +recho "$@" +recho $@ + +IFS='/' +set bob 'tom dick harry' joe +set $* +recho $# +recho $1 +recho $2 +recho $3 + +set bob 'tom dick harry' joe +set ${*} +recho $# +recho $1 +recho $2 +recho $3 + +set bob 'tom dick harry' joe +set $@ +recho $# +recho $1 +recho $2 +recho $3 + +set bob 'tom dick harry' joe +set ${@} +recho $# +recho $1 +recho $2 +recho $3 + +# according to POSIX.2, unquoted $* should expand to multiple words if +# $IFS is null, just like unquoted $@ +IFS='' +set bob 'tom dick harry' joe +set $* +recho $# +recho $1 +recho $2 +recho $3 + +set bob 'tom dick harry' joe +set $@ +recho $# +recho $1 +recho $2 +recho $3 + +# if IFS is unset, the individual positional parameters are split on +# " \t\n" if $* or $@ are unquoted +unset IFS +set bob 'tom dick harry' joe +set $* +recho $# +recho $1 +recho $2 +recho $3 + +set bob 'tom dick harry' joe +set $@ +recho $# +recho $1 +recho $2 +recho $3 + +# but not for "$@" or "$*" +set bob 'tom dick harry' joe +set "$*" +recho $# +recho $1 +recho $2 +recho $3 + +set bob 'tom dick harry' joe +set "$@" +recho $# +recho $1 +recho $2 +recho $3 + +# POSIX.2 says these should both expand the positional parameters +# to multiple words +set a b c d e +IFS="" +recho $@ +recho "$@" + +# this example is straight from the POSIX.2 rationale +set foo bar bam + +recho "$@" +recho "$*" + +unset IFS + +recho "$@" +recho $@ +recho "$*" + +IFS=: + +# special variables +set -- 1 2 3 4 5 6 7 8 9 10 + +bar=${*} +foo=$* +echo foo = "$foo" +echo bar = "$bar" + +foo1=$@ +bar1=${@} + +echo foo1 = "$foo1" +echo bar1 = "$bar1" + +foo2="$*" +bar2="${*}" + +echo foo2 = "$foo2" +echo bar2 = "$bar2" + +eval foo3='$*' bar3='${*}' +echo foo3 = "$foo3" +echo bar3 = "$bar3" + +case $* in +*\:*) echo ok 1;; +*) echo bad 1;; +esac + +case $@ in +*\:*) echo bad 2;; +*) echo ok 2;; +esac + +case "$*" in +*\:*) echo ok 3;; +*) echo bad 3;; +esac + +case "$@" in +*\:*) echo bad 4;; +*) echo ok 4;; +esac + +IFS=$' \t\n' + +bar=${*} +foo=$* +echo foo = "$foo" +echo bar = "$bar" + +foo1=$@ +bar1=${@} + +echo foo1 = "$foo1" +echo bar1 = "$bar1" + +foo2="$*" +bar2="${*}" + +echo foo2 = "$foo2" +echo bar2 = "$bar2" + +eval foo3='$*' bar3='${*}' +echo foo3 = "$foo3" +echo bar3 = "$bar3" + +case $* in +*\ *) echo ok 1;; +*) echo bad 1;; +esac + +case $@ in +*\ *) echo ok 2;; +*) echo bad 2;; +esac + +case "$*" in +*\ *) echo ok 3;; +*) echo bad 3;; +esac + +case "$@" in +*\ *) echo ok 4;; +*) echo bad 4;; +esac + +# tests for special expansion of "$*" and "${array[*]}" when used with other +# expansions -- bugs through bash-2.05b +${THIS_SH} ./dollar-star1.sub + +exit 0 diff --git a/tests/dollar-at1.sub b/tests/dollar-at1.sub new file mode 100644 index 000000000..6d407863f --- /dev/null +++ b/tests/dollar-at1.sub @@ -0,0 +1,29 @@ +echo_argc() +{ + echo $# +} + +a() +{ + shift + echo_argc "$@" + echo_argc ${1:+"$@"} + echo_argc "${1:+$@}" + echo_argc 1 2 3 +} + +b() +{ + _IFS="$IFS" + IFS="$1" + shift + echo_argc "$@" + echo_argc ${1:+"$@"} + echo_argc "${1:+$@}" + echo_argc 1 2 3 + IFS="$_IFS" +} + +a "X" foo bar hoge + +b "X" foo bar hoge diff --git a/tests/dollar-at1.sub~ b/tests/dollar-at1.sub~ new file mode 100644 index 000000000..45f7cc56d --- /dev/null +++ b/tests/dollar-at1.sub~ @@ -0,0 +1,29 @@ +echo_argc() +{ + echo $# +} + +a() +{ + shift + echo_argc "$@" + echo_argc ${1:+"$@"} + echo_argc "${1:+$@}" + echo_argc 1 2 3 +} + +b() +{ + _IFS="$IFS" + IFS="$1" + shift + echo_argc "$@" + echo_argc ${1:+"$@"} + echo_argc "${1:+$@}" + echo_argc 1 2 3 + IFS="$_IFS" +} + +#a "X" foo bar hoge +#echo +b "X" foo bar hoge diff --git a/tests/dollar.right b/tests/dollar.right index 42bb65e77..f836b8316 100644 --- a/tests/dollar.right +++ b/tests/dollar.right @@ -111,3 +111,11 @@ a|b|c a|b|c xa|xb|xc xa|xb|xc +3 +3 +3 +3 +3 +3 +3 +3 diff --git a/tests/exec.right b/tests/exec.right index 070ea58e3..fbd262486 100644 --- a/tests/exec.right +++ b/tests/exec.right @@ -6,15 +6,15 @@ after exec1.sub with args: 0 after exec1.sub without args: 0 ./execscript: line 20: notthere: command not found 127 -notthere: notthere: No such file or directory +/tmp/bash: notthere: No such file or directory 127 /bin/sh: /bin/sh: cannot execute binary file 126 -./execscript: line 32: /: is a directory +./execscript: line 39: /: is a directory 126 /: /: cannot execute binary file 126 -./execscript: line 39: .: /: is a directory +./execscript: line 46: .: /: is a directory 1 127 0 @@ -22,11 +22,11 @@ this is bashenv ./exec3.sub: line 3: /tmp/bash-notthere: No such file or directory ./exec3.sub: line 3: exec: /tmp/bash-notthere: cannot execute: No such file or directory 126 -./execscript: line 61: notthere: No such file or directory +./execscript: line 68: notthere: No such file or directory 127 -./execscript: line 64: notthere: No such file or directory +./execscript: line 71: notthere: No such file or directory 127 -./execscript: line 67: notthere: No such file or directory +./execscript: line 74: notthere: No such file or directory 127 this is sh this is sh diff --git a/tests/exec.right~ b/tests/exec.right~ new file mode 100644 index 000000000..ec3d9e2e1 --- /dev/null +++ b/tests/exec.right~ @@ -0,0 +1,53 @@ +before exec1.sub: one two three +calling exec1.sub +aa bb cc dd ee +after exec1.sub with args: 0 + +after exec1.sub without args: 0 +./execscript: line 20: notthere: command not found +127 +/tmp/bash: notthere: No such file or directory +127 +/bin/sh: /bin/sh: cannot execute binary file +126 +./execscript: line 38: /: is a directory +126 +/: /: cannot execute binary file +126 +./execscript: line 45: .: /: is a directory +1 +127 +0 +this is bashenv +./exec3.sub: line 3: /tmp/bash-notthere: No such file or directory +./exec3.sub: line 3: exec: /tmp/bash-notthere: cannot execute: No such file or directory +126 +./execscript: line 67: notthere: No such file or directory +127 +./execscript: line 70: notthere: No such file or directory +127 +./execscript: line 73: notthere: No such file or directory +127 +this is sh +this is sh +unset +ok +5 +./exec5.sub: line 4: exec: bash-notthere: not found +127 +this is ohio-state +0 +1 +1 +0 +42 +42 +0 +1 +1 +0 +0 +1 +0 +1 +testb diff --git a/tests/execscript b/tests/execscript index 03208c9e3..61722f2e2 100644 --- a/tests/execscript +++ b/tests/execscript @@ -21,8 +21,15 @@ notthere echo $? # this is iffy, since the error messages may vary from system to system -${THIS_SH} notthere +# and /tmp might not exist +ln -s ${THIS_SH} /tmp/bash 2>/dev/null +if [ -f /tmp/bash ]; then + /tmp/bash notthere +else + ${THIS_SH} notthere +fi echo $? +rm -f /tmp/bash # /bin/sh should be there on all systems ${THIS_SH} /bin/sh diff --git a/tests/execscript~ b/tests/execscript~ new file mode 100644 index 000000000..03f9570be --- /dev/null +++ b/tests/execscript~ @@ -0,0 +1,105 @@ +export LC_ALL=C +export LANG=C + +if [ $UID -eq 0 ]; then + echo "execscript: the test suite should not be run as root" >&2 +fi + +set -- one two three +echo before exec1.sub: "$@" +echo calling exec1.sub +./exec1.sub aa bb cc dd ee +echo after exec1.sub with args: $? +./exec1.sub +echo after exec1.sub without args: $? + +# set up a fixed path so we know notthere will not be found +PATH=/usr/bin:/bin:/usr/local/bin: +export PATH + +notthere +echo $? + +# this is iffy, since the error messages may vary from system to system +# and /tmp might not exist +ln -s ${THIS_SH} /tmp/bash 2>/dev/null +if [ -f /tmp/bash ]; then + /tmp/bash notthere +else + ${THIS_SH} notthere +fi +echo $? + +# /bin/sh should be there on all systems +${THIS_SH} /bin/sh +echo $? + +# try executing a directory +/ +echo $? + +${THIS_SH} / +echo $? + +# try sourcing a directory +. / +echo $? + +# try sourcing a binary file -- post-2.04 versions don't do the binary file +# check, and will probably fail with `command not found', or status 127 +. ${THIS_SH} 2>/dev/null +echo $? + +# post-bash-2.05 versions allow sourcing non-regular files +. /dev/null +echo $? + +# kill two birds with one test -- test out the BASH_ENV code +echo echo this is bashenv > /tmp/bashenv +export BASH_ENV=/tmp/bashenv +${THIS_SH} ./exec3.sub +rm -f /tmp/bashenv +unset BASH_ENV + +# we're resetting the $PATH to empty, so this should be last +PATH= + +notthere +echo $? + +command notthere +echo $? + +command -p notthere +echo $? + +# but -p should guarantee that we find all the standard utilities, even +# with an empty or unset $PATH +command -p sh -c 'echo this is $0' +unset PATH +command -p sh -c 'echo this is $0' + +# a bug in bash before bash-2.01 caused PATH to be set to the empty string +# when command -p was run with PATH unset +echo ${PATH-unset} + +echo "echo ok" | ${THIS_SH} -t + +${THIS_SH} ./exec2.sub +echo $? + +${THIS_SH} ./exec4.sub + +# try exec'ing a command that cannot be found in $PATH +${THIS_SH} ./exec5.sub + +# this was a bug in bash versions before bash-2.04 +${THIS_SH} -c 'cat /dev/null' >&- + +# checks for proper return values in subshell commands with inverted return +# values + +${THIS_SH} ./exec6.sub + +# checks for properly deciding what constitutes an executable file +${THIS_SH} ./exec7.sub diff --git a/variables.c b/variables.c index e29d9710b..af04f9780 100644 --- a/variables.c +++ b/variables.c @@ -2300,6 +2300,11 @@ makunbound (name, vc) We also need to add it back into the correct hash table. */ if (old_var && local_p (old_var) && variable_context == old_var->context) { + /* Reset the attributes. Preserve the export attribute if the variable + came from a temporary environment. Make sure it stays local, and + make it invisible. */ + old_var->attributes = (exported_p (old_var) && tempvar_p (old_var)) ? att_exported : 0; + VSETATTR (old_var, att_local); VSETATTR (old_var, att_invisible); FREE (value_cell (old_var)); var_setvalue (old_var, (char *)NULL);