From f157ca874d835ed85a7e95bfa989b4b555b93511 Mon Sep 17 00:00:00 2001 From: Dan Pasanen Date: Thu, 2 Oct 2014 14:08:59 -0500 Subject: [PATCH] Set up build for android Change-Id: I4a4fab8219f16762f28877b177cf5d9c8af449d0 --- .gitignore | 8 - Android.mk | 119 ++ builtins/Android.mk | 89 + builtins/alias.c | 192 ++ builtins/bind.c | 349 ++++ builtins/break.c | 104 + builtins/builtext.h | 188 ++ builtins/builtin.c | 54 + builtins/builtins.c | 2088 +++++++++++++++++++ builtins/caller.c | 120 ++ builtins/cd.c | 613 ++++++ builtins/colon.c | 33 + builtins/command.c | 109 + builtins/complete.c | 797 ++++++++ builtins/declare.c | 921 +++++++++ builtins/echo.c | 133 ++ builtins/enable.c | 507 +++++ builtins/eval.c | 28 + builtins/exec.c | 235 +++ builtins/exit.c | 136 ++ builtins/fc.c | 736 +++++++ builtins/fg_bg.c | 146 ++ builtins/getopts.c | 284 +++ builtins/hash.c | 264 +++ builtins/help.c | 513 +++++ builtins/history.c | 413 ++++ builtins/inlib.c | 46 + builtins/jobs.c | 240 +++ builtins/kill.c | 235 +++ builtins/let.c | 68 + builtins/mapfile.c | 314 +++ builtins/pipesize.h | 8 + builtins/printf.c | 1222 +++++++++++ builtins/pushd.c | 690 +++++++ builtins/read.c | 1126 ++++++++++ builtins/return.c | 40 + builtins/set.c | 880 ++++++++ builtins/setattr.c | 605 ++++++ builtins/shift.c | 61 + builtins/shopt.c | 861 ++++++++ builtins/source.c | 154 ++ builtins/suspend.c | 95 + builtins/test.c | 52 + builtins/times.c | 90 + builtins/tmpbuiltins.c | 2088 +++++++++++++++++++ builtins/tmpbuiltins.h | 188 ++ builtins/trap.c | 260 +++ builtins/type.c | 373 ++++ builtins/ulimit.c | 732 +++++++ builtins/umask.c | 281 +++ builtins/wait.c | 303 +++ config-top.h | 2 +- config.h | 1236 +++++++++++ doc/article.ps | 1442 ------------- doc/bash.html | 2 +- doc/bash.info | 2 +- doc/bash.ps | 2 +- doc/bashbug.ps | 2 +- doc/bashref.aux | 390 ++++ doc/bashref.bt | 59 + doc/bashref.bts | 80 + doc/bashref.cp | 121 ++ doc/bashref.cps | 139 ++ doc/bashref.dvi | Bin 789640 -> 789640 bytes doc/bashref.fn | 112 + doc/bashref.fns | 132 ++ doc/bashref.html | 4090 ++++++++++++++++--------------------- doc/bashref.info | 2 +- doc/bashref.log | 315 +++ doc/bashref.ps | 6 +- doc/bashref.rw | 21 + doc/bashref.rws | 35 + doc/bashref.toc | 141 ++ doc/bashref.vr | 168 ++ doc/bashref.vrs | 195 ++ doc/builtins.ps | 2 +- doc/rbash.ps | 2 +- general.c | 12 +- lib/Android.mk | 2 + lib/glob/Android.mk | 37 + lib/readline/Android.mk | 112 + lib/readline/doc/Makefile | 145 -- lib/sh/Android.mk | 107 + lib/tilde/Android.mk | 29 + pathnames.h | 33 + signames.h | 78 + syntax.c | 269 +++ version.h | 17 + 88 files changed, 25838 insertions(+), 3892 deletions(-) create mode 100644 Android.mk create mode 100644 builtins/Android.mk create mode 100644 builtins/alias.c create mode 100644 builtins/bind.c create mode 100644 builtins/break.c create mode 100644 builtins/builtext.h create mode 100644 builtins/builtin.c create mode 100644 builtins/builtins.c create mode 100644 builtins/caller.c create mode 100644 builtins/cd.c create mode 100644 builtins/colon.c create mode 100644 builtins/command.c create mode 100644 builtins/complete.c create mode 100644 builtins/declare.c create mode 100644 builtins/echo.c create mode 100644 builtins/enable.c create mode 100644 builtins/eval.c create mode 100644 builtins/exec.c create mode 100644 builtins/exit.c create mode 100644 builtins/fc.c create mode 100644 builtins/fg_bg.c create mode 100644 builtins/getopts.c create mode 100644 builtins/hash.c create mode 100644 builtins/help.c create mode 100644 builtins/history.c create mode 100644 builtins/inlib.c create mode 100644 builtins/jobs.c create mode 100644 builtins/kill.c create mode 100644 builtins/let.c create mode 100644 builtins/mapfile.c create mode 100644 builtins/pipesize.h create mode 100644 builtins/printf.c create mode 100644 builtins/pushd.c create mode 100644 builtins/read.c create mode 100644 builtins/return.c create mode 100644 builtins/set.c create mode 100644 builtins/setattr.c create mode 100644 builtins/shift.c create mode 100644 builtins/shopt.c create mode 100644 builtins/source.c create mode 100644 builtins/suspend.c create mode 100644 builtins/test.c create mode 100644 builtins/times.c create mode 100644 builtins/tmpbuiltins.c create mode 100644 builtins/tmpbuiltins.h create mode 100644 builtins/trap.c create mode 100644 builtins/type.c create mode 100644 builtins/ulimit.c create mode 100644 builtins/umask.c create mode 100644 builtins/wait.c create mode 100644 config.h create mode 100644 doc/bashref.aux create mode 100644 doc/bashref.bt create mode 100644 doc/bashref.bts create mode 100644 doc/bashref.cp create mode 100644 doc/bashref.cps create mode 100644 doc/bashref.fn create mode 100644 doc/bashref.fns create mode 100644 doc/bashref.log create mode 100644 doc/bashref.rw create mode 100644 doc/bashref.rws create mode 100644 doc/bashref.toc create mode 100644 doc/bashref.vr create mode 100644 doc/bashref.vrs create mode 100644 lib/Android.mk create mode 100644 lib/glob/Android.mk create mode 100644 lib/readline/Android.mk delete mode 100644 lib/readline/doc/Makefile create mode 100644 lib/sh/Android.mk create mode 100644 lib/tilde/Android.mk create mode 100644 pathnames.h create mode 100644 signames.h create mode 100644 syntax.c create mode 100644 version.h diff --git a/.gitignore b/.gitignore index a3f65e8..4dcde45 100644 --- a/.gitignore +++ b/.gitignore @@ -15,7 +15,6 @@ .build .made -config.h config.status config.cache config.log @@ -28,10 +27,7 @@ bashversion Makefile builtins/Makefile -builtins/builtext.h -builtins/builtins.c builtins/mkbuiltins -builtins/pipesize.h builtins/psize.aux doc/Makefile @@ -62,10 +58,6 @@ support/man2html support/bashbug.sh lsignames.h -pathnames.h -signames.h -version.h -syntax.c stamp-h mksignames diff --git a/Android.mk b/Android.mk new file mode 100644 index 0000000..69b2a11 --- /dev/null +++ b/Android.mk @@ -0,0 +1,119 @@ +LOCAL_PATH := $(call my-dir) + +# ======================================================== +# bash +# ======================================================== +include $(CLEAR_VARS) + +LOCAL_SRC_FILES:= \ + alias.c \ + array.c \ + arrayfunc.c \ + assoc.c \ + bashhist.c \ + bashline.c \ + bracecomp.c \ + braces.c \ + copy_cmd.c \ + dispose_cmd.c \ + error.c \ + eval.c \ + execute_cmd.c \ + expr.c \ + findcmd.c \ + flags.c \ + general.c \ + hashcmd.c \ + hashlib.c \ + input.c \ + jobs.c \ + list.c \ + locale.c \ + mailcheck.c \ + make_cmd.c \ + pathexp.c \ + pcomplete.c \ + pcomplib.c \ + print_cmd.c \ + redir.c \ + shell.c \ + sig.c \ + siglist.c \ + stringlib.c \ + subst.c \ + syntax.c \ + test.c \ + trap.c \ + unwind_prot.c \ + variables.c \ + version.c \ + xmalloc.c \ + y.tab.c + +LOCAL_C_INCLUDES += \ + $(LOCAL_PATH) \ + $(LOCAL_PATH)/include \ + $(LOCAL_PATH)/lib +LOCAL_CFLAGS += \ + -DHAVE_CONFIG_H \ + -DPROGRAM=\"bash\" \ + -DPACKAGE=\"bash\" \ + -DCONF_HOSTTYPE=\"arm\" \ + -DCONF_OSTYPE=\"android-eabi\" \ + -DCONF_MACHTYPE=\"arm-android-eabi\" \ + -DCONF_VENDOR=\"unknown\" \ + -DLOCALEDIR=\"/data/locale\" \ + -DSHELL +LOCAL_SHARED_LIBRARIES += \ + libncurses +LOCAL_STATIC_LIBRARIES += \ + libbuiltins \ + libglob \ + libsh \ + libtilde \ + libhistory \ + libreadline +LOCAL_CFLAGS += \ + -Wno-char-subscripts \ + -Wno-format \ + -Wno-implicit-function-declaration \ + -Wno-incompatible-pointer-types \ + -Wno-incompatible-pointer-types-discards-qualifiers \ + -Wno-missing-field-initializers \ + -Wno-non-literal-null-conversion \ + -Wno-parentheses \ + -Wno-sign-compare \ + -Wno-sometimes-uninitialized \ + -Wno-switch \ + -Wno-unused-function \ + -Wno-unused-label \ + -Wno-unused-parameter \ + -Wno-unused-variable \ + -Wno-user-defined-warnings + +LOCAL_MODULE := bash +LOCAL_MODULE_PATH := $(TARGET_OUT_OPTIONAL_EXECUTABLES) + +LOCAL_MODULE_TAGS := optional + +include $(BUILD_EXECUTABLE) + +# ======================================================== +# bash configs +# ======================================================== +etc_files := $(wildcard $(LOCAL_PATH)/etc/*) + +BASH_ETC := $(TARGET_OUT)/etc/$(LOCAL_MODULE) +BASH_CONFIGS := $(addprefix $(BASH_ETC)/,$(notdir $(etc_files))) +$(BASH_CONFIGS): $(BASH_ETC)/%: $(LOCAL_PATH)/etc/% | $(LOCAL_BUILT_MODULE) + @echo "Install: $@ -> $(BASH_ETC)" + @mkdir -p $(dir $@) + $(hide) cp $< $@ + +ALL_DEFAULT_INSTALLED_MODULES += $(BASH_CONFIGS) + +ALL_MODULES.$(LOCAL_MODULE).INSTALLED := \ + $(ALL_MODULES.$(LOCAL_MODULE).INSTALLED) $(BASH_CONFIGS) + +# ======================================================== +include $(call all-makefiles-under,$(LOCAL_PATH)) diff --git a/builtins/Android.mk b/builtins/Android.mk new file mode 100644 index 0000000..c7345eb --- /dev/null +++ b/builtins/Android.mk @@ -0,0 +1,89 @@ +LOCAL_PATH := $(call my-dir) + +# ======================================================== +# libbuiltins.a +# ======================================================== +include $(CLEAR_VARS) + +LOCAL_SRC_FILES:= \ + alias.c \ + bashgetopt.c \ + bind.c \ + break.c \ + builtin.c \ + builtins.c \ + caller.c \ + cd.c \ + colon.c \ + command.c \ + common.c \ + complete.c \ + declare.c \ + echo.c \ + enable.c \ + eval.c \ + evalfile.c \ + evalstring.c \ + exec.c \ + exit.c \ + fc.c \ + fg_bg.c \ + gen-helpfiles.c \ + getopt.c \ + getopts.c \ + hash.c \ + help.c \ + history.c \ + inlib.c \ + jobs.c \ + kill.c \ + let.c \ + mapfile.c \ + printf.c \ + psize.c \ + pushd.c \ + read.c \ + return.c \ + setattr.c \ + set.c \ + shift.c \ + shopt.c \ + source.c \ + suspend.c \ + test.c \ + times.c \ + tmpbuiltins.c \ + trap.c \ + type.c \ + ulimit.c \ + umask.c \ + wait.c + +LOCAL_C_INCLUDES += \ + $(LOCAL_PATH)/../ \ + $(LOCAL_PATH)/../include \ + $(LOCAL_PATH)/../lib +LOCAL_CFLAGS += \ + -DHAVE_CONFIG_H \ + -DPROGRAM=\"bash\" \ + -DCONF_HOSTTYPE=\"arm\" \ + -DCONF_OSTYPE=\"android-eabi\" \ + -DCONF_MACHTYPE=\"arm-android-eabi\" \ + -DCONF_VENDOR=\"unknown\" +LOCAL_CFLAGS += \ + -Wno-implicit-function-declaration \ + -Wno-incompatible-pointer-types-discards-qualifiers \ + -Wno-knr-promoted-parameter \ + -Wno-parentheses \ + -Wno-sign-compare \ + -Wno-sometimes-uninitialized \ + -Wno-unused-function \ + -Wno-unused-parameter \ + -Wno-unused-variable + +LOCAL_MODULE_TAGS := optional +LOCAL_MODULE := libbuiltins +include $(BUILD_STATIC_LIBRARY) + +# ======================================================== +include $(call all-makefiles-under,$(LOCAL_PATH)) diff --git a/builtins/alias.c b/builtins/alias.c new file mode 100644 index 0000000..e8c283e --- /dev/null +++ b/builtins/alias.c @@ -0,0 +1,192 @@ +/* alias.c, created from alias.def. */ +#line 42 "./alias.def" + +#include + +#if defined (ALIAS) + +#if defined (HAVE_UNISTD_H) +# ifdef _MINIX +# include +# endif +# include +#endif + +# include "../bashansi.h" +# include "../bashintl.h" + +# include +# include "../shell.h" +# include "../alias.h" +# include "common.h" +# include "bashgetopt.h" + +/* Flags for print_alias */ +#define AL_REUSABLE 0x01 + +static void print_alias PARAMS((alias_t *, int)); + +/* Hack the alias command in a Korn shell way. */ +int +alias_builtin (list) + WORD_LIST *list; +{ + int any_failed, offset, pflag, dflags; + alias_t **alias_list, *t; + char *name, *value; + + dflags = posixly_correct ? 0 : AL_REUSABLE; + pflag = 0; + reset_internal_getopt (); + while ((offset = internal_getopt (list, "p")) != -1) + { + switch (offset) + { + case 'p': + pflag = 1; + dflags |= AL_REUSABLE; + break; + CASE_HELPOPT; + default: + builtin_usage (); + return (EX_USAGE); + } + } + + list = loptend; + + if (list == 0 || pflag) + { + if (aliases == 0) + return (EXECUTION_SUCCESS); + + alias_list = all_aliases (); + + if (alias_list == 0) + return (EXECUTION_SUCCESS); + + for (offset = 0; alias_list[offset]; offset++) + print_alias (alias_list[offset], dflags); + + free (alias_list); /* XXX - Do not free the strings. */ + + if (list == 0) + return (sh_chkwrite (EXECUTION_SUCCESS)); + } + + any_failed = 0; + while (list) + { + name = list->word->word; + + for (offset = 0; name[offset] && name[offset] != '='; offset++) + ; + + if (offset && name[offset] == '=') + { + name[offset] = '\0'; + value = name + offset + 1; + + if (legal_alias_name (name, 0) == 0) + { + builtin_error (_("`%s': invalid alias name"), name); + any_failed++; + } + else + add_alias (name, value); + } + else + { + t = find_alias (name); + if (t) + print_alias (t, dflags); + else + { + sh_notfound (name); + any_failed++; + } + } + list = list->next; + } + + return (any_failed ? EXECUTION_FAILURE : EXECUTION_SUCCESS); +} +#endif /* ALIAS */ + +#line 166 "./alias.def" + +#if defined (ALIAS) +/* Remove aliases named in LIST from the aliases database. */ +int +unalias_builtin (list) + register WORD_LIST *list; +{ + register alias_t *alias; + int opt, aflag; + + aflag = 0; + reset_internal_getopt (); + while ((opt = internal_getopt (list, "a")) != -1) + { + switch (opt) + { + case 'a': + aflag = 1; + break; + CASE_HELPOPT; + default: + builtin_usage (); + return (EX_USAGE); + } + } + + list = loptend; + + if (aflag) + { + delete_all_aliases (); + return (EXECUTION_SUCCESS); + } + + if (list == 0) + { + builtin_usage (); + return (EX_USAGE); + } + + aflag = 0; + while (list) + { + alias = find_alias (list->word->word); + + if (alias) + remove_alias (alias->name); + else + { + sh_notfound (list->word->word); + aflag++; + } + + list = list->next; + } + + return (aflag ? EXECUTION_FAILURE : EXECUTION_SUCCESS); +} + +/* Output ALIAS in such a way as to allow it to be read back in. */ +static void +print_alias (alias, flags) + alias_t *alias; + int flags; +{ + char *value; + + value = sh_single_quote (alias->value); + if (flags & AL_REUSABLE) + printf ("alias %s", (alias->name && alias->name[0] == '-') ? "-- " : ""); + printf ("%s=%s\n", alias->name, value); + free (value); + + fflush (stdout); +} +#endif /* ALIAS */ diff --git a/builtins/bind.c b/builtins/bind.c new file mode 100644 index 0000000..940f2aa --- /dev/null +++ b/builtins/bind.c @@ -0,0 +1,349 @@ +/* bind.c, created from bind.def. */ +#line 22 "./bind.def" + +#include + +#line 63 "./bind.def" + +#if defined (READLINE) + +#if defined (HAVE_UNISTD_H) +# ifdef _MINIX +# include +# endif +# include +#endif + +#include +#include +#if !defined (errno) +extern int errno; +#endif /* !errno */ + +#include +#include + +#include "../bashintl.h" + +#include "../shell.h" +#include "../bashline.h" +#include "bashgetopt.h" +#include "common.h" + +static int query_bindings PARAMS((char *)); +static int unbind_command PARAMS((char *)); +static int unbind_keyseq PARAMS((char *)); + +#define BIND_RETURN(x) do { return_code = x; goto bind_exit; } while (0) + +#define LFLAG 0x0001 +#define PFLAG 0x0002 +#define FFLAG 0x0004 +#define VFLAG 0x0008 +#define QFLAG 0x0010 +#define MFLAG 0x0020 +#define RFLAG 0x0040 +#define PPFLAG 0x0080 +#define VVFLAG 0x0100 +#define SFLAG 0x0200 +#define SSFLAG 0x0400 +#define UFLAG 0x0800 +#define XFLAG 0x1000 +#define XXFLAG 0x2000 + +int +bind_builtin (list) + WORD_LIST *list; +{ + int return_code; + Keymap kmap, saved_keymap; + int flags, opt; + char *initfile, *map_name, *fun_name, *unbind_name, *remove_seq, *cmd_seq, *t; + + if (no_line_editing) + { +#if 0 + builtin_error (_("line editing not enabled")); + return (EXECUTION_FAILURE); +#else + builtin_warning (_("line editing not enabled")); +#endif + } + + kmap = saved_keymap = (Keymap) NULL; + flags = 0; + initfile = map_name = fun_name = unbind_name = remove_seq = cmd_seq = (char *)NULL; + return_code = EXECUTION_SUCCESS; + + if (bash_readline_initialized == 0) + initialize_readline (); + + begin_unwind_frame ("bind_builtin"); + unwind_protect_var (rl_outstream); + + rl_outstream = stdout; + + reset_internal_getopt (); + while ((opt = internal_getopt (list, "lvpVPsSXf:q:u:m:r:x:")) != -1) + { + switch (opt) + { + case 'l': + flags |= LFLAG; + break; + case 'v': + flags |= VFLAG; + break; + case 'p': + flags |= PFLAG; + break; + case 'f': + flags |= FFLAG; + initfile = list_optarg; + break; + case 'm': + flags |= MFLAG; + map_name = list_optarg; + break; + case 'q': + flags |= QFLAG; + fun_name = list_optarg; + break; + case 'u': + flags |= UFLAG; + unbind_name = list_optarg; + break; + case 'r': + flags |= RFLAG; + remove_seq = list_optarg; + break; + case 'V': + flags |= VVFLAG; + break; + case 'P': + flags |= PPFLAG; + break; + case 's': + flags |= SFLAG; + break; + case 'S': + flags |= SSFLAG; + break; + case 'x': + flags |= XFLAG; + cmd_seq = list_optarg; + break; + case 'X': + flags |= XXFLAG; + break; + case GETOPT_HELP: + default: + builtin_usage (); + BIND_RETURN (EX_USAGE); + } + } + + list = loptend; + + /* First, see if we need to install a special keymap for this + command. Then start on the arguments. */ + + if ((flags & MFLAG) && map_name) + { + kmap = rl_get_keymap_by_name (map_name); + if (kmap == 0) + { + builtin_error (_("`%s': invalid keymap name"), map_name); + BIND_RETURN (EXECUTION_FAILURE); + } + } + + if (kmap) + { + saved_keymap = rl_get_keymap (); + rl_set_keymap (kmap); + } + + /* XXX - we need to add exclusive use tests here. It doesn't make sense + to use some of these options together. */ + /* Now hack the option arguments */ + if (flags & LFLAG) + rl_list_funmap_names (); + + if (flags & PFLAG) + rl_function_dumper (1); + + if (flags & PPFLAG) + rl_function_dumper (0); + + if (flags & SFLAG) + rl_macro_dumper (1); + + if (flags & SSFLAG) + rl_macro_dumper (0); + + if (flags & VFLAG) + rl_variable_dumper (1); + + if (flags & VVFLAG) + rl_variable_dumper (0); + + if ((flags & FFLAG) && initfile) + { + if (rl_read_init_file (initfile) != 0) + { + t = printable_filename (initfile, 0); + builtin_error (_("%s: cannot read: %s"), t, strerror (errno)); + if (t != initfile) + free (t); + BIND_RETURN (EXECUTION_FAILURE); + } + } + + if ((flags & QFLAG) && fun_name) + return_code = query_bindings (fun_name); + + if ((flags & UFLAG) && unbind_name) + return_code = unbind_command (unbind_name); + + if ((flags & RFLAG) && remove_seq) + { + opt = unbind_keyseq (remove_seq); + BIND_RETURN (opt); + } + + if (flags & XFLAG) + return_code = bind_keyseq_to_unix_command (cmd_seq); + + if (flags & XXFLAG) + return_code = print_unix_command_map (); + + /* Process the rest of the arguments as binding specifications. */ + while (list) + { + int olen, nlen, d, i; + char **obindings, **nbindings; + + obindings = rl_invoking_keyseqs (bash_execute_unix_command); + olen = obindings ? strvec_len (obindings) : 0; + + rl_parse_and_bind (list->word->word); + + nbindings = rl_invoking_keyseqs (bash_execute_unix_command); + nlen = nbindings ? strvec_len (nbindings) : 0; + + if (nlen < olen) /* fewer bind -x bindings */ + for (d = olen - nlen, i = 0; i < olen && d > 0; i++) + if (nlen == 0 || strvec_search (nbindings, obindings[i]) >= 0) + { + unbind_unix_command (obindings[i]); + d--; + } + + strvec_dispose (obindings); + strvec_dispose (nbindings); + + list = list->next; + } + + bind_exit: + if (saved_keymap) + rl_set_keymap (saved_keymap); + + run_unwind_frame ("bind_builtin"); + + if (return_code < 0) + return_code = EXECUTION_FAILURE; + + return (sh_chkwrite (return_code)); +} + +static int +query_bindings (name) + char *name; +{ + rl_command_func_t *function; + char **keyseqs; + int j; + + function = rl_named_function (name); + if (function == 0) + { + builtin_error (_("`%s': unknown function name"), name); + return EXECUTION_FAILURE; + } + + keyseqs = rl_invoking_keyseqs (function); + + if (!keyseqs) + { + printf (_("%s is not bound to any keys.\n"), name); + return EXECUTION_FAILURE; + } + + printf (_("%s can be invoked via "), name); + for (j = 0; j < 5 && keyseqs[j]; j++) + printf ("\"%s\"%s", keyseqs[j], keyseqs[j + 1] ? ", " : ".\n"); + if (keyseqs[j]) + printf ("...\n"); + strvec_dispose (keyseqs); + return EXECUTION_SUCCESS; +} + +static int +unbind_command (name) + char *name; +{ + rl_command_func_t *function; + + function = rl_named_function (name); + if (function == 0) + { + builtin_error (_("`%s': unknown function name"), name); + return EXECUTION_FAILURE; + } + + rl_unbind_function_in_map (function, rl_get_keymap ()); + return EXECUTION_SUCCESS; +} + +static int +unbind_keyseq (seq) + char *seq; +{ + char *kseq; + int kslen, type; + rl_command_func_t *f; + + kseq = (char *)xmalloc ((2 * strlen (seq)) + 1); + if (rl_translate_keyseq (seq, kseq, &kslen)) + { + free (kseq); + builtin_error (_("`%s': cannot unbind"), seq); + return EXECUTION_FAILURE; + } + if ((f = rl_function_of_keyseq_len (kseq, kslen, (Keymap)0, &type)) == 0) + { + free (kseq); + return (EXECUTION_SUCCESS); + } + if (type == ISKMAP) + f = ((Keymap) f)[ANYOTHERKEY].function; + + /* I wish this didn't have to translate the key sequence again, but readline + doesn't have a binding function that takes a translated key sequence as + an argument. */ + if (rl_bind_keyseq (seq, (rl_command_func_t *)NULL) != 0) + { + free (kseq); + builtin_error (_("`%s': cannot unbind"), seq); + return (EXECUTION_FAILURE); + } + + if (f == bash_execute_unix_command) + unbind_unix_command (seq); + + free (kseq); + return (EXECUTION_SUCCESS); +} +#endif /* READLINE */ diff --git a/builtins/break.c b/builtins/break.c new file mode 100644 index 0000000..e70587a --- /dev/null +++ b/builtins/break.c @@ -0,0 +1,104 @@ +/* break.c, created from break.def. */ +#line 22 "./break.def" + +#line 34 "./break.def" +#include + +#if defined (HAVE_UNISTD_H) +# ifdef _MINIX +# include +# endif +# include +#endif + +#include "../bashintl.h" + +#include "../shell.h" +#include "../execute_cmd.h" +#include "common.h" + +static int check_loop_level PARAMS((void)); + +/* The depth of while's and until's. */ +int loop_level = 0; + +/* Non-zero when a "break" instruction is encountered. */ +int breaking = 0; + +/* Non-zero when we have encountered a continue instruction. */ +int continuing = 0; + +/* Set up to break x levels, where x defaults to 1, but can be specified + as the first argument. */ +int +break_builtin (list) + WORD_LIST *list; +{ + intmax_t newbreak; + + CHECK_HELPOPT (list); + + if (check_loop_level () == 0) + return (EXECUTION_SUCCESS); + + (void)get_numeric_arg (list, 1, &newbreak); + + if (newbreak <= 0) + { + sh_erange (list->word->word, _("loop count")); + breaking = loop_level; + return (EXECUTION_FAILURE); + } + + if (newbreak > loop_level) + newbreak = loop_level; + + breaking = newbreak; + + return (EXECUTION_SUCCESS); +} + +#line 101 "./break.def" + +/* Set up to continue x levels, where x defaults to 1, but can be specified + as the first argument. */ +int +continue_builtin (list) + WORD_LIST *list; +{ + intmax_t newcont; + + CHECK_HELPOPT (list); + + if (check_loop_level () == 0) + return (EXECUTION_SUCCESS); + + (void)get_numeric_arg (list, 1, &newcont); + + if (newcont <= 0) + { + sh_erange (list->word->word, _("loop count")); + breaking = loop_level; + return (EXECUTION_FAILURE); + } + + if (newcont > loop_level) + newcont = loop_level; + + continuing = newcont; + + return (EXECUTION_SUCCESS); +} + +/* Return non-zero if a break or continue command would be okay. + Print an error message if break or continue is meaningless here. */ +static int +check_loop_level () +{ +#if defined (BREAK_COMPLAINS) + if (loop_level == 0 && posixly_correct == 0) + builtin_error (_("only meaningful in a `for', `while', or `until' loop")); +#endif /* BREAK_COMPLAINS */ + + return (loop_level); +} diff --git a/builtins/builtext.h b/builtins/builtext.h new file mode 100644 index 0000000..a7723fa --- /dev/null +++ b/builtins/builtext.h @@ -0,0 +1,188 @@ +/* builtext.h - The list of builtins found in libbuiltins.a. */ +#if defined (ALIAS) +extern int alias_builtin PARAMS((WORD_LIST *)); +extern char * const alias_doc[]; +#endif /* ALIAS */ +#if defined (ALIAS) +extern int unalias_builtin PARAMS((WORD_LIST *)); +extern char * const unalias_doc[]; +#endif /* ALIAS */ +#if defined (READLINE) +extern int bind_builtin PARAMS((WORD_LIST *)); +extern char * const bind_doc[]; +#endif /* READLINE */ +extern int break_builtin PARAMS((WORD_LIST *)); +extern char * const break_doc[]; +extern int continue_builtin PARAMS((WORD_LIST *)); +extern char * const continue_doc[]; +extern int builtin_builtin PARAMS((WORD_LIST *)); +extern char * const builtin_doc[]; +#if defined (DEBUGGER) +extern int caller_builtin PARAMS((WORD_LIST *)); +extern char * const caller_doc[]; +#endif /* DEBUGGER */ +extern int cd_builtin PARAMS((WORD_LIST *)); +extern char * const cd_doc[]; +extern int pwd_builtin PARAMS((WORD_LIST *)); +extern char * const pwd_doc[]; +extern int colon_builtin PARAMS((WORD_LIST *)); +extern char * const colon_doc[]; +extern int colon_builtin PARAMS((WORD_LIST *)); +extern char * const true_doc[]; +extern int false_builtin PARAMS((WORD_LIST *)); +extern char * const false_doc[]; +extern int command_builtin PARAMS((WORD_LIST *)); +extern char * const command_doc[]; +extern int declare_builtin PARAMS((WORD_LIST *)); +extern char * const declare_doc[]; +extern int declare_builtin PARAMS((WORD_LIST *)); +extern char * const typeset_doc[]; +extern int local_builtin PARAMS((WORD_LIST *)); +extern char * const local_doc[]; +#if defined (V9_ECHO) +extern int echo_builtin PARAMS((WORD_LIST *)); +extern char * const echo_doc[]; +#endif /* V9_ECHO */ +#if !defined (V9_ECHO) +extern int echo_builtin PARAMS((WORD_LIST *)); +extern char * const echo_doc[]; +#endif /* !V9_ECHO */ +extern int enable_builtin PARAMS((WORD_LIST *)); +extern char * const enable_doc[]; +extern int eval_builtin PARAMS((WORD_LIST *)); +extern char * const eval_doc[]; +extern int getopts_builtin PARAMS((WORD_LIST *)); +extern char * const getopts_doc[]; +extern int exec_builtin PARAMS((WORD_LIST *)); +extern char * const exec_doc[]; +extern int exit_builtin PARAMS((WORD_LIST *)); +extern char * const exit_doc[]; +extern int logout_builtin PARAMS((WORD_LIST *)); +extern char * const logout_doc[]; +#if defined (HISTORY) +extern int fc_builtin PARAMS((WORD_LIST *)); +extern char * const fc_doc[]; +#endif /* HISTORY */ +#if defined (JOB_CONTROL) +extern int fg_builtin PARAMS((WORD_LIST *)); +extern char * const fg_doc[]; +#endif /* JOB_CONTROL */ +#if defined (JOB_CONTROL) +extern int bg_builtin PARAMS((WORD_LIST *)); +extern char * const bg_doc[]; +#endif /* JOB_CONTROL */ +extern int hash_builtin PARAMS((WORD_LIST *)); +extern char * const hash_doc[]; +#if defined (HELP_BUILTIN) +extern int help_builtin PARAMS((WORD_LIST *)); +extern char * const help_doc[]; +#endif /* HELP_BUILTIN */ +#if defined (HISTORY) +extern int history_builtin PARAMS((WORD_LIST *)); +extern char * const history_doc[]; +#endif /* HISTORY */ +#if defined (JOB_CONTROL) +extern int jobs_builtin PARAMS((WORD_LIST *)); +extern char * const jobs_doc[]; +#endif /* JOB_CONTROL */ +#if defined (JOB_CONTROL) +extern int disown_builtin PARAMS((WORD_LIST *)); +extern char * const disown_doc[]; +#endif /* JOB_CONTROL */ +extern int kill_builtin PARAMS((WORD_LIST *)); +extern char * const kill_doc[]; +extern int let_builtin PARAMS((WORD_LIST *)); +extern char * const let_doc[]; +extern int read_builtin PARAMS((WORD_LIST *)); +extern char * const read_doc[]; +extern int return_builtin PARAMS((WORD_LIST *)); +extern char * const return_doc[]; +extern int set_builtin PARAMS((WORD_LIST *)); +extern char * const set_doc[]; +extern int unset_builtin PARAMS((WORD_LIST *)); +extern char * const unset_doc[]; +extern int export_builtin PARAMS((WORD_LIST *)); +extern char * const export_doc[]; +extern int readonly_builtin PARAMS((WORD_LIST *)); +extern char * const readonly_doc[]; +extern int shift_builtin PARAMS((WORD_LIST *)); +extern char * const shift_doc[]; +extern int source_builtin PARAMS((WORD_LIST *)); +extern char * const source_doc[]; +extern int source_builtin PARAMS((WORD_LIST *)); +extern char * const dot_doc[]; +#if defined (JOB_CONTROL) +extern int suspend_builtin PARAMS((WORD_LIST *)); +extern char * const suspend_doc[]; +#endif /* JOB_CONTROL */ +extern int test_builtin PARAMS((WORD_LIST *)); +extern char * const test_doc[]; +extern int test_builtin PARAMS((WORD_LIST *)); +extern char * const test_bracket_doc[]; +extern int times_builtin PARAMS((WORD_LIST *)); +extern char * const times_doc[]; +extern int trap_builtin PARAMS((WORD_LIST *)); +extern char * const trap_doc[]; +extern int type_builtin PARAMS((WORD_LIST *)); +extern char * const type_doc[]; +#if !defined (_MINIX) +extern int ulimit_builtin PARAMS((WORD_LIST *)); +extern char * const ulimit_doc[]; +#endif /* !_MINIX */ +extern int umask_builtin PARAMS((WORD_LIST *)); +extern char * const umask_doc[]; +#if defined (JOB_CONTROL) +extern int wait_builtin PARAMS((WORD_LIST *)); +extern char * const wait_doc[]; +#endif /* JOB_CONTROL */ +#if !defined (JOB_CONTROL) +extern int wait_builtin PARAMS((WORD_LIST *)); +extern char * const wait_doc[]; +#endif /* !JOB_CONTROL */ +extern char * const for_doc[]; +extern char * const arith_for_doc[]; +extern char * const select_doc[]; +extern char * const time_doc[]; +extern char * const case_doc[]; +extern char * const if_doc[]; +extern char * const while_doc[]; +extern char * const until_doc[]; +extern char * const coproc_doc[]; +extern char * const function_doc[]; +extern char * const grouping_braces_doc[]; +extern char * const fg_percent_doc[]; +extern char * const arith_doc[]; +extern char * const conditional_doc[]; +extern char * const variable_help_doc[]; +#if defined (PUSHD_AND_POPD) +extern int pushd_builtin PARAMS((WORD_LIST *)); +extern char * const pushd_doc[]; +#endif /* PUSHD_AND_POPD */ +#if defined (PUSHD_AND_POPD) +extern int popd_builtin PARAMS((WORD_LIST *)); +extern char * const popd_doc[]; +#endif /* PUSHD_AND_POPD */ +#if defined (PUSHD_AND_POPD) +extern int dirs_builtin PARAMS((WORD_LIST *)); +extern char * const dirs_doc[]; +#endif /* PUSHD_AND_POPD */ +extern int shopt_builtin PARAMS((WORD_LIST *)); +extern char * const shopt_doc[]; +extern int printf_builtin PARAMS((WORD_LIST *)); +extern char * const printf_doc[]; +#if defined (PROGRAMMABLE_COMPLETION) +extern int complete_builtin PARAMS((WORD_LIST *)); +extern char * const complete_doc[]; +#endif /* PROGRAMMABLE_COMPLETION */ +#if defined (PROGRAMMABLE_COMPLETION) +extern int compgen_builtin PARAMS((WORD_LIST *)); +extern char * const compgen_doc[]; +#endif /* PROGRAMMABLE_COMPLETION */ +#if defined (PROGRAMMABLE_COMPLETION) +extern int compopt_builtin PARAMS((WORD_LIST *)); +extern char * const compopt_doc[]; +#endif /* PROGRAMMABLE_COMPLETION */ +extern int mapfile_builtin PARAMS((WORD_LIST *)); +extern char * const mapfile_doc[]; +extern int mapfile_builtin PARAMS((WORD_LIST *)); +extern char * const readarray_doc[]; diff --git a/builtins/builtin.c b/builtins/builtin.c new file mode 100644 index 0000000..07224d7 --- /dev/null +++ b/builtins/builtin.c @@ -0,0 +1,54 @@ +/* builtin.c, created from builtin.def. */ +#line 22 "./builtin.def" + +#line 36 "./builtin.def" +#include + +#if defined (HAVE_UNISTD_H) +# ifdef _MINIX +# include +# endif +# include +#endif + +#include "../shell.h" +#include "../execute_cmd.h" +#include "common.h" +#include "bashgetopt.h" + +/* Run the command mentioned in list directly, without going through the + normal alias/function/builtin/filename lookup process. */ +int +builtin_builtin (list) + WORD_LIST *list; +{ + sh_builtin_func_t *function; + register char *command; + + if (no_options (list)) + return (EX_USAGE); + list = loptend; /* skip over possible `--' */ + + if (list == 0) + return (EXECUTION_SUCCESS); + + command = list->word->word; +#if defined (DISABLED_BUILTINS) + function = builtin_address (command); +#else /* !DISABLED_BUILTINS */ + function = find_shell_builtin (command); +#endif /* !DISABLED_BUILTINS */ + + if (function == 0) + { + sh_notbuiltin (command); + return (EXECUTION_FAILURE); + } + else + { + this_command_name = command; + this_shell_builtin = function; /* overwrite "builtin" as this builtin */ + list = list->next; + return ((*function) (list)); + } +} diff --git a/builtins/builtins.c b/builtins/builtins.c new file mode 100644 index 0000000..7b7db38 --- /dev/null +++ b/builtins/builtins.c @@ -0,0 +1,2088 @@ +/* builtins.c -- the built in shell commands. */ + +/* This file is manufactured by ./mkbuiltins, and should not be + edited by hand. See the source to mkbuiltins for details. */ + +/* Copyright (C) 1987-2015 Free Software Foundation, Inc. + + This file is part of GNU Bash, the Bourne Again SHell. + + Bash is free software: you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation, either version 3 of the License, or + (at your option) any later version. + + Bash is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with Bash. If not, see . +*/ + +/* The list of shell builtins. Each element is name, function, flags, + long-doc, short-doc. The long-doc field contains a pointer to an array + of help lines. The function takes a WORD_LIST *; the first word in the + list is the first arg to the command. The list has already had word + expansion performed. + + Functions which need to look at only the simple commands (e.g. + the enable_builtin ()), should ignore entries where + (array[i].function == (sh_builtin_func_t *)NULL). Such entries are for + the list of shell reserved control structures, like `if' and `while'. + The end of the list is denoted with a NULL name field. */ + +/* TRANSLATORS: Please do not translate command names in descriptions */ + +#include "../builtins.h" +#include "builtext.h" +#include "bashintl.h" + +struct builtin static_shell_builtins[] = { +#if defined (ALIAS) + { "alias", alias_builtin, BUILTIN_ENABLED | STATIC_BUILTIN | ASSIGNMENT_BUILTIN | POSIX_BUILTIN, alias_doc, + N_("alias [-p] [name[=value] ... ]"), (char *)NULL }, +#endif /* ALIAS */ +#if defined (ALIAS) + { "unalias", unalias_builtin, BUILTIN_ENABLED | STATIC_BUILTIN | POSIX_BUILTIN, unalias_doc, + N_("unalias [-a] name [name ...]"), (char *)NULL }, +#endif /* ALIAS */ +#if defined (READLINE) + { "bind", bind_builtin, BUILTIN_ENABLED | STATIC_BUILTIN, bind_doc, + N_("bind [-lpsvPSVX] [-m keymap] [-f filename] [-q name] [-u name] [-r keyseq] [-x keyseq:shell-command] [keyseq:readline-function or readline-command]"), (char *)NULL }, +#endif /* READLINE */ + { "break", break_builtin, BUILTIN_ENABLED | STATIC_BUILTIN | SPECIAL_BUILTIN, break_doc, + N_("break [n]"), (char *)NULL }, + { "continue", continue_builtin, BUILTIN_ENABLED | STATIC_BUILTIN | SPECIAL_BUILTIN, continue_doc, + N_("continue [n]"), (char *)NULL }, + { "builtin", builtin_builtin, BUILTIN_ENABLED | STATIC_BUILTIN, builtin_doc, + N_("builtin [shell-builtin [arg ...]]"), (char *)NULL }, +#if defined (DEBUGGER) + { "caller", caller_builtin, BUILTIN_ENABLED | STATIC_BUILTIN, caller_doc, + N_("caller [expr]"), (char *)NULL }, +#endif /* DEBUGGER */ + { "cd", cd_builtin, BUILTIN_ENABLED | STATIC_BUILTIN | POSIX_BUILTIN, cd_doc, + N_("cd [-L|[-P [-e]] [-@]] [dir]"), (char *)NULL }, + { "pwd", pwd_builtin, BUILTIN_ENABLED | STATIC_BUILTIN | POSIX_BUILTIN, pwd_doc, + N_("pwd [-LP]"), (char *)NULL }, + { ":", colon_builtin, BUILTIN_ENABLED | STATIC_BUILTIN | SPECIAL_BUILTIN, colon_doc, + ":", (char *)NULL }, + { "true", colon_builtin, BUILTIN_ENABLED | STATIC_BUILTIN | POSIX_BUILTIN, true_doc, + "true", (char *)NULL }, + { "false", false_builtin, BUILTIN_ENABLED | STATIC_BUILTIN | POSIX_BUILTIN, false_doc, + "false", (char *)NULL }, + { "command", command_builtin, BUILTIN_ENABLED | STATIC_BUILTIN | POSIX_BUILTIN, command_doc, + N_("command [-pVv] command [arg ...]"), (char *)NULL }, + { "declare", declare_builtin, BUILTIN_ENABLED | STATIC_BUILTIN | ASSIGNMENT_BUILTIN | LOCALVAR_BUILTIN, declare_doc, + N_("declare [-aAfFgiIlnrtux] [-p] [name[=value] ...]"), (char *)NULL }, + { "typeset", declare_builtin, BUILTIN_ENABLED | STATIC_BUILTIN | ASSIGNMENT_BUILTIN | LOCALVAR_BUILTIN, typeset_doc, + N_("typeset [-aAfFgiIlnrtux] [-p] name[=value] ..."), (char *)NULL }, + { "local", local_builtin, BUILTIN_ENABLED | STATIC_BUILTIN | ASSIGNMENT_BUILTIN | LOCALVAR_BUILTIN, local_doc, + N_("local [option] name[=value] ..."), (char *)NULL }, +#if defined (V9_ECHO) + { "echo", echo_builtin, BUILTIN_ENABLED | STATIC_BUILTIN, echo_doc, + N_("echo [-neE] [arg ...]"), (char *)NULL }, +#endif /* V9_ECHO */ +#if !defined (V9_ECHO) + { "echo", echo_builtin, BUILTIN_ENABLED | STATIC_BUILTIN, echo_doc, + N_("echo [-n] [arg ...]"), (char *)NULL }, +#endif /* !V9_ECHO */ + { "enable", enable_builtin, BUILTIN_ENABLED | STATIC_BUILTIN, enable_doc, + N_("enable [-a] [-dnps] [-f filename] [name ...]"), (char *)NULL }, + { "eval", eval_builtin, BUILTIN_ENABLED | STATIC_BUILTIN | SPECIAL_BUILTIN, eval_doc, + N_("eval [arg ...]"), (char *)NULL }, + { "getopts", getopts_builtin, BUILTIN_ENABLED | STATIC_BUILTIN | POSIX_BUILTIN, getopts_doc, + N_("getopts optstring name [arg ...]"), (char *)NULL }, + { "exec", exec_builtin, BUILTIN_ENABLED | STATIC_BUILTIN | SPECIAL_BUILTIN, exec_doc, + N_("exec [-cl] [-a name] [command [argument ...]] [redirection ...]"), (char *)NULL }, + { "exit", exit_builtin, BUILTIN_ENABLED | STATIC_BUILTIN | SPECIAL_BUILTIN, exit_doc, + N_("exit [n]"), (char *)NULL }, + { "logout", logout_builtin, BUILTIN_ENABLED | STATIC_BUILTIN, logout_doc, + N_("logout [n]"), (char *)NULL }, +#if defined (HISTORY) + { "fc", fc_builtin, BUILTIN_ENABLED | STATIC_BUILTIN | POSIX_BUILTIN, fc_doc, + N_("fc [-e ename] [-lnr] [first] [last] or fc -s [pat=rep] [command]"), (char *)NULL }, +#endif /* HISTORY */ +#if defined (JOB_CONTROL) + { "fg", fg_builtin, BUILTIN_ENABLED | STATIC_BUILTIN | POSIX_BUILTIN, fg_doc, + N_("fg [job_spec]"), (char *)NULL }, +#endif /* JOB_CONTROL */ +#if defined (JOB_CONTROL) + { "bg", bg_builtin, BUILTIN_ENABLED | STATIC_BUILTIN | POSIX_BUILTIN, bg_doc, + N_("bg [job_spec ...]"), (char *)NULL }, +#endif /* JOB_CONTROL */ + { "hash", hash_builtin, BUILTIN_ENABLED | STATIC_BUILTIN, hash_doc, + N_("hash [-lr] [-p pathname] [-dt] [name ...]"), (char *)NULL }, +#if defined (HELP_BUILTIN) + { "help", help_builtin, BUILTIN_ENABLED | STATIC_BUILTIN, help_doc, + N_("help [-dms] [pattern ...]"), (char *)NULL }, +#endif /* HELP_BUILTIN */ +#if defined (HISTORY) + { "history", history_builtin, BUILTIN_ENABLED | STATIC_BUILTIN, history_doc, + N_("history [-c] [-d offset] [n] or history -anrw [filename] or history -ps arg [arg...]"), (char *)NULL }, +#endif /* HISTORY */ +#if defined (JOB_CONTROL) + { "jobs", jobs_builtin, BUILTIN_ENABLED | STATIC_BUILTIN | POSIX_BUILTIN, jobs_doc, + N_("jobs [-lnprs] [jobspec ...] or jobs -x command [args]"), (char *)NULL }, +#endif /* JOB_CONTROL */ +#if defined (JOB_CONTROL) + { "disown", disown_builtin, BUILTIN_ENABLED | STATIC_BUILTIN, disown_doc, + N_("disown [-h] [-ar] [jobspec ... | pid ...]"), (char *)NULL }, +#endif /* JOB_CONTROL */ + { "kill", kill_builtin, BUILTIN_ENABLED | STATIC_BUILTIN | POSIX_BUILTIN, kill_doc, + N_("kill [-s sigspec | -n signum | -sigspec] pid | jobspec ... or kill -l [sigspec]"), (char *)NULL }, + { "let", let_builtin, BUILTIN_ENABLED | STATIC_BUILTIN, let_doc, + N_("let arg [arg ...]"), (char *)NULL }, + { "read", read_builtin, BUILTIN_ENABLED | STATIC_BUILTIN | POSIX_BUILTIN, read_doc, + N_("read [-ers] [-a array] [-d delim] [-i text] [-n nchars] [-N nchars] [-p prompt] [-t timeout] [-u fd] [name ...]"), (char *)NULL }, + { "return", return_builtin, BUILTIN_ENABLED | STATIC_BUILTIN | SPECIAL_BUILTIN, return_doc, + N_("return [n]"), (char *)NULL }, + { "set", set_builtin, BUILTIN_ENABLED | STATIC_BUILTIN | SPECIAL_BUILTIN, set_doc, + N_("set [-abefhkmnptuvxBCHP] [-o option-name] [--] [arg ...]"), (char *)NULL }, + { "unset", unset_builtin, BUILTIN_ENABLED | STATIC_BUILTIN | SPECIAL_BUILTIN, unset_doc, + N_("unset [-f] [-v] [-n] [name ...]"), (char *)NULL }, + { "export", export_builtin, BUILTIN_ENABLED | STATIC_BUILTIN | SPECIAL_BUILTIN | ASSIGNMENT_BUILTIN, export_doc, + N_("export [-fn] [name[=value] ...] or export -p"), (char *)NULL }, + { "readonly", readonly_builtin, BUILTIN_ENABLED | STATIC_BUILTIN | SPECIAL_BUILTIN | ASSIGNMENT_BUILTIN, readonly_doc, + N_("readonly [-aAf] [name[=value] ...] or readonly -p"), (char *)NULL }, + { "shift", shift_builtin, BUILTIN_ENABLED | STATIC_BUILTIN | SPECIAL_BUILTIN, shift_doc, + N_("shift [n]"), (char *)NULL }, + { "source", source_builtin, BUILTIN_ENABLED | STATIC_BUILTIN | SPECIAL_BUILTIN, source_doc, + N_("source filename [arguments]"), (char *)NULL }, + { ".", source_builtin, BUILTIN_ENABLED | STATIC_BUILTIN | SPECIAL_BUILTIN, dot_doc, + N_(". filename [arguments]"), (char *)NULL }, +#if defined (JOB_CONTROL) + { "suspend", suspend_builtin, BUILTIN_ENABLED | STATIC_BUILTIN, suspend_doc, + N_("suspend [-f]"), (char *)NULL }, +#endif /* JOB_CONTROL */ + { "test", test_builtin, BUILTIN_ENABLED | STATIC_BUILTIN, test_doc, + N_("test [expr]"), (char *)NULL }, + { "[", test_builtin, BUILTIN_ENABLED | STATIC_BUILTIN, test_bracket_doc, + N_("[ arg... ]"), (char *)NULL }, + { "times", times_builtin, BUILTIN_ENABLED | STATIC_BUILTIN | SPECIAL_BUILTIN, times_doc, + "times", (char *)NULL }, + { "trap", trap_builtin, BUILTIN_ENABLED | STATIC_BUILTIN | SPECIAL_BUILTIN, trap_doc, + N_("trap [-lp] [[arg] signal_spec ...]"), (char *)NULL }, + { "type", type_builtin, BUILTIN_ENABLED | STATIC_BUILTIN, type_doc, + N_("type [-afptP] name [name ...]"), (char *)NULL }, +#if !defined (_MINIX) + { "ulimit", ulimit_builtin, BUILTIN_ENABLED | STATIC_BUILTIN, ulimit_doc, + N_("ulimit [-SHabcdefiklmnpqrstuvxPT] [limit]"), (char *)NULL }, +#endif /* !_MINIX */ + { "umask", umask_builtin, BUILTIN_ENABLED | STATIC_BUILTIN | POSIX_BUILTIN, umask_doc, + N_("umask [-p] [-S] [mode]"), (char *)NULL }, +#if defined (JOB_CONTROL) + { "wait", wait_builtin, BUILTIN_ENABLED | STATIC_BUILTIN | POSIX_BUILTIN, wait_doc, + N_("wait [-fn] [-p var] [id ...]"), (char *)NULL }, +#endif /* JOB_CONTROL */ +#if !defined (JOB_CONTROL) + { "wait", wait_builtin, BUILTIN_ENABLED | STATIC_BUILTIN | POSIX_BUILTIN, wait_doc, + N_("wait [pid ...]"), (char *)NULL }, +#endif /* !JOB_CONTROL */ + { "for", (sh_builtin_func_t *)0x0, BUILTIN_ENABLED | STATIC_BUILTIN, for_doc, + N_("for NAME [in WORDS ... ] ; do COMMANDS; done"), (char *)NULL }, + { "for ((", (sh_builtin_func_t *)0x0, BUILTIN_ENABLED | STATIC_BUILTIN, arith_for_doc, + N_("for (( exp1; exp2; exp3 )); do COMMANDS; done"), (char *)NULL }, + { "select", (sh_builtin_func_t *)0x0, BUILTIN_ENABLED | STATIC_BUILTIN, select_doc, + N_("select NAME [in WORDS ... ;] do COMMANDS; done"), (char *)NULL }, + { "time", (sh_builtin_func_t *)0x0, BUILTIN_ENABLED | STATIC_BUILTIN, time_doc, + N_("time [-p] pipeline"), (char *)NULL }, + { "case", (sh_builtin_func_t *)0x0, BUILTIN_ENABLED | STATIC_BUILTIN, case_doc, + N_("case WORD in [PATTERN [| PATTERN]...) COMMANDS ;;]... esac"), (char *)NULL }, + { "if", (sh_builtin_func_t *)0x0, BUILTIN_ENABLED | STATIC_BUILTIN, if_doc, + N_("if COMMANDS; then COMMANDS; [ elif COMMANDS; then COMMANDS; ]... [ else COMMANDS; ] fi"), (char *)NULL }, + { "while", (sh_builtin_func_t *)0x0, BUILTIN_ENABLED | STATIC_BUILTIN, while_doc, + N_("while COMMANDS; do COMMANDS; done"), (char *)NULL }, + { "until", (sh_builtin_func_t *)0x0, BUILTIN_ENABLED | STATIC_BUILTIN, until_doc, + N_("until COMMANDS; do COMMANDS; done"), (char *)NULL }, + { "coproc", (sh_builtin_func_t *)0x0, BUILTIN_ENABLED | STATIC_BUILTIN, coproc_doc, + N_("coproc [NAME] command [redirections]"), (char *)NULL }, + { "function", (sh_builtin_func_t *)0x0, BUILTIN_ENABLED | STATIC_BUILTIN, function_doc, + N_("function name { COMMANDS ; } or name () { COMMANDS ; }"), (char *)NULL }, + { "{ ... }", (sh_builtin_func_t *)0x0, BUILTIN_ENABLED | STATIC_BUILTIN, grouping_braces_doc, + N_("{ COMMANDS ; }"), (char *)NULL }, + { "%", (sh_builtin_func_t *)0x0, BUILTIN_ENABLED | STATIC_BUILTIN, fg_percent_doc, + N_("job_spec [&]"), (char *)NULL }, + { "(( ... ))", (sh_builtin_func_t *)0x0, BUILTIN_ENABLED | STATIC_BUILTIN, arith_doc, + N_("(( expression ))"), (char *)NULL }, + { "[[ ... ]]", (sh_builtin_func_t *)0x0, BUILTIN_ENABLED | STATIC_BUILTIN, conditional_doc, + N_("[[ expression ]]"), (char *)NULL }, + { "variables", (sh_builtin_func_t *)0x0, BUILTIN_ENABLED | STATIC_BUILTIN, variable_help_doc, + N_("variables - Names and meanings of some shell variables"), (char *)NULL }, +#if defined (PUSHD_AND_POPD) + { "pushd", pushd_builtin, BUILTIN_ENABLED | STATIC_BUILTIN, pushd_doc, + N_("pushd [-n] [+N | -N | dir]"), (char *)NULL }, +#endif /* PUSHD_AND_POPD */ +#if defined (PUSHD_AND_POPD) + { "popd", popd_builtin, BUILTIN_ENABLED | STATIC_BUILTIN, popd_doc, + N_("popd [-n] [+N | -N]"), (char *)NULL }, +#endif /* PUSHD_AND_POPD */ +#if defined (PUSHD_AND_POPD) + { "dirs", dirs_builtin, BUILTIN_ENABLED | STATIC_BUILTIN, dirs_doc, + N_("dirs [-clpv] [+N] [-N]"), (char *)NULL }, +#endif /* PUSHD_AND_POPD */ + { "shopt", shopt_builtin, BUILTIN_ENABLED | STATIC_BUILTIN, shopt_doc, + N_("shopt [-pqsu] [-o] [optname ...]"), (char *)NULL }, + { "printf", printf_builtin, BUILTIN_ENABLED | STATIC_BUILTIN, printf_doc, + N_("printf [-v var] format [arguments]"), (char *)NULL }, +#if defined (PROGRAMMABLE_COMPLETION) + { "complete", complete_builtin, BUILTIN_ENABLED | STATIC_BUILTIN, complete_doc, + N_("complete [-abcdefgjksuv] [-pr] [-DEI] [-o option] [-A action] [-G globpat] [-W wordlist] [-F function] [-C command] [-X filterpat] [-P prefix] [-S suffix] [name ...]"), (char *)NULL }, +#endif /* PROGRAMMABLE_COMPLETION */ +#if defined (PROGRAMMABLE_COMPLETION) + { "compgen", compgen_builtin, BUILTIN_ENABLED | STATIC_BUILTIN, compgen_doc, + N_("compgen [-abcdefgjksuv] [-o option] [-A action] [-G globpat] [-W wordlist] [-F function] [-C command] [-X filterpat] [-P prefix] [-S suffix] [word]"), (char *)NULL }, +#endif /* PROGRAMMABLE_COMPLETION */ +#if defined (PROGRAMMABLE_COMPLETION) + { "compopt", compopt_builtin, BUILTIN_ENABLED | STATIC_BUILTIN, compopt_doc, + N_("compopt [-o|+o option] [-DEI] [name ...]"), (char *)NULL }, +#endif /* PROGRAMMABLE_COMPLETION */ + { "mapfile", mapfile_builtin, BUILTIN_ENABLED | STATIC_BUILTIN, mapfile_doc, + N_("mapfile [-d delim] [-n count] [-O origin] [-s count] [-t] [-u fd] [-C callback] [-c quantum] [array]"), (char *)NULL }, + { "readarray", mapfile_builtin, BUILTIN_ENABLED | STATIC_BUILTIN, readarray_doc, + N_("readarray [-d delim] [-n count] [-O origin] [-s count] [-t] [-u fd] [-C callback] [-c quantum] [array]"), (char *)NULL }, + { (char *)0x0, (sh_builtin_func_t *)0x0, 0, (char **)0x0, (char *)0x0, (char *)0x0 } +}; + +struct builtin *shell_builtins = static_shell_builtins; +struct builtin *current_builtin; + +int num_shell_builtins = + sizeof (static_shell_builtins) / sizeof (struct builtin) - 1; +#if defined (ALIAS) +char * const alias_doc[] = { +#if defined (HELP_BUILTIN) +N_("Define or display aliases.\n\ + \n\ + Without arguments, `alias' prints the list of aliases in the reusable\n\ + form `alias NAME=VALUE' on standard output.\n\ + \n\ + Otherwise, an alias is defined for each NAME whose VALUE is given.\n\ + A trailing space in VALUE causes the next word to be checked for\n\ + alias substitution when the alias is expanded.\n\ + \n\ + Options:\n\ + -p print all defined aliases in a reusable format\n\ + \n\ + Exit Status:\n\ + alias returns true unless a NAME is supplied for which no alias has been\n\ + defined."), +#endif /* HELP_BUILTIN */ + (char *)NULL +}; +#endif /* ALIAS */ +#if defined (ALIAS) +char * const unalias_doc[] = { +#if defined (HELP_BUILTIN) +N_("Remove each NAME from the list of defined aliases.\n\ + \n\ + Options:\n\ + -a remove all alias definitions\n\ + \n\ + Return success unless a NAME is not an existing alias."), +#endif /* HELP_BUILTIN */ + (char *)NULL +}; +#endif /* ALIAS */ +#if defined (READLINE) +char * const bind_doc[] = { +#if defined (HELP_BUILTIN) +N_("Set Readline key bindings and variables.\n\ + \n\ + Bind a key sequence to a Readline function or a macro, or set a\n\ + Readline variable. The non-option argument syntax is equivalent to\n\ + that found in ~/.inputrc, but must be passed as a single argument:\n\ + e.g., bind '\"\\C-x\\C-r\": re-read-init-file'.\n\ + \n\ + Options:\n\ + -m keymap Use KEYMAP as the keymap for the duration of this\n\ + command. Acceptable keymap names are emacs,\n\ + emacs-standard, emacs-meta, emacs-ctlx, vi, vi-move,\n\ + vi-command, and vi-insert.\n\ + -l List names of functions.\n\ + -P List function names and bindings.\n\ + -p List functions and bindings in a form that can be\n\ + reused as input.\n\ + -S List key sequences that invoke macros and their values\n\ + -s List key sequences that invoke macros and their values\n\ + in a form that can be reused as input.\n\ + -V List variable names and values\n\ + -v List variable names and values in a form that can\n\ + be reused as input.\n\ + -q function-name Query about which keys invoke the named function.\n\ + -u function-name Unbind all keys which are bound to the named function.\n\ + -r keyseq Remove the binding for KEYSEQ.\n\ + -f filename Read key bindings from FILENAME.\n\ + -x keyseq:shell-command Cause SHELL-COMMAND to be executed when\n\ + KEYSEQ is entered.\n\ + -X List key sequences bound with -x and associated commands\n\ + in a form that can be reused as input.\n\ + \n\ + Exit Status:\n\ + bind returns 0 unless an unrecognized option is given or an error occurs."), +#endif /* HELP_BUILTIN */ + (char *)NULL +}; +#endif /* READLINE */ +char * const break_doc[] = { +#if defined (HELP_BUILTIN) +N_("Exit for, while, or until loops.\n\ + \n\ + Exit a FOR, WHILE or UNTIL loop. If N is specified, break N enclosing\n\ + loops.\n\ + \n\ + Exit Status:\n\ + The exit status is 0 unless N is not greater than or equal to 1."), +#endif /* HELP_BUILTIN */ + (char *)NULL +}; +char * const continue_doc[] = { +#if defined (HELP_BUILTIN) +N_("Resume for, while, or until loops.\n\ + \n\ + Resumes the next iteration of the enclosing FOR, WHILE or UNTIL loop.\n\ + If N is specified, resumes the Nth enclosing loop.\n\ + \n\ + Exit Status:\n\ + The exit status is 0 unless N is not greater than or equal to 1."), +#endif /* HELP_BUILTIN */ + (char *)NULL +}; +char * const builtin_doc[] = { +#if defined (HELP_BUILTIN) +N_("Execute shell builtins.\n\ + \n\ + Execute SHELL-BUILTIN with arguments ARGs without performing command\n\ + lookup. This is useful when you wish to reimplement a shell builtin\n\ + as a shell function, but need to execute the builtin within the function.\n\ + \n\ + Exit Status:\n\ + Returns the exit status of SHELL-BUILTIN, or false if SHELL-BUILTIN is\n\ + not a shell builtin."), +#endif /* HELP_BUILTIN */ + (char *)NULL +}; +#if defined (DEBUGGER) +char * const caller_doc[] = { +#if defined (HELP_BUILTIN) +N_("Return the context of the current subroutine call.\n\ + \n\ + Without EXPR, returns \"$line $filename\". With EXPR, returns\n\ + \"$line $subroutine $filename\"; this extra information can be used to\n\ + provide a stack trace.\n\ + \n\ + The value of EXPR indicates how many call frames to go back before the\n\ + current one; the top frame is frame 0.\n\ + \n\ + Exit Status:\n\ + Returns 0 unless the shell is not executing a shell function or EXPR\n\ + is invalid."), +#endif /* HELP_BUILTIN */ + (char *)NULL +}; +#endif /* DEBUGGER */ +char * const cd_doc[] = { +#if defined (HELP_BUILTIN) +N_("Change the shell working directory.\n\ + \n\ + Change the current directory to DIR. The default DIR is the value of the\n\ + HOME shell variable.\n\ + \n\ + The variable CDPATH defines the search path for the directory containing\n\ + DIR. Alternative directory names in CDPATH are separated by a colon (:).\n\ + A null directory name is the same as the current directory. If DIR begins\n\ + with a slash (/), then CDPATH is not used.\n\ + \n\ + If the directory is not found, and the shell option `cdable_vars' is set,\n\ + the word is assumed to be a variable name. If that variable has a value,\n\ + its value is used for DIR.\n\ + \n\ + Options:\n\ + -L force symbolic links to be followed: resolve symbolic\n\ + links in DIR after processing instances of `..'\n\ + -P use the physical directory structure without following\n\ + symbolic links: resolve symbolic links in DIR before\n\ + processing instances of `..'\n\ + -e if the -P option is supplied, and the current working\n\ + directory cannot be determined successfully, exit with\n\ + a non-zero status\n\ + -@ on systems that support it, present a file with extended\n\ + attributes as a directory containing the file attributes\n\ + \n\ + The default is to follow symbolic links, as if `-L' were specified.\n\ + `..' is processed by removing the immediately previous pathname component\n\ + back to a slash or the beginning of DIR.\n\ + \n\ + Exit Status:\n\ + Returns 0 if the directory is changed, and if $PWD is set successfully when\n\ + -P is used; non-zero otherwise."), +#endif /* HELP_BUILTIN */ + (char *)NULL +}; +char * const pwd_doc[] = { +#if defined (HELP_BUILTIN) +N_("Print the name of the current working directory.\n\ + \n\ + Options:\n\ + -L print the value of $PWD if it names the current working\n\ + directory\n\ + -P print the physical directory, without any symbolic links\n\ + \n\ + By default, `pwd' behaves as if `-L' were specified.\n\ + \n\ + Exit Status:\n\ + Returns 0 unless an invalid option is given or the current directory\n\ + cannot be read."), +#endif /* HELP_BUILTIN */ + (char *)NULL +}; +char * const colon_doc[] = { +#if defined (HELP_BUILTIN) +N_("Null command.\n\ + \n\ + No effect; the command does nothing.\n\ + \n\ + Exit Status:\n\ + Always succeeds."), +#endif /* HELP_BUILTIN */ + (char *)NULL +}; +char * const true_doc[] = { +#if defined (HELP_BUILTIN) +N_("Return a successful result.\n\ + \n\ + Exit Status:\n\ + Always succeeds."), +#endif /* HELP_BUILTIN */ + (char *)NULL +}; +char * const false_doc[] = { +#if defined (HELP_BUILTIN) +N_("Return an unsuccessful result.\n\ + \n\ + Exit Status:\n\ + Always fails."), +#endif /* HELP_BUILTIN */ + (char *)NULL +}; +char * const command_doc[] = { +#if defined (HELP_BUILTIN) +N_("Execute a simple command or display information about commands.\n\ + \n\ + Runs COMMAND with ARGS suppressing shell function lookup, or display\n\ + information about the specified COMMANDs. Can be used to invoke commands\n\ + on disk when a function with the same name exists.\n\ + \n\ + Options:\n\ + -p use a default value for PATH that is guaranteed to find all of\n\ + the standard utilities\n\ + -v print a description of COMMAND similar to the `type' builtin\n\ + -V print a more verbose description of each COMMAND\n\ + \n\ + Exit Status:\n\ + Returns exit status of COMMAND, or failure if COMMAND is not found."), +#endif /* HELP_BUILTIN */ + (char *)NULL +}; +char * const declare_doc[] = { +#if defined (HELP_BUILTIN) +N_("Set variable values and attributes.\n\ + \n\ + Declare variables and give them attributes. If no NAMEs are given,\n\ + display the attributes and values of all variables.\n\ + \n\ + Options:\n\ + -f restrict action or display to function names and definitions\n\ + -F restrict display to function names only (plus line number and\n\ + source file when debugging)\n\ + -g create global variables when used in a shell function; otherwise\n\ + ignored\n\ + -I if creating a local variable, inherit the attributes and value\n\ + of a variable with the same name at a previous scope\n\ + -p display the attributes and value of each NAME\n\ + \n\ + Options which set attributes:\n\ + -a to make NAMEs indexed arrays (if supported)\n\ + -A to make NAMEs associative arrays (if supported)\n\ + -i to make NAMEs have the `integer' attribute\n\ + -l to convert the value of each NAME to lower case on assignment\n\ + -n make NAME a reference to the variable named by its value\n\ + -r to make NAMEs readonly\n\ + -t to make NAMEs have the `trace' attribute\n\ + -u to convert the value of each NAME to upper case on assignment\n\ + -x to make NAMEs export\n\ + \n\ + Using `+' instead of `-' turns off the given attribute.\n\ + \n\ + Variables with the integer attribute have arithmetic evaluation (see\n\ + the `let' command) performed when the variable is assigned a value.\n\ + \n\ + When used in a function, `declare' makes NAMEs local, as with the `local'\n\ + command. The `-g' option suppresses this behavior.\n\ + \n\ + Exit Status:\n\ + Returns success unless an invalid option is supplied or a variable\n\ + assignment error occurs."), +#endif /* HELP_BUILTIN */ + (char *)NULL +}; +char * const typeset_doc[] = { +#if defined (HELP_BUILTIN) +N_("Set variable values and attributes.\n\ + \n\ + A synonym for `declare'. See `help declare'."), +#endif /* HELP_BUILTIN */ + (char *)NULL +}; +char * const local_doc[] = { +#if defined (HELP_BUILTIN) +N_("Define local variables.\n\ + \n\ + Create a local variable called NAME, and give it VALUE. OPTION can\n\ + be any option accepted by `declare'.\n\ + \n\ + Local variables can only be used within a function; they are visible\n\ + only to the function where they are defined and its children.\n\ + \n\ + Exit Status:\n\ + Returns success unless an invalid option is supplied, a variable\n\ + assignment error occurs, or the shell is not executing a function."), +#endif /* HELP_BUILTIN */ + (char *)NULL +}; +#if defined (V9_ECHO) +char * const echo_doc[] = { +#if defined (HELP_BUILTIN) +N_("Write arguments to the standard output.\n\ + \n\ + Display the ARGs, separated by a single space character and followed by a\n\ + newline, on the standard output.\n\ + \n\ + Options:\n\ + -n do not append a newline\n\ + -e enable interpretation of the following backslash escapes\n\ + -E explicitly suppress interpretation of backslash escapes\n\ + \n\ + `echo' interprets the following backslash-escaped characters:\n\ + \\a alert (bell)\n\ + \\b backspace\n\ + \\c suppress further output\n\ + \\e escape character\n\ + \\E escape character\n\ + \\f form feed\n\ + \\n new line\n\ + \\r carriage return\n\ + \\t horizontal tab\n\ + \\v vertical tab\n\ + \\\\ backslash\n\ + \\0nnn the character whose ASCII code is NNN (octal). NNN can be\n\ + 0 to 3 octal digits\n\ + \\xHH the eight-bit character whose value is HH (hexadecimal). HH\n\ + can be one or two hex digits\n\ + \\uHHHH the Unicode character whose value is the hexadecimal value HHHH.\n\ + HHHH can be one to four hex digits.\n\ + \\UHHHHHHHH the Unicode character whose value is the hexadecimal value\n\ + HHHHHHHH. HHHHHHHH can be one to eight hex digits.\n\ + \n\ + Exit Status:\n\ + Returns success unless a write error occurs."), +#endif /* HELP_BUILTIN */ + (char *)NULL +}; +#endif /* V9_ECHO */ +#if !defined (V9_ECHO) +char * const echo_doc[] = { +#if defined (HELP_BUILTIN) +N_("Write arguments to the standard output.\n\ + \n\ + Display the ARGs on the standard output followed by a newline.\n\ + \n\ + Options:\n\ + -n do not append a newline\n\ + \n\ + Exit Status:\n\ + Returns success unless a write error occurs."), +#endif /* HELP_BUILTIN */ + (char *)NULL +}; +#endif /* !V9_ECHO */ +char * const enable_doc[] = { +#if defined (HELP_BUILTIN) +N_("Enable and disable shell builtins.\n\ + \n\ + Enables and disables builtin shell commands. Disabling allows you to\n\ + execute a disk command which has the same name as a shell builtin\n\ + without using a full pathname.\n\ + \n\ + Options:\n\ + -a print a list of builtins showing whether or not each is enabled\n\ + -n disable each NAME or display a list of disabled builtins\n\ + -p print the list of builtins in a reusable format\n\ + -s print only the names of Posix `special' builtins\n\ + \n\ + Options controlling dynamic loading:\n\ + -f Load builtin NAME from shared object FILENAME\n\ + -d Remove a builtin loaded with -f\n\ + \n\ + Without options, each NAME is enabled.\n\ + \n\ + To use the `test' found in $PATH instead of the shell builtin\n\ + version, type `enable -n test'.\n\ + \n\ + Exit Status:\n\ + Returns success unless NAME is not a shell builtin or an error occurs."), +#endif /* HELP_BUILTIN */ + (char *)NULL +}; +char * const eval_doc[] = { +#if defined (HELP_BUILTIN) +N_("Execute arguments as a shell command.\n\ + \n\ + Combine ARGs into a single string, use the result as input to the shell,\n\ + and execute the resulting commands.\n\ + \n\ + Exit Status:\n\ + Returns exit status of command or success if command is null."), +#endif /* HELP_BUILTIN */ + (char *)NULL +}; +char * const getopts_doc[] = { +#if defined (HELP_BUILTIN) +N_("Parse option arguments.\n\ + \n\ + Getopts is used by shell procedures to parse positional parameters\n\ + as options.\n\ + \n\ + OPTSTRING contains the option letters to be recognized; if a letter\n\ + is followed by a colon, the option is expected to have an argument,\n\ + which should be separated from it by white space.\n\ + \n\ + Each time it is invoked, getopts will place the next option in the\n\ + shell variable $name, initializing name if it does not exist, and\n\ + the index of the next argument to be processed into the shell\n\ + variable OPTIND. OPTIND is initialized to 1 each time the shell or\n\ + a shell script is invoked. When an option requires an argument,\n\ + getopts places that argument into the shell variable OPTARG.\n\ + \n\ + getopts reports errors in one of two ways. If the first character\n\ + of OPTSTRING is a colon, getopts uses silent error reporting. In\n\ + this mode, no error messages are printed. If an invalid option is\n\ + seen, getopts places the option character found into OPTARG. If a\n\ + required argument is not found, getopts places a ':' into NAME and\n\ + sets OPTARG to the option character found. If getopts is not in\n\ + silent mode, and an invalid option is seen, getopts places '?' into\n\ + NAME and unsets OPTARG. If a required argument is not found, a '?'\n\ + is placed in NAME, OPTARG is unset, and a diagnostic message is\n\ + printed.\n\ + \n\ + If the shell variable OPTERR has the value 0, getopts disables the\n\ + printing of error messages, even if the first character of\n\ + OPTSTRING is not a colon. OPTERR has the value 1 by default.\n\ + \n\ + Getopts normally parses the positional parameters, but if arguments\n\ + are supplied as ARG values, they are parsed instead.\n\ + \n\ + Exit Status:\n\ + Returns success if an option is found; fails if the end of options is\n\ + encountered or an error occurs."), +#endif /* HELP_BUILTIN */ + (char *)NULL +}; +char * const exec_doc[] = { +#if defined (HELP_BUILTIN) +N_("Replace the shell with the given command.\n\ + \n\ + Execute COMMAND, replacing this shell with the specified program.\n\ + ARGUMENTS become the arguments to COMMAND. If COMMAND is not specified,\n\ + any redirections take effect in the current shell.\n\ + \n\ + Options:\n\ + -a name pass NAME as the zeroth argument to COMMAND\n\ + -c execute COMMAND with an empty environment\n\ + -l place a dash in the zeroth argument to COMMAND\n\ + \n\ + If the command cannot be executed, a non-interactive shell exits, unless\n\ + the shell option `execfail' is set.\n\ + \n\ + Exit Status:\n\ + Returns success unless COMMAND is not found or a redirection error occurs."), +#endif /* HELP_BUILTIN */ + (char *)NULL +}; +char * const exit_doc[] = { +#if defined (HELP_BUILTIN) +N_("Exit the shell.\n\ + \n\ + Exits the shell with a status of N. If N is omitted, the exit status\n\ + is that of the last command executed."), +#endif /* HELP_BUILTIN */ + (char *)NULL +}; +char * const logout_doc[] = { +#if defined (HELP_BUILTIN) +N_("Exit a login shell.\n\ + \n\ + Exits a login shell with exit status N. Returns an error if not executed\n\ + in a login shell."), +#endif /* HELP_BUILTIN */ + (char *)NULL +}; +#if defined (HISTORY) +char * const fc_doc[] = { +#if defined (HELP_BUILTIN) +N_("Display or execute commands from the history list.\n\ + \n\ + fc is used to list or edit and re-execute commands from the history list.\n\ + FIRST and LAST can be numbers specifying the range, or FIRST can be a\n\ + string, which means the most recent command beginning with that\n\ + string.\n\ + \n\ + Options:\n\ + -e ENAME select which editor to use. Default is FCEDIT, then EDITOR,\n\ + then vi\n\ + -l list lines instead of editing\n\ + -n omit line numbers when listing\n\ + -r reverse the order of the lines (newest listed first)\n\ + \n\ + With the `fc -s [pat=rep ...] [command]' format, COMMAND is\n\ + re-executed after the substitution OLD=NEW is performed.\n\ + \n\ + A useful alias to use with this is r='fc -s', so that typing `r cc'\n\ + runs the last command beginning with `cc' and typing `r' re-executes\n\ + the last command.\n\ + \n\ + Exit Status:\n\ + Returns success or status of executed command; non-zero if an error occurs."), +#endif /* HELP_BUILTIN */ + (char *)NULL +}; +#endif /* HISTORY */ +#if defined (JOB_CONTROL) +char * const fg_doc[] = { +#if defined (HELP_BUILTIN) +N_("Move job to the foreground.\n\ + \n\ + Place the job identified by JOB_SPEC in the foreground, making it the\n\ + current job. If JOB_SPEC is not present, the shell's notion of the\n\ + current job is used.\n\ + \n\ + Exit Status:\n\ + Status of command placed in foreground, or failure if an error occurs."), +#endif /* HELP_BUILTIN */ + (char *)NULL +}; +#endif /* JOB_CONTROL */ +#if defined (JOB_CONTROL) +char * const bg_doc[] = { +#if defined (HELP_BUILTIN) +N_("Move jobs to the background.\n\ + \n\ + Place the jobs identified by each JOB_SPEC in the background, as if they\n\ + had been started with `&'. If JOB_SPEC is not present, the shell's notion\n\ + of the current job is used.\n\ + \n\ + Exit Status:\n\ + Returns success unless job control is not enabled or an error occurs."), +#endif /* HELP_BUILTIN */ + (char *)NULL +}; +#endif /* JOB_CONTROL */ +char * const hash_doc[] = { +#if defined (HELP_BUILTIN) +N_("Remember or display program locations.\n\ + \n\ + Determine and remember the full pathname of each command NAME. If\n\ + no arguments are given, information about remembered commands is displayed.\n\ + \n\ + Options:\n\ + -d forget the remembered location of each NAME\n\ + -l display in a format that may be reused as input\n\ + -p pathname use PATHNAME as the full pathname of NAME\n\ + -r forget all remembered locations\n\ + -t print the remembered location of each NAME, preceding\n\ + each location with the corresponding NAME if multiple\n\ + NAMEs are given\n\ + Arguments:\n\ + NAME Each NAME is searched for in $PATH and added to the list\n\ + of remembered commands.\n\ + \n\ + Exit Status:\n\ + Returns success unless NAME is not found or an invalid option is given."), +#endif /* HELP_BUILTIN */ + (char *)NULL +}; +#if defined (HELP_BUILTIN) +char * const help_doc[] = { +#if defined (HELP_BUILTIN) +N_("Display information about builtin commands.\n\ + \n\ + Displays brief summaries of builtin commands. If PATTERN is\n\ + specified, gives detailed help on all commands matching PATTERN,\n\ + otherwise the list of help topics is printed.\n\ + \n\ + Options:\n\ + -d output short description for each topic\n\ + -m display usage in pseudo-manpage format\n\ + -s output only a short usage synopsis for each topic matching\n\ + PATTERN\n\ + \n\ + Arguments:\n\ + PATTERN Pattern specifying a help topic\n\ + \n\ + Exit Status:\n\ + Returns success unless PATTERN is not found or an invalid option is given."), +#endif /* HELP_BUILTIN */ + (char *)NULL +}; +#endif /* HELP_BUILTIN */ +#if defined (HISTORY) +char * const history_doc[] = { +#if defined (HELP_BUILTIN) +N_("Display or manipulate the history list.\n\ + \n\ + Display the history list with line numbers, prefixing each modified\n\ + entry with a `*'. An argument of N lists only the last N entries.\n\ + \n\ + Options:\n\ + -c clear the history list by deleting all of the entries\n\ + -d offset delete the history entry at position OFFSET. Negative\n\ + offsets count back from the end of the history list\n\ + \n\ + -a append history lines from this session to the history file\n\ + -n read all history lines not already read from the history file\n\ + and append them to the history list\n\ + -r read the history file and append the contents to the history\n\ + list\n\ + -w write the current history to the history file\n\ + \n\ + -p perform history expansion on each ARG and display the result\n\ + without storing it in the history list\n\ + -s append the ARGs to the history list as a single entry\n\ + \n\ + If FILENAME is given, it is used as the history file. Otherwise,\n\ + if HISTFILE has a value, that is used, else ~/.bash_history.\n\ + \n\ + If the HISTTIMEFORMAT variable is set and not null, its value is used\n\ + as a format string for strftime(3) to print the time stamp associated\n\ + with each displayed history entry. No time stamps are printed otherwise.\n\ + \n\ + Exit Status:\n\ + Returns success unless an invalid option is given or an error occurs."), +#endif /* HELP_BUILTIN */ + (char *)NULL +}; +#endif /* HISTORY */ +#if defined (JOB_CONTROL) +char * const jobs_doc[] = { +#if defined (HELP_BUILTIN) +N_("Display status of jobs.\n\ + \n\ + Lists the active jobs. JOBSPEC restricts output to that job.\n\ + Without options, the status of all active jobs is displayed.\n\ + \n\ + Options:\n\ + -l lists process IDs in addition to the normal information\n\ + -n lists only processes that have changed status since the last\n\ + notification\n\ + -p lists process IDs only\n\ + -r restrict output to running jobs\n\ + -s restrict output to stopped jobs\n\ + \n\ + If -x is supplied, COMMAND is run after all job specifications that\n\ + appear in ARGS have been replaced with the process ID of that job's\n\ + process group leader.\n\ + \n\ + Exit Status:\n\ + Returns success unless an invalid option is given or an error occurs.\n\ + If -x is used, returns the exit status of COMMAND."), +#endif /* HELP_BUILTIN */ + (char *)NULL +}; +#endif /* JOB_CONTROL */ +#if defined (JOB_CONTROL) +char * const disown_doc[] = { +#if defined (HELP_BUILTIN) +N_("Remove jobs from current shell.\n\ + \n\ + Removes each JOBSPEC argument from the table of active jobs. Without\n\ + any JOBSPECs, the shell uses its notion of the current job.\n\ + \n\ + Options:\n\ + -a remove all jobs if JOBSPEC is not supplied\n\ + -h mark each JOBSPEC so that SIGHUP is not sent to the job if the\n\ + shell receives a SIGHUP\n\ + -r remove only running jobs\n\ + \n\ + Exit Status:\n\ + Returns success unless an invalid option or JOBSPEC is given."), +#endif /* HELP_BUILTIN */ + (char *)NULL +}; +#endif /* JOB_CONTROL */ +char * const kill_doc[] = { +#if defined (HELP_BUILTIN) +N_("Send a signal to a job.\n\ + \n\ + Send the processes identified by PID or JOBSPEC the signal named by\n\ + SIGSPEC or SIGNUM. If neither SIGSPEC nor SIGNUM is present, then\n\ + SIGTERM is assumed.\n\ + \n\ + Options:\n\ + -s sig SIG is a signal name\n\ + -n sig SIG is a signal number\n\ + -l list the signal names; if arguments follow `-l' they are\n\ + assumed to be signal numbers for which names should be listed\n\ + -L synonym for -l\n\ + \n\ + Kill is a shell builtin for two reasons: it allows job IDs to be used\n\ + instead of process IDs, and allows processes to be killed if the limit\n\ + on processes that you can create is reached.\n\ + \n\ + Exit Status:\n\ + Returns success unless an invalid option is given or an error occurs."), +#endif /* HELP_BUILTIN */ + (char *)NULL +}; +char * const let_doc[] = { +#if defined (HELP_BUILTIN) +N_("Evaluate arithmetic expressions.\n\ + \n\ + Evaluate each ARG as an arithmetic expression. Evaluation is done in\n\ + fixed-width integers with no check for overflow, though division by 0\n\ + is trapped and flagged as an error. The following list of operators is\n\ + grouped into levels of equal-precedence operators. The levels are listed\n\ + in order of decreasing precedence.\n\ + \n\ + id++, id-- variable post-increment, post-decrement\n\ + ++id, --id variable pre-increment, pre-decrement\n\ + -, + unary minus, plus\n\ + !, ~ logical and bitwise negation\n\ + ** exponentiation\n\ + *, /, % multiplication, division, remainder\n\ + +, - addition, subtraction\n\ + <<, >> left and right bitwise shifts\n\ + <=, >=, <, > comparison\n\ + ==, != equality, inequality\n\ + & bitwise AND\n\ + ^ bitwise XOR\n\ + | bitwise OR\n\ + && logical AND\n\ + || logical OR\n\ + expr ? expr : expr\n\ + conditional operator\n\ + =, *=, /=, %=,\n\ + +=, -=, <<=, >>=,\n\ + &=, ^=, |= assignment\n\ + \n\ + Shell variables are allowed as operands. The name of the variable\n\ + is replaced by its value (coerced to a fixed-width integer) within\n\ + an expression. The variable need not have its integer attribute\n\ + turned on to be used in an expression.\n\ + \n\ + Operators are evaluated in order of precedence. Sub-expressions in\n\ + parentheses are evaluated first and may override the precedence\n\ + rules above.\n\ + \n\ + Exit Status:\n\ + If the last ARG evaluates to 0, let returns 1; let returns 0 otherwise."), +#endif /* HELP_BUILTIN */ + (char *)NULL +}; +char * const read_doc[] = { +#if defined (HELP_BUILTIN) +N_("Read a line from the standard input and split it into fields.\n\ + \n\ + Reads a single line from the standard input, or from file descriptor FD\n\ + if the -u option is supplied. The line is split into fields as with word\n\ + splitting, and the first word is assigned to the first NAME, the second\n\ + word to the second NAME, and so on, with any leftover words assigned to\n\ + the last NAME. Only the characters found in $IFS are recognized as word\n\ + delimiters.\n\ + \n\ + If no NAMEs are supplied, the line read is stored in the REPLY variable.\n\ + \n\ + Options:\n\ + -a array assign the words read to sequential indices of the array\n\ + variable ARRAY, starting at zero\n\ + -d delim continue until the first character of DELIM is read, rather\n\ + than newline\n\ + -e use Readline to obtain the line\n\ + -i text use TEXT as the initial text for Readline\n\ + -n nchars return after reading NCHARS characters rather than waiting\n\ + for a newline, but honor a delimiter if fewer than\n\ + NCHARS characters are read before the delimiter\n\ + -N nchars return only after reading exactly NCHARS characters, unless\n\ + EOF is encountered or read times out, ignoring any\n\ + delimiter\n\ + -p prompt output the string PROMPT without a trailing newline before\n\ + attempting to read\n\ + -r do not allow backslashes to escape any characters\n\ + -s do not echo input coming from a terminal\n\ + -t timeout time out and return failure if a complete line of\n\ + input is not read within TIMEOUT seconds. The value of the\n\ + TMOUT variable is the default timeout. TIMEOUT may be a\n\ + fractional number. If TIMEOUT is 0, read returns\n\ + immediately, without trying to read any data, returning\n\ + success only if input is available on the specified\n\ + file descriptor. The exit status is greater than 128\n\ + if the timeout is exceeded\n\ + -u fd read from file descriptor FD instead of the standard input\n\ + \n\ + Exit Status:\n\ + The return code is zero, unless end-of-file is encountered, read times out\n\ + (in which case it's greater than 128), a variable assignment error occurs,\n\ + or an invalid file descriptor is supplied as the argument to -u."), +#endif /* HELP_BUILTIN */ + (char *)NULL +}; +char * const return_doc[] = { +#if defined (HELP_BUILTIN) +N_("Return from a shell function.\n\ + \n\ + Causes a function or sourced script to exit with the return value\n\ + specified by N. If N is omitted, the return status is that of the\n\ + last command executed within the function or script.\n\ + \n\ + Exit Status:\n\ + Returns N, or failure if the shell is not executing a function or script."), +#endif /* HELP_BUILTIN */ + (char *)NULL +}; +char * const set_doc[] = { +#if defined (HELP_BUILTIN) +N_("Set or unset values of shell options and positional parameters.\n\ + \n\ + Change the value of shell attributes and positional parameters, or\n\ + display the names and values of shell variables.\n\ + \n\ + Options:\n\ + -a Mark variables which are modified or created for export.\n\ + -b Notify of job termination immediately.\n\ + -e Exit immediately if a command exits with a non-zero status.\n\ + -f Disable file name generation (globbing).\n\ + -h Remember the location of commands as they are looked up.\n\ + -k All assignment arguments are placed in the environment for a\n\ + command, not just those that precede the command name.\n\ + -m Job control is enabled.\n\ + -n Read commands but do not execute them.\n\ + -o option-name\n\ + Set the variable corresponding to option-name:\n\ + allexport same as -a\n\ + braceexpand same as -B\n\ + emacs use an emacs-style line editing interface\n\ + errexit same as -e\n\ + errtrace same as -E\n\ + functrace same as -T\n\ + hashall same as -h\n\ + histexpand same as -H\n\ + history enable command history\n\ + ignoreeof the shell will not exit upon reading EOF\n\ + interactive-comments\n\ + allow comments to appear in interactive commands\n\ + keyword same as -k\n\ + monitor same as -m\n\ + noclobber same as -C\n\ + noexec same as -n\n\ + noglob same as -f\n\ + nolog currently accepted but ignored\n\ + notify same as -b\n\ + nounset same as -u\n\ + onecmd same as -t\n\ + physical same as -P\n\ + pipefail the return value of a pipeline is the status of\n\ + the last command to exit with a non-zero status,\n\ + or zero if no command exited with a non-zero status\n\ + posix change the behavior of bash where the default\n\ + operation differs from the Posix standard to\n\ + match the standard\n\ + privileged same as -p\n\ + verbose same as -v\n\ + vi use a vi-style line editing interface\n\ + xtrace same as -x\n\ + -p Turned on whenever the real and effective user ids do not match.\n\ + Disables processing of the $ENV file and importing of shell\n\ + functions. Turning this option off causes the effective uid and\n\ + gid to be set to the real uid and gid.\n\ + -t Exit after reading and executing one command.\n\ + -u Treat unset variables as an error when substituting.\n\ + -v Print shell input lines as they are read.\n\ + -x Print commands and their arguments as they are executed.\n\ + -B the shell will perform brace expansion\n\ + -C If set, disallow existing regular files to be overwritten\n\ + by redirection of output.\n\ + -E If set, the ERR trap is inherited by shell functions.\n\ + -H Enable ! style history substitution. This flag is on\n\ + by default when the shell is interactive.\n\ + -P If set, do not resolve symbolic links when executing commands\n\ + such as cd which change the current directory.\n\ + -T If set, the DEBUG and RETURN traps are inherited by shell functions.\n\ + -- Assign any remaining arguments to the positional parameters.\n\ + If there are no remaining arguments, the positional parameters\n\ + are unset.\n\ + - Assign any remaining arguments to the positional parameters.\n\ + The -x and -v options are turned off.\n\ + \n\ + Using + rather than - causes these flags to be turned off. The\n\ + flags can also be used upon invocation of the shell. The current\n\ + set of flags may be found in $-. The remaining n ARGs are positional\n\ + parameters and are assigned, in order, to $1, $2, .. $n. If no\n\ + ARGs are given, all shell variables are printed.\n\ + \n\ + Exit Status:\n\ + Returns success unless an invalid option is given."), +#endif /* HELP_BUILTIN */ + (char *)NULL +}; +char * const unset_doc[] = { +#if defined (HELP_BUILTIN) +N_("Unset values and attributes of shell variables and functions.\n\ + \n\ + For each NAME, remove the corresponding variable or function.\n\ + \n\ + Options:\n\ + -f treat each NAME as a shell function\n\ + -v treat each NAME as a shell variable\n\ + -n treat each NAME as a name reference and unset the variable itself\n\ + rather than the variable it references\n\ + \n\ + Without options, unset first tries to unset a variable, and if that fails,\n\ + tries to unset a function.\n\ + \n\ + Some variables cannot be unset; also see `readonly'.\n\ + \n\ + Exit Status:\n\ + Returns success unless an invalid option is given or a NAME is read-only."), +#endif /* HELP_BUILTIN */ + (char *)NULL +}; +char * const export_doc[] = { +#if defined (HELP_BUILTIN) +N_("Set export attribute for shell variables.\n\ + \n\ + Marks each NAME for automatic export to the environment of subsequently\n\ + executed commands. If VALUE is supplied, assign VALUE before exporting.\n\ + \n\ + Options:\n\ + -f refer to shell functions\n\ + -n remove the export property from each NAME\n\ + -p display a list of all exported variables and functions\n\ + \n\ + An argument of `--' disables further option processing.\n\ + \n\ + Exit Status:\n\ + Returns success unless an invalid option is given or NAME is invalid."), +#endif /* HELP_BUILTIN */ + (char *)NULL +}; +char * const readonly_doc[] = { +#if defined (HELP_BUILTIN) +N_("Mark shell variables as unchangeable.\n\ + \n\ + Mark each NAME as read-only; the values of these NAMEs may not be\n\ + changed by subsequent assignment. If VALUE is supplied, assign VALUE\n\ + before marking as read-only.\n\ + \n\ + Options:\n\ + -a refer to indexed array variables\n\ + -A refer to associative array variables\n\ + -f refer to shell functions\n\ + -p display a list of all readonly variables or functions,\n\ + depending on whether or not the -f option is given\n\ + \n\ + An argument of `--' disables further option processing.\n\ + \n\ + Exit Status:\n\ + Returns success unless an invalid option is given or NAME is invalid."), +#endif /* HELP_BUILTIN */ + (char *)NULL +}; +char * const shift_doc[] = { +#if defined (HELP_BUILTIN) +N_("Shift positional parameters.\n\ + \n\ + Rename the positional parameters $N+1,$N+2 ... to $1,$2 ... If N is\n\ + not given, it is assumed to be 1.\n\ + \n\ + Exit Status:\n\ + Returns success unless N is negative or greater than $#."), +#endif /* HELP_BUILTIN */ + (char *)NULL +}; +char * const source_doc[] = { +#if defined (HELP_BUILTIN) +N_("Execute commands from a file in the current shell.\n\ + \n\ + Read and execute commands from FILENAME in the current shell. The\n\ + entries in $PATH are used to find the directory containing FILENAME.\n\ + If any ARGUMENTS are supplied, they become the positional parameters\n\ + when FILENAME is executed.\n\ + \n\ + Exit Status:\n\ + Returns the status of the last command executed in FILENAME; fails if\n\ + FILENAME cannot be read."), +#endif /* HELP_BUILTIN */ + (char *)NULL +}; +char * const dot_doc[] = { +#if defined (HELP_BUILTIN) +N_("Execute commands from a file in the current shell.\n\ + \n\ + Read and execute commands from FILENAME in the current shell. The\n\ + entries in $PATH are used to find the directory containing FILENAME.\n\ + If any ARGUMENTS are supplied, they become the positional parameters\n\ + when FILENAME is executed.\n\ + \n\ + Exit Status:\n\ + Returns the status of the last command executed in FILENAME; fails if\n\ + FILENAME cannot be read."), +#endif /* HELP_BUILTIN */ + (char *)NULL +}; +#if defined (JOB_CONTROL) +char * const suspend_doc[] = { +#if defined (HELP_BUILTIN) +N_("Suspend shell execution.\n\ + \n\ + Suspend the execution of this shell until it receives a SIGCONT signal.\n\ + Unless forced, login shells cannot be suspended.\n\ + \n\ + Options:\n\ + -f force the suspend, even if the shell is a login shell\n\ + \n\ + Exit Status:\n\ + Returns success unless job control is not enabled or an error occurs."), +#endif /* HELP_BUILTIN */ + (char *)NULL +}; +#endif /* JOB_CONTROL */ +char * const test_doc[] = { +#if defined (HELP_BUILTIN) +N_("Evaluate conditional expression.\n\ + \n\ + Exits with a status of 0 (true) or 1 (false) depending on\n\ + the evaluation of EXPR. Expressions may be unary or binary. Unary\n\ + expressions are often used to examine the status of a file. There\n\ + are string operators and numeric comparison operators as well.\n\ + \n\ + The behavior of test depends on the number of arguments. Read the\n\ + bash manual page for the complete specification.\n\ + \n\ + File operators:\n\ + \n\ + -a FILE True if file exists.\n\ + -b FILE True if file is block special.\n\ + -c FILE True if file is character special.\n\ + -d FILE True if file is a directory.\n\ + -e FILE True if file exists.\n\ + -f FILE True if file exists and is a regular file.\n\ + -g FILE True if file is set-group-id.\n\ + -h FILE True if file is a symbolic link.\n\ + -L FILE True if file is a symbolic link.\n\ + -k FILE True if file has its `sticky' bit set.\n\ + -p FILE True if file is a named pipe.\n\ + -r FILE True if file is readable by you.\n\ + -s FILE True if file exists and is not empty.\n\ + -S FILE True if file is a socket.\n\ + -t FD True if FD is opened on a terminal.\n\ + -u FILE True if the file is set-user-id.\n\ + -w FILE True if the file is writable by you.\n\ + -x FILE True if the file is executable by you.\n\ + -O FILE True if the file is effectively owned by you.\n\ + -G FILE True if the file is effectively owned by your group.\n\ + -N FILE True if the file has been modified since it was last read.\n\ + \n\ + FILE1 -nt FILE2 True if file1 is newer than file2 (according to\n\ + modification date).\n\ + \n\ + FILE1 -ot FILE2 True if file1 is older than file2.\n\ + \n\ + FILE1 -ef FILE2 True if file1 is a hard link to file2.\n\ + \n\ + String operators:\n\ + \n\ + -z STRING True if string is empty.\n\ + \n\ + -n STRING\n\ + STRING True if string is not empty.\n\ + \n\ + STRING1 = STRING2\n\ + True if the strings are equal.\n\ + STRING1 != STRING2\n\ + True if the strings are not equal.\n\ + STRING1 < STRING2\n\ + True if STRING1 sorts before STRING2 lexicographically.\n\ + STRING1 > STRING2\n\ + True if STRING1 sorts after STRING2 lexicographically.\n\ + \n\ + Other operators:\n\ + \n\ + -o OPTION True if the shell option OPTION is enabled.\n\ + -v VAR True if the shell variable VAR is set.\n\ + -R VAR True if the shell variable VAR is set and is a name\n\ + reference.\n\ + ! EXPR True if expr is false.\n\ + EXPR1 -a EXPR2 True if both expr1 AND expr2 are true.\n\ + EXPR1 -o EXPR2 True if either expr1 OR expr2 is true.\n\ + \n\ + arg1 OP arg2 Arithmetic tests. OP is one of -eq, -ne,\n\ + -lt, -le, -gt, or -ge.\n\ + \n\ + Arithmetic binary operators return true if ARG1 is equal, not-equal,\n\ + less-than, less-than-or-equal, greater-than, or greater-than-or-equal\n\ + than ARG2.\n\ + \n\ + Exit Status:\n\ + Returns success if EXPR evaluates to true; fails if EXPR evaluates to\n\ + false or an invalid argument is given."), +#endif /* HELP_BUILTIN */ + (char *)NULL +}; +char * const test_bracket_doc[] = { +#if defined (HELP_BUILTIN) +N_("Evaluate conditional expression.\n\ + \n\ + This is a synonym for the \"test\" builtin, but the last argument must\n\ + be a literal `]', to match the opening `['."), +#endif /* HELP_BUILTIN */ + (char *)NULL +}; +char * const times_doc[] = { +#if defined (HELP_BUILTIN) +N_("Display process times.\n\ + \n\ + Prints the accumulated user and system times for the shell and all of its\n\ + child processes.\n\ + \n\ + Exit Status:\n\ + Always succeeds."), +#endif /* HELP_BUILTIN */ + (char *)NULL +}; +char * const trap_doc[] = { +#if defined (HELP_BUILTIN) +N_("Trap signals and other events.\n\ + \n\ + Defines and activates handlers to be run when the shell receives signals\n\ + or other conditions.\n\ + \n\ + ARG is a command to be read and executed when the shell receives the\n\ + signal(s) SIGNAL_SPEC. If ARG is absent (and a single SIGNAL_SPEC\n\ + is supplied) or `-', each specified signal is reset to its original\n\ + value. If ARG is the null string each SIGNAL_SPEC is ignored by the\n\ + shell and by the commands it invokes.\n\ + \n\ + If a SIGNAL_SPEC is EXIT (0) ARG is executed on exit from the shell. If\n\ + a SIGNAL_SPEC is DEBUG, ARG is executed before every simple command. If\n\ + a SIGNAL_SPEC is RETURN, ARG is executed each time a shell function or a\n\ + script run by the . or source builtins finishes executing. A SIGNAL_SPEC\n\ + of ERR means to execute ARG each time a command's failure would cause the\n\ + shell to exit when the -e option is enabled.\n\ + \n\ + If no arguments are supplied, trap prints the list of commands associated\n\ + with each signal.\n\ + \n\ + Options:\n\ + -l print a list of signal names and their corresponding numbers\n\ + -p display the trap commands associated with each SIGNAL_SPEC\n\ + \n\ + Each SIGNAL_SPEC is either a signal name in or a signal number.\n\ + Signal names are case insensitive and the SIG prefix is optional. A\n\ + signal may be sent to the shell with \"kill -signal $$\".\n\ + \n\ + Exit Status:\n\ + Returns success unless a SIGSPEC is invalid or an invalid option is given."), +#endif /* HELP_BUILTIN */ + (char *)NULL +}; +char * const type_doc[] = { +#if defined (HELP_BUILTIN) +N_("Display information about command type.\n\ + \n\ + For each NAME, indicate how it would be interpreted if used as a\n\ + command name.\n\ + \n\ + Options:\n\ + -a display all locations containing an executable named NAME;\n\ + includes aliases, builtins, and functions, if and only if\n\ + the `-p' option is not also used\n\ + -f suppress shell function lookup\n\ + -P force a PATH search for each NAME, even if it is an alias,\n\ + builtin, or function, and returns the name of the disk file\n\ + that would be executed\n\ + -p returns either the name of the disk file that would be executed,\n\ + or nothing if `type -t NAME' would not return `file'\n\ + -t output a single word which is one of `alias', `keyword',\n\ + `function', `builtin', `file' or `', if NAME is an alias,\n\ + shell reserved word, shell function, shell builtin, disk file,\n\ + or not found, respectively\n\ + \n\ + Arguments:\n\ + NAME Command name to be interpreted.\n\ + \n\ + Exit Status:\n\ + Returns success if all of the NAMEs are found; fails if any are not found."), +#endif /* HELP_BUILTIN */ + (char *)NULL +}; +#if !defined (_MINIX) +char * const ulimit_doc[] = { +#if defined (HELP_BUILTIN) +N_("Modify shell resource limits.\n\ + \n\ + Provides control over the resources available to the shell and processes\n\ + it creates, on systems that allow such control.\n\ + \n\ + Options:\n\ + -S use the `soft' resource limit\n\ + -H use the `hard' resource limit\n\ + -a all current limits are reported\n\ + -b the socket buffer size\n\ + -c the maximum size of core files created\n\ + -d the maximum size of a process's data segment\n\ + -e the maximum scheduling priority (`nice')\n\ + -f the maximum size of files written by the shell and its children\n\ + -i the maximum number of pending signals\n\ + -k the maximum number of kqueues allocated for this process\n\ + -l the maximum size a process may lock into memory\n\ + -m the maximum resident set size\n\ + -n the maximum number of open file descriptors\n\ + -p the pipe buffer size\n\ + -q the maximum number of bytes in POSIX message queues\n\ + -r the maximum real-time scheduling priority\n\ + -s the maximum stack size\n\ + -t the maximum amount of cpu time in seconds\n\ + -u the maximum number of user processes\n\ + -v the size of virtual memory\n\ + -x the maximum number of file locks\n\ + -P the maximum number of pseudoterminals\n\ + -R the maximum time a real-time process can run before blocking\n\ + -T the maximum number of threads\n\ + \n\ + Not all options are available on all platforms.\n\ + \n\ + If LIMIT is given, it is the new value of the specified resource; the\n\ + special LIMIT values `soft', `hard', and `unlimited' stand for the\n\ + current soft limit, the current hard limit, and no limit, respectively.\n\ + Otherwise, the current value of the specified resource is printed. If\n\ + no option is given, then -f is assumed.\n\ + \n\ + Values are in 1024-byte increments, except for -t, which is in seconds,\n\ + -p, which is in increments of 512 bytes, and -u, which is an unscaled\n\ + number of processes.\n\ + \n\ + Exit Status:\n\ + Returns success unless an invalid option is supplied or an error occurs."), +#endif /* HELP_BUILTIN */ + (char *)NULL +}; +#endif /* !_MINIX */ +char * const umask_doc[] = { +#if defined (HELP_BUILTIN) +N_("Display or set file mode mask.\n\ + \n\ + Sets the user file-creation mask to MODE. If MODE is omitted, prints\n\ + the current value of the mask.\n\ + \n\ + If MODE begins with a digit, it is interpreted as an octal number;\n\ + otherwise it is a symbolic mode string like that accepted by chmod(1).\n\ + \n\ + Options:\n\ + -p if MODE is omitted, output in a form that may be reused as input\n\ + -S makes the output symbolic; otherwise an octal number is output\n\ + \n\ + Exit Status:\n\ + Returns success unless MODE is invalid or an invalid option is given."), +#endif /* HELP_BUILTIN */ + (char *)NULL +}; +#if defined (JOB_CONTROL) +char * const wait_doc[] = { +#if defined (HELP_BUILTIN) +N_("Wait for job completion and return exit status.\n\ + \n\ + Waits for each process identified by an ID, which may be a process ID or a\n\ + job specification, and reports its termination status. If ID is not\n\ + given, waits for all currently active child processes, and the return\n\ + status is zero. If ID is a job specification, waits for all processes\n\ + in that job's pipeline.\n\ + \n\ + If the -n option is supplied, waits for a single job from the list of IDs,\n\ + or, if no IDs are supplied, for the next job to complete and returns its\n\ + exit status.\n\ + \n\ + If the -p option is supplied, the process or job identifier of the job\n\ + for which the exit status is returned is assigned to the variable VAR\n\ + named by the option argument. The variable will be unset initially, before\n\ + any assignment. This is useful only when the -n option is supplied.\n\ + \n\ + If the -f option is supplied, and job control is enabled, waits for the\n\ + specified ID to terminate, instead of waiting for it to change status.\n\ + \n\ + Exit Status:\n\ + Returns the status of the last ID; fails if ID is invalid or an invalid\n\ + option is given, or if -n is supplied and the shell has no unwaited-for\n\ + children."), +#endif /* HELP_BUILTIN */ + (char *)NULL +}; +#endif /* JOB_CONTROL */ +#if !defined (JOB_CONTROL) +char * const wait_doc[] = { +#if defined (HELP_BUILTIN) +N_("Wait for process completion and return exit status.\n\ + \n\ + Waits for each process specified by a PID and reports its termination status.\n\ + If PID is not given, waits for all currently active child processes,\n\ + and the return status is zero. PID must be a process ID.\n\ + \n\ + Exit Status:\n\ + Returns the status of the last PID; fails if PID is invalid or an invalid\n\ + option is given."), +#endif /* HELP_BUILTIN */ + (char *)NULL +}; +#endif /* !JOB_CONTROL */ +char * const for_doc[] = { +#if defined (HELP_BUILTIN) +N_("Execute commands for each member in a list.\n\ + \n\ + The `for' loop executes a sequence of commands for each member in a\n\ + list of items. If `in WORDS ...;' is not present, then `in \"$@\"' is\n\ + assumed. For each element in WORDS, NAME is set to that element, and\n\ + the COMMANDS are executed.\n\ + \n\ + Exit Status:\n\ + Returns the status of the last command executed."), +#endif /* HELP_BUILTIN */ + (char *)NULL +}; +char * const arith_for_doc[] = { +#if defined (HELP_BUILTIN) +N_("Arithmetic for loop.\n\ + \n\ + Equivalent to\n\ + (( EXP1 ))\n\ + while (( EXP2 )); do\n\ + COMMANDS\n\ + (( EXP3 ))\n\ + done\n\ + EXP1, EXP2, and EXP3 are arithmetic expressions. If any expression is\n\ + omitted, it behaves as if it evaluates to 1.\n\ + \n\ + Exit Status:\n\ + Returns the status of the last command executed."), +#endif /* HELP_BUILTIN */ + (char *)NULL +}; +char * const select_doc[] = { +#if defined (HELP_BUILTIN) +N_("Select words from a list and execute commands.\n\ + \n\ + The WORDS are expanded, generating a list of words. The\n\ + set of expanded words is printed on the standard error, each\n\ + preceded by a number. If `in WORDS' is not present, `in \"$@\"'\n\ + is assumed. The PS3 prompt is then displayed and a line read\n\ + from the standard input. If the line consists of the number\n\ + corresponding to one of the displayed words, then NAME is set\n\ + to that word. If the line is empty, WORDS and the prompt are\n\ + redisplayed. If EOF is read, the command completes. Any other\n\ + value read causes NAME to be set to null. The line read is saved\n\ + in the variable REPLY. COMMANDS are executed after each selection\n\ + until a break command is executed.\n\ + \n\ + Exit Status:\n\ + Returns the status of the last command executed."), +#endif /* HELP_BUILTIN */ + (char *)NULL +}; +char * const time_doc[] = { +#if defined (HELP_BUILTIN) +N_("Report time consumed by pipeline's execution.\n\ + \n\ + Execute PIPELINE and print a summary of the real time, user CPU time,\n\ + and system CPU time spent executing PIPELINE when it terminates.\n\ + \n\ + Options:\n\ + -p print the timing summary in the portable Posix format\n\ + \n\ + The value of the TIMEFORMAT variable is used as the output format.\n\ + \n\ + Exit Status:\n\ + The return status is the return status of PIPELINE."), +#endif /* HELP_BUILTIN */ + (char *)NULL +}; +char * const case_doc[] = { +#if defined (HELP_BUILTIN) +N_("Execute commands based on pattern matching.\n\ + \n\ + Selectively execute COMMANDS based upon WORD matching PATTERN. The\n\ + `|' is used to separate multiple patterns.\n\ + \n\ + Exit Status:\n\ + Returns the status of the last command executed."), +#endif /* HELP_BUILTIN */ + (char *)NULL +}; +char * const if_doc[] = { +#if defined (HELP_BUILTIN) +N_("Execute commands based on conditional.\n\ + \n\ + The `if COMMANDS' list is executed. If its exit status is zero, then the\n\ + `then COMMANDS' list is executed. Otherwise, each `elif COMMANDS' list is\n\ + executed in turn, and if its exit status is zero, the corresponding\n\ + `then COMMANDS' list is executed and the if command completes. Otherwise,\n\ + the `else COMMANDS' list is executed, if present. The exit status of the\n\ + entire construct is the exit status of the last command executed, or zero\n\ + if no condition tested true.\n\ + \n\ + Exit Status:\n\ + Returns the status of the last command executed."), +#endif /* HELP_BUILTIN */ + (char *)NULL +}; +char * const while_doc[] = { +#if defined (HELP_BUILTIN) +N_("Execute commands as long as a test succeeds.\n\ + \n\ + Expand and execute COMMANDS as long as the final command in the\n\ + `while' COMMANDS has an exit status of zero.\n\ + \n\ + Exit Status:\n\ + Returns the status of the last command executed."), +#endif /* HELP_BUILTIN */ + (char *)NULL +}; +char * const until_doc[] = { +#if defined (HELP_BUILTIN) +N_("Execute commands as long as a test does not succeed.\n\ + \n\ + Expand and execute COMMANDS as long as the final command in the\n\ + `until' COMMANDS has an exit status which is not zero.\n\ + \n\ + Exit Status:\n\ + Returns the status of the last command executed."), +#endif /* HELP_BUILTIN */ + (char *)NULL +}; +char * const coproc_doc[] = { +#if defined (HELP_BUILTIN) +N_("Create a coprocess named NAME.\n\ + \n\ + Execute COMMAND asynchronously, with the standard output and standard\n\ + input of the command connected via a pipe to file descriptors assigned\n\ + to indices 0 and 1 of an array variable NAME in the executing shell.\n\ + The default NAME is \"COPROC\".\n\ + \n\ + Exit Status:\n\ + The coproc command returns an exit status of 0."), +#endif /* HELP_BUILTIN */ + (char *)NULL +}; +char * const function_doc[] = { +#if defined (HELP_BUILTIN) +N_("Define shell function.\n\ + \n\ + Create a shell function named NAME. When invoked as a simple command,\n\ + NAME runs COMMANDs in the calling shell's context. When NAME is invoked,\n\ + the arguments are passed to the function as $1...$n, and the function's\n\ + name is in $FUNCNAME.\n\ + \n\ + Exit Status:\n\ + Returns success unless NAME is readonly."), +#endif /* HELP_BUILTIN */ + (char *)NULL +}; +char * const grouping_braces_doc[] = { +#if defined (HELP_BUILTIN) +N_("Group commands as a unit.\n\ + \n\ + Run a set of commands in a group. This is one way to redirect an\n\ + entire set of commands.\n\ + \n\ + Exit Status:\n\ + Returns the status of the last command executed."), +#endif /* HELP_BUILTIN */ + (char *)NULL +}; +char * const fg_percent_doc[] = { +#if defined (HELP_BUILTIN) +N_("Resume job in foreground.\n\ + \n\ + Equivalent to the JOB_SPEC argument to the `fg' command. Resume a\n\ + stopped or background job. JOB_SPEC can specify either a job name\n\ + or a job number. Following JOB_SPEC with a `&' places the job in\n\ + the background, as if the job specification had been supplied as an\n\ + argument to `bg'.\n\ + \n\ + Exit Status:\n\ + Returns the status of the resumed job."), +#endif /* HELP_BUILTIN */ + (char *)NULL +}; +char * const arith_doc[] = { +#if defined (HELP_BUILTIN) +N_("Evaluate arithmetic expression.\n\ + \n\ + The EXPRESSION is evaluated according to the rules for arithmetic\n\ + evaluation. Equivalent to `let \"EXPRESSION\"'.\n\ + \n\ + Exit Status:\n\ + Returns 1 if EXPRESSION evaluates to 0; returns 0 otherwise."), +#endif /* HELP_BUILTIN */ + (char *)NULL +}; +char * const conditional_doc[] = { +#if defined (HELP_BUILTIN) +N_("Execute conditional command.\n\ + \n\ + Returns a status of 0 or 1 depending on the evaluation of the conditional\n\ + expression EXPRESSION. Expressions are composed of the same primaries used\n\ + by the `test' builtin, and may be combined using the following operators:\n\ + \n\ + ( EXPRESSION ) Returns the value of EXPRESSION\n\ + ! EXPRESSION True if EXPRESSION is false; else false\n\ + EXPR1 && EXPR2 True if both EXPR1 and EXPR2 are true; else false\n\ + EXPR1 || EXPR2 True if either EXPR1 or EXPR2 is true; else false\n\ + \n\ + When the `==' and `!=' operators are used, the string to the right of\n\ + the operator is used as a pattern and pattern matching is performed.\n\ + When the `=~' operator is used, the string to the right of the operator\n\ + is matched as a regular expression.\n\ + \n\ + The && and || operators do not evaluate EXPR2 if EXPR1 is sufficient to\n\ + determine the expression's value.\n\ + \n\ + Exit Status:\n\ + 0 or 1 depending on value of EXPRESSION."), +#endif /* HELP_BUILTIN */ + (char *)NULL +}; +char * const variable_help_doc[] = { +#if defined (HELP_BUILTIN) +N_("Common shell variable names and usage.\n\ + \n\ + BASH_VERSION Version information for this Bash.\n\ + CDPATH A colon-separated list of directories to search\n\ + for directories given as arguments to `cd'.\n\ + GLOBIGNORE A colon-separated list of patterns describing filenames to\n\ + be ignored by pathname expansion.\n\ + HISTFILE The name of the file where your command history is stored.\n\ + HISTFILESIZE The maximum number of lines this file can contain.\n\ + HISTSIZE The maximum number of history lines that a running\n\ + shell can access.\n\ + HOME The complete pathname to your login directory.\n\ + HOSTNAME The name of the current host.\n\ + HOSTTYPE The type of CPU this version of Bash is running under.\n\ + IGNOREEOF Controls the action of the shell on receipt of an EOF\n\ + character as the sole input. If set, then the value\n\ + of it is the number of EOF characters that can be seen\n\ + in a row on an empty line before the shell will exit\n\ + (default 10). When unset, EOF signifies the end of input.\n\ + MACHTYPE A string describing the current system Bash is running on.\n\ + MAILCHECK How often, in seconds, Bash checks for new mail.\n\ + MAILPATH A colon-separated list of filenames which Bash checks\n\ + for new mail.\n\ + OSTYPE The version of Unix this version of Bash is running on.\n\ + PATH A colon-separated list of directories to search when\n\ + looking for commands.\n\ + PROMPT_COMMAND A command to be executed before the printing of each\n\ + primary prompt.\n\ + PS1 The primary prompt string.\n\ + PS2 The secondary prompt string.\n\ + PWD The full pathname of the current directory.\n\ + SHELLOPTS A colon-separated list of enabled shell options.\n\ + TERM The name of the current terminal type.\n\ + TIMEFORMAT The output format for timing statistics displayed by the\n\ + `time' reserved word.\n\ + auto_resume Non-null means a command word appearing on a line by\n\ + itself is first looked for in the list of currently\n\ + stopped jobs. If found there, that job is foregrounded.\n\ + A value of `exact' means that the command word must\n\ + exactly match a command in the list of stopped jobs. A\n\ + value of `substring' means that the command word must\n\ + match a substring of the job. Any other value means that\n\ + the command must be a prefix of a stopped job.\n\ + histchars Characters controlling history expansion and quick\n\ + substitution. The first character is the history\n\ + substitution character, usually `!'. The second is\n\ + the `quick substitution' character, usually `^'. The\n\ + third is the `history comment' character, usually `#'.\n\ + HISTIGNORE A colon-separated list of patterns used to decide which\n\ + commands should be saved on the history list.\n\ +"), +#endif /* HELP_BUILTIN */ + (char *)NULL +}; +#if defined (PUSHD_AND_POPD) +char * const pushd_doc[] = { +#if defined (HELP_BUILTIN) +N_("Add directories to stack.\n\ + \n\ + Adds a directory to the top of the directory stack, or rotates\n\ + the stack, making the new top of the stack the current working\n\ + directory. With no arguments, exchanges the top two directories.\n\ + \n\ + Options:\n\ + -n Suppresses the normal change of directory when adding\n\ + directories to the stack, so only the stack is manipulated.\n\ + \n\ + Arguments:\n\ + +N Rotates the stack so that the Nth directory (counting\n\ + from the left of the list shown by `dirs', starting with\n\ + zero) is at the top.\n\ + \n\ + -N Rotates the stack so that the Nth directory (counting\n\ + from the right of the list shown by `dirs', starting with\n\ + zero) is at the top.\n\ + \n\ + dir Adds DIR to the directory stack at the top, making it the\n\ + new current working directory.\n\ + \n\ + The `dirs' builtin displays the directory stack.\n\ + \n\ + Exit Status:\n\ + Returns success unless an invalid argument is supplied or the directory\n\ + change fails."), +#endif /* HELP_BUILTIN */ + (char *)NULL +}; +#endif /* PUSHD_AND_POPD */ +#if defined (PUSHD_AND_POPD) +char * const popd_doc[] = { +#if defined (HELP_BUILTIN) +N_("Remove directories from stack.\n\ + \n\ + Removes entries from the directory stack. With no arguments, removes\n\ + the top directory from the stack, and changes to the new top directory.\n\ + \n\ + Options:\n\ + -n Suppresses the normal change of directory when removing\n\ + directories from the stack, so only the stack is manipulated.\n\ + \n\ + Arguments:\n\ + +N Removes the Nth entry counting from the left of the list\n\ + shown by `dirs', starting with zero. For example: `popd +0'\n\ + removes the first directory, `popd +1' the second.\n\ + \n\ + -N Removes the Nth entry counting from the right of the list\n\ + shown by `dirs', starting with zero. For example: `popd -0'\n\ + removes the last directory, `popd -1' the next to last.\n\ + \n\ + The `dirs' builtin displays the directory stack.\n\ + \n\ + Exit Status:\n\ + Returns success unless an invalid argument is supplied or the directory\n\ + change fails."), +#endif /* HELP_BUILTIN */ + (char *)NULL +}; +#endif /* PUSHD_AND_POPD */ +#if defined (PUSHD_AND_POPD) +char * const dirs_doc[] = { +#if defined (HELP_BUILTIN) +N_("Display directory stack.\n\ + \n\ + Display the list of currently remembered directories. Directories\n\ + find their way onto the list with the `pushd' command; you can get\n\ + back up through the list with the `popd' command.\n\ + \n\ + Options:\n\ + -c clear the directory stack by deleting all of the elements\n\ + -l do not print tilde-prefixed versions of directories relative\n\ + to your home directory\n\ + -p print the directory stack with one entry per line\n\ + -v print the directory stack with one entry per line prefixed\n\ + with its position in the stack\n\ + \n\ + Arguments:\n\ + +N Displays the Nth entry counting from the left of the list\n\ + shown by dirs when invoked without options, starting with\n\ + zero.\n\ + \n\ + -N Displays the Nth entry counting from the right of the list\n\ + shown by dirs when invoked without options, starting with\n\ + zero.\n\ + \n\ + Exit Status:\n\ + Returns success unless an invalid option is supplied or an error occurs."), +#endif /* HELP_BUILTIN */ + (char *)NULL +}; +#endif /* PUSHD_AND_POPD */ +char * const shopt_doc[] = { +#if defined (HELP_BUILTIN) +N_("Set and unset shell options.\n\ + \n\ + Change the setting of each shell option OPTNAME. Without any option\n\ + arguments, list each supplied OPTNAME, or all shell options if no\n\ + OPTNAMEs are given, with an indication of whether or not each is set.\n\ + \n\ + Options:\n\ + -o restrict OPTNAMEs to those defined for use with `set -o'\n\ + -p print each shell option with an indication of its status\n\ + -q suppress output\n\ + -s enable (set) each OPTNAME\n\ + -u disable (unset) each OPTNAME\n\ + \n\ + Exit Status:\n\ + Returns success if OPTNAME is enabled; fails if an invalid option is\n\ + given or OPTNAME is disabled."), +#endif /* HELP_BUILTIN */ + (char *)NULL +}; +char * const printf_doc[] = { +#if defined (HELP_BUILTIN) +N_("Formats and prints ARGUMENTS under control of the FORMAT.\n\ + \n\ + Options:\n\ + -v var assign the output to shell variable VAR rather than\n\ + display it on the standard output\n\ + \n\ + FORMAT is a character string which contains three types of objects: plain\n\ + characters, which are simply copied to standard output; character escape\n\ + sequences, which are converted and copied to the standard output; and\n\ + format specifications, each of which causes printing of the next successive\n\ + argument.\n\ + \n\ + In addition to the standard format specifications described in printf(1),\n\ + printf interprets:\n\ + \n\ + %b expand backslash escape sequences in the corresponding argument\n\ + %q quote the argument in a way that can be reused as shell input\n\ + %(fmt)T output the date-time string resulting from using FMT as a format\n\ + string for strftime(3)\n\ + \n\ + The format is re-used as necessary to consume all of the arguments. If\n\ + there are fewer arguments than the format requires, extra format\n\ + specifications behave as if a zero value or null string, as appropriate,\n\ + had been supplied.\n\ + \n\ + Exit Status:\n\ + Returns success unless an invalid option is given or a write or assignment\n\ + error occurs."), +#endif /* HELP_BUILTIN */ + (char *)NULL +}; +#if defined (PROGRAMMABLE_COMPLETION) +char * const complete_doc[] = { +#if defined (HELP_BUILTIN) +N_("Specify how arguments are to be completed by Readline.\n\ + \n\ + For each NAME, specify how arguments are to be completed. If no options\n\ + are supplied, existing completion specifications are printed in a way that\n\ + allows them to be reused as input.\n\ + \n\ + Options:\n\ + -p print existing completion specifications in a reusable format\n\ + -r remove a completion specification for each NAME, or, if no\n\ + NAMEs are supplied, all completion specifications\n\ + -D apply the completions and actions as the default for commands\n\ + without any specific completion defined\n\ + -E apply the completions and actions to \"empty\" commands --\n\ + completion attempted on a blank line\n\ + -I apply the completions and actions to the initial (usually the\n\ + command) word\n\ + \n\ + When completion is attempted, the actions are applied in the order the\n\ + uppercase-letter options are listed above. If multiple options are supplied,\n\ + the -D option takes precedence over -E, and both take precedence over -I.\n\ + \n\ + Exit Status:\n\ + Returns success unless an invalid option is supplied or an error occurs."), +#endif /* HELP_BUILTIN */ + (char *)NULL +}; +#endif /* PROGRAMMABLE_COMPLETION */ +#if defined (PROGRAMMABLE_COMPLETION) +char * const compgen_doc[] = { +#if defined (HELP_BUILTIN) +N_("Display possible completions depending on the options.\n\ + \n\ + Intended to be used from within a shell function generating possible\n\ + completions. If the optional WORD argument is supplied, matches against\n\ + WORD are generated.\n\ + \n\ + Exit Status:\n\ + Returns success unless an invalid option is supplied or an error occurs."), +#endif /* HELP_BUILTIN */ + (char *)NULL +}; +#endif /* PROGRAMMABLE_COMPLETION */ +#if defined (PROGRAMMABLE_COMPLETION) +char * const compopt_doc[] = { +#if defined (HELP_BUILTIN) +N_("Modify or display completion options.\n\ + \n\ + Modify the completion options for each NAME, or, if no NAMEs are supplied,\n\ + the completion currently being executed. If no OPTIONs are given, print\n\ + the completion options for each NAME or the current completion specification.\n\ + \n\ + Options:\n\ + -o option Set completion option OPTION for each NAME\n\ + -D Change options for the \"default\" command completion\n\ + -E Change options for the \"empty\" command completion\n\ + -I Change options for completion on the initial word\n\ + \n\ + Using `+o' instead of `-o' turns off the specified option.\n\ + \n\ + Arguments:\n\ + \n\ + Each NAME refers to a command for which a completion specification must\n\ + have previously been defined using the `complete' builtin. If no NAMEs\n\ + are supplied, compopt must be called by a function currently generating\n\ + completions, and the options for that currently-executing completion\n\ + generator are modified.\n\ + \n\ + Exit Status:\n\ + Returns success unless an invalid option is supplied or NAME does not\n\ + have a completion specification defined."), +#endif /* HELP_BUILTIN */ + (char *)NULL +}; +#endif /* PROGRAMMABLE_COMPLETION */ +char * const mapfile_doc[] = { +#if defined (HELP_BUILTIN) +N_("Read lines from the standard input into an indexed array variable.\n\ + \n\ + Read lines from the standard input into the indexed array variable ARRAY, or\n\ + from file descriptor FD if the -u option is supplied. The variable MAPFILE\n\ + is the default ARRAY.\n\ + \n\ + Options:\n\ + -d delim Use DELIM to terminate lines, instead of newline\n\ + -n count Copy at most COUNT lines. If COUNT is 0, all lines are copied\n\ + -O origin Begin assigning to ARRAY at index ORIGIN. The default index is 0\n\ + -s count Discard the first COUNT lines read\n\ + -t Remove a trailing DELIM from each line read (default newline)\n\ + -u fd Read lines from file descriptor FD instead of the standard input\n\ + -C callback Evaluate CALLBACK each time QUANTUM lines are read\n\ + -c quantum Specify the number of lines read between each call to\n\ + CALLBACK\n\ + \n\ + Arguments:\n\ + ARRAY Array variable name to use for file data\n\ + \n\ + If -C is supplied without -c, the default quantum is 5000. When\n\ + CALLBACK is evaluated, it is supplied the index of the next array\n\ + element to be assigned and the line to be assigned to that element\n\ + as additional arguments.\n\ + \n\ + If not supplied with an explicit origin, mapfile will clear ARRAY before\n\ + assigning to it.\n\ + \n\ + Exit Status:\n\ + Returns success unless an invalid option is given or ARRAY is readonly or\n\ + not an indexed array."), +#endif /* HELP_BUILTIN */ + (char *)NULL +}; +char * const readarray_doc[] = { +#if defined (HELP_BUILTIN) +N_("Read lines from a file into an array variable.\n\ + \n\ + A synonym for `mapfile'."), +#endif /* HELP_BUILTIN */ + (char *)NULL +}; diff --git a/builtins/caller.c b/builtins/caller.c new file mode 100644 index 0000000..8731b43 --- /dev/null +++ b/builtins/caller.c @@ -0,0 +1,120 @@ +/* caller.c, created from caller.def. */ +#line 23 "./caller.def" + +#line 41 "./caller.def" + +#include +#include +#include "chartypes.h" +#include "bashtypes.h" + +#if defined (HAVE_UNISTD_H) +# ifdef _MINIX +# include +# endif +# include +#endif + +#include + +#include "../bashintl.h" + +#include "../shell.h" +#include "common.h" +#include "builtext.h" +#include "bashgetopt.h" + +#ifdef LOADABLE_BUILTIN +# include "builtins.h" +#endif + +#if !defined (errno) +extern int errno; +#endif /* !errno */ + +int +caller_builtin (list) + WORD_LIST *list; +{ +#if !defined (ARRAY_VARS) + printf ("1 NULL\n"); + return (EXECUTION_FAILURE); +#else + SHELL_VAR *funcname_v, *bash_source_v, *bash_lineno_v; + ARRAY *funcname_a, *bash_source_a, *bash_lineno_a; + char *funcname_s, *source_s, *lineno_s; + intmax_t num; + + CHECK_HELPOPT (list); + + 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); + + if (bash_lineno_a == 0 || array_empty (bash_lineno_a)) + return (EXECUTION_FAILURE); + + if (bash_source_a == 0 || array_empty (bash_source_a)) + return (EXECUTION_FAILURE); + + if (no_options (list)) + return (EX_USAGE); + list = loptend; /* skip over possible `--' */ + + /* If there is no argument list, then give short form: line filename. */ + if (list == 0) + { + lineno_s = array_reference (bash_lineno_a, 0); + source_s = array_reference (bash_source_a, 1); + printf("%s %s\n", lineno_s ? lineno_s : "NULL", source_s ? source_s : "NULL"); + return (EXECUTION_SUCCESS); + } + + if (funcname_a == 0 || array_empty (funcname_a)) + return (EXECUTION_FAILURE); + + if (legal_number (list->word->word, &num)) + { + lineno_s = array_reference (bash_lineno_a, num); + source_s = array_reference (bash_source_a, num+1); + funcname_s = array_reference (funcname_a, num+1); + + if (lineno_s == NULL|| source_s == NULL || funcname_s == NULL) + return (EXECUTION_FAILURE); + + printf("%s %s %s\n", lineno_s, funcname_s, source_s); + } + else + { + sh_invalidnum (list->word->word); + builtin_usage (); + return (EX_USAGE); + } + + return (EXECUTION_SUCCESS); +#endif +} + +#ifdef LOADABLE_BUILTIN +static char *caller_doc[] = { +N_("Returns the context of the current subroutine call.\n\ + \n\ + Without EXPR, returns \"$line $filename\". With EXPR, returns\n\ + \"$line $subroutine $filename\"; this extra information can be used to\n\ + provide a stack trace.\n\ + \n\ + The value of EXPR indicates how many call frames to go back before the\n\ + current one; the top frame is frame 0."), + (char *)NULL +}; + +struct builtin caller_struct = { + "caller", + caller_builtin, + BUILTIN_ENABLED, + caller_doc, + "caller [EXPR]", + 0 +}; + +#endif /* LOADABLE_BUILTIN */ diff --git a/builtins/cd.c b/builtins/cd.c new file mode 100644 index 0000000..619b328 --- /dev/null +++ b/builtins/cd.c @@ -0,0 +1,613 @@ +/* cd.c, created from cd.def. */ +#line 22 "./cd.def" +#include + +#if defined (HAVE_UNISTD_H) +# ifdef _MINIX +# include +# endif +# include +#endif + +#include "../bashtypes.h" +#include "posixdir.h" +#include "posixstat.h" +#if defined (HAVE_SYS_PARAM_H) +#include +#endif +#include + +#include + +#include "../bashansi.h" +#include "../bashintl.h" + +#include +#include + +#include "../shell.h" +#include "../flags.h" +#include "maxpath.h" +#include "common.h" +#include "bashgetopt.h" + +#if !defined (errno) +extern int errno; +#endif /* !errno */ + +extern const char * const bash_getcwd_errstr; + +static int bindpwd PARAMS((int)); +static int setpwd PARAMS((char *)); +static char *resetpwd PARAMS((char *)); +static int change_to_directory PARAMS((char *, int, int)); + +static int cdxattr PARAMS((char *, char **)); +static void resetxattr PARAMS((void)); + +/* Change this to 1 to get cd spelling correction by default. */ +int cdspelling = 0; + +int cdable_vars; + +static int eflag; /* file scope so bindpwd() can see it */ +static int xattrflag; /* O_XATTR support for openat */ +static int xattrfd = -1; + +#line 115 "./cd.def" + +/* Just set $PWD, don't change OLDPWD. Used by `pwd -P' in posix mode. */ +static int +setpwd (dirname) + char *dirname; +{ + int old_anm; + SHELL_VAR *tvar; + + old_anm = array_needs_making; + tvar = bind_variable ("PWD", dirname ? dirname : "", 0); + if (tvar && readonly_p (tvar)) + return EXECUTION_FAILURE; + if (tvar && old_anm == 0 && array_needs_making && exported_p (tvar)) + { + update_export_env_inplace ("PWD=", 4, dirname ? dirname : ""); + array_needs_making = 0; + } + return EXECUTION_SUCCESS; +} + +static int +bindpwd (no_symlinks) + int no_symlinks; +{ + char *dirname, *pwdvar; + int old_anm, r, canon_failed; + SHELL_VAR *tvar; + + r = sh_chkwrite (EXECUTION_SUCCESS); + +#define tcwd the_current_working_directory + dirname = tcwd ? (no_symlinks ? sh_physpath (tcwd, 0) : tcwd) + : get_working_directory ("cd"); +#undef tcwd + + /* If canonicalization fails, reset dirname to the_current_working_directory */ + canon_failed = 0; + if (dirname == 0) + { + canon_failed = 1; + dirname = the_current_working_directory; + } + + old_anm = array_needs_making; + pwdvar = get_string_value ("PWD"); + + tvar = bind_variable ("OLDPWD", pwdvar, 0); + if (tvar && readonly_p (tvar)) + r = EXECUTION_FAILURE; + + if (old_anm == 0 && array_needs_making && exported_p (tvar)) + { + update_export_env_inplace ("OLDPWD=", 7, pwdvar); + array_needs_making = 0; + } + + if (setpwd (dirname) == EXECUTION_FAILURE) + r = EXECUTION_FAILURE; + if (canon_failed && eflag) + r = EXECUTION_FAILURE; + + if (dirname && dirname != the_current_working_directory) + free (dirname); + + return (r); +} + +/* Call get_working_directory to reset the value of + the_current_working_directory () */ +static char * +resetpwd (caller) + char *caller; +{ + char *tdir; + + FREE (the_current_working_directory); + the_current_working_directory = (char *)NULL; + tdir = get_working_directory (caller); + return (tdir); +} + +static int +cdxattr (dir, ndirp) + char *dir; /* don't assume we can always free DIR */ + char **ndirp; /* return new constructed directory name */ +{ +#if defined (O_XATTR) + int apfd, fd, r, e; + char buf[11+40+40]; /* construct new `fake' path for pwd */ + + apfd = openat (AT_FDCWD, dir, O_RDONLY|O_NONBLOCK); + if (apfd < 0) + return -1; + fd = openat (apfd, ".", O_XATTR); + e = errno; + close (apfd); /* ignore close error for now */ + errno = e; + if (fd < 0) + return -1; + r = fchdir (fd); /* assume fchdir exists everywhere with O_XATTR */ + if (r < 0) + { + close (fd); + return -1; + } + /* NFSv4 and ZFS extended attribute directories do not have names which are + visible in the standard Unix directory tree structure. To ensure we have + a valid name for $PWD, we synthesize one under /proc, but to keep that + path valid, we need to keep the file descriptor open as long as we are in + this directory. This imposes a certain structure on /proc. */ + if (ndirp) + { + sprintf (buf, "/proc/%d/fd/%d", getpid(), fd); + *ndirp = savestring (buf); + } + + if (xattrfd >= 0) + close (xattrfd); + xattrfd = fd; + + return r; +#else + return -1; +#endif +} + +/* Clean up the O_XATTR baggage. Currently only closes xattrfd */ +static void +resetxattr () +{ +#if defined (O_XATTR) + if (xattrfd >= 0) + { + close (xattrfd); + xattrfd = -1; + } +#else + xattrfd = -1; /* not strictly necessary */ +#endif +} + +#define LCD_DOVARS 0x001 +#define LCD_DOSPELL 0x002 +#define LCD_PRINTPATH 0x004 +#define LCD_FREEDIRNAME 0x008 + +/* This builtin is ultimately the way that all user-visible commands should + change the current working directory. It is called by cd_to_string (), + so the programming interface is simple, and it handles errors and + restrictions properly. */ +int +cd_builtin (list) + WORD_LIST *list; +{ + char *dirname, *cdpath, *path, *temp; + int path_index, no_symlinks, opt, lflag, e; + +#if defined (RESTRICTED_SHELL) + if (restricted) + { + sh_restricted ((char *)NULL); + return (EXECUTION_FAILURE); + } +#endif /* RESTRICTED_SHELL */ + + eflag = 0; + no_symlinks = no_symbolic_links; + xattrflag = 0; + reset_internal_getopt (); +#if defined (O_XATTR) + while ((opt = internal_getopt (list, "eLP@")) != -1) +#else + while ((opt = internal_getopt (list, "eLP")) != -1) +#endif + { + switch (opt) + { + case 'P': + no_symlinks = 1; + break; + case 'L': + no_symlinks = 0; + break; + case 'e': + eflag = 1; + break; +#if defined (O_XATTR) + case '@': + xattrflag = 1; + break; +#endif + CASE_HELPOPT; + default: + builtin_usage (); + return (EX_USAGE); + } + } + list = loptend; + + lflag = (cdable_vars ? LCD_DOVARS : 0) | + ((interactive && cdspelling) ? LCD_DOSPELL : 0); + if (eflag && no_symlinks == 0) + eflag = 0; + + if (list == 0) + { + /* `cd' without arguments is equivalent to `cd $HOME' */ + dirname = get_string_value ("HOME"); + + if (dirname == 0) + { + builtin_error (_("HOME not set")); + return (EXECUTION_FAILURE); + } + lflag = 0; + } +#if defined (CD_COMPLAINS) + else if (list->next) + { + builtin_error (_("too many arguments")); + return (EXECUTION_FAILURE); + } +#endif +#if 0 + else if (list->word->word[0] == '\0') + { + builtin_error (_("null directory")); + return (EXECUTION_FAILURE); + } +#endif + else if (list->word->word[0] == '-' && list->word->word[1] == '\0') + { + /* This is `cd -', equivalent to `cd $OLDPWD' */ + dirname = get_string_value ("OLDPWD"); + + if (dirname == 0) + { + builtin_error (_("OLDPWD not set")); + return (EXECUTION_FAILURE); + } +#if 0 + lflag = interactive ? LCD_PRINTPATH : 0; +#else + lflag = LCD_PRINTPATH; /* According to SUSv3 */ +#endif + } + else if (absolute_pathname (list->word->word)) + dirname = list->word->word; + else if (privileged_mode == 0 && (cdpath = get_string_value ("CDPATH"))) + { + dirname = list->word->word; + + /* Find directory in $CDPATH. */ + path_index = 0; + while (path = extract_colon_unit (cdpath, &path_index)) + { + /* OPT is 1 if the path element is non-empty */ + opt = path[0] != '\0'; + temp = sh_makepath (path, dirname, MP_DOTILDE); + free (path); + + if (change_to_directory (temp, no_symlinks, xattrflag)) + { + /* POSIX.2 says that if a nonempty directory from CDPATH + is used to find the directory to change to, the new + directory name is echoed to stdout, whether or not + the shell is interactive. */ + if (opt && (path = no_symlinks ? temp : the_current_working_directory)) + printf ("%s\n", path); + + free (temp); +#if 0 + /* Posix.2 says that after using CDPATH, the resultant + value of $PWD will not contain `.' or `..'. */ + return (bindpwd (posixly_correct || no_symlinks)); +#else + return (bindpwd (no_symlinks)); +#endif + } + else + free (temp); + } + +#if 0 + /* changed for bash-4.2 Posix cd description steps 5-6 */ + /* POSIX.2 says that if `.' does not appear in $CDPATH, we don't + try the current directory, so we just punt now with an error + message if POSIXLY_CORRECT is non-zero. The check for cdpath[0] + is so we don't mistakenly treat a CDPATH value of "" as not + specifying the current directory. */ + if (posixly_correct && cdpath[0]) + { + builtin_error ("%s: %s", dirname, strerror (ENOENT)); + return (EXECUTION_FAILURE); + } +#endif + } + else + dirname = list->word->word; + + /* When we get here, DIRNAME is the directory to change to. If we + chdir successfully, just return. */ + if (change_to_directory (dirname, no_symlinks, xattrflag)) + { + if (lflag & LCD_PRINTPATH) + printf ("%s\n", dirname); + return (bindpwd (no_symlinks)); + } + + /* If the user requests it, then perhaps this is the name of + a shell variable, whose value contains the directory to + change to. */ + if (lflag & LCD_DOVARS) + { + temp = get_string_value (dirname); + if (temp && change_to_directory (temp, no_symlinks, xattrflag)) + { + printf ("%s\n", temp); + return (bindpwd (no_symlinks)); + } + } + + /* If the user requests it, try to find a directory name similar in + spelling to the one requested, in case the user made a simple + typo. This is similar to the UNIX 8th and 9th Edition shells. */ + if (lflag & LCD_DOSPELL) + { + temp = dirspell (dirname); + if (temp && change_to_directory (temp, no_symlinks, xattrflag)) + { + printf ("%s\n", temp); + free (temp); + return (bindpwd (no_symlinks)); + } + else + FREE (temp); + } + + e = errno; + temp = printable_filename (dirname, 0); + builtin_error ("%s: %s", temp, strerror (e)); + if (temp != dirname) + free (temp); + return (EXECUTION_FAILURE); +} + +#line 478 "./cd.def" + +/* Non-zero means that pwd always prints the physical directory, without + symbolic links. */ +static int verbatim_pwd; + +/* Print the name of the current working directory. */ +int +pwd_builtin (list) + WORD_LIST *list; +{ + char *directory; + int opt, pflag; + + verbatim_pwd = no_symbolic_links; + pflag = 0; + reset_internal_getopt (); + while ((opt = internal_getopt (list, "LP")) != -1) + { + switch (opt) + { + case 'P': + verbatim_pwd = pflag = 1; + break; + case 'L': + verbatim_pwd = 0; + break; + CASE_HELPOPT; + default: + builtin_usage (); + return (EX_USAGE); + } + } + list = loptend; + +#define tcwd the_current_working_directory + + directory = tcwd ? (verbatim_pwd ? sh_physpath (tcwd, 0) : tcwd) + : get_working_directory ("pwd"); + + /* Try again using getcwd() if canonicalization fails (for instance, if + the file system has changed state underneath bash). */ + if ((tcwd && directory == 0) || + (posixly_correct && same_file (".", tcwd, (struct stat *)0, (struct stat *)0) == 0)) + { + if (directory && directory != tcwd) + free (directory); + directory = resetpwd ("pwd"); + } + +#undef tcwd + + if (directory) + { + opt = EXECUTION_SUCCESS; + printf ("%s\n", directory); + /* This is dumb but posix-mandated. */ + if (posixly_correct && pflag) + opt = setpwd (directory); + if (directory != the_current_working_directory) + free (directory); + return (sh_chkwrite (opt)); + } + else + return (EXECUTION_FAILURE); +} + +/* Do the work of changing to the directory NEWDIR. Handle symbolic + link following, etc. This function *must* return with + the_current_working_directory either set to NULL (in which case + getcwd() will eventually be called), or set to a string corresponding + to the working directory. Return 1 on success, 0 on failure. */ + +static int +change_to_directory (newdir, nolinks, xattr) + char *newdir; + int nolinks, xattr; +{ + char *t, *tdir, *ndir; + int err, canon_failed, r, ndlen; + + tdir = (char *)NULL; + + if (the_current_working_directory == 0) + { + t = get_working_directory ("chdir"); + FREE (t); + } + + t = make_absolute (newdir, the_current_working_directory); + + /* TDIR is either the canonicalized absolute pathname of NEWDIR + (nolinks == 0) or the absolute physical pathname of NEWDIR + (nolinks != 0). */ + tdir = nolinks ? sh_physpath (t, 0) + : sh_canonpath (t, PATH_CHECKDOTDOT|PATH_CHECKEXISTS); + + ndlen = strlen (newdir); + + /* Use the canonicalized version of NEWDIR, or, if canonicalization + failed, use the non-canonical form. */ + canon_failed = 0; + if (tdir && *tdir) + free (t); + else + { + FREE (tdir); + tdir = t; + canon_failed = 1; + } + + /* In POSIX mode, if we're resolving symlinks logically and sh_canonpath + returns NULL (because it checks the path, it will return NULL if the + resolved path doesn't exist), fail immediately. */ +#if defined (ENAMETOOLONG) + if (posixly_correct && nolinks == 0 && canon_failed && (errno != ENAMETOOLONG || ndlen > PATH_MAX)) +#else + if (posixly_correct && nolinks == 0 && canon_failed && ndlen > PATH_MAX) +#endif + { +#if defined ENAMETOOLONG + if (errno != ENOENT && errno != ENAMETOOLONG) +#else + if (errno != ENOENT) +#endif + errno = ENOTDIR; + free (tdir); + return (0); + } + +#if defined (O_XATTR) + if (xattrflag) + { + r = cdxattr (nolinks ? newdir : tdir, &ndir); + if (r >= 0) + { + canon_failed = 0; + free (tdir); + tdir = ndir; + } + else + { + err = errno; + free (tdir); + errno = err; + return (0); /* no xattr */ + } + } + else +#endif + { + r = chdir (nolinks ? newdir : tdir); + if (r >= 0) + resetxattr (); + } + + /* If the chdir succeeds, update the_current_working_directory. */ + if (r == 0) + { + /* If canonicalization failed, but the chdir succeeded, reset the + shell's idea of the_current_working_directory. */ + if (canon_failed) + { + t = resetpwd ("cd"); + if (t == 0) + set_working_directory (tdir); + else + free (t); + } + else + set_working_directory (tdir); + + free (tdir); + return (1); + } + + /* We failed to change to the appropriate directory name. If we tried + what the user passed (nolinks != 0), punt now. */ + if (nolinks) + { + free (tdir); + return (0); + } + + err = errno; + + /* We're not in physical mode (nolinks == 0), but we failed to change to + the canonicalized directory name (TDIR). Try what the user passed + verbatim. If we succeed, reinitialize the_current_working_directory. + POSIX requires that we just fail here, so we do in posix mode. */ + if (posixly_correct == 0 && chdir (newdir) == 0) + { + t = resetpwd ("cd"); + if (t == 0) + set_working_directory (tdir); + else + free (t); + + r = 1; + } + else + { + errno = err; + r = 0; + } + + free (tdir); + return r; +} diff --git a/builtins/colon.c b/builtins/colon.c new file mode 100644 index 0000000..995691b --- /dev/null +++ b/builtins/colon.c @@ -0,0 +1,33 @@ +/* colon.c, created from colon.def. */ +#line 22 "./colon.def" + +#line 34 "./colon.def" + +#line 43 "./colon.def" + +#line 52 "./colon.def" + +#include + +#if defined (HAVE_UNISTD_H) +# include +#endif + +#include "../bashansi.h" +#include "../shell.h" + +/* Return a successful result. */ +int +colon_builtin (ignore) + WORD_LIST *ignore; +{ + return (0); +} + +/* Return an unsuccessful result. */ +int +false_builtin (ignore) + WORD_LIST *ignore; +{ + return (1); +} diff --git a/builtins/command.c b/builtins/command.c new file mode 100644 index 0000000..d6cf12d --- /dev/null +++ b/builtins/command.c @@ -0,0 +1,109 @@ +/* command.c, created from command.def. */ +#line 22 "./command.def" + +#line 41 "./command.def" + +#include + +#if defined (HAVE_UNISTD_H) +# ifdef _MINIX +# include +# endif +# include +#endif + +#include "../bashansi.h" + +#include "../shell.h" +#include "../execute_cmd.h" +#include "../flags.h" +#include "bashgetopt.h" +#include "common.h" + +#if defined (_CS_PATH) && defined (HAVE_CONFSTR) && !HAVE_DECL_CONFSTR +extern size_t confstr PARAMS((int, char *, size_t)); +#endif + +/* Run the commands mentioned in LIST without paying attention to shell + functions. */ +int +command_builtin (list) + WORD_LIST *list; +{ + int result, verbose, use_standard_path, opt; + COMMAND *command; + + verbose = use_standard_path = 0; + reset_internal_getopt (); + while ((opt = internal_getopt (list, "pvV")) != -1) + { + switch (opt) + { + case 'p': + use_standard_path = CDESC_STDPATH; + break; + case 'V': + verbose = CDESC_SHORTDESC|CDESC_ABSPATH; /* look in common.h for constants */ + break; + case 'v': + verbose = CDESC_REUSABLE; /* ditto */ + break; + CASE_HELPOPT; + default: + builtin_usage (); + return (EX_USAGE); + } + } + list = loptend; + + if (list == 0) + return (EXECUTION_SUCCESS); + +#if defined (RESTRICTED_SHELL) + if (use_standard_path && restricted) + { + sh_restricted ("-p"); + return (EXECUTION_FAILURE); + } +#endif + + if (verbose) + { + int found, any_found; + + for (any_found = 0; list; list = list->next) + { + found = describe_command (list->word->word, verbose|use_standard_path); + + if (found == 0 && verbose != CDESC_REUSABLE) + sh_notfound (list->word->word); + + any_found += found; + } + + return (any_found ? EXECUTION_SUCCESS : EXECUTION_FAILURE); + } + + begin_unwind_frame ("command_builtin"); + +#define COMMAND_BUILTIN_FLAGS (CMD_NO_FUNCTIONS | CMD_INHIBIT_EXPANSION | CMD_COMMAND_BUILTIN | (use_standard_path ? CMD_STDPATH : 0)) + +#ifdef DEBUG + itrace("command_builtin: running execute_command for `%s'", list->word->word); +#endif + + /* We don't want this to be reparsed (consider command echo 'foo &'), so + just make a simple_command structure and call execute_command with it. */ + command = make_bare_simple_command (); + command->value.Simple->words = (WORD_LIST *)copy_word_list (list); + command->value.Simple->redirects = (REDIRECT *)NULL; + command->flags |= COMMAND_BUILTIN_FLAGS; + command->value.Simple->flags |= COMMAND_BUILTIN_FLAGS; + + add_unwind_protect ((char *)dispose_command, command); + result = execute_command (command); + + run_unwind_frame ("command_builtin"); + + return (result); +} diff --git a/builtins/complete.c b/builtins/complete.c new file mode 100644 index 0000000..64efe0c --- /dev/null +++ b/builtins/complete.c @@ -0,0 +1,797 @@ +/* complete.c, created from complete.def. */ +#line 22 "./complete.def" + +#line 51 "./complete.def" + +#include + +#include + +#include "../bashtypes.h" + +#if defined (HAVE_UNISTD_H) +# include +#endif + +#include "../bashansi.h" +#include "../bashintl.h" + +#include "../shell.h" +#include "../builtins.h" +#include "../pcomplete.h" +#include "../bashline.h" + +#include "common.h" +#include "bashgetopt.h" + +#include + +#define STRDUP(x) ((x) ? savestring (x) : (char *)NULL) + +/* Structure containing all the non-action (binary) options; filled in by + build_actions(). */ +struct _optflags { + int pflag; + int rflag; + int Dflag; + int Eflag; + int Iflag; +}; + +static int find_compact PARAMS((char *)); +static int find_compopt PARAMS((char *)); + +static int build_actions PARAMS((WORD_LIST *, struct _optflags *, unsigned long *, unsigned long *)); + +static int remove_cmd_completions PARAMS((WORD_LIST *)); + +static int print_one_completion PARAMS((char *, COMPSPEC *)); +static int print_compitem PARAMS((BUCKET_CONTENTS *)); +static void print_compopts PARAMS((const char *, COMPSPEC *, int)); +static void print_all_completions PARAMS((void)); +static int print_cmd_completions PARAMS((WORD_LIST *)); + +static void print_compoptions PARAMS((unsigned long, int)); +static void print_compactions PARAMS((unsigned long)); +static void print_arg PARAMS((const char *, const char *, int)); +static void print_cmd_name PARAMS((const char *)); + +static char *Garg, *Warg, *Parg, *Sarg, *Xarg, *Farg, *Carg; + +static const struct _compacts { + const char * const actname; + unsigned long actflag; + int actopt; +} compacts[] = { + { "alias", CA_ALIAS, 'a' }, + { "arrayvar", CA_ARRAYVAR, 0 }, + { "binding", CA_BINDING, 0 }, + { "builtin", CA_BUILTIN, 'b' }, + { "command", CA_COMMAND, 'c' }, + { "directory", CA_DIRECTORY, 'd' }, + { "disabled", CA_DISABLED, 0 }, + { "enabled", CA_ENABLED, 0 }, + { "export", CA_EXPORT, 'e' }, + { "file", CA_FILE, 'f' }, + { "function", CA_FUNCTION, 0 }, + { "helptopic", CA_HELPTOPIC, 0 }, + { "hostname", CA_HOSTNAME, 0 }, + { "group", CA_GROUP, 'g' }, + { "job", CA_JOB, 'j' }, + { "keyword", CA_KEYWORD, 'k' }, + { "running", CA_RUNNING, 0 }, + { "service", CA_SERVICE, 's' }, + { "setopt", CA_SETOPT, 0 }, + { "shopt", CA_SHOPT, 0 }, + { "signal", CA_SIGNAL, 0 }, + { "stopped", CA_STOPPED, 0 }, + { "user", CA_USER, 'u' }, + { "variable", CA_VARIABLE, 'v' }, + { (char *)NULL, 0, 0 }, +}; + +/* This should be a STRING_INT_ALIST */ +static const struct _compopt { + const char * const optname; + unsigned long optflag; +} compopts[] = { + { "bashdefault", COPT_BASHDEFAULT }, + { "default", COPT_DEFAULT }, + { "dirnames", COPT_DIRNAMES }, + { "filenames",COPT_FILENAMES}, + { "noquote", COPT_NOQUOTE }, + { "nosort", COPT_NOSORT }, + { "nospace", COPT_NOSPACE }, + { "plusdirs", COPT_PLUSDIRS }, + { (char *)NULL, 0 }, +}; + +static int +find_compact (name) + char *name; +{ + register int i; + + for (i = 0; compacts[i].actname; i++) + if (STREQ (name, compacts[i].actname)) + return i; + return -1; +} + +static int +find_compopt (name) + char *name; +{ + register int i; + + for (i = 0; compopts[i].optname; i++) + if (STREQ (name, compopts[i].optname)) + return i; + return -1; +} + +/* Build the actions and compspec options from the options specified in LIST. + ACTP is a pointer to an unsigned long in which to place the bitmap of + actions. OPTP is a pointer to an unsigned long in which to place the + bitmap of compspec options (arguments to `-o'). PP, if non-null, gets 1 + if -p is supplied; RP, if non-null, gets 1 if -r is supplied. + If either is null, the corresponding option generates an error. + This also sets variables corresponding to options that take arguments as + a side effect; the caller should ensure that those variables are set to + NULL before calling build_actions. Return value: + EX_USAGE = bad option + EXECUTION_SUCCESS = some options supplied + EXECUTION_FAILURE = no options supplied +*/ + +static int +build_actions (list, flagp, actp, optp) + WORD_LIST *list; + struct _optflags *flagp; + unsigned long *actp, *optp; +{ + int opt, ind, opt_given; + unsigned long acts, copts; + WORD_DESC w; + + acts = copts = (unsigned long)0L; + opt_given = 0; + + reset_internal_getopt (); + while ((opt = internal_getopt (list, "abcdefgjko:prsuvA:G:W:P:S:X:F:C:DEI")) != -1) + { + opt_given = 1; + switch (opt) + { + case 'r': + if (flagp) + { + flagp->rflag = 1; + break; + } + else + { + sh_invalidopt ("-r"); + builtin_usage (); + return (EX_USAGE); + } + + case 'p': + if (flagp) + { + flagp->pflag = 1; + break; + } + else + { + sh_invalidopt ("-p"); + builtin_usage (); + return (EX_USAGE); + } + + case 'a': + acts |= CA_ALIAS; + break; + case 'b': + acts |= CA_BUILTIN; + break; + case 'c': + acts |= CA_COMMAND; + break; + case 'd': + acts |= CA_DIRECTORY; + break; + case 'e': + acts |= CA_EXPORT; + break; + case 'f': + acts |= CA_FILE; + break; + case 'g': + acts |= CA_GROUP; + break; + case 'j': + acts |= CA_JOB; + break; + case 'k': + acts |= CA_KEYWORD; + break; + case 's': + acts |= CA_SERVICE; + break; + case 'u': + acts |= CA_USER; + break; + case 'v': + acts |= CA_VARIABLE; + break; + case 'o': + ind = find_compopt (list_optarg); + if (ind < 0) + { + sh_invalidoptname (list_optarg); + return (EX_USAGE); + } + copts |= compopts[ind].optflag; + break; + case 'A': + ind = find_compact (list_optarg); + if (ind < 0) + { + builtin_error (_("%s: invalid action name"), list_optarg); + return (EX_USAGE); + } + acts |= compacts[ind].actflag; + break; + case 'C': + Carg = list_optarg; + break; + case 'D': + if (flagp) + { + flagp->Dflag = 1; + break; + } + else + { + sh_invalidopt ("-D"); + builtin_usage (); + return (EX_USAGE); + } + case 'E': + if (flagp) + { + flagp->Eflag = 1; + break; + } + else + { + sh_invalidopt ("-E"); + builtin_usage (); + return (EX_USAGE); + } + case 'I': + if (flagp) + { + flagp->Iflag = 1; + break; + } + else + { + sh_invalidopt ("-I"); + builtin_usage (); + return (EX_USAGE); + } + case 'F': + w.word = Farg = list_optarg; + w.flags = 0; + if (check_identifier (&w, posixly_correct) == 0 || strpbrk (Farg, shell_break_chars) != 0) + { + sh_invalidid (Farg); + return (EX_USAGE); + } + break; + case 'G': + Garg = list_optarg; + break; + case 'P': + Parg = list_optarg; + break; + case 'S': + Sarg = list_optarg; + break; + case 'W': + Warg = list_optarg; + break; + case 'X': + Xarg = list_optarg; + break; + CASE_HELPOPT; + default: + builtin_usage (); + return (EX_USAGE); + } + } + + *actp = acts; + *optp = copts; + + return (opt_given ? EXECUTION_SUCCESS : EXECUTION_FAILURE); +} + +/* Add, remove, and display completion specifiers. */ +int +complete_builtin (list) + WORD_LIST *list; +{ + int opt_given, rval; + unsigned long acts, copts; + COMPSPEC *cs; + struct _optflags oflags; + WORD_LIST *l, *wl; + + if (list == 0) + { + print_all_completions (); + return (EXECUTION_SUCCESS); + } + + opt_given = oflags.pflag = oflags.rflag = 0; + oflags.Dflag = oflags.Eflag = oflags.Iflag = 0; + + acts = copts = (unsigned long)0L; + Garg = Warg = Parg = Sarg = Xarg = Farg = Carg = (char *)NULL; + cs = (COMPSPEC *)NULL; + + /* Build the actions from the arguments. Also sets the [A-Z]arg variables + as a side effect if they are supplied as options. */ + rval = build_actions (list, &oflags, &acts, &copts); + if (rval == EX_USAGE) + return (rval); + opt_given = rval != EXECUTION_FAILURE; + + list = loptend; + + if (oflags.Dflag) + wl = make_word_list (make_bare_word (DEFAULTCMD), (WORD_LIST *)NULL); + else if (oflags.Eflag) + wl = make_word_list (make_bare_word (EMPTYCMD), (WORD_LIST *)NULL); + else if (oflags.Iflag) + wl = make_word_list (make_bare_word (INITIALWORD), (WORD_LIST *)NULL); + else + wl = (WORD_LIST *)NULL; + + /* -p overrides everything else */ + if (oflags.pflag || (list == 0 && opt_given == 0)) + { + if (wl) + { + rval = print_cmd_completions (wl); + dispose_words (wl); + return rval; + } + else if (list == 0) + { + print_all_completions (); + return (EXECUTION_SUCCESS); + } + return (print_cmd_completions (list)); + } + + /* next, -r overrides everything else. */ + if (oflags.rflag) + { + if (wl) + { + rval = remove_cmd_completions (wl); + dispose_words (wl); + return rval; + } + else if (list == 0) + { + progcomp_flush (); + return (EXECUTION_SUCCESS); + } + return (remove_cmd_completions (list)); + } + + if (wl == 0 && list == 0 && opt_given) + { + builtin_usage (); + return (EX_USAGE); + } + + /* If we get here, we need to build a compspec and add it for each + remaining argument. */ + cs = compspec_create (); + cs->actions = acts; + cs->options = copts; + + cs->globpat = STRDUP (Garg); + cs->words = STRDUP (Warg); + cs->prefix = STRDUP (Parg); + cs->suffix = STRDUP (Sarg); + cs->funcname = STRDUP (Farg); + cs->command = STRDUP (Carg); + cs->filterpat = STRDUP (Xarg); + + for (rval = EXECUTION_SUCCESS, l = wl ? wl : list ; l; l = l->next) + { + /* Add CS as the compspec for the specified commands. */ + if (progcomp_insert (l->word->word, cs) == 0) + rval = EXECUTION_FAILURE; + } + + dispose_words (wl); + return (rval); +} + +static int +remove_cmd_completions (list) + WORD_LIST *list; +{ + WORD_LIST *l; + int ret; + + for (ret = EXECUTION_SUCCESS, l = list; l; l = l->next) + { + if (progcomp_remove (l->word->word) == 0) + { + builtin_error (_("%s: no completion specification"), l->word->word); + ret = EXECUTION_FAILURE; + } + } + return ret; +} + +static void +print_compoptions (copts, full) + unsigned long copts; + int full; +{ + const struct _compopt *co; + + for (co = compopts; co->optname; co++) + if (copts & co->optflag) + printf ("-o %s ", co->optname); + else if (full) + printf ("+o %s ", co->optname); +} + +static void +print_compactions (acts) + unsigned long acts; +{ + const struct _compacts *ca; + + /* simple flags first */ + for (ca = compacts; ca->actname; ca++) + if (ca->actopt && (acts & ca->actflag)) + printf ("-%c ", ca->actopt); + + /* then the rest of the actions */ + for (ca = compacts; ca->actname; ca++) + if (ca->actopt == 0 && (acts & ca->actflag)) + printf ("-A %s ", ca->actname); +} + +static void +print_arg (arg, flag, quote) + const char *arg, *flag; + int quote; +{ + char *x; + + if (arg) + { + x = quote ? sh_single_quote (arg) : (char *)arg; + printf ("%s %s ", flag, x); + if (x != arg) + free (x); + } +} + +static void +print_cmd_name (cmd) + const char *cmd; +{ + if (STREQ (cmd, DEFAULTCMD)) + printf ("-D"); + else if (STREQ (cmd, EMPTYCMD)) + printf ("-E"); + else if (STREQ (cmd, INITIALWORD)) + printf ("-I"); + else if (*cmd == 0) /* XXX - can this happen? */ + printf ("''"); + else + printf ("%s", cmd); +} + +static int +print_one_completion (cmd, cs) + char *cmd; + COMPSPEC *cs; +{ + printf ("complete "); + + print_compoptions (cs->options, 0); + print_compactions (cs->actions); + + /* now the rest of the arguments */ + + /* arguments that require quoting */ + print_arg (cs->globpat, "-G", 1); + print_arg (cs->words, "-W", 1); + print_arg (cs->prefix, "-P", 1); + print_arg (cs->suffix, "-S", 1); + print_arg (cs->filterpat, "-X", 1); + + print_arg (cs->command, "-C", 1); + + /* simple arguments that don't require quoting */ + print_arg (cs->funcname, "-F", 0); + + print_cmd_name (cmd); + printf ("\n"); + + return (0); +} + +static void +print_compopts (cmd, cs, full) + const char *cmd; + COMPSPEC *cs; + int full; +{ + printf ("compopt "); + + print_compoptions (cs->options, full); + print_cmd_name (cmd); + + printf ("\n"); +} + +static int +print_compitem (item) + BUCKET_CONTENTS *item; +{ + COMPSPEC *cs; + char *cmd; + + cmd = item->key; + cs = (COMPSPEC *)item->data; + + return (print_one_completion (cmd, cs)); +} + +static void +print_all_completions () +{ + progcomp_walk (print_compitem); +} + +static int +print_cmd_completions (list) + WORD_LIST *list; +{ + WORD_LIST *l; + COMPSPEC *cs; + int ret; + + for (ret = EXECUTION_SUCCESS, l = list; l; l = l->next) + { + cs = progcomp_search (l->word->word); + if (cs) + print_one_completion (l->word->word, cs); + else + { + builtin_error (_("%s: no completion specification"), l->word->word); + ret = EXECUTION_FAILURE; + } + } + + return (sh_chkwrite (ret)); +} + +#line 655 "./complete.def" + +int +compgen_builtin (list) + WORD_LIST *list; +{ + int rval; + unsigned long acts, copts; + COMPSPEC *cs; + STRINGLIST *sl; + char *word, **matches; + char *old_line; + int old_ind; + + if (list == 0) + return (EXECUTION_SUCCESS); + + acts = copts = (unsigned long)0L; + Garg = Warg = Parg = Sarg = Xarg = Farg = Carg = (char *)NULL; + cs = (COMPSPEC *)NULL; + + /* Build the actions from the arguments. Also sets the [A-Z]arg variables + as a side effect if they are supplied as options. */ + rval = build_actions (list, (struct _optflags *)NULL, &acts, &copts); + if (rval == EX_USAGE) + return (rval); + if (rval == EXECUTION_FAILURE) + return (EXECUTION_SUCCESS); + + list = loptend; + + word = (list && list->word) ? list->word->word : ""; + + if (Farg) + builtin_error (_("warning: -F option may not work as you expect")); + if (Carg) + builtin_error (_("warning: -C option may not work as you expect")); + + /* If we get here, we need to build a compspec and evaluate it. */ + cs = compspec_create (); + cs->actions = acts; + cs->options = copts; + cs->refcount = 1; + + cs->globpat = STRDUP (Garg); + cs->words = STRDUP (Warg); + cs->prefix = STRDUP (Parg); + cs->suffix = STRDUP (Sarg); + cs->funcname = STRDUP (Farg); + cs->command = STRDUP (Carg); + cs->filterpat = STRDUP (Xarg); + + rval = EXECUTION_FAILURE; + + /* probably don't have to save these, just being safe */ + old_line = pcomp_line; + old_ind = pcomp_ind; + pcomp_line = (char *)NULL; + pcomp_ind = 0; + sl = gen_compspec_completions (cs, "compgen", word, 0, 0, 0); + pcomp_line = old_line; + pcomp_ind = old_ind; + + /* If the compspec wants the bash default completions, temporarily + turn off programmable completion and call the bash completion code. */ + if ((sl == 0 || sl->list_len == 0) && (copts & COPT_BASHDEFAULT)) + { + matches = bash_default_completion (word, 0, 0, 0, 0); + sl = completions_to_stringlist (matches); + strvec_dispose (matches); + } + + /* This isn't perfect, but it's the best we can do, given what readline + exports from its set of completion utility functions. */ + if ((sl == 0 || sl->list_len == 0) && (copts & COPT_DEFAULT)) + { + matches = rl_completion_matches (word, rl_filename_completion_function); + strlist_dispose (sl); + sl = completions_to_stringlist (matches); + strvec_dispose (matches); + } + + if (sl) + { + if (sl->list && sl->list_len) + { + rval = EXECUTION_SUCCESS; + strlist_print (sl, (char *)NULL); + } + strlist_dispose (sl); + } + + compspec_dispose (cs); + return (rval); +} + +#line 780 "./complete.def" + +int +compopt_builtin (list) + WORD_LIST *list; +{ + int opts_on, opts_off, *opts, opt, oind, ret, Dflag, Eflag, Iflag; + WORD_LIST *l, *wl; + COMPSPEC *cs; + + opts_on = opts_off = Eflag = Dflag = Iflag = 0; + ret = EXECUTION_SUCCESS; + + reset_internal_getopt (); + while ((opt = internal_getopt (list, "+o:DEI")) != -1) + { + opts = (list_opttype == '-') ? &opts_on : &opts_off; + + switch (opt) + { + case 'o': + oind = find_compopt (list_optarg); + if (oind < 0) + { + sh_invalidoptname (list_optarg); + return (EX_USAGE); + } + *opts |= compopts[oind].optflag; + break; + case 'D': + Dflag = 1; + break; + case 'E': + Eflag = 1; + break; + case 'I': + Iflag = 1; + break; + CASE_HELPOPT; + default: + builtin_usage (); + return (EX_USAGE); + } + } + list = loptend; + + if (Dflag) + wl = make_word_list (make_bare_word (DEFAULTCMD), (WORD_LIST *)NULL); + else if (Eflag) + wl = make_word_list (make_bare_word (EMPTYCMD), (WORD_LIST *)NULL); + else if (Iflag) + wl = make_word_list (make_bare_word (INITIALWORD), (WORD_LIST *)NULL); + else + wl = (WORD_LIST *)NULL; + + if (list == 0 && wl == 0) + { + if (RL_ISSTATE (RL_STATE_COMPLETING) == 0 || pcomp_curcs == 0) + { + builtin_error (_("not currently executing completion function")); + return (EXECUTION_FAILURE); + } + cs = pcomp_curcs; + + if (opts_on == 0 && opts_off == 0) + { + print_compopts (pcomp_curcmd, cs, 1); + return (sh_chkwrite (ret)); + } + + /* Set the compspec options */ + pcomp_set_compspec_options (cs, opts_on, 1); + pcomp_set_compspec_options (cs, opts_off, 0); + + /* And change the readline variables the options control */ + pcomp_set_readline_variables (opts_on, 1); + pcomp_set_readline_variables (opts_off, 0); + + return (ret); + } + + for (l = wl ? wl : list; l; l = l->next) + { + cs = progcomp_search (l->word->word); + if (cs == 0) + { + builtin_error (_("%s: no completion specification"), l->word->word); + ret = EXECUTION_FAILURE; + continue; + } + if (opts_on == 0 && opts_off == 0) + { + print_compopts (l->word->word, cs, 1); + continue; /* XXX -- fill in later */ + } + + /* Set the compspec options */ + pcomp_set_compspec_options (cs, opts_on, 1); + pcomp_set_compspec_options (cs, opts_off, 0); + } + + if (wl) + dispose_words (wl); + + return (ret); +} diff --git a/builtins/declare.c b/builtins/declare.c new file mode 100644 index 0000000..3e49fe9 --- /dev/null +++ b/builtins/declare.c @@ -0,0 +1,921 @@ +/* declare.c, created from declare.def. */ +#line 22 "./declare.def" + +#line 64 "./declare.def" + +#line 72 "./declare.def" + +#include + +#if defined (HAVE_UNISTD_H) +# ifdef _MINIX +# include +# endif +# include +#endif + +#include + +#include "../bashansi.h" +#include "../bashintl.h" + +#include "../shell.h" +#include "../flags.h" +#include "common.h" +#include "builtext.h" +#include "bashgetopt.h" + +static SHELL_VAR *declare_find_variable PARAMS((const char *, int, int)); +static int declare_internal PARAMS((register WORD_LIST *, int)); + +/* Declare or change variable attributes. */ +int +declare_builtin (list) + register WORD_LIST *list; +{ + return (declare_internal (list, 0)); +} + +#line 119 "./declare.def" +int +local_builtin (list) + register WORD_LIST *list; +{ + /* Catch a straight `local --help' before checking function context */ + if (list && list->word && STREQ (list->word->word, "--help")) + { + builtin_help (); + return (EX_USAGE); + } + + if (variable_context) + return (declare_internal (list, 1)); + else + { + builtin_error (_("can only be used in a function")); + return (EXECUTION_FAILURE); + } +} + +#if defined (ARRAY_VARS) +# define DECLARE_OPTS "+acfgilnprtuxAFGI" +#else +# define DECLARE_OPTS "+cfgilnprtuxFGI" +#endif + +static SHELL_VAR * +declare_find_variable (name, mkglobal, chklocal) + const char *name; + int mkglobal, chklocal; +{ + SHELL_VAR *var; + + if (mkglobal == 0) + return (find_variable (name)); + else if (chklocal) + { + var = find_variable (name); + if (var && local_p (var) && var->context == variable_context) + return var; + return (find_global_variable (name)); + } + else + return (find_global_variable (name)); +} + +/* The workhorse function. */ +static int +declare_internal (list, local_var) + register WORD_LIST *list; + int local_var; +{ + int flags_on, flags_off, *flags; + int any_failed, assign_error, pflag, nodefs, opt, onref, offref; + int mkglobal, chklocal, inherit_flag; + char *t, *subscript_start; + SHELL_VAR *var, *refvar, *v; + FUNCTION_DEF *shell_fn; + + flags_on = flags_off = any_failed = assign_error = pflag = nodefs = 0; + mkglobal = chklocal = inherit_flag = 0; + refvar = (SHELL_VAR *)NULL; + reset_internal_getopt (); + while ((opt = internal_getopt (list, DECLARE_OPTS)) != -1) + { + flags = list_opttype == '+' ? &flags_off : &flags_on; + + /* If you add options here, see whether or not they need to be added to + the loop in subst.c:shell_expand_word_list() */ + switch (opt) + { + case 'a': +#if defined (ARRAY_VARS) + *flags |= att_array; + break; +#else + builtin_usage (); + return (EX_USAGE); +#endif + case 'A': +#if defined (ARRAY_VARS) + *flags |= att_assoc; + break; +#else + builtin_usage (); + return (EX_USAGE); +#endif + case 'p': +/* if (local_var == 0) */ + pflag++; + break; + case 'F': + nodefs++; + *flags |= att_function; + break; + case 'f': + *flags |= att_function; + break; + case 'G': + if (flags == &flags_on) + chklocal = 1; + /*FALLTHROUGH*/ + case 'g': + if (flags == &flags_on) + mkglobal = 1; + break; + case 'i': + *flags |= att_integer; + break; + case 'n': + *flags |= att_nameref; + break; + case 'r': + *flags |= att_readonly; + break; + case 't': + *flags |= att_trace; + break; + case 'x': + *flags |= att_exported; + array_needs_making = 1; + break; +#if defined (CASEMOD_ATTRS) +# if defined (CASEMOD_CAPCASE) + case 'c': + *flags |= att_capcase; + if (flags == &flags_on) + flags_off |= att_uppercase|att_lowercase; + break; +# endif + case 'l': + *flags |= att_lowercase; + if (flags == &flags_on) + flags_off |= att_capcase|att_uppercase; + break; + case 'u': + *flags |= att_uppercase; + if (flags == &flags_on) + flags_off |= att_capcase|att_lowercase; + break; +#endif /* CASEMOD_ATTRS */ + case 'I': + inherit_flag = MKLOC_INHERIT; + break; + CASE_HELPOPT; + default: + builtin_usage (); + return (EX_USAGE); + } + } + + list = loptend; + + /* If there are no more arguments left, then we just want to show + some variables. */ + if (list == 0) /* declare -[aAfFirtx] */ + { + /* Show local variables defined at this context level if this is + the `local' builtin. */ + if (local_var) + show_local_var_attributes (0, nodefs); /* XXX - fix up args later */ + else if (pflag && (flags_on == 0 || flags_on == att_function)) + show_all_var_attributes (flags_on == 0, nodefs); + else if (flags_on == 0) + return (set_builtin ((WORD_LIST *)NULL)); + else + set_or_show_attributes ((WORD_LIST *)NULL, flags_on, nodefs); + + return (sh_chkwrite (EXECUTION_SUCCESS)); + } + + if (pflag) /* declare -p [-aAfFirtx] name [name...] */ + { + for (any_failed = 0; list; list = list->next) + { + if (flags_on & att_function) + pflag = show_func_attributes (list->word->word, nodefs); + else if (local_var) + pflag = show_localname_attributes (list->word->word, nodefs); + else + pflag = show_name_attributes (list->word->word, nodefs); + if (pflag) + { + sh_notfound (list->word->word); + any_failed++; + } + } + return (sh_chkwrite (any_failed ? EXECUTION_FAILURE : EXECUTION_SUCCESS)); + } + +#define NEXT_VARIABLE() free (name); list = list->next; continue + + /* There are arguments left, so we are making variables. */ + while (list) /* declare [-aAfFirx] name [name ...] */ + { + char *value, *name, *oldname; + int offset, aflags, wflags, created_var, namelen; + int assoc_noexpand; +#if defined (ARRAY_VARS) + int making_array_special, compound_array_assign, simple_array_assign; + int var_exists, array_exists, creating_array, array_subscript_assignment; +#endif + + name = savestring (list->word->word); + wflags = list->word->flags; +#if defined (ARRAY_VARS) + assoc_noexpand = assoc_expand_once && (wflags & W_ASSIGNMENT); +#else + assoc_noexpand = 0; +#endif + offset = assignment (name, assoc_noexpand ? 2 : 0); + aflags = 0; + created_var = 0; + + if (local_var && variable_context && STREQ (name, "-")) + { + var = make_local_variable ("-", 0); + FREE (value_cell (var)); /* just in case */ + value = get_current_options (); + var_setvalue (var, value); + VSETATTR (var, att_invisible); + NEXT_VARIABLE (); + } + + if (offset) /* declare [-aAfFirx] name=value */ + { + name[offset] = '\0'; + value = name + offset + 1; + if (name[offset - 1] == '+') + { + aflags |= ASS_APPEND; + name[offset - 1] = '\0'; + } + } + else + value = ""; + + /* Do some lexical error checking on the LHS and RHS of the assignment + that is specific to nameref variables. */ + if (flags_on & att_nameref) + { +#if defined (ARRAY_VARS) + if (valid_array_reference (name, 0)) + { + builtin_error (_("%s: reference variable cannot be an array"), name); + assign_error++; + NEXT_VARIABLE (); + } + else +#endif + /* disallow self references at global scope, warn at function scope */ + if (check_selfref (name, value, 0)) + { + if (variable_context == 0) + { + builtin_error (_("%s: nameref variable self references not allowed"), name); + assign_error++; + NEXT_VARIABLE (); + } + else + builtin_warning (_("%s: circular name reference"), name); + } +#if 1 + if (value && *value && (aflags & ASS_APPEND) == 0 && valid_nameref_value (value, 1) == 0) + { + builtin_error (_("`%s': invalid variable name for name reference"), value); + assign_error++; + NEXT_VARIABLE (); + } +#endif + } + +restart_new_var_name: +#if defined (ARRAY_VARS) + var_exists = array_exists = creating_array = 0; + compound_array_assign = simple_array_assign = 0; + array_subscript_assignment = 0; + subscript_start = (char *)NULL; + if ((t = strchr (name, '[')) && (flags_on & att_function) == 0) /* ] */ + { + /* If offset != 0 we have already validated any array reference + because assignment() calls skipsubscript() */ + if (offset == 0 && valid_array_reference (name, 0) == 0) + { + sh_invalidid (name); + assign_error++; + NEXT_VARIABLE (); + } + subscript_start = t; + *t = '\0'; + making_array_special = 1; /* XXX - should this check offset? */ + array_subscript_assignment = offset != 0; + } + else + making_array_special = 0; +#endif + + /* If we're in posix mode or not looking for a shell function (since + shell function names don't have to be valid identifiers when the + shell's not in posix mode), check whether or not the argument is a + valid, well-formed shell identifier. */ + if ((posixly_correct || (flags_on & att_function) == 0) && legal_identifier (name) == 0) + { + sh_invalidid (name); + assign_error++; + NEXT_VARIABLE (); + } + + /* If VARIABLE_CONTEXT has a non-zero value, then we are executing + inside of a function. This means we should make local variables, + not global ones. */ + + /* XXX - this has consequences when we're making a local copy of a + variable that was in the temporary environment. Watch out + for this. */ + refvar = (SHELL_VAR *)NULL; + if (variable_context && mkglobal == 0 && ((flags_on & att_function) == 0)) + { + char *newname; + + /* check name for validity here? */ + var = find_variable (name); + if (var == 0) + newname = nameref_transform_name (name, ASS_MKLOCAL); + else if ((flags_on & att_nameref) == 0 && (flags_off & att_nameref) == 0) + { + /* Ok, we're following namerefs here, so let's make sure that if + we followed one, it was at the same context (see below for + more details). */ + refvar = find_variable_last_nameref (name, 1); + newname = (refvar && refvar->context != variable_context) ? name : var->name; + refvar = (SHELL_VAR *)NULL; + } + else + newname = name; /* dealing with nameref attribute */ + +#if defined (ARRAY_VARS) + /* Pass 1 as second argument to make_local_{assoc,array}_variable + return an existing {array,assoc} variable to be flagged as an + error below. */ + if (flags_on & att_assoc) + var = make_local_assoc_variable (newname, MKLOC_ARRAYOK|inherit_flag); + else if ((flags_on & att_array) || making_array_special) + var = make_local_array_variable (newname, MKLOC_ASSOCOK|inherit_flag); + else +#endif + if (offset == 0 && (flags_on & att_nameref)) + { + /* First look for refvar at current scope */ + refvar = find_variable_last_nameref (name, 1); + /* VARIABLE_CONTEXT != 0, so we are attempting to create or modify + the attributes for a local variable at the same scope. If we've + used a reference from a previous context to resolve VAR, we + want to throw REFVAR and VAR away and create a new local var. */ + if (refvar && refvar->context != variable_context) + { + refvar = 0; + var = make_local_variable (name, inherit_flag); + } + else if (refvar && refvar->context == variable_context) + var = refvar; + /* Maybe we just want to create a new local variable */ + else if (var == 0 || var->context != variable_context) + var = make_local_variable (name, inherit_flag); + /* otherwise we have a var at the right context */ + } + else + /* XXX - check name for validity here with valid_nameref_value */ + var = make_local_variable ((flags_on & att_nameref) ? name : newname, inherit_flag); /* sets att_invisible for new vars */ + + if (var == 0) + { + any_failed++; + NEXT_VARIABLE (); + } + if (var && nameref_p (var) && readonly_p (var) && nameref_cell (var) && (flags_off & att_nameref)) + { + sh_readonly (name); + any_failed++; + NEXT_VARIABLE (); + } + } + else + var = (SHELL_VAR *)NULL; + + /* If we are declaring a function, then complain about it in some way. + We don't let people make functions by saying `typeset -f foo=bar'. */ + + /* There should be a way, however, to let people look at a particular + function definition by saying `typeset -f foo'. */ + + if (flags_on & att_function) + { + if (offset) /* declare -f [-rix] foo=bar */ + { + builtin_error (_("cannot use `-f' to make functions")); + free (name); + return (EXECUTION_FAILURE); + } + else /* declare -f [-rx] name [name...] */ + { + var = find_function (name); + + if (var) + { + if (readonly_p (var) && (flags_off & att_readonly)) + { + builtin_error (_("%s: readonly function"), name); + any_failed++; + NEXT_VARIABLE (); + } + else if (flags_on & (att_array|att_assoc)) + { + sh_invalidopt ((flags_on & att_array) ? "-a" : "-A"); + any_failed++; + NEXT_VARIABLE (); + } + /* declare -[Ff] name [name...] */ + if (flags_on == att_function && flags_off == 0) + { +#if defined (DEBUGGER) + if (nodefs && debugging_mode) + { + shell_fn = find_function_def (var->name); + if (shell_fn) + printf ("%s %d %s\n", var->name, shell_fn->line, shell_fn->source_file); + else + printf ("%s\n", var->name); + } + else +#endif /* DEBUGGER */ + { + t = nodefs ? var->name + : named_function_string (name, function_cell (var), FUNC_MULTILINE|FUNC_EXTERNAL); + printf ("%s\n", t); + any_failed = sh_chkwrite (any_failed); + } + } + else /* declare -[fF] -[rx] name [name...] */ + { + VSETATTR (var, flags_on); + flags_off &= ~att_function; /* makes no sense */ + VUNSETATTR (var, flags_off); + } + } + else + any_failed++; + NEXT_VARIABLE (); + } + } + else /* declare -[aAinrx] name [name...] */ + { + /* Non-null if we just created or fetched a local variable. */ +#if 0 + /* This is bash-4.3 code. */ + /* Here's what ksh93 seems to do. If we are modifying an existing + nameref variable, we don't follow the nameref chain past the last + nameref, and we set the nameref variable's value so future + references to that variable will return the value of the variable + we're assigning right now. */ +#else + /* Here's what ksh93 seems to do as of the 2012 version: if we are + using declare -n to modify the value of an existing nameref + variable, don't follow the nameref chain at all and just search + for a nameref at the current context. If we have a nameref, + modify its value (changing which variable it references). */ +#endif + if (var == 0 && (flags_on & att_nameref)) + { + /* See if we are trying to modify an existing nameref variable, + but don't follow the nameref chain. */ + var = mkglobal ? find_global_variable_noref (name) : find_variable_noref (name); + if (var && nameref_p (var) == 0) + var = 0; + } + /* However, if we're turning off the nameref attribute on an existing + nameref variable, we first follow the nameref chain to the end, + modify the value of the variable this nameref variable references + if there is an assignment statement argument, + *CHANGING ITS VALUE AS A SIDE EFFECT*, then turn off the nameref + flag *LEAVING THE NAMEREF VARIABLE'S VALUE UNCHANGED* */ + else if (var == 0 && (flags_off & att_nameref)) + { + /* See if we are trying to modify an existing nameref variable */ + refvar = mkglobal ? find_global_variable_last_nameref (name, 0) : find_variable_last_nameref (name, 0); + if (refvar && nameref_p (refvar) == 0) + refvar = 0; + /* If the nameref is readonly but doesn't have a value, ksh93 + allows the nameref attribute to be removed. If it's readonly + and has a value, even if the value doesn't reference an + existing variable, we disallow the modification */ + if (refvar && nameref_cell (refvar) && readonly_p (refvar)) + { + sh_readonly (name); + any_failed++; + NEXT_VARIABLE (); + } + + /* If all we're doing is turning off the nameref attribute, don't + bother with VAR at all, whether it exists or not. Just turn it + off and go on. */ + if (refvar && flags_on == 0 && offset == 0 && (flags_off & ~att_nameref) == 0) + { + VUNSETATTR (refvar, att_nameref); + NEXT_VARIABLE (); + } + + if (refvar) + /* XXX - use declare_find_variable here? */ + var = mkglobal ? find_global_variable (nameref_cell (refvar)) : find_variable (nameref_cell (refvar)); + } +#if defined (ARRAY_VARS) + /* If we have an array assignment to a nameref, remove the nameref + attribute and go on. */ + else if (var == 0 && offset && array_subscript_assignment) + { + var = mkglobal ? find_global_variable_noref (name) : find_variable_noref (name); + if (var && nameref_p (var)) + { + internal_warning (_("%s: removing nameref attribute"), name); + FREE (value_cell (var)); /* XXX - bash-4.3 compat */ + var_setvalue (var, (char *)NULL); + VUNSETATTR (var, att_nameref); + } + } +#endif + + /* See if we are trying to set flags or value (or create) for an + existing nameref that points to a non-existent variable: e.g., + declare -n foo=bar + unset foo # unsets bar + declare -i foo + foo=4+4 + declare -p foo */ + if (var == 0 && (mkglobal || flags_on || flags_off || offset)) + { + refvar = mkglobal ? find_global_variable_last_nameref (name, 0) : find_variable_last_nameref (name, 0); + if (refvar && nameref_p (refvar) == 0) + refvar = 0; + if (refvar) + /* XXX - use declare_find_variable here? */ + var = mkglobal ? find_global_variable (nameref_cell (refvar)) : find_variable (nameref_cell (refvar)); + if (refvar && var == 0) + { + oldname = name; /* need to free this */ + + namelen = strlen (nameref_cell (refvar)); +#if defined (ARRAY_VARS) + if (subscript_start) + { + *subscript_start = '['; /*]*/ + namelen += strlen (subscript_start); + } +#endif + name = xmalloc (namelen + 2 + strlen (value) + 1); + strcpy (name, nameref_cell (refvar)); +#if defined (ARRAY_VARS) + if (subscript_start) + strcpy (name + strlen (nameref_cell (refvar)), subscript_start); +#endif + /* We are committed to using the new name, so reset */ + if (offset) + { + /* Rebuild assignment and restore offset and value */ + if (aflags & ASS_APPEND) + name[namelen++] = '+'; + name[namelen++] = '='; + if (value && *value) + strcpy (name + namelen, value); + else + name[namelen] = '\0'; + offset = assignment (name, 0); + /* if offset was valid previously, but the substituting + of the nameref value results in an invalid assignment, + throw an invalid identifier error */ + if (offset == 0) + { + free (oldname); + sh_invalidid (name); + assign_error++; + NEXT_VARIABLE (); + } + name[offset] = '\0'; + value = name + namelen; + } + free (oldname); + + /* OK, let's turn off the nameref attribute. + Now everything else applies to VAR. */ + if (flags_off & att_nameref) + VUNSETATTR (refvar, att_nameref); + + goto restart_new_var_name; + /* NOTREACHED */ + } + } + if (var == 0) + var = declare_find_variable (name, mkglobal, chklocal); + +#if defined (ARRAY_VARS) + var_exists = var != 0; + array_exists = var && (array_p (var) || assoc_p (var)); + creating_array = flags_on & (att_array|att_assoc); +#endif + + if (var == 0) + { +#if defined (ARRAY_VARS) + if (flags_on & att_assoc) + { + var = make_new_assoc_variable (name); + if (var && offset == 0) + VSETATTR (var, att_invisible); + } + else if ((flags_on & att_array) || making_array_special) + { + var = make_new_array_variable (name); + if (var && offset == 0) + VSETATTR (var, att_invisible); + } + else +#endif + { + var = mkglobal ? bind_global_variable (name, (char *)NULL, ASS_FORCE) : bind_variable (name, (char *)NULL, ASS_FORCE); + if (var && offset == 0) + VSETATTR (var, att_invisible); + } + if (var == 0) + { + /* Has to appear in brackets */ + NEXT_VARIABLE (); + } + created_var = 1; + } + /* Can't take an existing array variable and make it a nameref */ + else if ((array_p (var) || assoc_p (var)) && (flags_on & att_nameref)) + { + builtin_error (_("%s: reference variable cannot be an array"), name); + assign_error++; + NEXT_VARIABLE (); + } + else if (nameref_p (var) && (flags_on & att_nameref) == 0 && (flags_off & att_nameref) == 0 && offset && valid_nameref_value (value, 1) == 0) + { + builtin_error (_("`%s': invalid variable name for name reference"), value); + any_failed++; + NEXT_VARIABLE (); + } + else if (flags_on & att_nameref) + { +#if 1 + /* Check of offset is to allow an assignment to a nameref var as + part of the declare word to override existing value */ + if (nameref_p (var) == 0 && var_isset (var) && offset == 0 && valid_nameref_value (value_cell (var), 0) == 0) + { + builtin_error (_("`%s': invalid variable name for name reference"), value_cell (var)); + any_failed++; + NEXT_VARIABLE (); + } +#endif + if (readonly_p (var)) + { + sh_readonly (name); + any_failed++; + NEXT_VARIABLE (); + } + /* ksh93 compat: turning on nameref attribute turns off -ilu */ + VUNSETATTR (var, att_integer|att_uppercase|att_lowercase|att_capcase); + } + + /* Cannot use declare +r to turn off readonly attribute. */ + if (readonly_p (var) && (flags_off & att_readonly)) + { + sh_readonly (name_cell (var)); + any_failed++; + NEXT_VARIABLE (); + } + + /* Cannot use declare to assign value to readonly or noassign + variable. */ + if ((readonly_p (var) || noassign_p (var)) && offset) + { + if (readonly_p (var)) + sh_readonly (name); + assign_error++; + NEXT_VARIABLE (); + } + +#if defined (ARRAY_VARS) + /* make declare a[2]=foo as similar to a[2]=foo as possible if + a is already an array or assoc variable. */ + if (array_subscript_assignment && array_exists && creating_array == 0) + simple_array_assign = 1; + else if ((making_array_special || creating_array || array_exists) && offset) + { + int vlen; + vlen = STRLEN (value); +/*itrace("declare_builtin: name = %s value = %s flags = %d", name, value, wflags);*/ + if (shell_compatibility_level > 43 && (wflags & W_COMPASSIGN) == 0 && + value[0] == '(' && value[vlen-1] == ')') + { + /* The warning is only printed when using compound assignment + to an array variable that doesn't already exist. We use + creating_array to allow things like + declare -a foo$bar='(abc)' to work. */ + if (array_exists == 0 && creating_array == 0) + internal_warning (_("%s: quoted compound array assignment deprecated"), list->word->word); + compound_array_assign = array_exists || creating_array; + simple_array_assign = making_array_special; + } + else if (value[0] == '(' && value[vlen-1] == ')' && (shell_compatibility_level < 44 || (wflags & W_COMPASSIGN))) + compound_array_assign = 1; + else + simple_array_assign = 1; + } + + /* Cannot use declare +a name or declare +A name to remove an + array variable. */ + if (((flags_off & att_array) && array_p (var)) || ((flags_off & att_assoc) && assoc_p (var))) + { + builtin_error (_("%s: cannot destroy array variables in this way"), name); + any_failed++; + NEXT_VARIABLE (); + } + + if ((flags_on & att_array) && assoc_p (var)) + { + builtin_error (_("%s: cannot convert associative to indexed array"), name); + any_failed++; + NEXT_VARIABLE (); + } + if ((flags_on & att_assoc) && array_p (var)) + { + builtin_error (_("%s: cannot convert indexed to associative array"), name); + any_failed++; + NEXT_VARIABLE (); + } + + /* declare -A name[[n]] makes name an associative array variable. */ + if (flags_on & att_assoc) + { + if (assoc_p (var) == 0) + var = convert_var_to_assoc (var); + } + /* declare -a name[[n]] or declare name[n] makes name an indexed + array variable. */ + else if ((making_array_special || (flags_on & att_array)) && array_p (var) == 0 && assoc_p (var) == 0) + var = convert_var_to_array (var); +#endif /* ARRAY_VARS */ + + /* XXX - we note that we are turning on nameref attribute and defer + setting it until the assignment has been made so we don't do an + inadvertent nameref lookup. Might have to do the same thing for + flags_off&att_nameref. */ + /* XXX - ksh93 makes it an error to set a readonly nameref variable + using a single typeset command. */ + onref = (flags_on & att_nameref); + flags_on &= ~att_nameref; +#if defined (ARRAY_VARS) + if (array_p (var) || assoc_p (var) + || (offset && compound_array_assign) + || simple_array_assign) + onref = 0; /* array variables may not be namerefs */ +#endif + + /* ksh93 seems to do this */ + offref = (flags_off & att_nameref); + flags_off &= ~att_nameref; + + VSETATTR (var, flags_on); + VUNSETATTR (var, flags_off); + +#if defined (ARRAY_VARS) + if (offset && compound_array_assign) + assign_array_var_from_string (var, value, aflags|ASS_FORCE); + else if (simple_array_assign && subscript_start) + { + int local_aflags; + /* declare [-aA] name[N]=value */ + *subscript_start = '['; /* ] */ + /* XXX - problem here with appending */ + local_aflags = aflags&ASS_APPEND; + local_aflags |= assoc_noexpand ? ASS_NOEXPAND : 0; + var = assign_array_element (name, value, local_aflags); /* XXX - not aflags */ + *subscript_start = '\0'; + if (var == 0) /* some kind of assignment error */ + { + assign_error++; + flags_on |= onref; + flags_off |= offref; + NEXT_VARIABLE (); + } + } + else if (simple_array_assign) + { + /* let bind_{array,assoc}_variable take care of this. */ + if (assoc_p (var)) + bind_assoc_variable (var, name, savestring ("0"), value, aflags|ASS_FORCE); + else + bind_array_variable (name, 0, value, aflags|ASS_FORCE); + } + else +#endif + /* XXX - no ASS_FORCE here */ + /* bind_variable_value duplicates the essential internals of + bind_variable() */ + if (offset) + { + if (onref || nameref_p (var)) + aflags |= ASS_NAMEREF; + v = bind_variable_value (var, value, aflags); + if (v == 0 && (onref || nameref_p (var))) + { + if (valid_nameref_value (value, 1) == 0) + sh_invalidid (value); + assign_error++; + /* XXX - unset this variable? or leave it as normal var? */ + if (created_var) + delete_var (var->name, mkglobal ? global_variables : shell_variables); + flags_on |= onref; /* undo change from above */ + flags_off |= offref; + NEXT_VARIABLE (); + } + } + + /* If we found this variable in the temporary environment, as with + `var=value declare -x var', make sure it is treated identically + to `var=value export var'. Do the same for `declare -r' and + `readonly'. Preserve the attributes, except for att_tempvar. */ + /* XXX -- should this create a variable in the global scope, or + modify the local variable flags? ksh93 has it modify the + global scope. + Need to handle case like in set_var_attribute where a temporary + variable is in the same table as the function local vars. */ + if ((flags_on & (att_exported|att_readonly)) && tempvar_p (var)) + { + SHELL_VAR *tv; + char *tvalue; + + tv = find_tempenv_variable (var->name); + if (tv) + { + tvalue = var_isset (var) ? savestring (value_cell (var)) : savestring (""); + tv = bind_variable (var->name, tvalue, 0); + if (tv) + { + tv->attributes |= var->attributes & ~att_tempvar; + if (tv->context > 0) + VSETATTR (tv, att_propagate); + } + free (tvalue); + } + VSETATTR (var, att_propagate); + } + } + + /* Turn on nameref attribute we deferred above. */ + /* XXX - should we turn on the noassign attribute for consistency with + ksh93 when we turn on the nameref attribute? */ + VSETATTR (var, onref); + flags_on |= onref; + VUNSETATTR (var, offref); + flags_off |= offref; + /* Yuck. ksh93 compatibility. XXX - need to investigate more but + definitely happens when turning off nameref attribute on nameref + (see comments above). Under no circumstances allow this to turn + off readonly attribute on readonly nameref variable. */ + if (refvar) + { + if (flags_off & att_readonly) + flags_off &= ~att_readonly; + VUNSETATTR (refvar, flags_off); + } + + stupidly_hack_special_variables (name); + + NEXT_VARIABLE (); + } + + return (assign_error ? EX_BADASSIGN + : ((any_failed == 0) ? EXECUTION_SUCCESS + : EXECUTION_FAILURE)); +} diff --git a/builtins/echo.c b/builtins/echo.c new file mode 100644 index 0000000..70a719e --- /dev/null +++ b/builtins/echo.c @@ -0,0 +1,133 @@ +/* echo.c, created from echo.def. */ +#line 22 "./echo.def" +#include + +#if defined (HAVE_UNISTD_H) +# include +#endif + +#include "../bashansi.h" + +#include +#include "../shell.h" + +#include "common.h" + +#line 73 "./echo.def" + +#line 88 "./echo.def" + +#if defined (V9_ECHO) +# define VALID_ECHO_OPTIONS "neE" +#else /* !V9_ECHO */ +# define VALID_ECHO_OPTIONS "n" +#endif /* !V9_ECHO */ + +/* System V machines already have a /bin/sh with a v9 behaviour. We + give Bash the identical behaviour for these machines so that the + existing system shells won't barf. Regrettably, the SUS v2 has + standardized the Sys V echo behavior. This variable is external + so that we can have a `shopt' variable to control it at runtime. */ +#if defined (DEFAULT_ECHO_TO_XPG) || defined (STRICT_POSIX) +int xpg_echo = 1; +#else +int xpg_echo = 0; +#endif /* DEFAULT_ECHO_TO_XPG */ + +/* Print the words in LIST to standard output. If the first word is + `-n', then don't print a trailing newline. We also support the + echo syntax from Version 9 Unix systems. */ +int +echo_builtin (list) + WORD_LIST *list; +{ + int display_return, do_v9, i, len; + char *temp, *s; + + do_v9 = xpg_echo; + display_return = 1; + + if (posixly_correct && xpg_echo) + goto just_echo; + + for (; list && (temp = list->word->word) && *temp == '-'; list = list->next) + { + /* If it appears that we are handling options, then make sure that + all of the options specified are actually valid. Otherwise, the + string should just be echoed. */ + temp++; + + for (i = 0; temp[i]; i++) + { + if (strchr (VALID_ECHO_OPTIONS, temp[i]) == 0) + break; + } + + /* echo - and echo - both mean to just echo the arguments. */ + if (*temp == 0 || temp[i]) + break; + + /* All of the options in TEMP are valid options to ECHO. + Handle them. */ + while (i = *temp++) + { + switch (i) + { + case 'n': + display_return = 0; + break; +#if defined (V9_ECHO) + case 'e': + do_v9 = 1; + break; + case 'E': + do_v9 = 0; + break; +#endif /* V9_ECHO */ + default: + goto just_echo; /* XXX */ + } + } + } + +just_echo: + + clearerr (stdout); /* clear error before writing and testing success */ + + while (list) + { + i = len = 0; + temp = do_v9 ? ansicstr (list->word->word, STRLEN (list->word->word), 1, &i, &len) + : list->word->word; + if (temp) + { + if (do_v9) + { + for (s = temp; len > 0; len--) + putchar (*s++); + } + else + printf ("%s", temp); +#if defined (SunOS5) + fflush (stdout); /* Fix for bug in SunOS 5.5 printf(3) */ +#endif + } + QUIT; + if (do_v9 && temp) + free (temp); + list = list->next; + if (i) + { + display_return = 0; + break; + } + if (list) + putchar(' '); + QUIT; + } + + if (display_return) + putchar ('\n'); + + return (sh_chkwrite (EXECUTION_SUCCESS)); +} diff --git a/builtins/enable.c b/builtins/enable.c new file mode 100644 index 0000000..5cdd8da --- /dev/null +++ b/builtins/enable.c @@ -0,0 +1,507 @@ +/* enable.c, created from enable.def. */ +#line 22 "./enable.def" + +#line 50 "./enable.def" + +#include + +#if defined (HAVE_UNISTD_H) +# ifdef _MINIX +# include +# endif +# include +#endif + +#include +#include "../bashansi.h" +#include "../bashintl.h" + +#include "../shell.h" +#include "../builtins.h" +#include "../flags.h" +#include "common.h" +#include "bashgetopt.h" +#include "findcmd.h" + +#if defined (PROGRAMMABLE_COMPLETION) +# include "../pcomplete.h" +#endif + +#define ENABLED 1 +#define DISABLED 2 +#define SPECIAL 4 + +#define AFLAG 0x01 +#define DFLAG 0x02 +#define FFLAG 0x04 +#define NFLAG 0x08 +#define PFLAG 0x10 +#define SFLAG 0x20 + +#if defined (HAVE_DLOPEN) && defined (HAVE_DLSYM) +static int dyn_load_builtin PARAMS((WORD_LIST *, int, char *)); +#endif + +#if defined (HAVE_DLCLOSE) +static int dyn_unload_builtin PARAMS((char *)); +static void delete_builtin PARAMS((struct builtin *)); +static int local_dlclose PARAMS((void *)); +#endif + +#define STRUCT_SUFFIX "_struct" +/* for now */ +#define LOAD_SUFFIX "_builtin_load" +#define UNLOAD_SUFFIX "_builtin_unload" + +static void list_some_builtins PARAMS((int)); +static int enable_shell_command PARAMS((char *, int)); + +/* Enable/disable shell commands present in LIST. If list is not specified, + then print out a list of shell commands showing which are enabled and + which are disabled. */ +int +enable_builtin (list) + WORD_LIST *list; +{ + int result, flags; + int opt, filter; +#if defined (HAVE_DLOPEN) && defined (HAVE_DLSYM) + char *filename; +#endif + + result = EXECUTION_SUCCESS; + flags = 0; + + reset_internal_getopt (); + while ((opt = internal_getopt (list, "adnpsf:")) != -1) + { + switch (opt) + { + case 'a': + flags |= AFLAG; + break; + case 'n': + flags |= NFLAG; + break; + case 'p': + flags |= PFLAG; + break; + case 's': + flags |= SFLAG; + break; + case 'f': +#if defined (HAVE_DLOPEN) && defined (HAVE_DLSYM) + flags |= FFLAG; + filename = list_optarg; + break; +#else + builtin_error (_("dynamic loading not available")); + return (EX_USAGE); +#endif +#if defined (HAVE_DLCLOSE) + case 'd': + flags |= DFLAG; + break; +#else + builtin_error (_("dynamic loading not available")); + return (EX_USAGE); +#endif /* HAVE_DLCLOSE */ + CASE_HELPOPT; + default: + builtin_usage (); + return (EX_USAGE); + } + } + + list = loptend; + +#if defined (RESTRICTED_SHELL) + /* Restricted shells cannot load new builtins. */ + if (restricted && (flags & (FFLAG|DFLAG))) + { + sh_restricted ((char *)NULL); + return (EXECUTION_FAILURE); + } +#endif + + if (list == 0 || (flags & PFLAG)) + { + filter = (flags & AFLAG) ? (ENABLED | DISABLED) + : (flags & NFLAG) ? DISABLED : ENABLED; + + if (flags & SFLAG) + filter |= SPECIAL; + + list_some_builtins (filter); + } +#if defined (HAVE_DLOPEN) && defined (HAVE_DLSYM) + else if (flags & FFLAG) + { + filter = (flags & NFLAG) ? DISABLED : ENABLED; + if (flags & SFLAG) + filter |= SPECIAL; + + result = dyn_load_builtin (list, filter, filename); +#if defined (PROGRAMMABLE_COMPLETION) + set_itemlist_dirty (&it_builtins); +#endif + } +#endif +#if defined (HAVE_DLCLOSE) + else if (flags & DFLAG) + { + while (list) + { + opt = dyn_unload_builtin (list->word->word); + if (opt == EXECUTION_FAILURE) + result = EXECUTION_FAILURE; + list = list->next; + } +#if defined (PROGRAMMABLE_COMPLETION) + set_itemlist_dirty (&it_builtins); +#endif + } +#endif + else + { + while (list) + { + opt = enable_shell_command (list->word->word, flags & NFLAG); + + if (opt == EXECUTION_FAILURE) + { + sh_notbuiltin (list->word->word); + result = EXECUTION_FAILURE; + } + list = list->next; + } + } + return (result); +} + +/* List some builtins. + FILTER is a mask with two slots: ENABLED and DISABLED. */ +static void +list_some_builtins (filter) + int filter; +{ + register int i; + + for (i = 0; i < num_shell_builtins; i++) + { + if (shell_builtins[i].function == 0 || (shell_builtins[i].flags & BUILTIN_DELETED)) + continue; + + if ((filter & SPECIAL) && + (shell_builtins[i].flags & SPECIAL_BUILTIN) == 0) + continue; + + if ((filter & ENABLED) && (shell_builtins[i].flags & BUILTIN_ENABLED)) + printf ("enable %s\n", shell_builtins[i].name); + else if ((filter & DISABLED) && + ((shell_builtins[i].flags & BUILTIN_ENABLED) == 0)) + printf ("enable -n %s\n", shell_builtins[i].name); + } +} + +/* Enable the shell command NAME. If DISABLE_P is non-zero, then + disable NAME instead. */ +static int +enable_shell_command (name, disable_p) + char *name; + int disable_p; +{ + struct builtin *b; + + b = builtin_address_internal (name, 1); + if (b == 0) + return (EXECUTION_FAILURE); + + if (disable_p) + b->flags &= ~BUILTIN_ENABLED; +#if defined (RESTRICTED_SHELL) + else if (restricted && ((b->flags & BUILTIN_ENABLED) == 0)) + { + sh_restricted ((char *)NULL); + return (EXECUTION_FAILURE); + } +#endif + else + b->flags |= BUILTIN_ENABLED; + +#if defined (PROGRAMMABLE_COMPLETION) + set_itemlist_dirty (&it_enabled); + set_itemlist_dirty (&it_disabled); +#endif + + return (EXECUTION_SUCCESS); +} + +#if defined (HAVE_DLOPEN) && defined (HAVE_DLSYM) + +#if defined (HAVE_DLFCN_H) +# include +#endif + +static int +dyn_load_builtin (list, flags, filename) + WORD_LIST *list; + int flags; + char *filename; +{ + WORD_LIST *l; + void *handle; + + int total, size, new, replaced, r; + char *struct_name, *name, *funcname; + sh_load_func_t *loadfunc; + struct builtin **new_builtins, *b, *new_shell_builtins, *old_builtin; + char *loadables_path, *load_path; + + if (list == 0) + return (EXECUTION_FAILURE); + +#ifndef RTLD_LAZY +#define RTLD_LAZY 1 +#endif + + handle = 0; + if (absolute_program (filename) == 0) + { + loadables_path = get_string_value ("BASH_LOADABLES_PATH"); + if (loadables_path) + { + load_path = find_in_path (filename, loadables_path, FS_NODIRS|FS_EXEC_PREFERRED); + if (load_path) + { +#if defined (_AIX) + handle = dlopen (load_path, RTLD_NOW|RTLD_GLOBAL); +#else + handle = dlopen (load_path, RTLD_LAZY); +#endif /* !_AIX */ + free (load_path); + } + } + } + + /* Fall back to current directory for now */ + if (handle == 0) +#if defined (_AIX) + handle = dlopen (filename, RTLD_NOW|RTLD_GLOBAL); +#else + handle = dlopen (filename, RTLD_LAZY); +#endif /* !_AIX */ + + if (handle == 0) + { + name = printable_filename (filename, 0); + builtin_error (_("cannot open shared object %s: %s"), name, dlerror ()); + if (name != filename) + free (name); + return (EXECUTION_FAILURE); + } + + for (new = 0, l = list; l; l = l->next, new++) + ; + new_builtins = (struct builtin **)xmalloc (new * sizeof (struct builtin *)); + + /* For each new builtin in the shared object, find it and its describing + structure. If this is overwriting an existing builtin, do so, otherwise + save the loaded struct for creating the new list of builtins. */ + for (replaced = new = 0; list; list = list->next) + { + name = list->word->word; + + size = strlen (name); + struct_name = (char *)xmalloc (size + 8); + strcpy (struct_name, name); + strcpy (struct_name + size, STRUCT_SUFFIX); + + old_builtin = builtin_address_internal (name, 1); + + b = (struct builtin *)dlsym (handle, struct_name); + if (b == 0) + { + name = printable_filename (filename, 0); + builtin_error (_("cannot find %s in shared object %s: %s"), + struct_name, name, dlerror ()); + if (name != filename) + free (name); + free (struct_name); + continue; + } + + funcname = xrealloc (struct_name, size + sizeof (LOAD_SUFFIX) + 1); + strcpy (funcname, name); + strcpy (funcname + size, LOAD_SUFFIX); + + loadfunc = (sh_load_func_t *)dlsym (handle, funcname); + if (loadfunc) + { + /* Add warning if running an init function more than once */ + if (old_builtin && (old_builtin->flags & STATIC_BUILTIN) == 0) + builtin_warning (_("%s: dynamic builtin already loaded"), name); + r = (*loadfunc) (name); + if (r == 0) + { + builtin_error (_("load function for %s returns failure (%d): not loaded"), name, r); + free (funcname); + continue; + } + } + free (funcname); + + b->flags &= ~STATIC_BUILTIN; + if (flags & SPECIAL) + b->flags |= SPECIAL_BUILTIN; + b->handle = handle; + + if (old_builtin) + { + replaced++; + FASTCOPY ((char *)b, (char *)old_builtin, sizeof (struct builtin)); + } + else + new_builtins[new++] = b; + } + + if (replaced == 0 && new == 0) + { + free (new_builtins); + dlclose (handle); + return (EXECUTION_FAILURE); + } + + if (new) + { + total = num_shell_builtins + new; + size = (total + 1) * sizeof (struct builtin); + + new_shell_builtins = (struct builtin *)xmalloc (size); + FASTCOPY ((char *)shell_builtins, (char *)new_shell_builtins, + num_shell_builtins * sizeof (struct builtin)); + for (replaced = 0; replaced < new; replaced++) + FASTCOPY ((char *)new_builtins[replaced], + (char *)&new_shell_builtins[num_shell_builtins + replaced], + sizeof (struct builtin)); + + new_shell_builtins[total].name = (char *)0; + new_shell_builtins[total].function = (sh_builtin_func_t *)0; + new_shell_builtins[total].flags = 0; + + if (shell_builtins != static_shell_builtins) + free (shell_builtins); + + shell_builtins = new_shell_builtins; + num_shell_builtins = total; + initialize_shell_builtins (); + } + + free (new_builtins); + return (EXECUTION_SUCCESS); +} +#endif + +#if defined (HAVE_DLCLOSE) +static void +delete_builtin (b) + struct builtin *b; +{ + int ind, size; + struct builtin *new_shell_builtins; + + /* XXX - funky pointer arithmetic - XXX */ +#ifdef __STDC__ + ind = b - shell_builtins; +#else + ind = ((int)b - (int)shell_builtins) / sizeof (struct builtin); +#endif + size = num_shell_builtins * sizeof (struct builtin); + new_shell_builtins = (struct builtin *)xmalloc (size); + + /* Copy shell_builtins[0]...shell_builtins[ind - 1] to new_shell_builtins */ + if (ind) + FASTCOPY ((char *)shell_builtins, (char *)new_shell_builtins, + ind * sizeof (struct builtin)); + /* Copy shell_builtins[ind+1]...shell_builtins[num_shell_builtins to + new_shell_builtins, starting at ind. */ + FASTCOPY ((char *)(&shell_builtins[ind+1]), + (char *)(&new_shell_builtins[ind]), + (num_shell_builtins - ind) * sizeof (struct builtin)); + + if (shell_builtins != static_shell_builtins) + free (shell_builtins); + + /* The result is still sorted. */ + num_shell_builtins--; + shell_builtins = new_shell_builtins; +} + +/* Tenon's MachTen has a dlclose that doesn't return a value, so we + finesse it with a local wrapper. */ +static int +local_dlclose (handle) + void *handle; +{ +#if !defined (__MACHTEN__) + return (dlclose (handle)); +#else /* __MACHTEN__ */ + dlclose (handle); + return ((dlerror () != NULL) ? -1 : 0); +#endif /* __MACHTEN__ */ +} + +static int +dyn_unload_builtin (name) + char *name; +{ + struct builtin *b; + void *handle; + char *funcname; + sh_unload_func_t *unloadfunc; + int ref, i, size; + + b = builtin_address_internal (name, 1); + if (b == 0) + { + sh_notbuiltin (name); + return (EXECUTION_FAILURE); + } + if (b->flags & STATIC_BUILTIN) + { + builtin_error (_("%s: not dynamically loaded"), name); + return (EXECUTION_FAILURE); + } + + handle = (void *)b->handle; + for (ref = i = 0; i < num_shell_builtins; i++) + { + if (shell_builtins[i].handle == b->handle) + ref++; + } + + /* Call any unload function */ + size = strlen (name); + funcname = xmalloc (size + sizeof (UNLOAD_SUFFIX) + 1); + strcpy (funcname, name); + strcpy (funcname + size, UNLOAD_SUFFIX); + + unloadfunc = (sh_unload_func_t *)dlsym (handle, funcname); + if (unloadfunc) + (*unloadfunc) (name); /* void function */ + free (funcname); + + /* Don't remove the shared object unless the reference count of builtins + using it drops to zero. */ + if (ref == 1 && local_dlclose (handle) != 0) + { + builtin_error (_("%s: cannot delete: %s"), name, dlerror ()); + return (EXECUTION_FAILURE); + } + + /* Now remove this entry from the builtin table and reinitialize. */ + delete_builtin (b); + + return (EXECUTION_SUCCESS); +} +#endif diff --git a/builtins/eval.c b/builtins/eval.c new file mode 100644 index 0000000..e370677 --- /dev/null +++ b/builtins/eval.c @@ -0,0 +1,28 @@ +/* eval.c, created from eval.def. */ +#line 22 "./eval.def" + +#line 34 "./eval.def" + +#include +#if defined (HAVE_UNISTD_H) +# ifdef _MINIX +# include +# endif +# include +#endif + +#include "../shell.h" +#include "bashgetopt.h" +#include "common.h" + +/* Parse the string that these words make, and execute the command found. */ +int +eval_builtin (list) + WORD_LIST *list; +{ + if (no_options (list)) + return (EX_USAGE); + list = loptend; /* skip over possible `--' */ + + return (list ? evalstring (string_list (list), "eval", SEVAL_NOHIST) : EXECUTION_SUCCESS); +} diff --git a/builtins/exec.c b/builtins/exec.c new file mode 100644 index 0000000..7d01cfd --- /dev/null +++ b/builtins/exec.c @@ -0,0 +1,235 @@ +/* exec.c, created from exec.def. */ +#line 22 "./exec.def" + +#line 43 "./exec.def" + +#include + +#include "../bashtypes.h" +#include "posixstat.h" +#include +#include + +#if defined (HAVE_UNISTD_H) +# include +#endif + +#include + +#include "../bashansi.h" +#include "../bashintl.h" + +#include "../shell.h" +#include "../execute_cmd.h" +#include "../findcmd.h" +#if defined (JOB_CONTROL) +# include "../jobs.h" +#endif +#include "../flags.h" +#include "../trap.h" +#if defined (HISTORY) +# include "../bashhist.h" +#endif +#include "common.h" +#include "bashgetopt.h" +#include "input.h" + +/* Not all systems declare ERRNO in errno.h... and some systems #define it! */ +#if !defined (errno) +extern int errno; +#endif /* !errno */ + +extern REDIRECT *redirection_undo_list; +extern char *exec_argv0; + +int no_exit_on_failed_exec; + +/* If the user wants this to look like a login shell, then + prepend a `-' onto NAME and return the new name. */ +static char * +mkdashname (name) + char *name; +{ + char *ret; + + ret = (char *)xmalloc (2 + strlen (name)); + ret[0] = '-'; + strcpy (ret + 1, name); + return ret; +} + +int +exec_builtin (list) + WORD_LIST *list; +{ + int exit_value = EXECUTION_FAILURE; + int cleanenv, login, opt, orig_job_control; + char *argv0, *command, **args, **env, *newname, *com2; + + cleanenv = login = 0; + exec_argv0 = argv0 = (char *)NULL; + + reset_internal_getopt (); + while ((opt = internal_getopt (list, "cla:")) != -1) + { + switch (opt) + { + case 'c': + cleanenv = 1; + break; + case 'l': + login = 1; + break; + case 'a': + argv0 = list_optarg; + break; + CASE_HELPOPT; + default: + builtin_usage (); + return (EX_USAGE); + } + } + list = loptend; + + /* First, let the redirections remain. */ + dispose_redirects (redirection_undo_list); + redirection_undo_list = (REDIRECT *)NULL; + + if (list == 0) + return (EXECUTION_SUCCESS); + +#if defined (RESTRICTED_SHELL) + if (restricted) + { + sh_restricted ((char *)NULL); + return (EXECUTION_FAILURE); + } +#endif /* RESTRICTED_SHELL */ + + args = strvec_from_word_list (list, 1, 0, (int *)NULL); + env = (char **)0; + + /* A command with a slash anywhere in its name is not looked up in $PATH. */ + command = absolute_program (args[0]) ? args[0] : search_for_command (args[0], 1); + + if (command == 0) + { + if (file_isdir (args[0])) + { +#if defined (EISDIR) + builtin_error (_("%s: cannot execute: %s"), args[0], strerror (EISDIR)); +#else + builtin_error (_("%s: cannot execute: %s"), args[0], strerror (errno)); +#endif + exit_value = EX_NOEXEC; + } + else + { + sh_notfound (args[0]); + exit_value = EX_NOTFOUND; /* As per Posix.2, 3.14.6 */ + } + goto failed_exec; + } + + com2 = full_pathname (command); + if (com2) + { + if (command != args[0]) + free (command); + command = com2; + } + + if (argv0) + { + free (args[0]); + args[0] = login ? mkdashname (argv0) : savestring (argv0); + exec_argv0 = savestring (args[0]); + } + else if (login) + { + newname = mkdashname (args[0]); + free (args[0]); + args[0] = newname; + } + + /* Decrement SHLVL by 1 so a new shell started here has the same value, + preserving the appearance. After we do that, we need to change the + exported environment to include the new value. If we've already forked + and are in a subshell, we don't want to decrement the shell level, + since we are `increasing' the level */ + + if (cleanenv == 0 && (subshell_environment & SUBSHELL_PAREN) == 0) + adjust_shell_level (-1); + + if (cleanenv) + { + env = strvec_create (1); + env[0] = (char *)0; + } + else + { + maybe_make_export_env (); + env = export_env; + } + +#if defined (HISTORY) + if (interactive_shell && subshell_environment == 0) + maybe_save_shell_history (); +#endif /* HISTORY */ + + restore_original_signals (); + +#if defined (JOB_CONTROL) + orig_job_control = job_control; /* XXX - was also interactive_shell */ + if (subshell_environment == 0) + end_job_control (); + if (interactive || job_control) + default_tty_job_signals (); /* undo initialize_job_signals */ +#endif /* JOB_CONTROL */ + +#if defined (BUFFERED_INPUT) + if (default_buffered_input >= 0) + sync_buffered_stream (default_buffered_input); +#endif + + exit_value = shell_execve (command, args, env); + + /* We have to set this to NULL because shell_execve has called realloc() + to stuff more items at the front of the array, which may have caused + the memory to be freed by realloc(). We don't want to free it twice. */ + args = (char **)NULL; + if (cleanenv == 0) + adjust_shell_level (1); + + if (exit_value == EX_NOTFOUND) /* no duplicate error message */ + goto failed_exec; + else if (executable_file (command) == 0) + { + builtin_error (_("%s: cannot execute: %s"), command, strerror (errno)); + exit_value = EX_NOEXEC; /* As per Posix.2, 3.14.6 */ + } + else + file_error (command); + +failed_exec: + FREE (command); + + if (subshell_environment || (interactive == 0 && no_exit_on_failed_exec == 0)) + exit_shell (exit_value); + + if (args) + strvec_dispose (args); + + if (env && env != export_env) + strvec_dispose (env); + + initialize_traps (); + initialize_signals (1); + +#if defined (JOB_CONTROL) + if (orig_job_control) + restart_job_control (); +#endif /* JOB_CONTROL */ + + return (exit_value); +} diff --git a/builtins/exit.c b/builtins/exit.c new file mode 100644 index 0000000..4a6b3a2 --- /dev/null +++ b/builtins/exit.c @@ -0,0 +1,136 @@ +/* exit.c, created from exit.def. */ +#line 22 "./exit.def" + +#line 31 "./exit.def" + +#include + +#include "../bashtypes.h" +#include + +#if defined (HAVE_UNISTD_H) +# include +#endif + +#include "../bashintl.h" + +#include "../shell.h" +#include "../execute_cmd.h" +#include "../jobs.h" +#include "../trap.h" + +#include "common.h" +#include "builtext.h" /* for jobs_builtin */ + +extern int check_jobs_at_exit; + +static int exit_or_logout PARAMS((WORD_LIST *)); +static int sourced_logout; + +int +exit_builtin (list) + WORD_LIST *list; +{ + CHECK_HELPOPT (list); + + if (interactive) + { + fprintf (stderr, login_shell ? _("logout\n") : "exit\n"); + fflush (stderr); + } + + return (exit_or_logout (list)); +} + +#line 79 "./exit.def" + +/* How to logout. */ +int +logout_builtin (list) + WORD_LIST *list; +{ + CHECK_HELPOPT (list); + + if (login_shell == 0 /* && interactive */) + { + builtin_error (_("not login shell: use `exit'")); + return (EXECUTION_FAILURE); + } + else + return (exit_or_logout (list)); +} + +static int +exit_or_logout (list) + WORD_LIST *list; +{ + int exit_value; + +#if defined (JOB_CONTROL) + int exit_immediate_okay, stopmsg; + + exit_immediate_okay = (interactive == 0 || + last_shell_builtin == exit_builtin || + last_shell_builtin == logout_builtin || + last_shell_builtin == jobs_builtin); + + /* Check for stopped jobs if the user wants to. */ + if (exit_immediate_okay == 0) + { + register int i; + for (i = stopmsg = 0; i < js.j_jobslots; i++) + if (jobs[i] && STOPPED (i)) + stopmsg = JSTOPPED; + else if (check_jobs_at_exit && stopmsg == 0 && jobs[i] && RUNNING (i)) + stopmsg = JRUNNING; + + if (stopmsg == JSTOPPED) + fprintf (stderr, _("There are stopped jobs.\n")); + else if (stopmsg == JRUNNING) + fprintf (stderr, _("There are running jobs.\n")); + + if (stopmsg && check_jobs_at_exit) + list_all_jobs (JLIST_STANDARD); + + if (stopmsg) + { + /* This is NOT superfluous because EOF can get here without + going through the command parser. Set both last and this + so that either `exit', `logout', or ^D will work to exit + immediately if nothing intervenes. */ + this_shell_builtin = last_shell_builtin = exit_builtin; + return (EXECUTION_FAILURE); + } + } +#endif /* JOB_CONTROL */ + + /* Get return value if present. This means that you can type + `logout 5' to a shell, and it returns 5. */ + + /* If we're running the exit trap (running_trap == 1, since running_trap + gets set to SIG+1), and we don't have a argument given to `exit' + (list == 0), use the exit status we saved before running the trap + commands (trap_saved_exit_value). */ + exit_value = (running_trap == 1 && list == 0) ? trap_saved_exit_value : get_exitstat (list); + + bash_logout (); + + last_command_exit_value = exit_value; + + /* Exit the program. */ + jump_to_top_level (EXITPROG); + /*NOTREACHED*/ +} + +void +bash_logout () +{ + /* Run our `~/.bash_logout' file if it exists, and this is a login shell. */ + if (login_shell && sourced_logout++ == 0 && subshell_environment == 0) + { + maybe_execute_file ("~/.bash_logout", 1); +#ifdef SYS_BASH_LOGOUT + maybe_execute_file (SYS_BASH_LOGOUT, 1); +#endif + } +} diff --git a/builtins/fc.c b/builtins/fc.c new file mode 100644 index 0000000..50771cc --- /dev/null +++ b/builtins/fc.c @@ -0,0 +1,736 @@ +/* fc.c, created from fc.def. */ +#line 22 "./fc.def" + +#line 51 "./fc.def" + +#include + +#if defined (HISTORY) +#if defined (HAVE_SYS_PARAM_H) +# include +#endif +#include "../bashtypes.h" +#include "posixstat.h" +#if ! defined(_MINIX) && defined (HAVE_SYS_FILE_H) +# include +#endif + +#if defined (HAVE_UNISTD_H) +# include +#endif + +#include +#include + +#include "../bashansi.h" +#include "../bashintl.h" +#include + +#include "../shell.h" +#include "../builtins.h" +#include "../flags.h" +#include "../parser.h" +#include "../bashhist.h" +#include "maxpath.h" +#include +#include "bashgetopt.h" +#include "common.h" + +#if !defined (errno) +extern int errno; +#endif /* !errno */ + +#define HIST_INVALID INT_MIN +#define HIST_ERANGE INT_MIN+1 +#define HIST_NOTFOUND INT_MIN+2 + +/* Values for the flags argument to fc_gethnum */ +#define HN_LISTING 0x01 +#define HN_FIRST 0x02 + +extern int unlink PARAMS((const char *)); + +extern FILE *sh_mktmpfp PARAMS((char *, int, char **)); + +extern int suppress_debug_trap_verbose; + +/* **************************************************************** */ +/* */ +/* The K*rn shell style fc command (Fix Command) */ +/* */ +/* **************************************************************** */ + +/* fc builtin command (fix command) for Bash for those who + like K*rn-style history better than csh-style. + + fc [-e ename] [-nlr] [first] [last] + + FIRST and LAST can be numbers specifying the range, or FIRST can be + a string, which means the most recent command beginning with that + string. + + -e ENAME selects which editor to use. Default is FCEDIT, then EDITOR, + then the editor which corresponds to the current readline editing + mode, then vi. + + -l means list lines instead of editing. + -n means no line numbers listed. + -r means reverse the order of the lines (making it newest listed first). + + fc -e - [pat=rep ...] [command] + fc -s [pat=rep ...] [command] + + Equivalent to !command:sg/pat/rep execpt there can be multiple PAT=REP's. +*/ + +/* Data structure describing a list of global replacements to perform. */ +typedef struct repl { + struct repl *next; + char *pat; + char *rep; +} REPL; + +/* Accessors for HIST_ENTRY lists that are called HLIST. */ +#define histline(i) (hlist[(i)]->line) +#define histdata(i) (hlist[(i)]->data) + +#define FREE_RLIST() \ + do { \ + for (rl = rlist; rl; ) { \ + REPL *r; \ + r = rl->next; \ + if (rl->pat) \ + free (rl->pat); \ + if (rl->rep) \ + free (rl->rep); \ + free (rl); \ + rl = r; \ + } \ + } while (0) + +static char *fc_dosubs PARAMS((char *, REPL *)); +static char *fc_gethist PARAMS((char *, HIST_ENTRY **, int)); +static int fc_gethnum PARAMS((char *, HIST_ENTRY **, int)); +static int fc_number PARAMS((WORD_LIST *)); +static void fc_replhist PARAMS((char *)); +#ifdef INCLUDE_UNUSED +static char *fc_readline PARAMS((FILE *)); +static void fc_addhist PARAMS((char *)); +#endif + +static void +set_verbose_flag () +{ + echo_input_at_read = verbose_flag; +} + +/* String to execute on a file that we want to edit. */ +#define FC_EDIT_COMMAND "${FCEDIT:-${EDITOR:-vi}}" +#if defined (STRICT_POSIX) +# define POSIX_FC_EDIT_COMMAND "${FCEDIT:-ed}" +#else +# define POSIX_FC_EDIT_COMMAND "${FCEDIT:-${EDITOR:-ed}}" +#endif + +int +fc_builtin (list) + WORD_LIST *list; +{ + register int i; + register char *sep; + int numbering, reverse, listing, execute; + int histbeg, histend, last_hist, retval, opt, rh, real_last; + FILE *stream; + REPL *rlist, *rl; + char *ename, *command, *newcom, *fcedit; + HIST_ENTRY **hlist; + char *fn; + + numbering = 1; + reverse = listing = execute = 0; + ename = (char *)NULL; + + /* Parse out the options and set which of the two forms we're in. */ + reset_internal_getopt (); + lcurrent = list; /* XXX */ + while (fc_number (loptend = lcurrent) == 0 && + (opt = internal_getopt (list, ":e:lnrs")) != -1) + { + switch (opt) + { + case 'n': + numbering = 0; + break; + + case 'l': + listing = HN_LISTING; /* for fc_gethnum */ + break; + + case 'r': + reverse = 1; + break; + + case 's': + execute = 1; + break; + + case 'e': + ename = list_optarg; + break; + + CASE_HELPOPT; + default: + builtin_usage (); + return (EX_USAGE); + } + } + + list = loptend; + + if (ename && (*ename == '-') && (ename[1] == '\0')) + execute = 1; + + /* The "execute" form of the command (re-run, with possible string + substitutions). */ + if (execute) + { + rlist = (REPL *)NULL; + while (list && ((sep = (char *)strchr (list->word->word, '=')) != NULL)) + { + *sep++ = '\0'; + rl = (REPL *)xmalloc (sizeof (REPL)); + rl->next = (REPL *)NULL; + rl->pat = savestring (list->word->word); + rl->rep = savestring (sep); + + if (rlist == NULL) + rlist = rl; + else + { + rl->next = rlist; + rlist = rl; + } + list = list->next; + } + + /* If we have a list of substitutions to do, then reverse it + to get the replacements in the proper order. */ + + rlist = REVERSE_LIST (rlist, REPL *); + + hlist = history_list (); + + /* If we still have something in list, it is a command spec. + Otherwise, we use the most recent command in time. */ + command = fc_gethist (list ? list->word->word : (char *)NULL, hlist, 0); + + if (command == NULL) + { + builtin_error (_("no command found")); + if (rlist) + FREE_RLIST (); + + return (EXECUTION_FAILURE); + } + + if (rlist) + { + newcom = fc_dosubs (command, rlist); + free (command); + FREE_RLIST (); + command = newcom; + } + + fprintf (stderr, "%s\n", command); + fc_replhist (command); /* replace `fc -s' with command */ + /* Posix says that the re-executed commands should be entered into the + history. */ + return (parse_and_execute (command, "fc", SEVAL_NOHIST)); + } + + /* This is the second form of the command (the list-or-edit-and-rerun + form). */ + hlist = history_list (); + if (hlist == 0) + return (EXECUTION_SUCCESS); + for (i = 0; hlist[i]; i++); + + /* With the Bash implementation of history, the current command line + ("fc blah..." and so on) is already part of the history list by + the time we get to this point. This just skips over that command + and makes the last command that this deals with be the last command + the user entered before the fc. We need to check whether the + line was actually added (HISTIGNORE may have caused it to not be), + so we check hist_last_line_added. */ + + /* Even though command substitution through parse_and_execute turns off + remember_on_history, command substitution in a shell when set -o history + has been enabled (interactive or not) should use it in the last_hist + calculation as if it were on. */ + rh = remember_on_history || ((subshell_environment & SUBSHELL_COMSUB) && enable_history_list); + last_hist = i - rh - hist_last_line_added; + + /* Make sure that real_last is calculated the same way here and in + fc_gethnum. The return value from fc_gethnum is treated specially if + it is == real_last and we are listing commands. */ + real_last = i; + /* back up from the end to the last non-null history entry */ + while (hlist[real_last] == 0 && real_last > 0) + real_last--; + + /* XXX */ + if (i == last_hist && hlist[last_hist] == 0) + while (last_hist >= 0 && hlist[last_hist] == 0) + last_hist--; + if (last_hist < 0) + last_hist = 0; /* per POSIX */ + + if (list) + { + histbeg = fc_gethnum (list->word->word, hlist, listing|HN_FIRST); + list = list->next; + + if (list) + histend = fc_gethnum (list->word->word, hlist, listing); + else if (histbeg == real_last) + histend = listing ? real_last : histbeg; + else + histend = listing ? last_hist : histbeg; + } + else + { + /* The default for listing is the last 16 history items. */ + if (listing) + { + histend = last_hist; + histbeg = histend - 16 + 1; /* +1 because loop below uses >= */ + if (histbeg < 0) + histbeg = 0; + } + else + /* For editing, it is the last history command. */ + histbeg = histend = last_hist; + } + + if (histbeg == HIST_INVALID || histend == HIST_INVALID) + { + sh_erange ((char *)NULL, _("history specification")); + return (EXECUTION_FAILURE); + } + else if (histbeg == HIST_ERANGE || histend == HIST_ERANGE) + { + sh_erange ((char *)NULL, _("history specification")); + return (EXECUTION_FAILURE); + } + else if (histbeg == HIST_NOTFOUND || histend == HIST_NOTFOUND) + { + builtin_error (_("no command found")); + return (EXECUTION_FAILURE); + } + + /* We don't throw an error for line specifications out of range, per POSIX */ + if (histbeg < 0) + histbeg = 0; + if (histend < 0) + histend = 0; + + /* "When not listing, the fc command that caused the editing shall not be + entered into the history list." */ + if (listing == 0 && hist_last_line_added) + { + bash_delete_last_history (); + /* If we're editing a single command -- the last command in the + history -- and we just removed the dummy command added by + edit_and_execute_command (), we need to check whether or not we + just removed the last command in the history and need to back + the pointer up. remember_on_history is off because we're running + in parse_and_execute(). */ + if (histbeg == histend && histend == last_hist && hlist[last_hist] == 0) + last_hist = histbeg = --histend; + + if (hlist[last_hist] == 0) + last_hist--; + if (histend >= last_hist) + histend = last_hist; + else if (histbeg >= last_hist) + histbeg = last_hist; + } + + if (histbeg == HIST_INVALID || histend == HIST_INVALID) + { + sh_erange ((char *)NULL, _("history specification")); + return (EXECUTION_FAILURE); + } + else if (histbeg == HIST_ERANGE || histend == HIST_ERANGE) + { + sh_erange ((char *)NULL, _("history specification")); + return (EXECUTION_FAILURE); + } + else if (histbeg == HIST_NOTFOUND || histend == HIST_NOTFOUND) + { + builtin_error (_("no command found")); + return (EXECUTION_FAILURE); + } + + /* We don't throw an error for line specifications out of range, per POSIX */ + if (histbeg < 0) + histbeg = 0; + if (histend < 0) + histend = 0; + + if (histend < histbeg) + { + i = histend; + histend = histbeg; + histbeg = i; + + reverse = 1; + } + + if (listing) + stream = stdout; + else + { + numbering = 0; + stream = sh_mktmpfp ("bash-fc", MT_USERANDOM|MT_USETMPDIR, &fn); + if (stream == 0) + { + builtin_error (_("%s: cannot open temp file: %s"), fn ? fn : "", strerror (errno)); + FREE (fn); + return (EXECUTION_FAILURE); + } + } + + for (i = reverse ? histend : histbeg; reverse ? i >= histbeg : i <= histend; reverse ? i-- : i++) + { + QUIT; + if (numbering) + fprintf (stream, "%d", i + history_base); + if (listing) + { + if (posixly_correct) + fputs ("\t", stream); + else + fprintf (stream, "\t%c", histdata (i) ? '*' : ' '); + } + fprintf (stream, "%s\n", histline (i)); + } + + if (listing) + return (sh_chkwrite (EXECUTION_SUCCESS)); + + fflush (stream); + if (ferror (stream)) + { + sh_wrerror (); + fclose (stream); + FREE (fn); + return (EXECUTION_FAILURE); + } + fclose (stream); + + /* Now edit the file of commands. */ + if (ename) + { + command = (char *)xmalloc (strlen (ename) + strlen (fn) + 2); + sprintf (command, "%s %s", ename, fn); + } + else + { + fcedit = posixly_correct ? POSIX_FC_EDIT_COMMAND : FC_EDIT_COMMAND; + command = (char *)xmalloc (3 + strlen (fcedit) + strlen (fn)); + sprintf (command, "%s %s", fcedit, fn); + } + retval = parse_and_execute (command, "fc", SEVAL_NOHIST); + if (retval != EXECUTION_SUCCESS) + { + unlink (fn); + free (fn); + return (EXECUTION_FAILURE); + } + +#if defined (READLINE) + /* If we're executing as part of a dispatched readline command like + {emacs,vi}_edit_and_execute_command, the readline state will indicate it. + We could remove the partial command from the history, but ksh93 doesn't + so we stay compatible. */ +#endif + + /* Make sure parse_and_execute doesn't turn this off, even though a + call to parse_and_execute farther up the function call stack (e.g., + if this is called by vi_edit_and_execute_command) may have already + called bash_history_disable. */ + remember_on_history = 1; + + /* Turn on the `v' flag while fc_execute_file runs so the commands + will be echoed as they are read by the parser. */ + begin_unwind_frame ("fc builtin"); + add_unwind_protect (xfree, fn); + add_unwind_protect (unlink, fn); + add_unwind_protect (set_verbose_flag, (char *)NULL); + unwind_protect_int (suppress_debug_trap_verbose); + echo_input_at_read = 1; + suppress_debug_trap_verbose = 1; + + retval = fc_execute_file (fn); + run_unwind_frame ("fc builtin"); + + return (retval); +} + +/* Return 1 if LIST->word->word is a legal number for fc's use. */ +static int +fc_number (list) + WORD_LIST *list; +{ + char *s; + + if (list == 0) + return 0; + s = list->word->word; + if (*s == '-') + s++; + return (legal_number (s, (intmax_t *)NULL)); +} + +/* Return an absolute index into HLIST which corresponds to COMMAND. If + COMMAND is a number, then it was specified in relative terms. If it + is a string, then it is the start of a command line present in HLIST. + MODE includes HN_LISTING if we are listing commands, and does not if we + are executing them. If MODE includes HN_FIRST we are looking for the + first history number specification. */ +static int +fc_gethnum (command, hlist, mode) + char *command; + HIST_ENTRY **hlist; + int mode; +{ + int sign, n, clen, rh; + register int i, j, last_hist, real_last, listing; + register char *s; + + listing = mode & HN_LISTING; + sign = 1; + /* Count history elements. */ + for (i = 0; hlist[i]; i++); + + /* With the Bash implementation of history, the current command line + ("fc blah..." and so on) is already part of the history list by + the time we get to this point. This just skips over that command + and makes the last command that this deals with be the last command + the user entered before the fc. We need to check whether the + line was actually added (HISTIGNORE may have caused it to not be), + so we check hist_last_line_added. This needs to agree with the + calculation of last_hist in fc_builtin above. */ + /* Even though command substitution through parse_and_execute turns off + remember_on_history, command substitution in a shell when set -o history + has been enabled (interactive or not) should use it in the last_hist + calculation as if it were on. */ + rh = remember_on_history || ((subshell_environment & SUBSHELL_COMSUB) && enable_history_list); + last_hist = i - rh - hist_last_line_added; + + if (i == last_hist && hlist[last_hist] == 0) + while (last_hist >= 0 && hlist[last_hist] == 0) + last_hist--; + if (last_hist < 0) + return (-1); + + real_last = i; + i = last_hist; + + /* No specification defaults to most recent command. */ + if (command == NULL) + return (i); + + /* back up from the end to the last non-null history entry */ + while (hlist[real_last] == 0 && real_last > 0) + real_last--; + + /* Otherwise, there is a specification. It can be a number relative to + the current position, or an absolute history number. */ + s = command; + + /* Handle possible leading minus sign. */ + if (s && (*s == '-')) + { + sign = -1; + s++; + } + + if (s && DIGIT(*s)) + { + n = atoi (s); + n *= sign; + + /* We want to return something that is an offset to HISTORY_BASE. */ + + /* If the value is negative or zero, then it is an offset from + the current history item. */ + /* We don't use HN_FIRST here, so we don't return different values + depending on whether we're looking for the first or last in a + pair of range arguments, but nobody else does, either. */ + if (n < 0) + { + n += i + 1; + return (n < 0 ? 0 : n); + } + else if (n == 0) + return ((sign == -1) ? (listing ? real_last : HIST_INVALID) : i); + else + { + /* If we're out of range (greater than I (last history entry) or + less than HISTORY_BASE, we want to return different values + based on whether or not we are looking for the first or last + value in a desired range of history entries. */ + n -= history_base; + if (n < 0) + return (mode & HN_FIRST ? 0 : i); + else if (n >= i) + return (mode & HN_FIRST ? 0 : i); + else + return n; + } + } + + clen = strlen (command); + for (j = i; j >= 0; j--) + { + if (STREQN (command, histline (j), clen)) + return (j); + } + return (HIST_NOTFOUND); +} + +/* Locate the most recent history line which begins with + COMMAND in HLIST, and return a malloc()'ed copy of it. + MODE is 1 if we are listing commands, 0 if we are executing them. */ +static char * +fc_gethist (command, hlist, mode) + char *command; + HIST_ENTRY **hlist; + int mode; +{ + int i; + + if (hlist == 0) + return ((char *)NULL); + + i = fc_gethnum (command, hlist, mode); + + if (i >= 0) + return (savestring (histline (i))); + else + return ((char *)NULL); +} + +#ifdef INCLUDE_UNUSED +/* Read the edited history lines from STREAM and return them + one at a time. This can read unlimited length lines. The + caller should free the storage. */ +static char * +fc_readline (stream) + FILE *stream; +{ + register int c; + int line_len = 0, lindex = 0; + char *line = (char *)NULL; + + while ((c = getc (stream)) != EOF) + { + if ((lindex + 2) >= line_len) + line = (char *)xrealloc (line, (line_len += 128)); + + if (c == '\n') + { + line[lindex++] = '\n'; + line[lindex++] = '\0'; + return (line); + } + else + line[lindex++] = c; + } + + if (!lindex) + { + if (line) + free (line); + + return ((char *)NULL); + } + + if (lindex + 2 >= line_len) + line = (char *)xrealloc (line, lindex + 3); + + line[lindex++] = '\n'; /* Finish with newline if none in file */ + line[lindex++] = '\0'; + return (line); +} +#endif + +/* Perform the SUBS on COMMAND. + SUBS is a list of substitutions, and COMMAND is a simple string. + Return a pointer to a malloc'ed string which contains the substituted + command. */ +static char * +fc_dosubs (command, subs) + char *command; + REPL *subs; +{ + register char *new, *t; + register REPL *r; + + for (new = savestring (command), r = subs; r; r = r->next) + { + t = strsub (new, r->pat, r->rep, 1); + free (new); + new = t; + } + return (new); +} + +/* Use `command' to replace the last entry in the history list, which, + by this time, is `fc blah...'. The intent is that the new command + become the history entry, and that `fc' should never appear in the + history list. This way you can do `r' to your heart's content. */ +static void +fc_replhist (command) + char *command; +{ + int n; + + if (command == 0 || *command == '\0') + return; + + n = strlen (command); + if (command[n - 1] == '\n') + command[n - 1] = '\0'; + + if (command && *command) + { + bash_delete_last_history (); + maybe_add_history (command); /* Obeys HISTCONTROL setting. */ + } +} + +#ifdef INCLUDE_UNUSED +/* Add LINE to the history, after removing a single trailing newline. */ +static void +fc_addhist (line) + char *line; +{ + register int n; + + if (line == 0 || *line == 0) + return; + + n = strlen (line); + + if (line[n - 1] == '\n') + line[n - 1] = '\0'; + + if (line && *line) + maybe_add_history (line); /* Obeys HISTCONTROL setting. */ +} +#endif + +#endif /* HISTORY */ diff --git a/builtins/fg_bg.c b/builtins/fg_bg.c new file mode 100644 index 0000000..837feba --- /dev/null +++ b/builtins/fg_bg.c @@ -0,0 +1,146 @@ +/* fg_bg.c, created from fg_bg.def. */ +#line 22 "./fg_bg.def" + +#line 36 "./fg_bg.def" + +#include + +#include "../bashtypes.h" +#include + +#if defined (HAVE_UNISTD_H) +# include +#endif + +#include "../bashintl.h" + +#include "../shell.h" +#include "../execute_cmd.h" +#include "../jobs.h" +#include "common.h" +#include "bashgetopt.h" + +#if defined (JOB_CONTROL) +static int fg_bg PARAMS((WORD_LIST *, int)); + +/* How to bring a job into the foreground. */ +int +fg_builtin (list) + WORD_LIST *list; +{ + int fg_bit; + register WORD_LIST *t; + + CHECK_HELPOPT (list); + + if (job_control == 0) + { + sh_nojobs ((char *)NULL); + return (EXECUTION_FAILURE); + } + + if (no_options (list)) + return (EX_USAGE); + list = loptend; + + /* If the last arg on the line is '&', then start this job in the + background. Else, fg the job. */ + for (t = list; t && t->next; t = t->next) + ; + fg_bit = (t && t->word->word[0] == '&' && t->word->word[1] == '\0') == 0; + + return (fg_bg (list, fg_bit)); +} +#endif /* JOB_CONTROL */ + +#line 100 "./fg_bg.def" + +#if defined (JOB_CONTROL) +/* How to put a job into the background. */ +int +bg_builtin (list) + WORD_LIST *list; +{ + int r; + + CHECK_HELPOPT (list); + + if (job_control == 0) + { + sh_nojobs ((char *)NULL); + return (EXECUTION_FAILURE); + } + + if (no_options (list)) + return (EX_USAGE); + list = loptend; + + /* This relies on the fact that fg_bg() takes a WORD_LIST *, but only acts + on the first member (if any) of that list. */ + r = EXECUTION_SUCCESS; + do + { + if (fg_bg (list, 0) == EXECUTION_FAILURE) + r = EXECUTION_FAILURE; + if (list) + list = list->next; + } + while (list); + + return r; +} + +/* How to put a job into the foreground/background. */ +static int +fg_bg (list, foreground) + WORD_LIST *list; + int foreground; +{ + sigset_t set, oset; + int job, status, old_async_pid; + JOB *j; + + BLOCK_CHILD (set, oset); + job = get_job_spec (list); + + if (INVALID_JOB (job)) + { + if (job != DUP_JOB) + sh_badjob (list ? list->word->word : _("current")); + + goto failure; + } + + j = get_job_by_jid (job); + /* Or if j->pgrp == shell_pgrp. */ + if (IS_JOBCONTROL (job) == 0) + { + builtin_error (_("job %d started without job control"), job + 1); + goto failure; + } + + if (foreground == 0) + { + old_async_pid = last_asynchronous_pid; + last_asynchronous_pid = j->pgrp; /* As per Posix.2 5.4.2 */ + } + + status = start_job (job, foreground); + + if (status >= 0) + { + /* win: */ + UNBLOCK_CHILD (oset); + return (foreground ? status : EXECUTION_SUCCESS); + } + else + { + if (foreground == 0) + last_asynchronous_pid = old_async_pid; + + failure: + UNBLOCK_CHILD (oset); + return (EXECUTION_FAILURE); + } +} +#endif /* JOB_CONTROL */ diff --git a/builtins/getopts.c b/builtins/getopts.c new file mode 100644 index 0000000..57fba56 --- /dev/null +++ b/builtins/getopts.c @@ -0,0 +1,284 @@ +/* getopts.c, created from getopts.def. */ +#line 22 "./getopts.def" + +#line 64 "./getopts.def" + +#include + +#include + +#if defined (HAVE_UNISTD_H) +# ifdef _MINIX +# include +# endif +# include +#endif + +#include "../bashansi.h" +#include "../bashintl.h" + +#include "../shell.h" +#include "../execute_cmd.h" +#include "common.h" +#include "bashgetopt.h" +#include "getopt.h" + +#define G_EOF -1 +#define G_INVALID_OPT -2 +#define G_ARG_MISSING -3 + +static int getopts_unbind_variable PARAMS((char *)); +static int getopts_bind_variable PARAMS((char *, char *)); +static int dogetopts PARAMS((int, char **)); + +/* getopts_reset is magic code for when OPTIND is reset. N is the + value that has just been assigned to OPTIND. */ +void +getopts_reset (newind) + int newind; +{ + sh_optind = newind; + sh_badopt = 0; +} + +static int +getopts_unbind_variable (name) + char *name; +{ +#if 0 + return (unbind_variable (name)); +#else + return (unbind_variable_noref (name)); +#endif +} + +static int +getopts_bind_variable (name, value) + char *name, *value; +{ + SHELL_VAR *v; + + if (legal_identifier (name)) + { + v = bind_variable (name, value, 0); + if (v && (readonly_p (v) || noassign_p (v))) + return (EX_MISCERROR); + return (v ? EXECUTION_SUCCESS : EXECUTION_FAILURE); + } + else + { + sh_invalidid (name); + return (EXECUTION_FAILURE); + } +} + +/* Error handling is now performed as specified by Posix.2, draft 11 + (identical to that of ksh-88). The special handling is enabled if + the first character of the option string is a colon; this handling + disables diagnostic messages concerning missing option arguments + and invalid option characters. The handling is as follows. + + INVALID OPTIONS: + name -> "?" + if (special_error) then + OPTARG = option character found + no error output + else + OPTARG unset + diagnostic message + fi + + MISSING OPTION ARGUMENT; + if (special_error) then + name -> ":" + OPTARG = option character found + else + name -> "?" + OPTARG unset + diagnostic message + fi + */ + +static int +dogetopts (argc, argv) + int argc; + char **argv; +{ + int ret, special_error, old_opterr, i, n; + char strval[2], numval[16]; + char *optstr; /* list of options */ + char *name; /* variable to get flag val */ + char *t; + + if (argc < 3) + { + builtin_usage (); + return (EX_USAGE); + } + + /* argv[0] is "getopts". */ + + optstr = argv[1]; + name = argv[2]; + argc -= 2; + argv += 2; + + special_error = optstr[0] == ':'; + + if (special_error) + { + old_opterr = sh_opterr; + optstr++; + sh_opterr = 0; /* suppress diagnostic messages */ + } + + if (argc > 1) + { + sh_getopt_restore_state (argv); + t = argv[0]; + argv[0] = dollar_vars[0]; + ret = sh_getopt (argc, argv, optstr); + argv[0] = t; + } + else if (rest_of_args == (WORD_LIST *)NULL) + { + for (i = 0; i < 10 && dollar_vars[i]; i++) + ; + + sh_getopt_restore_state (dollar_vars); + ret = sh_getopt (i, dollar_vars, optstr); + } + else + { + register WORD_LIST *words; + char **v; + + i = number_of_args () + 1; /* +1 for $0 */ + v = strvec_create (i + 1); + for (i = 0; i < 10 && dollar_vars[i]; i++) + v[i] = dollar_vars[i]; + for (words = rest_of_args; words; words = words->next, i++) + v[i] = words->word->word; + v[i] = (char *)NULL; + sh_getopt_restore_state (v); + ret = sh_getopt (i, v, optstr); + free (v); + } + + if (special_error) + sh_opterr = old_opterr; + + /* Set the OPTIND variable in any case, to handle "--" skipping. It's + highly unlikely that 14 digits will be too few. */ + if (sh_optind < 10) + { + numval[14] = sh_optind + '0'; + numval[15] = '\0'; + i = 14; + } + else + { + numval[i = 15] = '\0'; + n = sh_optind; + do + { + numval[--i] = (n % 10) + '0'; + } + while (n /= 10); + } + bind_variable ("OPTIND", numval + i, 0); + + /* If an error occurred, decide which one it is and set the return + code appropriately. In all cases, the option character in error + is in OPTOPT. If an invalid option was encountered, OPTARG is + NULL. If a required option argument was missing, OPTARG points + to a NULL string (that is, sh_optarg[0] == 0). */ + if (ret == '?') + { + if (sh_optarg == NULL) + ret = G_INVALID_OPT; + else if (sh_optarg[0] == '\0') + ret = G_ARG_MISSING; + } + + if (ret == G_EOF) + { + getopts_unbind_variable ("OPTARG"); + getopts_bind_variable (name, "?"); + return (EXECUTION_FAILURE); + } + + if (ret == G_INVALID_OPT) + { + /* Invalid option encountered. */ + ret = getopts_bind_variable (name, "?"); + + if (special_error) + { + strval[0] = (char)sh_optopt; + strval[1] = '\0'; + bind_variable ("OPTARG", strval, 0); + } + else + getopts_unbind_variable ("OPTARG"); + + return (ret); + } + + if (ret == G_ARG_MISSING) + { + /* Required argument missing. */ + if (special_error) + { + ret = getopts_bind_variable (name, ":"); + + strval[0] = (char)sh_optopt; + strval[1] = '\0'; + bind_variable ("OPTARG", strval, 0); + } + else + { + ret = getopts_bind_variable (name, "?"); + getopts_unbind_variable ("OPTARG"); + } + return (ret); + } + + bind_variable ("OPTARG", sh_optarg, 0); + + strval[0] = (char) ret; + strval[1] = '\0'; + return (getopts_bind_variable (name, strval)); +} + +/* The getopts builtin. Build an argv, and call dogetopts with it. */ +int +getopts_builtin (list) + WORD_LIST *list; +{ + char **av; + int ac, ret; + + if (list == 0) + { + builtin_usage (); + return EX_USAGE; + } + + reset_internal_getopt (); + if ((ret = internal_getopt (list, "")) != -1) + { + if (ret == GETOPT_HELP) + builtin_help (); + else + builtin_usage (); + return (EX_USAGE); + } + list = loptend; + + av = make_builtin_argv (list, &ac); + ret = dogetopts (ac, av); + free ((char *)av); + + return (ret); +} diff --git a/builtins/hash.c b/builtins/hash.c new file mode 100644 index 0000000..7a6efc8 --- /dev/null +++ b/builtins/hash.c @@ -0,0 +1,264 @@ +/* hash.c, created from hash.def. */ +#line 22 "./hash.def" + +#line 46 "./hash.def" + +#include + +#include + +#include "../bashtypes.h" + +#if defined (HAVE_UNISTD_H) +# include +#endif + +#include + +#include "../bashansi.h" +#include "../bashintl.h" + +#include "../shell.h" +#include "../builtins.h" +#include "../execute_cmd.h" +#include "../flags.h" +#include "../findcmd.h" +#include "../hashcmd.h" +#include "common.h" +#include "bashgetopt.h" + +extern int dot_found_in_search; + +static int add_hashed_command PARAMS((char *, int)); +static int print_hash_info PARAMS((BUCKET_CONTENTS *)); +static int print_portable_hash_info PARAMS((BUCKET_CONTENTS *)); +static int print_hashed_commands PARAMS((int)); +static int list_hashed_filename_targets PARAMS((WORD_LIST *, int)); + +/* Print statistics on the current state of hashed commands. If LIST is + not empty, then rehash (or hash in the first place) the specified + commands. */ +int +hash_builtin (list) + WORD_LIST *list; +{ + int expunge_hash_table, list_targets, list_portably, delete, opt; + char *w, *pathname; + + if (hashing_enabled == 0) + { + builtin_error (_("hashing disabled")); + return (EXECUTION_FAILURE); + } + + expunge_hash_table = list_targets = list_portably = delete = 0; + pathname = (char *)NULL; + reset_internal_getopt (); + while ((opt = internal_getopt (list, "dlp:rt")) != -1) + { + switch (opt) + { + case 'd': + delete = 1; + break; + case 'l': + list_portably = 1; + break; + case 'p': + pathname = list_optarg; + break; + case 'r': + expunge_hash_table = 1; + break; + case 't': + list_targets = 1; + break; + CASE_HELPOPT; + default: + builtin_usage (); + return (EX_USAGE); + } + } + list = loptend; + + /* hash -t requires at least one argument. */ + if (list == 0 && (delete || list_targets)) + { + sh_needarg (delete ? "-d" : "-t"); + return (EXECUTION_FAILURE); + } + + /* We want hash -r to be silent, but hash -- to print hashing info, so + we test expunge_hash_table. */ + if (list == 0 && expunge_hash_table == 0) + { + opt = print_hashed_commands (list_portably); + if (opt == 0 && posixly_correct == 0 && + (list_portably == 0 || shell_compatibility_level <= 50)) + printf (_("%s: hash table empty\n"), this_command_name); + + return (EXECUTION_SUCCESS); + } + + if (expunge_hash_table) + phash_flush (); + + /* If someone runs `hash -r -t xyz' he will be disappointed. */ + if (list_targets) + return (list_hashed_filename_targets (list, list_portably)); + +#if defined (RESTRICTED_SHELL) + if (restricted && pathname) + { + if (strchr (pathname, '/')) + { + sh_restricted (pathname); + return (EXECUTION_FAILURE); + } + /* If we are changing the hash table in a restricted shell, make sure the + target pathname can be found using a $PATH search. */ + w = find_user_command (pathname); + if (w == 0 || *w == 0 || executable_file (w) == 0) + { + sh_notfound (pathname); + free (w); + return (EXECUTION_FAILURE); + } + free (w); + } +#endif + + for (opt = EXECUTION_SUCCESS; list; list = list->next) + { + /* Add, remove or rehash the specified commands. */ + w = list->word->word; + if (absolute_program (w)) + continue; + else if (pathname) + { + if (is_directory (pathname)) + { +#ifdef EISDIR + builtin_error ("%s: %s", pathname, strerror (EISDIR)); +#else + builtin_error (_("%s: is a directory"), pathname); +#endif + opt = EXECUTION_FAILURE; + } + else + phash_insert (w, pathname, 0, 0); + } + else if (delete) + { + if (phash_remove (w)) + { + sh_notfound (w); + opt = EXECUTION_FAILURE; + } + } + else if (add_hashed_command (w, 0)) + opt = EXECUTION_FAILURE; + } + + fflush (stdout); + return (opt); +} + +static int +add_hashed_command (w, quiet) + char *w; + int quiet; +{ + int rv; + char *full_path; + + rv = 0; + if (find_function (w) == 0 && find_shell_builtin (w) == 0) + { + phash_remove (w); + full_path = find_user_command (w); + if (full_path && executable_file (full_path)) + phash_insert (w, full_path, dot_found_in_search, 0); + else + { + if (quiet == 0) + sh_notfound (w); + rv++; + } + FREE (full_path); + } + return (rv); +} + +/* Print information about current hashed info. */ +static int +print_hash_info (item) + BUCKET_CONTENTS *item; +{ + printf ("%4d\t%s\n", item->times_found, pathdata(item)->path); + return 0; +} + +static int +print_portable_hash_info (item) + BUCKET_CONTENTS *item; +{ + char *fp, *fn; + + fp = printable_filename (pathdata(item)->path, 1); + fn = printable_filename (item->key, 1); + printf ("builtin hash -p %s %s\n", fp, fn); + if (fp != pathdata(item)->path) + free (fp); + if (fn != item->key) + free (fn); + return 0; +} + +static int +print_hashed_commands (fmt) + int fmt; +{ + if (hashed_filenames == 0 || HASH_ENTRIES (hashed_filenames) == 0) + return (0); + + if (fmt == 0) + printf (_("hits\tcommand\n")); + hash_walk (hashed_filenames, fmt ? print_portable_hash_info : print_hash_info); + return (1); +} + +static int +list_hashed_filename_targets (list, fmt) + WORD_LIST *list; + int fmt; +{ + int all_found, multiple; + char *target; + WORD_LIST *l; + + all_found = 1; + multiple = list->next != 0; + + for (l = list; l; l = l->next) + { + target = phash_search (l->word->word); + if (target == 0) + { + all_found = 0; + sh_notfound (l->word->word); + continue; + } + if (fmt) + printf ("builtin hash -p %s %s\n", target, l->word->word); + else + { + if (multiple) + printf ("%s\t", l->word->word); + printf ("%s\n", target); + } + free (target); + } + + return (all_found ? EXECUTION_SUCCESS : EXECUTION_FAILURE); +} diff --git a/builtins/help.c b/builtins/help.c new file mode 100644 index 0000000..447a488 --- /dev/null +++ b/builtins/help.c @@ -0,0 +1,513 @@ +/* help.c, created from help.def. */ +#line 22 "./help.def" + +#line 45 "./help.def" + +#include + +#if defined (HELP_BUILTIN) +#include + +#if defined (HAVE_UNISTD_H) +# ifdef _MINIX +# include +# endif +# include +#endif + +#include + +#include +#include + +#include "../bashintl.h" + +#include "../shell.h" +#include "../builtins.h" +#include "../execute_cmd.h" +#include "../pathexp.h" +#include "common.h" +#include "bashgetopt.h" + +#include +#include + +#ifndef errno +extern int errno; +#endif + +extern const char * const bash_copyright; +extern const char * const bash_license; + +static void show_builtin_command_help PARAMS((void)); +static int open_helpfile PARAMS((char *)); +static void show_desc PARAMS((char *, int)); +static void show_manpage PARAMS((char *, int)); +static void show_longdoc PARAMS((int)); + +/* Print out a list of the known functions in the shell, and what they do. + If LIST is supplied, print out the list which matches for each pattern + specified. */ +int +help_builtin (list) + WORD_LIST *list; +{ + register int i; + char *pattern, *name; + int plen, match_found, sflag, dflag, mflag, m, pass, this_found; + + dflag = sflag = mflag = 0; + reset_internal_getopt (); + while ((i = internal_getopt (list, "dms")) != -1) + { + switch (i) + { + case 'd': + dflag = 1; + break; + case 'm': + mflag = 1; + break; + case 's': + sflag = 1; + break; + CASE_HELPOPT; + default: + builtin_usage (); + return (EX_USAGE); + } + } + list = loptend; + + if (list == 0) + { + show_shell_version (0); + show_builtin_command_help (); + return (EXECUTION_SUCCESS); + } + + /* We should consider making `help bash' do something. */ + + if (glob_pattern_p (list->word->word) == 1) + { + printf ("%s", ngettext ("Shell commands matching keyword `", "Shell commands matching keywords `", (list->next ? 2 : 1))); + print_word_list (list, ", "); + printf ("%s", _("'\n\n")); + } + + for (match_found = 0, pattern = ""; list; list = list->next) + { + pattern = list->word->word; + plen = strlen (pattern); + + for (pass = 1, this_found = 0; pass < 3; pass++) + { + for (i = 0; name = shell_builtins[i].name; i++) + { + QUIT; + + /* First pass: look for exact string or pattern matches. + Second pass: look for prefix matches like bash-4.2 */ + if (pass == 1) + m = (strcmp (pattern, name) == 0) || + (strmatch (pattern, name, FNMATCH_EXTFLAG) != FNM_NOMATCH); + else + m = strncmp (pattern, name, plen) == 0; + + if (m) + { + this_found = 1; + match_found++; + if (dflag) + { + show_desc (name, i); + continue; + } + else if (mflag) + { + show_manpage (name, i); + continue; + } + + printf ("%s: %s\n", name, _(shell_builtins[i].short_doc)); + + if (sflag == 0) + show_longdoc (i); + } + } + if (pass == 1 && this_found == 1) + break; + } + } + + if (match_found == 0) + { + builtin_error (_("no help topics match `%s'. Try `help help' or `man -k %s' or `info %s'."), pattern, pattern, pattern); + return (EXECUTION_FAILURE); + } + + fflush (stdout); + return (EXECUTION_SUCCESS); +} + +void +builtin_help () +{ + int ind; + ptrdiff_t d; + + current_builtin = builtin_address_internal (this_command_name, 0); + if (current_builtin == 0) + return; + + d = current_builtin - shell_builtins; + +#if defined (__STDC__) + ind = (int)d; +#else + ind = (int)d / sizeof (struct builtin); +#endif + + printf ("%s: %s\n", this_command_name, _(shell_builtins[ind].short_doc)); + show_longdoc (ind); +} + +static int +open_helpfile (name) + char *name; +{ + int fd; + + fd = open (name, O_RDONLY); + if (fd == -1) + { + builtin_error (_("%s: cannot open: %s"), name, strerror (errno)); + return -1; + } + return fd; +} + +/* By convention, enforced by mkbuiltins.c, if separate help files are being + used, the long_doc array contains one string -- the full pathname of the + help file for this builtin. */ +static void +show_longdoc (i) + int i; +{ + register int j; + char * const *doc; + int fd; + + doc = shell_builtins[i].long_doc; + + if (doc && doc[0] && *doc[0] == '/' && doc[1] == (char *)NULL) + { + fd = open_helpfile (doc[0]); + if (fd < 0) + return; + zcatfd (fd, 1, doc[0]); + close (fd); + } + else if (doc) + for (j = 0; doc[j]; j++) + printf ("%*s%s\n", BASE_INDENT, " ", _(doc[j])); +} + +static void +show_desc (name, i) + char *name; + int i; +{ + register int j, r; + char **doc, *line; + int fd, usefile; + + doc = (char **)shell_builtins[i].long_doc; + + usefile = (doc && doc[0] && *doc[0] == '/' && doc[1] == (char *)NULL); + if (usefile) + { + fd = open_helpfile (doc[0]); + if (fd < 0) + return; + r = zmapfd (fd, &line, doc[0]); + close (fd); + /* XXX - handle errors if zmapfd returns < 0 */ + } + else + line = doc ? doc[0] : (char *)NULL; + + printf ("%s - ", name); + for (j = 0; line && line[j]; j++) + { + putchar (line[j]); + if (line[j] == '\n') + break; + } + + fflush (stdout); + + if (usefile) + free (line); +} + +/* Print builtin help in pseudo-manpage format. */ +static void +show_manpage (name, i) + char *name; + int i; +{ + register int j; + char **doc, *line; + int fd, usefile; + + doc = (char **)shell_builtins[i].long_doc; + + usefile = (doc && doc[0] && *doc[0] == '/' && doc[1] == (char *)NULL); + if (usefile) + { + fd = open_helpfile (doc[0]); + if (fd < 0) + return; + zmapfd (fd, &line, doc[0]); + close (fd); + } + else + line = doc ? _(doc[0]) : (char *)NULL; + + /* NAME */ + printf ("NAME\n"); + printf ("%*s%s - ", BASE_INDENT, " ", name); + for (j = 0; line && line[j]; j++) + { + putchar (line[j]); + if (line[j] == '\n') + break; + } + printf ("\n"); + + /* SYNOPSIS */ + printf ("SYNOPSIS\n"); + printf ("%*s%s\n\n", BASE_INDENT, " ", _(shell_builtins[i].short_doc)); + + /* DESCRIPTION */ + printf ("DESCRIPTION\n"); + if (usefile == 0) + { + for (j = 0; doc[j]; j++) + printf ("%*s%s\n", BASE_INDENT, " ", _(doc[j])); + } + else + { + for (j = 0; line && line[j]; j++) + { + putchar (line[j]); + if (line[j] == '\n') + printf ("%*s", BASE_INDENT, " "); + } + } + putchar ('\n'); + + /* SEE ALSO */ + printf ("SEE ALSO\n"); + printf ("%*sbash(1)\n\n", BASE_INDENT, " "); + + /* IMPLEMENTATION */ + printf ("IMPLEMENTATION\n"); + printf ("%*s", BASE_INDENT, " "); + show_shell_version (0); + printf ("%*s", BASE_INDENT, " "); + printf ("%s\n", _(bash_copyright)); + printf ("%*s", BASE_INDENT, " "); + printf ("%s\n", _(bash_license)); + + fflush (stdout); + if (usefile) + free (line); +} + +static void +dispcolumn (i, buf, bufsize, width, height) + int i; + char *buf; + size_t bufsize; + int width, height; +{ + int j; + int dispcols; + char *helpdoc; + + /* first column */ + helpdoc = _(shell_builtins[i].short_doc); + + buf[0] = (shell_builtins[i].flags & BUILTIN_ENABLED) ? ' ' : '*'; + strncpy (buf + 1, helpdoc, width - 2); + buf[width - 2] = '>'; /* indicate truncation */ + buf[width - 1] = '\0'; + printf ("%s", buf); + if (((i << 1) >= num_shell_builtins) || (i+height >= num_shell_builtins)) + { + printf ("\n"); + return; + } + + dispcols = strlen (buf); + /* two spaces */ + for (j = dispcols; j < width; j++) + putc (' ', stdout); + + /* second column */ + helpdoc = _(shell_builtins[i+height].short_doc); + + buf[0] = (shell_builtins[i+height].flags & BUILTIN_ENABLED) ? ' ' : '*'; + strncpy (buf + 1, helpdoc, width - 3); + buf[width - 3] = '>'; /* indicate truncation */ + buf[width - 2] = '\0'; + + printf ("%s\n", buf); +} + +#if defined (HANDLE_MULTIBYTE) +static void +wdispcolumn (i, buf, bufsize, width, height) + int i; + char *buf; + size_t bufsize; + int width, height; +{ + int j; + int dispcols, dispchars; + char *helpdoc; + wchar_t *wcstr; + size_t slen, n; + + /* first column */ + helpdoc = _(shell_builtins[i].short_doc); + + wcstr = 0; + slen = mbstowcs ((wchar_t *)0, helpdoc, 0); + if (slen == -1) + { + dispcolumn (i, buf, bufsize, width, height); + return; + } + + /* No bigger than the passed max width */ + if (slen >= width) + slen = width - 2; + wcstr = (wchar_t *)xmalloc (sizeof (wchar_t) * (width + 2)); + n = mbstowcs (wcstr+1, helpdoc, slen + 1); + wcstr[n+1] = L'\0'; + + /* Turn tabs and newlines into spaces for column display, since wcwidth + returns -1 for them */ + for (j = 1; j < n; j++) + if (wcstr[j] == L'\n' || wcstr[j] == L'\t') + wcstr[j] = L' '; + + /* dispchars == number of characters that will be displayed */ + dispchars = wcsnwidth (wcstr+1, slen, width - 2); + /* dispcols == number of columns required to display DISPCHARS */ + dispcols = wcswidth (wcstr+1, dispchars) + 1; /* +1 for ' ' or '*' */ + + wcstr[0] = (shell_builtins[i].flags & BUILTIN_ENABLED) ? L' ' : L'*'; + + if (dispcols >= width-2) + { + wcstr[dispchars] = L'>'; /* indicate truncation */ + wcstr[dispchars+1] = L'\0'; + } + + printf ("%ls", wcstr); + if (((i << 1) >= num_shell_builtins) || (i+height >= num_shell_builtins)) + { + printf ("\n"); + free (wcstr); + return; + } + + /* at least one space */ + for (j = dispcols; j < width; j++) + putc (' ', stdout); + + /* second column */ + helpdoc = _(shell_builtins[i+height].short_doc); + slen = mbstowcs ((wchar_t *)0, helpdoc, 0); + if (slen == -1) + { + /* for now */ + printf ("%c%s\n", (shell_builtins[i+height].flags & BUILTIN_ENABLED) ? ' ' : '*', helpdoc); + free (wcstr); + return; + } + + /* Reuse wcstr since it is already width wide chars long */ + if (slen >= width) + slen = width - 2; + n = mbstowcs (wcstr+1, helpdoc, slen + 1); + wcstr[n+1] = L'\0'; /* make sure null-terminated */ + + /* Turn tabs and newlines into spaces for column display */ + for (j = 1; j < n; j++) + if (wcstr[j] == L'\n' || wcstr[j] == L'\t') + wcstr[j] = L' '; + + /* dispchars == number of characters that will be displayed */ + dispchars = wcsnwidth (wcstr+1, slen, width - 2); + dispcols = wcswidth (wcstr+1, dispchars) + 1; /* +1 for ' ' or '*' */ + + wcstr[0] = (shell_builtins[i+height].flags & BUILTIN_ENABLED) ? L' ' : L'*'; + + /* The dispchars-1 is there for terminals that behave strangely when you + have \n in the nth column for terminal width n; this is what bash-4.3 + did. */ + if (dispcols >= width - 2) + { + wcstr[dispchars-1] = L'>'; /* indicate truncation */ + wcstr[dispchars] = L'\0'; + } + + printf ("%ls\n", wcstr); + + free (wcstr); +} +#endif /* HANDLE_MULTIBYTE */ + +static void +show_builtin_command_help () +{ + int i, j; + int height, width; + char *t, blurb[128]; + + printf ( +_("These shell commands are defined internally. Type `help' to see this list.\n\ +Type `help name' to find out more about the function `name'.\n\ +Use `info bash' to find out more about the shell in general.\n\ +Use `man -k' or `info' to find out more about commands not in this list.\n\ +\n\ +A star (*) next to a name means that the command is disabled.\n\ +\n")); + + width = default_columns (); + + width /= 2; + if (width > sizeof (blurb)) + width = sizeof (blurb); + if (width <= 3) + width = 40; + height = (num_shell_builtins + 1) / 2; /* number of rows */ + + for (i = 0; i < height; i++) + { + QUIT; + +#if defined (HANDLE_MULTIBYTE) + if (MB_CUR_MAX > 1) + wdispcolumn (i, blurb, sizeof (blurb), width, height); + else +#endif + dispcolumn (i, blurb, sizeof (blurb), width, height); + } +} +#endif /* HELP_BUILTIN */ diff --git a/builtins/history.c b/builtins/history.c new file mode 100644 index 0000000..476694b --- /dev/null +++ b/builtins/history.c @@ -0,0 +1,413 @@ +/* history.c, created from history.def. */ +#line 22 "./history.def" + +#line 58 "./history.def" + +#include + +#if defined (HISTORY) +#include "../bashtypes.h" +#if ! defined(_MINIX) && defined (HAVE_SYS_FILE_H) +# include +#endif +#include "posixstat.h" +#include "filecntl.h" +#include +#include +#if defined (HAVE_UNISTD_H) +# include +#endif + +#include "../bashansi.h" +#include "../bashintl.h" + +#include "../shell.h" +#include "../flags.h" +#include "../parser.h" +#include "../bashhist.h" +#include +#include "bashgetopt.h" +#include "common.h" + +#if !defined (errno) +extern int errno; +#endif + +static char *histtime PARAMS((HIST_ENTRY *, const char *)); +static int display_history PARAMS((WORD_LIST *)); +static void push_history PARAMS((WORD_LIST *)); +static int expand_and_print_history PARAMS((WORD_LIST *)); + +#define AFLAG 0x01 +#define RFLAG 0x02 +#define WFLAG 0x04 +#define NFLAG 0x08 +#define SFLAG 0x10 +#define PFLAG 0x20 +#define CFLAG 0x40 +#define DFLAG 0x80 + +int +history_builtin (list) + WORD_LIST *list; +{ + int flags, opt, result, old_history_lines, obase, ind; + char *filename, *delete_arg, *range; + intmax_t delete_offset; + + flags = 0; + reset_internal_getopt (); + while ((opt = internal_getopt (list, "acd:npsrw")) != -1) + { + switch (opt) + { + case 'a': + flags |= AFLAG; + break; + case 'c': + flags |= CFLAG; + break; + case 'n': + flags |= NFLAG; + break; + case 'r': + flags |= RFLAG; + break; + case 'w': + flags |= WFLAG; + break; + case 's': + flags |= SFLAG; + break; + case 'd': + flags |= DFLAG; + delete_arg = list_optarg; + break; + case 'p': +#if defined (BANG_HISTORY) + flags |= PFLAG; +#endif + break; + CASE_HELPOPT; + default: + builtin_usage (); + return (EX_USAGE); + } + } + list = loptend; + + opt = flags & (AFLAG|RFLAG|WFLAG|NFLAG); + if (opt && opt != AFLAG && opt != RFLAG && opt != WFLAG && opt != NFLAG) + { + builtin_error (_("cannot use more than one of -anrw")); + return (EXECUTION_FAILURE); + } + + /* clear the history, but allow other arguments to add to it again. */ + if (flags & CFLAG) + { + bash_clear_history (); + if (list == 0) + return (EXECUTION_SUCCESS); + } + + if (flags & SFLAG) + { + if (list) + push_history (list); + return (EXECUTION_SUCCESS); + } +#if defined (BANG_HISTORY) + else if (flags & PFLAG) + { + if (list) + return (expand_and_print_history (list)); + return (sh_chkwrite (EXECUTION_SUCCESS)); + } +#endif + else if ((flags & DFLAG) && (range = strchr ((delete_arg[0] == '-') ? delete_arg + 1 : delete_arg, '-'))) + { + intmax_t delete_start, delete_end; + *range++ = '\0'; + if (legal_number (delete_arg, &delete_start) == 0 || legal_number (range, &delete_end) == 0) + { + range[-1] = '-'; + sh_erange (delete_arg, _("history position")); + return (EXECUTION_FAILURE); + } + if (delete_arg[0] == '-' && delete_start < 0) + { + /* the_history[history_length] == 0x0, so this is correct */ + delete_start += history_length; + if (delete_start < history_base) + { +start_error: + sh_erange (delete_arg, _("history position")); + return (EXECUTION_FAILURE); + } + } + /* numbers as displayed by display_history are offset by history_base */ + else if (delete_start > 0) + delete_start -= history_base; + if (delete_start < 0 || delete_start >= history_length) + goto start_error; + if (range[0] == '-' && delete_end < 0) + { + delete_end += history_length; + if (delete_end < history_base) + { +range_error: + sh_erange (range, _("history position")); + return (EXECUTION_FAILURE); + } + } + else if (delete_end > 0) + delete_end -= history_base; + if (delete_end < 0 || delete_end >= history_length) + goto range_error; + result = bash_delete_history_range (delete_start, delete_end); + if (where_history () > history_length) + history_set_pos (history_length); + return (result ? EXECUTION_SUCCESS : EXECUTION_FAILURE); + } + else if (flags & DFLAG) + { + if (legal_number (delete_arg, &delete_offset) == 0) + { + sh_erange (delete_arg, _("history position")); + return (EXECUTION_FAILURE); + } + /* check for negative offsets, count back from end of list */ + if (delete_arg[0] == '-' && delete_offset < 0) + { + /* since the_history[history_length] == 0x0, this calculation means + that history -d -1 will delete the last history entry, which at + this point is the history -d -1 we just added. */ + ind = history_length + delete_offset; + if (ind < history_base) + { + sh_erange (delete_arg, _("history position")); + return (EXECUTION_FAILURE); + } + opt = ind + history_base; /* compensate for opt - history_base below */ + } + else if ((delete_offset < history_base) || (delete_offset >= (history_base + history_length))) + { + sh_erange (delete_arg, _("history position")); + return (EXECUTION_FAILURE); + } + else + opt = delete_offset; + + /* Positive arguments from numbers as displayed by display_history need + to be offset by history_base */ + result = bash_delete_histent (opt - history_base); + /* Since remove_history changes history_length, this can happen if + we delete the last history entry. */ + if (where_history () > history_length) + history_set_pos (history_length); + return (result ? EXECUTION_SUCCESS : EXECUTION_FAILURE); + } + else if ((flags & (AFLAG|RFLAG|NFLAG|WFLAG|CFLAG)) == 0) + { + result = display_history (list); + return (sh_chkwrite (result)); + } + + filename = list ? list->word->word : get_string_value ("HISTFILE"); + result = EXECUTION_SUCCESS; + +#if defined (RESTRICTED_SHELL) + if (restricted && strchr (filename, '/')) + { + sh_restricted (filename); + return (EXECUTION_FAILURE); + } +#endif + + if (flags & AFLAG) /* Append session's history to file. */ + result = maybe_append_history (filename); + else if (flags & WFLAG) /* Write entire history. */ + result = write_history (filename); + else if (flags & RFLAG) /* Read entire file. */ + { + result = read_history (filename); + history_lines_in_file = history_lines_read_from_file; + /* history_lines_in_file = where_history () + history_base - 1; */ + } + else if (flags & NFLAG) /* Read `new' history from file. */ + { + /* Read all of the lines in the file that we haven't already read. */ + old_history_lines = history_lines_in_file; + obase = history_base; + + using_history (); + result = read_history_range (filename, history_lines_in_file, -1); + using_history (); + + history_lines_in_file = history_lines_read_from_file; + /* history_lines_in_file = where_history () + history_base - 1; */ + + /* If we're rewriting the history file at shell exit rather than just + appending the lines from this session to it, the question is whether + we reset history_lines_this_session to 0, losing any history entries + we had before we read the new entries from the history file, or + whether we count the new entries we just read from the file as + history lines added during this session. + Right now, we do the latter. This will cause these history entries + to be written to the history file along with any intermediate entries + we add when we do a `history -a', but the alternative is losing + them altogether. */ + if (force_append_history == 0) + history_lines_this_session += history_lines_in_file - old_history_lines + + history_base - obase; + } + + return (result ? EXECUTION_FAILURE : EXECUTION_SUCCESS); +} + +/* Accessors for HIST_ENTRY lists that are called HLIST. */ +#define histline(i) (hlist[(i)]->line) +#define histdata(i) (hlist[(i)]->data) + +static char * +histtime (hlist, histtimefmt) + HIST_ENTRY *hlist; + const char *histtimefmt; +{ + static char timestr[128]; + time_t t; + struct tm *tm; + + t = history_get_time (hlist); + tm = t ? localtime (&t) : 0; + if (t && tm) + strftime (timestr, sizeof (timestr), histtimefmt, tm); + else if (hlist->timestamp && hlist->timestamp[0]) + snprintf (timestr, sizeof (timestr), _("%s: invalid timestamp"), + (hlist->timestamp[0] == '#') ? hlist->timestamp + 1: hlist->timestamp); + else + strcpy (timestr, "??"); + return timestr; +} + +static int +display_history (list) + WORD_LIST *list; +{ + register int i; + intmax_t limit; + HIST_ENTRY **hlist; + char *histtimefmt, *timestr; + + if (list) + { + if (get_numeric_arg (list, 0, &limit) == 0) + return (EXECUTION_FAILURE); + + if (limit < 0) + limit = -limit; + } + else + limit = -1; + + hlist = history_list (); + + if (hlist) + { + for (i = 0; hlist[i]; i++) + ; + + if (0 <= limit && limit < i) + i -= limit; + else + i = 0; + + histtimefmt = get_string_value ("HISTTIMEFORMAT"); + + while (hlist[i]) + { + QUIT; + + timestr = (histtimefmt && *histtimefmt) ? histtime (hlist[i], histtimefmt) : (char *)NULL; + printf ("%5d%c %s%s\n", i + history_base, + histdata(i) ? '*' : ' ', + ((timestr && *timestr) ? timestr : ""), + histline(i)); + i++; + } + } + + return (EXECUTION_SUCCESS); +} + +/* Remove the last entry in the history list and add each argument in + LIST to the history. */ +static void +push_history (list) + WORD_LIST *list; +{ + char *s; + + /* Delete the last history entry if it was a single entry added to the + history list (generally the `history -s' itself), or if `history -s' + is being used in a compound command and the compound command was + added to the history as a single element (command-oriented history). + If you don't want history -s to remove the compound command from the + history, change #if 0 to #if 1 below. */ +#if 0 + if (remember_on_history && hist_last_line_pushed == 0 && + hist_last_line_added && bash_delete_last_history () == 0) +#else + if (remember_on_history && hist_last_line_pushed == 0 && + (hist_last_line_added || + (current_command_line_count > 0 && current_command_first_line_saved && command_oriented_history)) + && bash_delete_last_history () == 0) +#endif + return; + + s = string_list (list); + /* Call check_add_history with FORCE set to 1 to skip the check against + current_command_line_count. If history -s is used in a compound + command, the above code will delete the compound command's history + entry and this call will add the line to the history as a separate + entry. Without FORCE=1, if current_command_line_count were > 1, the + line would be appended to the entry before the just-deleted entry. */ + check_add_history (s, 1); /* obeys HISTCONTROL, HISTIGNORE */ + + hist_last_line_pushed = 1; /* XXX */ + free (s); +} + +#if defined (BANG_HISTORY) +static int +expand_and_print_history (list) + WORD_LIST *list; +{ + char *s; + int r, result; + + if (hist_last_line_pushed == 0 && hist_last_line_added && bash_delete_last_history () == 0) + return EXECUTION_FAILURE; + result = EXECUTION_SUCCESS; + while (list) + { + r = history_expand (list->word->word, &s); + if (r < 0) + { + builtin_error (_("%s: history expansion failed"), list->word->word); + result = EXECUTION_FAILURE; + } + else + { + fputs (s, stdout); + putchar ('\n'); + } + FREE (s); + list = list->next; + } + fflush (stdout); + return result; +} +#endif /* BANG_HISTORY */ +#endif /* HISTORY */ diff --git a/builtins/inlib.c b/builtins/inlib.c new file mode 100644 index 0000000..8e218b1 --- /dev/null +++ b/builtins/inlib.c @@ -0,0 +1,46 @@ +/* inlib.c, created from inlib.def. */ +#line 22 "./inlib.def" +#include + +#include +#include "../shell.h" + +#line 43 "./inlib.def" + +#if defined (apollo) + +#include +#include + +inlib_builtin (list) + WORD_LIST *list; +{ + status_$t status; + int return_value; + short len; + + if (!list) + { + builtin_usage (); + return (EX_USAGE); + } + + return_value = EXECUTION_SUCCESS; + + while (list) + { + len = (short)strlen (list->word->word); + loader_$inlib (list->word->word, len, &status); + + if (status.all != status_$ok) + { + builtin_error (_("%s: inlib failed"), list->word->word); + return_value = EXECUTION_FAILURE; + } + + list = list->next; + } + + return (return_value); +} +#endif /* apollo */ diff --git a/builtins/jobs.c b/builtins/jobs.c new file mode 100644 index 0000000..4b858df --- /dev/null +++ b/builtins/jobs.c @@ -0,0 +1,240 @@ +/* jobs.c, created from jobs.def. */ +#line 22 "./jobs.def" + +#line 48 "./jobs.def" + +#include + +#if defined (JOB_CONTROL) +#include "../bashtypes.h" +#include +#if defined (HAVE_UNISTD_H) +# include +#endif + +#include "../bashansi.h" +#include "../bashintl.h" + +#include "../shell.h" +#include "../jobs.h" +#include "../execute_cmd.h" +#include "bashgetopt.h" +#include "common.h" + +#define JSTATE_ANY 0x0 +#define JSTATE_RUNNING 0x1 +#define JSTATE_STOPPED 0x2 + +static int execute_list_with_replacements PARAMS((WORD_LIST *)); + +/* The `jobs' command. Prints outs a list of active jobs. If the + argument `-l' is given, then the process id's are printed also. + If the argument `-p' is given, print the process group leader's + pid only. If `-n' is given, only processes that have changed + status since the last notification are printed. If -x is given, + replace all job specs with the pid of the appropriate process + group leader and execute the command. The -r and -s options mean + to print info about running and stopped jobs only, respectively. */ +int +jobs_builtin (list) + WORD_LIST *list; +{ + int form, execute, state, opt, any_failed, job; + sigset_t set, oset; + + execute = any_failed = 0; + form = JLIST_STANDARD; + state = JSTATE_ANY; + + reset_internal_getopt (); + while ((opt = internal_getopt (list, "lpnxrs")) != -1) + { + switch (opt) + { + case 'l': + form = JLIST_LONG; + break; + case 'p': + form = JLIST_PID_ONLY; + break; + case 'n': + form = JLIST_CHANGED_ONLY; + break; + case 'x': + if (form != JLIST_STANDARD) + { + builtin_error (_("no other options allowed with `-x'")); + return (EXECUTION_FAILURE); + } + execute++; + break; + case 'r': + state = JSTATE_RUNNING; + break; + case 's': + state = JSTATE_STOPPED; + break; + + CASE_HELPOPT; + default: + builtin_usage (); + return (EX_USAGE); + } + } + + list = loptend; + + if (execute) + return (execute_list_with_replacements (list)); + + if (!list) + { + switch (state) + { + case JSTATE_ANY: + list_all_jobs (form); + break; + case JSTATE_RUNNING: + list_running_jobs (form); + break; + case JSTATE_STOPPED: + list_stopped_jobs (form); + break; + } + return (EXECUTION_SUCCESS); + } + + while (list) + { + BLOCK_CHILD (set, oset); + job = get_job_spec (list); + + if ((job == NO_JOB) || jobs == 0 || get_job_by_jid (job) == 0) + { + sh_badjob (list->word->word); + any_failed++; + } + else if (job != DUP_JOB) + list_one_job ((JOB *)NULL, form, 0, job); + + UNBLOCK_CHILD (oset); + list = list->next; + } + return (any_failed ? EXECUTION_FAILURE : EXECUTION_SUCCESS); +} + +static int +execute_list_with_replacements (list) + WORD_LIST *list; +{ + register WORD_LIST *l; + int job, result; + COMMAND *command; + JOB *j; + + /* First do the replacement of job specifications with pids. */ + for (l = list; l; l = l->next) + { + if (l->word->word[0] == '%') /* we have a winner */ + { + job = get_job_spec (l); + + /* A bad job spec is not really a job spec! Pass it through. */ + if (INVALID_JOB (job)) + continue; + + j = get_job_by_jid (job); + free (l->word->word); + l->word->word = itos (j->pgrp); + } + } + + /* Next make a new simple command and execute it. */ + begin_unwind_frame ("jobs_builtin"); + + command = make_bare_simple_command (); + command->value.Simple->words = copy_word_list (list); + command->value.Simple->redirects = (REDIRECT *)NULL; + command->flags |= CMD_INHIBIT_EXPANSION; + command->value.Simple->flags |= CMD_INHIBIT_EXPANSION; + + add_unwind_protect (dispose_command, command); + result = execute_command (command); + dispose_command (command); + + discard_unwind_frame ("jobs_builtin"); + return (result); +} +#endif /* JOB_CONTROL */ + +#line 231 "./jobs.def" + +#if defined (JOB_CONTROL) +int +disown_builtin (list) + WORD_LIST *list; +{ + int opt, job, retval, nohup_only, running_jobs, all_jobs; + sigset_t set, oset; + intmax_t pid_value; + + nohup_only = running_jobs = all_jobs = 0; + reset_internal_getopt (); + while ((opt = internal_getopt (list, "ahr")) != -1) + { + switch (opt) + { + case 'a': + all_jobs = 1; + break; + case 'h': + nohup_only = 1; + break; + case 'r': + running_jobs = 1; + break; + CASE_HELPOPT; + default: + builtin_usage (); + return (EX_USAGE); + } + } + list = loptend; + retval = EXECUTION_SUCCESS; + + /* `disown -a' or `disown -r' */ + if (list == 0 && (all_jobs || running_jobs)) + { + if (nohup_only) + nohup_all_jobs (running_jobs); + else + delete_all_jobs (running_jobs); + return (EXECUTION_SUCCESS); + } + + do + { + BLOCK_CHILD (set, oset); + job = (list && legal_number (list->word->word, &pid_value) && pid_value == (pid_t) pid_value) + ? get_job_by_pid ((pid_t) pid_value, 0, 0) + : get_job_spec (list); + + if (job == NO_JOB || jobs == 0 || INVALID_JOB (job)) + { + sh_badjob (list ? list->word->word : _("current")); + retval = EXECUTION_FAILURE; + } + else if (nohup_only) + nohup_job (job); + else + delete_job (job, 1); + UNBLOCK_CHILD (oset); + + if (list) + list = list->next; + } + while (list); + + return (retval); +} +#endif /* JOB_CONTROL */ diff --git a/builtins/kill.c b/builtins/kill.c new file mode 100644 index 0000000..de2de06 --- /dev/null +++ b/builtins/kill.c @@ -0,0 +1,235 @@ +/* kill.c, created from kill.def. */ +#line 22 "./kill.def" + +#line 46 "./kill.def" + +#include + +#include +#include +#if defined (HAVE_UNISTD_H) +# ifdef _MINIX +# include +# endif +# include +#endif + +#include "../bashansi.h" +#include "../bashintl.h" + +#include + +#include "../shell.h" +#include "../trap.h" +#include "../jobs.h" +#include "common.h" + +/* Not all systems declare ERRNO in errno.h... and some systems #define it! */ +#if !defined (errno) +extern int errno; +#endif /* !errno */ + +static void kill_error PARAMS((pid_t, int)); + +#if !defined (CONTINUE_AFTER_KILL_ERROR) +# define CONTINUE_OR_FAIL return (EXECUTION_FAILURE) +#else +# define CONTINUE_OR_FAIL goto continue_killing +#endif /* CONTINUE_AFTER_KILL_ERROR */ + +/* Here is the kill builtin. We only have it so that people can type + kill -KILL %1? No, if you fill up the process table this way you + can still kill some. */ +int +kill_builtin (list) + WORD_LIST *list; +{ + int sig, any_succeeded, listing, saw_signal, dflags; + char *sigspec, *word; + pid_t pid; + intmax_t pid_value; + + if (list == 0) + { + builtin_usage (); + return (EX_USAGE); + } + CHECK_HELPOPT (list); + + any_succeeded = listing = saw_signal = 0; + sig = SIGTERM; + sigspec = "TERM"; + + dflags = DSIG_NOCASE | ((posixly_correct == 0) ? DSIG_SIGPREFIX : 0); + /* Process options. */ + while (list) + { + word = list->word->word; + + if (ISOPTION (word, 'l') || ISOPTION (word, 'L')) + { + listing++; + list = list->next; + } + else if (ISOPTION (word, 's') || ISOPTION (word, 'n')) + { + list = list->next; + if (list) + { + sigspec = list->word->word; +use_sigspec: + if (sigspec[0] == '0' && sigspec[1] == '\0') + sig = 0; + else + sig = decode_signal (sigspec, dflags); + list = list->next; + saw_signal++; + } + else + { + sh_needarg (word); + return (EXECUTION_FAILURE); + } + } + else if (word[0] == '-' && word[1] == 's' && ISALPHA (word[2])) + { + sigspec = word + 2; + goto use_sigspec; + } + else if (word[0] == '-' && word[1] == 'n' && ISDIGIT (word[2])) + { + sigspec = word + 2; + goto use_sigspec; + } + else if (ISOPTION (word, '-')) + { + list = list->next; + break; + } + else if (ISOPTION (word, '?')) + { + builtin_usage (); + return (EX_USAGE); + } + /* If this is a signal specification then process it. We only process + the first one seen; other arguments may signify process groups (e.g, + -num == process group num). */ + else if (*word == '-' && saw_signal == 0) + { + sigspec = word + 1; + sig = decode_signal (sigspec, dflags); + saw_signal++; + list = list->next; + } + else + break; + } + + if (listing) + return (display_signal_list (list, 0)); + + /* OK, we are killing processes. */ + if (sig == NO_SIG) + { + sh_invalidsig (sigspec); + return (EXECUTION_FAILURE); + } + + if (list == 0) + { + builtin_usage (); + return (EX_USAGE); + } + + while (list) + { + word = list->word->word; + + if (*word == '-') + word++; + + /* Use the entire argument in case of minus sign presence. */ + if (*word && legal_number (list->word->word, &pid_value) && (pid_value == (pid_t)pid_value)) + { + pid = (pid_t) pid_value; + + if (kill_pid (pid, sig, pid < -1) < 0) + { + if (errno == EINVAL) + sh_invalidsig (sigspec); + else + kill_error (pid, errno); + CONTINUE_OR_FAIL; + } + else + any_succeeded++; + } +#if defined (JOB_CONTROL) + else if (*list->word->word && *list->word->word != '%') + { + builtin_error (_("%s: arguments must be process or job IDs"), list->word->word); + CONTINUE_OR_FAIL; + } + else if (*word) + /* Posix.2 says you can kill without job control active (4.32.4) */ + { /* Must be a job spec. Check it out. */ + int job; + sigset_t set, oset; + JOB *j; + + BLOCK_CHILD (set, oset); + job = get_job_spec (list); + + if (INVALID_JOB (job)) + { + if (job != DUP_JOB) + sh_badjob (list->word->word); + UNBLOCK_CHILD (oset); + CONTINUE_OR_FAIL; + } + + j = get_job_by_jid (job); + /* Job spec used. Kill the process group. If the job was started + without job control, then its pgrp == shell_pgrp, so we have + to be careful. We take the pid of the first job in the pipeline + in that case. */ + pid = IS_JOBCONTROL (job) ? j->pgrp : j->pipe->pid; + + UNBLOCK_CHILD (oset); + + if (kill_pid (pid, sig, 1) < 0) + { + if (errno == EINVAL) + sh_invalidsig (sigspec); + else + kill_error (pid, errno); + CONTINUE_OR_FAIL; + } + else + any_succeeded++; + } +#endif /* !JOB_CONTROL */ + else + { + sh_badpid (list->word->word); + CONTINUE_OR_FAIL; + } + continue_killing: + list = list->next; + } + + return (any_succeeded ? EXECUTION_SUCCESS : EXECUTION_FAILURE); +} + +static void +kill_error (pid, e) + pid_t pid; + int e; +{ + char *x; + + x = strerror (e); + if (x == 0) + x = _("Unknown error"); + builtin_error ("(%ld) - %s", (long)pid, x); +} diff --git a/builtins/let.c b/builtins/let.c new file mode 100644 index 0000000..3df05e5 --- /dev/null +++ b/builtins/let.c @@ -0,0 +1,68 @@ +/* let.c, created from let.def. */ +#line 66 "./let.def" + +#include + +#if defined (HAVE_UNISTD_H) +# ifdef _MINIX +# include +# endif +# include +#endif + +#include "../bashintl.h" + +#include "../shell.h" +#include "common.h" + +/* Arithmetic LET function. */ +int +let_builtin (list) + WORD_LIST *list; +{ + intmax_t ret; + int expok; + + CHECK_HELPOPT (list); + + /* Skip over leading `--' argument. */ + if (list && list->word && ISOPTION (list->word->word, '-')) + list = list->next; + + if (list == 0) + { + builtin_error (_("expression expected")); + return (EXECUTION_FAILURE); + } + + for (; list; list = list->next) + { + ret = evalexp (list->word->word, EXP_EXPANDED, &expok); + if (expok == 0) + return (EXECUTION_FAILURE); + } + + return ((ret == 0) ? EXECUTION_FAILURE : EXECUTION_SUCCESS); +} + +#ifdef INCLUDE_UNUSED +int +exp_builtin (list) + WORD_LIST *list; +{ + char *exp; + intmax_t ret; + int expok; + + if (list == 0) + { + builtin_error (_("expression expected")); + return (EXECUTION_FAILURE); + } + + exp = string_list (list); + ret = evalexp (exp, EXP_EXPANDED, &expok); + (void)free (exp); + return (((ret == 0) || (expok == 0)) ? EXECUTION_FAILURE : EXECUTION_SUCCESS); +} +#endif diff --git a/builtins/mapfile.c b/builtins/mapfile.c new file mode 100644 index 0000000..bb1b0fb --- /dev/null +++ b/builtins/mapfile.c @@ -0,0 +1,314 @@ +/* mapfile.c, created from mapfile.def. */ +#line 23 "./mapfile.def" + +#line 59 "./mapfile.def" + +#line 67 "./mapfile.def" + +#include + +#include "builtins.h" +#include "posixstat.h" + +#if defined (HAVE_UNISTD_H) +# include +#endif + +#include "bashansi.h" +#include "bashintl.h" + +#include +#include + +#include "../bashintl.h" +#include "../shell.h" +#include "common.h" +#include "bashgetopt.h" + +#if !defined (errno) +extern int errno; +#endif + +#if defined (ARRAY_VARS) + +static int run_callback PARAMS((const char *, unsigned int, const char *)); + +#define DEFAULT_ARRAY_NAME "MAPFILE" +#define DEFAULT_VARIABLE_NAME "MAPLINE" /* not used right now */ + +/* The value specifying how frequently `mapfile' calls the callback. */ +#define DEFAULT_QUANTUM 5000 + +/* Values for FLAGS */ +#define MAPF_CLEARARRAY 0x01 +#define MAPF_CHOP 0x02 + +static int delim; + +static int +run_callback (callback, curindex, curline) + const char *callback; + unsigned int curindex; + const char *curline; +{ + unsigned int execlen; + char *execstr, *qline; + int flags; + + qline = sh_single_quote (curline); + execlen = strlen (callback) + strlen (qline) + 10; + /* 1 for each space between %s and %d, + another 1 for the last nul char for C string. */ + execlen += 3; + execstr = xmalloc (execlen); + + flags = SEVAL_NOHIST; +#if 0 + if (interactive) + flags |= SEVAL_INTERACT; +#endif + snprintf (execstr, execlen, "%s %d %s", callback, curindex, qline); + free (qline); + return evalstring (execstr, NULL, flags); +} + +static void +do_chop(line, delim) + char *line; + unsigned char delim; +{ + int length; + + length = strlen (line); + if (length && line[length-1] == delim) + line[length-1] = '\0'; +} + +static int +mapfile (fd, line_count_goal, origin, nskip, callback_quantum, callback, array_name, delim, flags) + int fd; + long line_count_goal, origin, nskip, callback_quantum; + char *callback, *array_name; + int delim; + int flags; +{ + char *line; + size_t line_length; + unsigned int array_index, line_count; + SHELL_VAR *entry; + int unbuffered_read; + + line = NULL; + line_length = 0; + unbuffered_read = 0; + + /* The following check should be done before reading any lines. Doing it + here allows us to call bind_array_element instead of bind_array_variable + and skip the variable lookup on every call. */ + entry = find_or_make_array_variable (array_name, 1); + if (entry == 0 || readonly_p (entry) || noassign_p (entry)) + { + if (entry && readonly_p (entry)) + err_readonly (array_name); + + return (EXECUTION_FAILURE); + } + else if (array_p (entry) == 0) + { + builtin_error (_("%s: not an indexed array"), array_name); + return (EXECUTION_FAILURE); + } + else if (invisible_p (entry)) + VUNSETATTR (entry, att_invisible); /* no longer invisible */ + + if (flags & MAPF_CLEARARRAY) + array_flush (array_cell (entry)); + +#ifndef __CYGWIN__ + unbuffered_read = (lseek (fd, 0L, SEEK_CUR) < 0) && (errno == ESPIPE); +#else + unbuffered_read = 1; +#endif + + if (delim != '\n') + unbuffered_read = 1; + + zreset (); + + /* Skip any lines at beginning of file? */ + for (line_count = 0; line_count < nskip; line_count++) + if (zgetline (fd, &line, &line_length, delim, unbuffered_read) < 0) + break; + + line = 0; + line_length = 0; + + /* Reset the buffer for bash own stream */ + for (array_index = origin, line_count = 1; + zgetline (fd, &line, &line_length, delim, unbuffered_read) != -1; + array_index++) + { + /* Remove trailing newlines? */ + if (flags & MAPF_CHOP) + do_chop (line, delim); + + /* Has a callback been registered and if so is it time to call it? */ + if (callback && line_count && (line_count % callback_quantum) == 0) + { + run_callback (callback, array_index, line); + + /* Reset the buffer for bash own stream. */ + if (unbuffered_read == 0) + zsyncfd (fd); + } + + /* XXX - bad things can happen if the callback modifies ENTRY, e.g., + unsetting it or changing it to a non-indexed-array type. */ + bind_array_element (entry, array_index, line, 0); + + /* Have we exceeded # of lines to store? */ + line_count++; + if (line_count_goal != 0 && line_count > line_count_goal) + break; + } + + free (line); + + if (unbuffered_read == 0) + zsyncfd (fd); + + return EXECUTION_SUCCESS; +} + +int +mapfile_builtin (list) + WORD_LIST *list; +{ + int opt, code, fd, flags; + intmax_t intval; + long lines, origin, nskip, callback_quantum; + char *array_name, *callback; + + fd = 0; + lines = origin = nskip = 0; + flags = MAPF_CLEARARRAY; + callback_quantum = DEFAULT_QUANTUM; + callback = 0; + delim = '\n'; + + reset_internal_getopt (); + while ((opt = internal_getopt (list, "d:u:n:O:tC:c:s:")) != -1) + { + switch (opt) + { + case 'd': + delim = *list_optarg; + 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 'n': + code = legal_number (list_optarg, &intval); + if (code == 0 || intval < 0 || intval != (unsigned)intval) + { + builtin_error (_("%s: invalid line count"), list_optarg); + return (EXECUTION_FAILURE); + } + else + lines = intval; + break; + + case 'O': + code = legal_number (list_optarg, &intval); + if (code == 0 || intval < 0 || intval != (unsigned)intval) + { + builtin_error (_("%s: invalid array origin"), list_optarg); + return (EXECUTION_FAILURE); + } + else + origin = intval; + flags &= ~MAPF_CLEARARRAY; + break; + case 't': + flags |= MAPF_CHOP; + break; + case 'C': + callback = list_optarg; + break; + case 'c': + code = legal_number (list_optarg, &intval); + if (code == 0 || intval <= 0 || intval != (unsigned)intval) + { + builtin_error (_("%s: invalid callback quantum"), list_optarg); + return (EXECUTION_FAILURE); + } + else + callback_quantum = intval; + break; + case 's': + code = legal_number (list_optarg, &intval); + if (code == 0 || intval < 0 || intval != (unsigned)intval) + { + builtin_error (_("%s: invalid line count"), list_optarg); + return (EXECUTION_FAILURE); + } + else + nskip = intval; + break; + CASE_HELPOPT; + default: + builtin_usage (); + return (EX_USAGE); + } + } + list = loptend; + + if (list == 0) + array_name = DEFAULT_ARRAY_NAME; + else if (list->word == 0 || list->word->word == 0) + { + builtin_error ("internal error: getting variable name"); + return (EXECUTION_FAILURE); + } + else if (list->word->word[0] == '\0') + { + builtin_error (_("empty array variable name")); + return (EX_USAGE); + } + else + array_name = list->word->word; + + if (legal_identifier (array_name) == 0) + { + sh_invalidid (array_name); + return (EXECUTION_FAILURE); + } + + return mapfile (fd, lines, origin, nskip, callback_quantum, callback, array_name, delim, flags); +} + +#else + +int +mapfile_builtin (list) + WORD_LIST *list; +{ + builtin_error (_("array variable support required")); + return (EXECUTION_FAILURE); +} + +#endif /* ARRAY_VARS */ diff --git a/builtins/pipesize.h b/builtins/pipesize.h new file mode 100644 index 0000000..816a0b2 --- /dev/null +++ b/builtins/pipesize.h @@ -0,0 +1,8 @@ +/* + * pipesize.h + * + * This file is automatically generated by psize.sh + * Do not edit! + */ + +#define PIPESIZE 65536 diff --git a/builtins/printf.c b/builtins/printf.c new file mode 100644 index 0000000..b2d64d6 --- /dev/null +++ b/builtins/printf.c @@ -0,0 +1,1222 @@ +/* printf.c, created from printf.def. */ +#line 22 "./printf.def" + +#line 55 "./printf.def" + +#include + +#include "../bashtypes.h" + +#include +#if defined (HAVE_LIMITS_H) +# include +#else + /* Assume 32-bit ints. */ +# define INT_MAX 2147483647 +# define INT_MIN (-2147483647-1) +#endif + +#if defined (PREFER_STDARG) +# include +#else +# include +#endif + +#include +#include + +#ifdef HAVE_INTTYPES_H +# include +#endif + +#include "posixtime.h" +#include "../bashansi.h" +#include "../bashintl.h" + +#define NEED_STRFTIME_DECL + +#include "../shell.h" +#include "shmbutil.h" +#include "stdc.h" +#include "bashgetopt.h" +#include "common.h" + +#if defined (PRI_MACROS_BROKEN) +# undef PRIdMAX +#endif + +#if !defined (PRIdMAX) +# if HAVE_LONG_LONG +# define PRIdMAX "lld" +# else +# define PRIdMAX "ld" +# endif +#endif + +#if !defined (errno) +extern int errno; +#endif + +#define PC(c) \ + do { \ + char b[2]; \ + tw++; \ + b[0] = c; b[1] = '\0'; \ + if (vflag) \ + vbadd (b, 1); \ + else \ + putchar (c); \ + QUIT; \ + } while (0) + +#define PF(f, func) \ + do { \ + int nw; \ + clearerr (stdout); \ + if (have_fieldwidth && have_precision) \ + nw = vflag ? vbprintf (f, fieldwidth, precision, func) : printf (f, fieldwidth, precision, func); \ + else if (have_fieldwidth) \ + nw = vflag ? vbprintf (f, fieldwidth, func) : printf (f, fieldwidth, func); \ + else if (have_precision) \ + nw = vflag ? vbprintf (f, precision, func) : printf (f, precision, func); \ + else \ + nw = vflag ? vbprintf (f, func) : printf (f, func); \ + tw += nw; \ + QUIT; \ + if (ferror (stdout)) \ + { \ + sh_wrerror (); \ + clearerr (stdout); \ + return (EXECUTION_FAILURE); \ + } \ + } while (0) + +/* We free the buffer used by mklong() if it's `too big'. */ +#define PRETURN(value) \ + do \ + { \ + QUIT; \ + if (vflag) \ + { \ + SHELL_VAR *v; \ + v = builtin_bind_variable (vname, vbuf, 0); \ + stupidly_hack_special_variables (vname); \ + if (v == 0 || readonly_p (v) || noassign_p (v)) \ + return (EXECUTION_FAILURE); \ + } \ + if (conv_bufsize > 4096 ) \ + { \ + free (conv_buf); \ + conv_bufsize = 0; \ + conv_buf = 0; \ + } \ + if (vbsize > 4096) \ + { \ + free (vbuf); \ + vbsize = 0; \ + vbuf = 0; \ + } \ + else if (vbuf) \ + vbuf[0] = 0; \ + if (ferror (stdout) == 0) \ + fflush (stdout); \ + QUIT; \ + if (ferror (stdout)) \ + { \ + sh_wrerror (); \ + clearerr (stdout); \ + return (EXECUTION_FAILURE); \ + } \ + return (value); \ + } \ + while (0) + +#define SKIP1 "#'-+ 0" +#define LENMODS "hjlLtz" + +extern time_t shell_start_time; + +#if !HAVE_ASPRINTF +extern int asprintf PARAMS((char **, const char *, ...)) __attribute__((__format__ (printf, 2, 3))); +#endif + +#if !HAVE_VSNPRINTF +extern int vsnprintf PARAMS((char *, size_t, const char *, va_list)) __attribute__((__format__ (printf, 3, 0))); +#endif + +static void printf_erange PARAMS((char *)); +static int printstr PARAMS((char *, char *, int, int, int)); +static int tescape PARAMS((char *, char *, int *, int *)); +static char *bexpand PARAMS((char *, int, int *, int *)); +static char *vbadd PARAMS((char *, int)); +static int vbprintf PARAMS((const char *, ...)) __attribute__((__format__ (printf, 1, 2))); +static char *mklong PARAMS((char *, char *, size_t)); +static int getchr PARAMS((void)); +static char *getstr PARAMS((void)); +static int getint PARAMS((void)); +static intmax_t getintmax PARAMS((void)); +static uintmax_t getuintmax PARAMS((void)); + +#if defined (HAVE_LONG_DOUBLE) && HAVE_DECL_STRTOLD && !defined(STRTOLD_BROKEN) +typedef long double floatmax_t; +# define FLOATMAX_CONV "L" +# define strtofltmax strtold +#else +typedef double floatmax_t; +# define FLOATMAX_CONV "" +# define strtofltmax strtod +#endif +static floatmax_t getfloatmax PARAMS((void)); + +static intmax_t asciicode PARAMS((void)); + +static WORD_LIST *garglist, *orig_arglist; +static int retval; +static int conversion_error; + +/* printf -v var support */ +static int vflag = 0; +static char *vbuf, *vname; +static size_t vbsize; +static int vblen; + +static intmax_t tw; + +static char *conv_buf; +static size_t conv_bufsize; + +int +printf_builtin (list) + WORD_LIST *list; +{ + int ch, fieldwidth, precision; + int have_fieldwidth, have_precision; + char convch, thisch, nextch, *format, *modstart, *fmt, *start; +#if defined (HANDLE_MULTIBYTE) + char mbch[25]; /* 25 > MB_LEN_MAX, plus can handle 4-byte UTF-8 and large Unicode characters*/ + int mbind, mblen; +#endif +#if defined (ARRAY_VARS) + int arrayflags; +#endif + + conversion_error = 0; + retval = EXECUTION_SUCCESS; + + vflag = 0; + + reset_internal_getopt (); + while ((ch = internal_getopt (list, "v:")) != -1) + { + switch (ch) + { + case 'v': + vname = list_optarg; +#if defined (ARRAY_VARS) + arrayflags = assoc_expand_once ? (VA_NOEXPAND|VA_ONEWORD) : 0; + if (legal_identifier (vname) || valid_array_reference (vname, arrayflags)) +#else + if (legal_identifier (vname)) +#endif + { + vflag = 1; + if (vbsize == 0) + vbuf = xmalloc (vbsize = 16); + vblen = 0; + if (vbuf) + vbuf[0] = 0; + } + else + { + sh_invalidid (vname); + return (EX_USAGE); + } + break; + CASE_HELPOPT; + default: + builtin_usage (); + return (EX_USAGE); + } + } + list = loptend; /* skip over possible `--' */ + + if (list == 0) + { + builtin_usage (); + return (EX_USAGE); + } + + /* Allow printf -v var "" to act like var="" */ + if (vflag && list->word->word && list->word->word[0] == '\0') + { + SHELL_VAR *v; + v = builtin_bind_variable (vname, "", 0); + stupidly_hack_special_variables (vname); + return ((v == 0 || readonly_p (v) || noassign_p (v)) ? EXECUTION_FAILURE : EXECUTION_SUCCESS); + } + + if (list->word->word == 0 || list->word->word[0] == '\0') + return (EXECUTION_SUCCESS); + + format = list->word->word; + tw = 0; + + garglist = orig_arglist = list->next; + + /* If the format string is empty after preprocessing, return immediately. */ + if (format == 0 || *format == 0) + return (EXECUTION_SUCCESS); + + /* Basic algorithm is to scan the format string for conversion + specifications -- once one is found, find out if the field + width or precision is a '*'; if it is, gather up value. Note, + format strings are reused as necessary to use up the provided + arguments, arguments of zero/null string are provided to use + up the format string. */ + do + { + tw = 0; + /* find next format specification */ + for (fmt = format; *fmt; fmt++) + { + precision = fieldwidth = 0; + have_fieldwidth = have_precision = 0; + + if (*fmt == '\\') + { + fmt++; + /* A NULL third argument to tescape means to bypass the + special processing for arguments to %b. */ +#if defined (HANDLE_MULTIBYTE) + /* Accommodate possible use of \u or \U, which can result in + multibyte characters */ + memset (mbch, '\0', sizeof (mbch)); + fmt += tescape (fmt, mbch, &mblen, (int *)NULL); + for (mbind = 0; mbind < mblen; mbind++) + PC (mbch[mbind]); +#else + fmt += tescape (fmt, &nextch, (int *)NULL, (int *)NULL); + PC (nextch); +#endif + fmt--; /* for loop will increment it for us again */ + continue; + } + + if (*fmt != '%') + { + PC (*fmt); + continue; + } + + /* ASSERT(*fmt == '%') */ + start = fmt++; + + if (*fmt == '%') /* %% prints a % */ + { + PC ('%'); + continue; + } + + /* found format specification, skip to field width */ + for (; *fmt && strchr(SKIP1, *fmt); ++fmt) + ; + + /* Skip optional field width. */ + if (*fmt == '*') + { + fmt++; + have_fieldwidth = 1; + fieldwidth = getint (); + } + else + while (DIGIT (*fmt)) + fmt++; + + /* Skip optional '.' and precision */ + if (*fmt == '.') + { + ++fmt; + if (*fmt == '*') + { + fmt++; + have_precision = 1; + precision = getint (); + } + else + { + /* Negative precisions are allowed but treated as if the + precision were missing; I would like to allow a leading + `+' in the precision number as an extension, but lots + of asprintf/fprintf implementations get this wrong. */ +#if 0 + if (*fmt == '-' || *fmt == '+') +#else + if (*fmt == '-') +#endif + fmt++; + while (DIGIT (*fmt)) + fmt++; + } + } + + /* skip possible format modifiers */ + modstart = fmt; + while (*fmt && strchr (LENMODS, *fmt)) + fmt++; + + if (*fmt == 0) + { + builtin_error (_("`%s': missing format character"), start); + PRETURN (EXECUTION_FAILURE); + } + + convch = *fmt; + thisch = modstart[0]; + nextch = modstart[1]; + modstart[0] = convch; + modstart[1] = '\0'; + + QUIT; + switch(convch) + { + case 'c': + { + char p; + + p = getchr (); + PF(start, p); + break; + } + + case 's': + { + char *p; + + p = getstr (); + PF(start, p); + break; + } + + case '(': + { + char *timefmt, timebuf[128], *t; + int n; + intmax_t arg; + time_t secs; + struct tm *tm; + + modstart[1] = nextch; /* restore char after left paren */ + timefmt = xmalloc (strlen (fmt) + 3); + fmt++; /* skip over left paren */ + for (t = timefmt, n = 1; *fmt; ) + { + if (*fmt == '(') + n++; + else if (*fmt == ')') + n--; + if (n == 0) + break; + *t++ = *fmt++; + } + *t = '\0'; + if (*++fmt != 'T') + { + builtin_warning (_("`%c': invalid time format specification"), *fmt); + fmt = start; + free (timefmt); + PC (*fmt); + continue; + } + if (timefmt[0] == '\0') + { + timefmt[0] = '%'; + timefmt[1] = 'X'; /* locale-specific current time - should we use `+'? */ + timefmt[2] = '\0'; + } + /* argument is seconds since the epoch with special -1 and -2 */ + /* default argument is equivalent to -1; special case */ + arg = garglist ? getintmax () : -1; + if (arg == -1) + secs = NOW; /* roughly date +%s */ + else if (arg == -2) + secs = shell_start_time; /* roughly $SECONDS */ + else + secs = arg; +#if defined (HAVE_TZSET) + sv_tz ("TZ"); /* XXX -- just make sure */ +#endif + tm = localtime (&secs); + if (tm == 0) + { + secs = 0; + tm = localtime (&secs); + } + n = tm ? strftime (timebuf, sizeof (timebuf), timefmt, tm) : 0; + free (timefmt); + if (n == 0) + timebuf[0] = '\0'; + else + timebuf[sizeof(timebuf) - 1] = '\0'; + /* convert to %s format that preserves fieldwidth and precision */ + modstart[0] = 's'; + modstart[1] = '\0'; + n = printstr (start, timebuf, strlen (timebuf), fieldwidth, precision); /* XXX - %s for now */ + if (n < 0) + { + if (ferror (stdout) == 0) + { + sh_wrerror (); + clearerr (stdout); + } + PRETURN (EXECUTION_FAILURE); + } + break; + } + + case 'n': + { + char *var; + + var = getstr (); + if (var && *var) + { + if (legal_identifier (var)) + bind_var_to_int (var, tw); + else + { + sh_invalidid (var); + PRETURN (EXECUTION_FAILURE); + } + } + break; + } + + case 'b': /* expand escapes in argument */ + { + char *p, *xp; + int rlen, r; + + p = getstr (); + ch = rlen = r = 0; + xp = bexpand (p, strlen (p), &ch, &rlen); + + if (xp) + { + /* Have to use printstr because of possible NUL bytes + in XP -- printf does not handle that well. */ + r = printstr (start, xp, rlen, fieldwidth, precision); + if (r < 0) + { + if (ferror (stdout) == 0) + { + sh_wrerror (); + clearerr (stdout); + } + retval = EXECUTION_FAILURE; + } + free (xp); + } + + if (ch || r < 0) + PRETURN (retval); + break; + } + + case 'q': /* print with shell quoting */ + { + char *p, *xp; + int r; + + r = 0; + p = getstr (); + if (p && *p == 0) /* XXX - getstr never returns null */ + xp = savestring ("''"); + else if (ansic_shouldquote (p)) + xp = ansic_quote (p, 0, (int *)0); + else + xp = sh_backslash_quote (p, 0, 3); + if (xp) + { + /* Use printstr to get fieldwidth and precision right. */ + r = printstr (start, xp, strlen (xp), fieldwidth, precision); + if (r < 0) + { + sh_wrerror (); + clearerr (stdout); + } + free (xp); + } + + if (r < 0) + PRETURN (EXECUTION_FAILURE); + break; + } + + case 'd': + case 'i': + { + char *f; + long p; + intmax_t pp; + + p = pp = getintmax (); + if (p != pp) + { + f = mklong (start, PRIdMAX, sizeof (PRIdMAX) - 2); + PF (f, pp); + } + else + { + /* Optimize the common case where the integer fits + in "long". This also works around some long + long and/or intmax_t library bugs in the common + case, e.g. glibc 2.2 x86. */ + f = mklong (start, "l", 1); + PF (f, p); + } + break; + } + + case 'o': + case 'u': + case 'x': + case 'X': + { + char *f; + unsigned long p; + uintmax_t pp; + + p = pp = getuintmax (); + if (p != pp) + { + f = mklong (start, PRIdMAX, sizeof (PRIdMAX) - 2); + PF (f, pp); + } + else + { + f = mklong (start, "l", 1); + PF (f, p); + } + break; + } + + case 'e': + case 'E': + case 'f': + case 'F': + case 'g': + case 'G': +#if defined (HAVE_PRINTF_A_FORMAT) + case 'a': + case 'A': +#endif + { + char *f; + floatmax_t p; + + p = getfloatmax (); + f = mklong (start, FLOATMAX_CONV, sizeof(FLOATMAX_CONV) - 1); + PF (f, p); + break; + } + + /* We don't output unrecognized format characters; we print an + error message and return a failure exit status. */ + default: + builtin_error (_("`%c': invalid format character"), convch); + PRETURN (EXECUTION_FAILURE); + } + + modstart[0] = thisch; + modstart[1] = nextch; + } + + if (ferror (stdout)) + { + /* PRETURN will print error message. */ + PRETURN (EXECUTION_FAILURE); + } + } + while (garglist && garglist != list->next); + + if (conversion_error) + retval = EXECUTION_FAILURE; + + PRETURN (retval); +} + +static void +printf_erange (s) + char *s; +{ + builtin_error (_("warning: %s: %s"), s, strerror(ERANGE)); +} + +/* We duplicate a lot of what printf(3) does here. */ +static int +printstr (fmt, string, len, fieldwidth, precision) + char *fmt; /* format */ + char *string; /* expanded string argument */ + int len; /* length of expanded string */ + int fieldwidth; /* argument for width of `*' */ + int precision; /* argument for precision of `*' */ +{ +#if 0 + char *s; +#endif + int padlen, nc, ljust, i; + int fw, pr; /* fieldwidth and precision */ + intmax_t mfw, mpr; + + if (string == 0) + string = ""; + +#if 0 + s = fmt; +#endif + if (*fmt == '%') + fmt++; + + ljust = fw = 0; + pr = -1; + mfw = 0; + mpr = -1; + + /* skip flags */ + while (strchr (SKIP1, *fmt)) + { + if (*fmt == '-') + ljust = 1; + fmt++; + } + + /* get fieldwidth, if present. rely on caller to clamp fieldwidth at INT_MAX */ + if (*fmt == '*') + { + fmt++; + fw = fieldwidth; + if (fw < 0) + { + fw = -fw; + ljust = 1; + } + } + else if (DIGIT (*fmt)) + { + mfw = *fmt++ - '0'; + while (DIGIT (*fmt)) + mfw = (mfw * 10) + (*fmt++ - '0'); + /* Error if fieldwidth > INT_MAX here? */ + fw = (mfw < 0 || mfw > INT_MAX) ? INT_MAX : mfw; + } + + /* get precision, if present */ + if (*fmt == '.') + { + fmt++; + if (*fmt == '*') + { + fmt++; + pr = precision; + } + else if (DIGIT (*fmt)) + { + mpr = *fmt++ - '0'; + while (DIGIT (*fmt)) + mpr = (mpr * 10) + (*fmt++ - '0'); + /* Error if precision > INT_MAX here? */ + pr = (mpr < 0 || mpr > INT_MAX) ? INT_MAX : mpr; + } + else + pr = 0; /* "a null digit string is treated as zero" */ + } + +#if 0 + /* If we remove this, get rid of `s'. */ + if (*fmt != 'b' && *fmt != 'q') + { + internal_error (_("format parsing problem: %s"), s); + fw = pr = 0; + } +#endif + + /* chars from string to print */ + nc = (pr >= 0 && pr <= len) ? pr : len; + + padlen = fw - nc; + if (padlen < 0) + padlen = 0; + if (ljust) + padlen = -padlen; + + /* leading pad characters */ + for (; padlen > 0; padlen--) + PC (' '); + + /* output NC characters from STRING */ + for (i = 0; i < nc; i++) + PC (string[i]); + + /* output any necessary trailing padding */ + for (; padlen < 0; padlen++) + PC (' '); + + return (ferror (stdout) ? -1 : 0); +} + +/* Convert STRING by expanding the escape sequences specified by the + POSIX standard for printf's `%b' format string. If SAWC is non-null, + perform the processing appropriate for %b arguments. In particular, + recognize `\c' and use that as a string terminator. If we see \c, set + *SAWC to 1 before returning. LEN is the length of STRING. */ + +/* Translate a single backslash-escape sequence starting at ESTART (the + character after the backslash) and return the number of characters + consumed by the sequence. CP is the place to return the translated + value. *SAWC is set to 1 if the escape sequence was \c, since that means + to short-circuit the rest of the processing. If SAWC is null, we don't + do the \c short-circuiting, and \c is treated as an unrecognized escape + sequence; we also bypass the other processing specific to %b arguments. */ +static int +tescape (estart, cp, lenp, sawc) + char *estart; + char *cp; + int *lenp, *sawc; +{ + register char *p; + int temp, c, evalue; + unsigned long uvalue; + + p = estart; + if (lenp) + *lenp = 1; + + switch (c = *p++) + { +#if defined (__STDC__) + case 'a': *cp = '\a'; break; +#else + case 'a': *cp = '\007'; break; +#endif + + case 'b': *cp = '\b'; break; + + case 'e': + case 'E': *cp = '\033'; break; /* ESC -- non-ANSI */ + + case 'f': *cp = '\f'; break; + + case 'n': *cp = '\n'; break; + + case 'r': *cp = '\r'; break; + + case 't': *cp = '\t'; break; + + case 'v': *cp = '\v'; break; + + /* The octal escape sequences are `\0' followed by up to three octal + digits (if SAWC), or `\' followed by up to three octal digits (if + !SAWC). As an extension, we allow the latter form even if SAWC. */ + case '0': case '1': case '2': case '3': + case '4': case '5': case '6': case '7': + evalue = OCTVALUE (c); + for (temp = 2 + (!evalue && !!sawc); ISOCTAL (*p) && temp--; p++) + evalue = (evalue * 8) + OCTVALUE (*p); + *cp = evalue & 0xFF; + break; + + /* And, as another extension, we allow \xNN, where each N is a + hex digit. */ + case 'x': + for (temp = 2, evalue = 0; ISXDIGIT ((unsigned char)*p) && temp--; p++) + evalue = (evalue * 16) + HEXVALUE (*p); + if (p == estart + 1) + { + builtin_error (_("missing hex digit for \\x")); + *cp = '\\'; + return 0; + } + *cp = evalue & 0xFF; + break; + +#if defined (HANDLE_MULTIBYTE) + case 'u': + case 'U': + temp = (c == 'u') ? 4 : 8; /* \uNNNN \UNNNNNNNN */ + for (uvalue = 0; ISXDIGIT ((unsigned char)*p) && temp--; p++) + uvalue = (uvalue * 16) + HEXVALUE (*p); + if (p == estart + 1) + { + builtin_error (_("missing unicode digit for \\%c"), c); + *cp = '\\'; + return 0; + } + if (uvalue <= 0x7f) /* <= 0x7f translates directly */ + *cp = uvalue; + else + { + temp = u32cconv (uvalue, cp); + cp[temp] = '\0'; + if (lenp) + *lenp = temp; + } + break; +#endif + + case '\\': /* \\ -> \ */ + *cp = c; + break; + + /* SAWC == 0 means that \', \", and \? are recognized as escape + sequences, though the only processing performed is backslash + removal. */ + case '\'': case '"': case '?': + if (!sawc) + *cp = c; + else + { + *cp = '\\'; + return 0; + } + break; + + case 'c': + if (sawc) + { + *sawc = 1; + break; + } + /* other backslash escapes are passed through unaltered */ + default: + *cp = '\\'; + return 0; + } + return (p - estart); +} + +static char * +bexpand (string, len, sawc, lenp) + char *string; + int len, *sawc, *lenp; +{ + int temp; + char *ret, *r, *s, c; +#if defined (HANDLE_MULTIBYTE) + char mbch[25]; + int mbind, mblen; +#endif + + if (string == 0 || len == 0) + { + if (sawc) + *sawc = 0; + if (lenp) + *lenp = 0; + ret = (char *)xmalloc (1); + ret[0] = '\0'; + return (ret); + } + + ret = (char *)xmalloc (len + 1); + for (r = ret, s = string; s && *s; ) + { + c = *s++; + if (c != '\\' || *s == '\0') + { + *r++ = c; + continue; + } + temp = 0; +#if defined (HANDLE_MULTIBYTE) + memset (mbch, '\0', sizeof (mbch)); + s += tescape (s, mbch, &mblen, &temp); +#else + s += tescape (s, &c, (int *)NULL, &temp); +#endif + if (temp) + { + if (sawc) + *sawc = 1; + break; + } + +#if defined (HANDLE_MULTIBYTE) + for (mbind = 0; mbind < mblen; mbind++) + *r++ = mbch[mbind]; +#else + *r++ = c; +#endif + } + + *r = '\0'; + if (lenp) + *lenp = r - ret; + return ret; +} + +static char * +vbadd (buf, blen) + char *buf; + int blen; +{ + size_t nlen; + + nlen = vblen + blen + 1; + if (nlen >= vbsize) + { + vbsize = ((nlen + 63) >> 6) << 6; + vbuf = (char *)xrealloc (vbuf, vbsize); + } + + if (blen == 1) + vbuf[vblen++] = buf[0]; + else if (blen > 1) + { + FASTCOPY (buf, vbuf + vblen, blen); + vblen += blen; + } + vbuf[vblen] = '\0'; + +#ifdef DEBUG + if (strlen (vbuf) != vblen) + internal_error ("printf:vbadd: vblen (%d) != strlen (vbuf) (%d)", vblen, (int)strlen (vbuf)); +#endif + + return vbuf; +} + +static int +#if defined (PREFER_STDARG) +vbprintf (const char *format, ...) +#else +vbprintf (format, va_alist) + const char *format; + va_dcl +#endif +{ + va_list args; + size_t nlen; + int blen; + + SH_VA_START (args, format); + blen = vsnprintf (vbuf + vblen, vbsize - vblen, format, args); + va_end (args); + + nlen = vblen + blen + 1; + if (nlen >= vbsize) + { + vbsize = ((nlen + 63) >> 6) << 6; + vbuf = (char *)xrealloc (vbuf, vbsize); + SH_VA_START (args, format); + blen = vsnprintf (vbuf + vblen, vbsize - vblen, format, args); + va_end (args); + } + + vblen += blen; + vbuf[vblen] = '\0'; + +#ifdef DEBUG + if (strlen (vbuf) != vblen) + internal_error ("printf:vbprintf: vblen (%d) != strlen (vbuf) (%d)", vblen, (int)strlen (vbuf)); +#endif + + return (blen); +} + +static char * +mklong (str, modifiers, mlen) + char *str; + char *modifiers; + size_t mlen; +{ + size_t len, slen; + + slen = strlen (str); + len = slen + mlen + 1; + + if (len > conv_bufsize) + { + conv_bufsize = (((len + 1023) >> 10) << 10); + conv_buf = (char *)xrealloc (conv_buf, conv_bufsize); + } + + FASTCOPY (str, conv_buf, slen - 1); + FASTCOPY (modifiers, conv_buf + slen - 1, mlen); + + conv_buf[len - 2] = str[slen - 1]; + conv_buf[len - 1] = '\0'; + return (conv_buf); +} + +static int +getchr () +{ + int ret; + + if (garglist == 0) + return ('\0'); + + ret = (int)garglist->word->word[0]; + garglist = garglist->next; + return ret; +} + +static char * +getstr () +{ + char *ret; + + if (garglist == 0) + return (""); + + ret = garglist->word->word; + garglist = garglist->next; + return ret; +} + +static int +getint () +{ + intmax_t ret; + + ret = getintmax (); + + if (garglist == 0) + return ret; + + if (ret > INT_MAX) + { + printf_erange (garglist->word->word); + ret = INT_MAX; + } + else if (ret < INT_MIN) + { + printf_erange (garglist->word->word); + ret = INT_MIN; + } + + return ((int)ret); +} + +static intmax_t +getintmax () +{ + intmax_t ret; + char *ep; + + if (garglist == 0) + return (0); + + if (garglist->word->word[0] == '\'' || garglist->word->word[0] == '"') + return asciicode (); + + errno = 0; + ret = strtoimax (garglist->word->word, &ep, 0); + + if (*ep) + { + sh_invalidnum (garglist->word->word); + /* POSIX.2 says ``...a diagnostic message shall be written to standard + error, and the utility shall not exit with a zero exit status, but + shall continue processing any remaining operands and shall write the + value accumulated at the time the error was detected to standard + output.'' Yecch. */ +#if 0 + ret = 0; /* return partially-converted value from strtoimax */ +#endif + conversion_error = 1; + } + else if (errno == ERANGE) + printf_erange (garglist->word->word); + + garglist = garglist->next; + return (ret); +} + +static uintmax_t +getuintmax () +{ + uintmax_t ret; + char *ep; + + if (garglist == 0) + return (0); + + if (garglist->word->word[0] == '\'' || garglist->word->word[0] == '"') + return asciicode (); + + errno = 0; + ret = strtoumax (garglist->word->word, &ep, 0); + + if (*ep) + { + sh_invalidnum (garglist->word->word); +#if 0 + /* Same POSIX.2 conversion error requirements as getintmax(). */ + ret = 0; +#endif + conversion_error = 1; + } + else if (errno == ERANGE) + printf_erange (garglist->word->word); + + garglist = garglist->next; + return (ret); +} + +static floatmax_t +getfloatmax () +{ + floatmax_t ret; + char *ep; + + if (garglist == 0) + return (0); + + if (garglist->word->word[0] == '\'' || garglist->word->word[0] == '"') + return asciicode (); + + errno = 0; + ret = strtofltmax (garglist->word->word, &ep); + + if (*ep) + { + sh_invalidnum (garglist->word->word); +#if 0 + /* Same thing about POSIX.2 conversion error requirements. */ + ret = 0; +#endif + conversion_error = 1; + } + else if (errno == ERANGE) + printf_erange (garglist->word->word); + + garglist = garglist->next; + return (ret); +} + +/* NO check is needed for garglist here. */ +static intmax_t +asciicode () +{ + register intmax_t ch; +#if defined (HANDLE_MULTIBYTE) + wchar_t wc; + size_t slen; + int mblength; +#endif + DECLARE_MBSTATE; + +#if defined (HANDLE_MULTIBYTE) + slen = strlen (garglist->word->word+1); + wc = 0; + mblength = mbtowc (&wc, garglist->word->word+1, slen); + if (mblength > 0) + ch = wc; /* XXX */ + else +#endif + ch = (unsigned char)garglist->word->word[1]; + + garglist = garglist->next; + return (ch); +} diff --git a/builtins/pushd.c b/builtins/pushd.c new file mode 100644 index 0000000..a8154ef --- /dev/null +++ b/builtins/pushd.c @@ -0,0 +1,690 @@ +/* pushd.c, created from pushd.def. */ +#line 22 "./pushd.def" + +#line 55 "./pushd.def" + +#line 84 "./pushd.def" + +#line 115 "./pushd.def" + +#include + +#if defined (PUSHD_AND_POPD) +#include +#if defined (HAVE_SYS_PARAM_H) +# include +#endif + +#if defined (HAVE_UNISTD_H) +# ifdef _MINIX +# include +# endif +# include +#endif + +#include "../bashansi.h" +#include "../bashintl.h" + +#include + +#include + +#include "../shell.h" +#include "maxpath.h" +#include "common.h" +#include "builtext.h" + +#ifdef LOADABLE_BUILTIN +# include "builtins.h" +#endif + +#if !defined (errno) +extern int errno; +#endif /* !errno */ + +/* The list of remembered directories. */ +static char **pushd_directory_list = (char **)NULL; + +/* Number of existing slots in this list. */ +static int directory_list_size; + +/* Offset to the end of the list. */ +static int directory_list_offset; + +static void pushd_error PARAMS((int, char *)); +static void clear_directory_stack PARAMS((void)); +static int cd_to_string PARAMS((char *)); +static int change_to_temp PARAMS((char *)); +static void add_dirstack_element PARAMS((char *)); +static int get_dirstack_index PARAMS((intmax_t, int, int *)); + +#define NOCD 0x01 +#define ROTATE 0x02 +#define LONGFORM 0x04 +#define CLEARSTAK 0x08 + +int +pushd_builtin (list) + WORD_LIST *list; +{ + WORD_LIST *orig_list; + char *temp, *current_directory, *top; + int j, flags, skipopt; + intmax_t num; + char direction; + + orig_list = list; + + CHECK_HELPOPT (list); + if (list && list->word && ISOPTION (list->word->word, '-')) + { + list = list->next; + skipopt = 1; + } + else + skipopt = 0; + + /* If there is no argument list then switch current and + top of list. */ + if (list == 0) + { + if (directory_list_offset == 0) + { + builtin_error (_("no other directory")); + return (EXECUTION_FAILURE); + } + + current_directory = get_working_directory ("pushd"); + if (current_directory == 0) + return (EXECUTION_FAILURE); + + j = directory_list_offset - 1; + temp = pushd_directory_list[j]; + pushd_directory_list[j] = current_directory; + j = change_to_temp (temp); + free (temp); + return j; + } + + for (flags = 0; skipopt == 0 && list; list = list->next) + { + if (ISOPTION (list->word->word, 'n')) + { + flags |= NOCD; + } + else if (ISOPTION (list->word->word, '-')) + { + list = list->next; + break; + } + else if (list->word->word[0] == '-' && list->word->word[1] == '\0') + /* Let `pushd -' work like it used to. */ + break; + else if (((direction = list->word->word[0]) == '+') || direction == '-') + { + if (legal_number (list->word->word + 1, &num) == 0) + { + sh_invalidnum (list->word->word); + builtin_usage (); + return (EX_USAGE); + } + + if (direction == '-') + num = directory_list_offset - num; + + if (num > directory_list_offset || num < 0) + { + pushd_error (directory_list_offset, list->word->word); + return (EXECUTION_FAILURE); + } + flags |= ROTATE; + } + else if (*list->word->word == '-') + { + sh_invalidopt (list->word->word); + builtin_usage (); + return (EX_USAGE); + } + else + break; + } + + if (flags & ROTATE) + { + /* Rotate the stack num times. Remember, the current + directory acts like it is part of the stack. */ + temp = get_working_directory ("pushd"); + + if (num == 0) + { + j = ((flags & NOCD) == 0) ? change_to_temp (temp) : EXECUTION_SUCCESS; + free (temp); + return j; + } + + do + { + top = pushd_directory_list[directory_list_offset - 1]; + + for (j = directory_list_offset - 2; j > -1; j--) + pushd_directory_list[j + 1] = pushd_directory_list[j]; + + pushd_directory_list[j + 1] = temp; + + temp = top; + num--; + } + while (num); + + j = ((flags & NOCD) == 0) ? change_to_temp (temp) : EXECUTION_SUCCESS; + free (temp); + return j; + } + + if (list == 0) + return (EXECUTION_SUCCESS); + + /* Change to the directory in list->word->word. Save the current + directory on the top of the stack. */ + current_directory = get_working_directory ("pushd"); + if (current_directory == 0) + return (EXECUTION_FAILURE); + + j = ((flags & NOCD) == 0) ? cd_builtin (skipopt ? orig_list : list) : EXECUTION_SUCCESS; + if (j == EXECUTION_SUCCESS) + { + add_dirstack_element ((flags & NOCD) ? savestring (list->word->word) : current_directory); + dirs_builtin ((WORD_LIST *)NULL); + if (flags & NOCD) + free (current_directory); + return (EXECUTION_SUCCESS); + } + else + { + free (current_directory); + return (EXECUTION_FAILURE); + } +} + +/* Pop the directory stack, and then change to the new top of the stack. + If LIST is non-null it should consist of a word +N or -N, which says + what element to delete from the stack. The default is the top one. */ +int +popd_builtin (list) + WORD_LIST *list; +{ + register int i; + intmax_t which; + int flags; + char direction; + char *which_word; + + CHECK_HELPOPT (list); + + which_word = (char *)NULL; + for (flags = 0, which = 0, direction = '+'; list; list = list->next) + { + if (ISOPTION (list->word->word, 'n')) + { + flags |= NOCD; + } + else if (ISOPTION (list->word->word, '-')) + { + list = list->next; + break; + } + else if (((direction = list->word->word[0]) == '+') || direction == '-') + { + if (legal_number (list->word->word + 1, &which) == 0) + { + sh_invalidnum (list->word->word); + builtin_usage (); + return (EX_USAGE); + } + which_word = list->word->word; + } + else if (*list->word->word == '-') + { + sh_invalidopt (list->word->word); + builtin_usage (); + return (EX_USAGE); + } + else if (*list->word->word) + { + builtin_error (_("%s: invalid argument"), list->word->word); + builtin_usage (); + return (EX_USAGE); + } + else + break; + } + + if (which > directory_list_offset || (which < -directory_list_offset) || (directory_list_offset == 0 && which == 0)) + { + pushd_error (directory_list_offset, which_word ? which_word : ""); + return (EXECUTION_FAILURE); + } + + /* Handle case of no specification, or top of stack specification. */ + if ((direction == '+' && which == 0) || + (direction == '-' && which == directory_list_offset)) + { + i = ((flags & NOCD) == 0) ? cd_to_string (pushd_directory_list[directory_list_offset - 1]) + : EXECUTION_SUCCESS; + if (i != EXECUTION_SUCCESS) + return (i); + free (pushd_directory_list[--directory_list_offset]); + } + else + { + /* Since an offset other than the top directory was specified, + remove that directory from the list and shift the remainder + of the list into place. */ + i = (direction == '+') ? directory_list_offset - which : which; + if (i < 0 || i > directory_list_offset) + { + pushd_error (directory_list_offset, which_word ? which_word : ""); + return (EXECUTION_FAILURE); + } + free (pushd_directory_list[i]); + directory_list_offset--; + + /* Shift the remainder of the list into place. */ + for (; i < directory_list_offset; i++) + pushd_directory_list[i] = pushd_directory_list[i + 1]; + } + + dirs_builtin ((WORD_LIST *)NULL); + return (EXECUTION_SUCCESS); +} + +/* Print the current list of directories on the directory stack. */ +int +dirs_builtin (list) + WORD_LIST *list; +{ + int flags, desired_index, index_flag, vflag; + intmax_t i; + char *temp, *w; + + CHECK_HELPOPT (list); + for (flags = vflag = index_flag = 0, desired_index = -1, w = ""; list; list = list->next) + { + if (ISOPTION (list->word->word, 'l')) + { + flags |= LONGFORM; + } + else if (ISOPTION (list->word->word, 'c')) + { + flags |= CLEARSTAK; + } + else if (ISOPTION (list->word->word, 'v')) + { + vflag |= 2; + } + else if (ISOPTION (list->word->word, 'p')) + { + vflag |= 1; + } + else if (ISOPTION (list->word->word, '-')) + { + list = list->next; + break; + } + else if (*list->word->word == '+' || *list->word->word == '-') + { + int sign; + if (legal_number (w = list->word->word + 1, &i) == 0) + { + sh_invalidnum (list->word->word); + builtin_usage (); + return (EX_USAGE); + } + sign = (*list->word->word == '+') ? 1 : -1; + desired_index = get_dirstack_index (i, sign, &index_flag); + } + else + { + sh_invalidopt (list->word->word); + builtin_usage (); + return (EX_USAGE); + } + } + + if (flags & CLEARSTAK) + { + clear_directory_stack (); + return (EXECUTION_SUCCESS); + } + + if (index_flag && (desired_index < 0 || desired_index > directory_list_offset)) + { + pushd_error (directory_list_offset, w); + return (EXECUTION_FAILURE); + } + +#define DIRSTACK_FORMAT(temp) \ + (flags & LONGFORM) ? temp : polite_directory_format (temp) + + /* The first directory printed is always the current working directory. */ + if (index_flag == 0 || (index_flag == 1 && desired_index == 0)) + { + temp = get_working_directory ("dirs"); + if (temp == 0) + temp = savestring (_("")); + if (vflag & 2) + printf ("%2d %s", 0, DIRSTACK_FORMAT (temp)); + else + printf ("%s", DIRSTACK_FORMAT (temp)); + free (temp); + if (index_flag) + { + putchar ('\n'); + return (sh_chkwrite (EXECUTION_SUCCESS)); + } + } + +#define DIRSTACK_ENTRY(i) \ + (flags & LONGFORM) ? pushd_directory_list[i] \ + : polite_directory_format (pushd_directory_list[i]) + + /* Now print the requested directory stack entries. */ + if (index_flag) + { + if (vflag & 2) + printf ("%2d %s", directory_list_offset - desired_index, + DIRSTACK_ENTRY (desired_index)); + else + printf ("%s", DIRSTACK_ENTRY (desired_index)); + } + else + for (i = directory_list_offset - 1; i >= 0; i--) + if (vflag >= 2) + printf ("\n%2d %s", directory_list_offset - (int)i, DIRSTACK_ENTRY (i)); + else + printf ("%s%s", (vflag & 1) ? "\n" : " ", DIRSTACK_ENTRY (i)); + + putchar ('\n'); + + return (sh_chkwrite (EXECUTION_SUCCESS)); +} + +static void +pushd_error (offset, arg) + int offset; + char *arg; +{ + if (offset == 0) + builtin_error (_("directory stack empty")); + else + sh_erange (arg, _("directory stack index")); +} + +static void +clear_directory_stack () +{ + register int i; + + for (i = 0; i < directory_list_offset; i++) + free (pushd_directory_list[i]); + directory_list_offset = 0; +} + +/* Switch to the directory in NAME. This uses the cd_builtin to do the work, + so if the result is EXECUTION_FAILURE then an error message has already + been printed. */ +static int +cd_to_string (name) + char *name; +{ + WORD_LIST *tlist; + WORD_LIST *dir; + int result; + + dir = make_word_list (make_word (name), NULL); + tlist = make_word_list (make_word ("--"), dir); + result = cd_builtin (tlist); + dispose_words (tlist); + return (result); +} + +static int +change_to_temp (temp) + char *temp; +{ + int tt; + + tt = temp ? cd_to_string (temp) : EXECUTION_FAILURE; + + if (tt == EXECUTION_SUCCESS) + dirs_builtin ((WORD_LIST *)NULL); + + return (tt); +} + +static void +add_dirstack_element (dir) + char *dir; +{ + if (directory_list_offset == directory_list_size) + pushd_directory_list = strvec_resize (pushd_directory_list, directory_list_size += 10); + pushd_directory_list[directory_list_offset++] = dir; +} + +static int +get_dirstack_index (ind, sign, indexp) + intmax_t ind; + int sign, *indexp; +{ + if (indexp) + *indexp = sign > 0 ? 1 : 2; + + /* dirs +0 prints the current working directory. */ + /* dirs -0 prints last element in directory stack */ + if (ind == 0 && sign > 0) + return 0; + else if (ind == directory_list_offset) + { + if (indexp) + *indexp = sign > 0 ? 2 : 1; + return 0; + } + else if (ind >= 0 && ind <= directory_list_offset) + return (sign > 0 ? directory_list_offset - ind : ind); + else + return -1; +} + +/* Used by the tilde expansion code. */ +char * +get_dirstack_from_string (string) + char *string; +{ + int ind, sign, index_flag; + intmax_t i; + + sign = 1; + if (*string == '-' || *string == '+') + { + sign = (*string == '-') ? -1 : 1; + string++; + } + if (legal_number (string, &i) == 0) + return ((char *)NULL); + + index_flag = 0; + ind = get_dirstack_index (i, sign, &index_flag); + if (index_flag && (ind < 0 || ind > directory_list_offset)) + return ((char *)NULL); + if (index_flag == 0 || (index_flag == 1 && ind == 0)) + return (get_string_value ("PWD")); + else + return (pushd_directory_list[ind]); +} + +#ifdef INCLUDE_UNUSED +char * +get_dirstack_element (ind, sign) + intmax_t ind; + int sign; +{ + int i; + + i = get_dirstack_index (ind, sign, (int *)NULL); + return (i < 0 || i > directory_list_offset) ? (char *)NULL + : pushd_directory_list[i]; +} +#endif + +void +set_dirstack_element (ind, sign, value) + intmax_t ind; + int sign; + char *value; +{ + int i; + + i = get_dirstack_index (ind, sign, (int *)NULL); + if (ind == 0 || i < 0 || i > directory_list_offset) + return; + free (pushd_directory_list[i]); + pushd_directory_list[i] = savestring (value); +} + +WORD_LIST * +get_directory_stack (flags) + int flags; +{ + register int i; + WORD_LIST *ret; + char *d, *t; + + for (ret = (WORD_LIST *)NULL, i = 0; i < directory_list_offset; i++) + { + d = (flags&1) ? polite_directory_format (pushd_directory_list[i]) + : pushd_directory_list[i]; + ret = make_word_list (make_word (d), ret); + } + /* Now the current directory. */ + d = get_working_directory ("dirstack"); + i = 0; /* sentinel to decide whether or not to free d */ + if (d == 0) + d = "."; + else + { + t = (flags&1) ? polite_directory_format (d) : d; + /* polite_directory_format sometimes returns its argument unchanged. + If it does not, we can free d right away. If it does, we need to + mark d to be deleted later. */ + if (t != d) + { + free (d); + d = t; + } + else /* t == d, so d is what we want */ + i = 1; + } + ret = make_word_list (make_word (d), ret); + if (i) + free (d); + return ret; /* was (REVERSE_LIST (ret, (WORD_LIST *)); */ +} + +#ifdef LOADABLE_BUILTIN +char * const dirs_doc[] = { +N_("Display the list of currently remembered directories. Directories\n\ + find their way onto the list with the `pushd' command; you can get\n\ + back up through the list with the `popd' command.\n\ + \n\ + Options:\n\ + -c clear the directory stack by deleting all of the elements\n\ + -l do not print tilde-prefixed versions of directories relative\n\ + to your home directory\n\ + -p print the directory stack with one entry per line\n\ + -v print the directory stack with one entry per line prefixed\n\ + with its position in the stack\n\ + \n\ + Arguments:\n\ + +N Displays the Nth entry counting from the left of the list shown by\n\ + dirs when invoked without options, starting with zero.\n\ + \n\ + -N Displays the Nth entry counting from the right of the list shown by\n\ + dirs when invoked without options, starting with zero."), + (char *)NULL +}; + +char * const pushd_doc[] = { +N_("Adds a directory to the top of the directory stack, or rotates\n\ + the stack, making the new top of the stack the current working\n\ + directory. With no arguments, exchanges the top two directories.\n\ + \n\ + Options:\n\ + -n Suppresses the normal change of directory when adding\n\ + directories to the stack, so only the stack is manipulated.\n\ + \n\ + Arguments:\n\ + +N Rotates the stack so that the Nth directory (counting\n\ + from the left of the list shown by `dirs', starting with\n\ + zero) is at the top.\n\ + \n\ + -N Rotates the stack so that the Nth directory (counting\n\ + from the right of the list shown by `dirs', starting with\n\ + zero) is at the top.\n\ + \n\ + dir Adds DIR to the directory stack at the top, making it the\n\ + new current working directory.\n\ + \n\ + The `dirs' builtin displays the directory stack."), + (char *)NULL +}; + +char * const popd_doc[] = { +N_("Removes entries from the directory stack. With no arguments, removes\n\ + the top directory from the stack, and changes to the new top directory.\n\ + \n\ + Options:\n\ + -n Suppresses the normal change of directory when removing\n\ + directories from the stack, so only the stack is manipulated.\n\ + \n\ + Arguments:\n\ + +N Removes the Nth entry counting from the left of the list\n\ + shown by `dirs', starting with zero. For example: `popd +0'\n\ + removes the first directory, `popd +1' the second.\n\ + \n\ + -N Removes the Nth entry counting from the right of the list\n\ + shown by `dirs', starting with zero. For example: `popd -0'\n\ + removes the last directory, `popd -1' the next to last.\n\ + \n\ + The `dirs' builtin displays the directory stack."), + (char *)NULL +}; + +struct builtin pushd_struct = { + "pushd", + pushd_builtin, + BUILTIN_ENABLED, + pushd_doc, + "pushd [+N | -N] [-n] [dir]", + 0 +}; + +struct builtin popd_struct = { + "popd", + popd_builtin, + BUILTIN_ENABLED, + popd_doc, + "popd [+N | -N] [-n]", + 0 +}; + +struct builtin dirs_struct = { + "dirs", + dirs_builtin, + BUILTIN_ENABLED, + dirs_doc, + "dirs [-clpv] [+N] [-N]", + 0 +}; +#endif /* LOADABLE_BUILTIN */ + +#endif /* PUSHD_AND_POPD */ diff --git a/builtins/read.c b/builtins/read.c new file mode 100644 index 0000000..9f50aac --- /dev/null +++ b/builtins/read.c @@ -0,0 +1,1126 @@ +/* read.c, created from read.def. */ +#line 22 "./read.def" + +#line 69 "./read.def" + +#include + +#include "bashtypes.h" +#include "posixstat.h" + +#include + +#include "bashansi.h" + +#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 "trap.h" + +#include + +#if defined (READLINE) +#include "../bashline.h" +#include +#endif + +#if defined (BUFFERED_INPUT) +# include "input.h" +#endif + +#include "shmbutil.h" + +#if !defined(errno) +extern int errno; +#endif + +struct ttsave +{ + int fd; + TTYSTRUCT attrs; +}; + +#if defined (READLINE) +static void reset_attempted_completion_function PARAMS((char *)); +static int set_itext PARAMS((void)); +static char *edit_line PARAMS((char *, char *)); +static void set_eol_delim PARAMS((int)); +static void reset_eol_delim PARAMS((char *)); +#endif +static SHELL_VAR *bind_read_variable PARAMS((char *, char *)); +#if defined (HANDLE_MULTIBYTE) +static int read_mbchar PARAMS((int, char *, int, int, int)); +#endif +static void ttyrestore PARAMS((struct ttsave *)); + +static sighandler sigalrm PARAMS((int)); +static void reset_alarm PARAMS((void)); + +/* Try this to see what the rest of the shell can do with the information. */ +procenv_t alrmbuf; +int sigalrm_seen; + +static int reading, tty_modified; +static SigHandler *old_alrm; +static unsigned char delim; + +static struct ttsave termsave; + +/* In all cases, SIGALRM just sets a flag that we check periodically. This + avoids problems with the semi-tricky stuff we do with the xfree of + input_string at the top of the unwind-protect list (see below). */ + +/* Set a flag that CHECK_ALRM can check. This relies on zread or read_builtin + calling trap.c:check_signals(), which knows about sigalrm_seen and alrmbuf. */ +static sighandler +sigalrm (s) + int s; +{ + sigalrm_seen = 1; +} + +static void +reset_alarm () +{ + /* Cancel alarm before restoring signal handler. */ + falarm (0, 0); + set_signal_handler (SIGALRM, old_alrm); +} + +/* 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, nr, pass_next, saw_escape, eof, opt, retval, code, print_ps2, nflag; + volatile int i; + int input_is_tty, input_is_pipe, unbuffered_read, skip_ctlesc, skip_ctlnul; + int raw, edit, nchars, silent, have_timeout, ignore_delim, fd; + int lastsig, t_errno; + int mb_cur_max; + unsigned int tmsec, tmusec; + long ival, uval; + intmax_t intval; + char c; + char *input_string, *orig_input_string, *ifs_chars, *prompt, *arrayname; + char *e, *t, *t1, *ps2, *tofree; + struct stat tsb; + SHELL_VAR *var; + TTYSTRUCT ttattrs, ttset; +#if defined (ARRAY_VARS) + WORD_LIST *alist; + int vflags; +#endif +#if defined (READLINE) + char *rlbuf, *itext; + int rlind; + FILE *save_instream; +#endif + + USE_VAR(size); + USE_VAR(i); + USE_VAR(pass_next); + USE_VAR(print_ps2); + USE_VAR(saw_escape); + USE_VAR(input_is_pipe); +/* USE_VAR(raw); */ + USE_VAR(edit); + USE_VAR(tmsec); + USE_VAR(tmusec); + 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); + USE_VAR(itext); +#endif + USE_VAR(list); + USE_VAR(ps2); + USE_VAR(lastsig); + + sigalrm_seen = reading = tty_modified = 0; + + 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 = itext = (char *)0; + rlind = 0; +#endif + + mb_cur_max = MB_CUR_MAX; + tmsec = tmusec = 0; /* no timeout */ + nr = nchars = input_is_tty = input_is_pipe = unbuffered_read = have_timeout = 0; + delim = '\n'; /* read until newline */ + ignore_delim = nflag = 0; + + reset_internal_getopt (); + while ((opt = internal_getopt (list, "ersa:d:i:n:p:t:u:N:")) != -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; + case 'i': +#if defined (READLINE) + itext = list_optarg; +#endif + break; +#if defined (ARRAY_VARS) + case 'a': + arrayname = list_optarg; + break; +#endif + case 't': + code = uconvert (list_optarg, &ival, &uval, (char **)NULL); + if (code == 0 || ival < 0 || uval < 0) + { + builtin_error (_("%s: invalid timeout specification"), list_optarg); + return (EXECUTION_FAILURE); + } + else + { + have_timeout = 1; + tmsec = ival; + tmusec = uval; + } + break; + case 'N': + ignore_delim = 1; + delim = -1; + case 'n': + nflag = 1; + 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; + CASE_HELPOPT; + default: + builtin_usage (); + return (EX_USAGE); + } + } + list = loptend; + + /* `read -t 0 var' tests whether input is available with select/FIONREAD, + and fails if those are unavailable */ + if (have_timeout && tmsec == 0 && tmusec == 0) +#if 0 + return (EXECUTION_FAILURE); +#else + return (input_avail (fd) ? EXECUTION_SUCCESS : EXECUTION_FAILURE); +#endif + + /* Convenience: check early whether or not the first of possibly several + variable names is a valid identifier, and bail early if so. */ +#if defined (ARRAY_VARS) + vflags = assoc_expand_once ? (VA_NOEXPAND|VA_ONEWORD) : 0; + if (list && legal_identifier (list->word->word) == 0 && valid_array_reference (list->word->word, vflags) == 0) +#else + if (list && legal_identifier (list->word->word) == 0) +#endif + { + sh_invalidid (list->word->word); + return (EXECUTION_FAILURE); + } + + /* If we're asked to ignore the delimiter, make sure we do. */ + if (ignore_delim) + delim = -1; + + /* IF IFS is unset, we use the default of " \t\n". */ + ifs_chars = getifs (); + if (ifs_chars == 0) /* XXX - shouldn't happen */ + ifs_chars = ""; + /* If we want to read exactly NCHARS chars, don't split on IFS */ + if (ignore_delim) + ifs_chars = ""; + for (skip_ctlesc = skip_ctlnul = 0, e = ifs_chars; *e; e++) + skip_ctlesc |= *e == CTLESC, skip_ctlnul |= *e == CTLNUL; + + input_string = (char *)xmalloc (size = 112); /* XXX was 128 */ + input_string[0] = '\0'; + + /* More input and options validation */ + if (nflag == 1 && nchars == 0) + { + retval = read (fd, &c, 0); + retval = (retval >= 0) ? EXECUTION_SUCCESS : EXECUTION_FAILURE; + goto assign_vars; /* bail early if asked to read 0 chars */ + } + + /* $TMOUT, if set, is the default timeout for read. */ + if (have_timeout == 0 && (e = get_string_value ("TMOUT"))) + { + code = uconvert (e, &ival, &uval, (char **)NULL); + if (code == 0 || ival < 0 || uval < 0) + tmsec = tmusec = 0; + else + { + tmsec = ival; + tmusec = uval; + } + } + + begin_unwind_frame ("read_builtin"); + +#if defined (BUFFERED_INPUT) + if (interactive == 0 && default_buffered_input >= 0 && fd_is_bash_input (fd)) + sync_buffered_stream (default_buffered_input); +#endif + +#if 1 + input_is_tty = isatty (fd); +#else + input_is_tty = 1; +#endif + if (input_is_tty == 0) +#ifndef __CYGWIN__ + input_is_pipe = (lseek (fd, 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; +#if defined (READLINE) + itext = (char *)NULL; +#endif + edit = silent = 0; + } + +#if defined (READLINE) + if (edit) + add_unwind_protect (xfree, rlbuf); +#endif + + pass_next = 0; /* Non-zero signifies last char was backslash. */ + saw_escape = 0; /* Non-zero signifies that we saw an escape char */ + + if (tmsec > 0 || tmusec > 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)) + tmsec = tmusec = 0; + } + + if (tmsec > 0 || tmusec > 0) + { + code = setjmp_nosigs (alrmbuf); + if (code) + { + sigalrm_seen = 0; + /* Tricky. The top of the unwind-protect stack is the free of + input_string. We want to run all the rest and use input_string, + so we have to save input_string temporarily, run the unwind- + protects, then restore input_string so we can use it later */ + orig_input_string = 0; + input_string[i] = '\0'; /* make sure it's terminated */ + if (i == 0) + { + t = (char *)xmalloc (1); + t[0] = 0; + } + else + t = savestring (input_string); + + run_unwind_frame ("read_builtin"); + input_string = t; + retval = 128+SIGALRM; + goto assign_vars; + } + if (interactive_shell == 0) + initialize_terminating_signals (); + old_alrm = set_signal_handler (SIGALRM, sigalrm); + add_unwind_protect (reset_alarm, (char *)NULL); +#if defined (READLINE) + if (edit) + { + add_unwind_protect (reset_attempted_completion_function, (char *)NULL); + add_unwind_protect (bashline_reset_event_hook, (char *)NULL); + } +#endif + falarm (tmsec, tmusec); + } + + /* 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() */ + termsave.fd = fd; + ttgetattr (fd, &ttattrs); + termsave.attrs = ttattrs; + + ttset = ttattrs; + i = silent ? ttfd_cbreak (fd, &ttset) : ttfd_onechar (fd, &ttset); + if (i < 0) + sh_ttyerror (1); + tty_modified = 1; + add_unwind_protect ((Function *)ttyrestore, (char *)&termsave); + if (interactive_shell == 0) + initialize_terminating_signals (); + } + } + else if (silent) /* turn off echo but leave term in canonical mode */ + { + /* ttsave (); */ + termsave.fd = fd; + ttgetattr (fd, &ttattrs); + termsave.attrs = ttattrs; + + ttset = ttattrs; + i = ttfd_noecho (fd, &ttset); /* ttnoecho (); */ + if (i < 0) + sh_ttyerror (1); + + tty_modified = 1; + add_unwind_protect ((Function *)ttyrestore, (char *)&termsave); + if (interactive_shell == 0) + initialize_terminating_signals (); + } + +#if defined (READLINE) + save_instream = 0; + if (edit && fd != 0) + { + if (bash_readline_initialized == 0) + initialize_readline (); + + unwind_protect_var (rl_instream); + save_instream = rl_instream; + rl_instream = fdopen (fd, "r"); + } +#endif + + /* 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); + + CHECK_ALRM; + if ((nchars > 0) && (input_is_tty == 0) && ignore_delim) /* read -N */ + unbuffered_read = 2; + else if ((nchars > 0) || (delim != '\n') || input_is_pipe) + unbuffered_read = 1; + + if (prompt && edit == 0) + { + fprintf (stderr, "%s", prompt); + fflush (stderr); + } + +#if defined (__CYGWIN__) && defined (O_TEXT) + setmode (0, O_TEXT); +#endif + + ps2 = 0; + for (print_ps2 = eof = retval = 0;;) + { + CHECK_ALRM; + +#if defined (READLINE) + if (edit) + { + /* If we have a null delimiter, don't treat NULL as ending the line */ + if (rlbuf && rlbuf[rlind] == '\0' && delim != '\0') + { + free (rlbuf); + rlbuf = (char *)0; + } + if (rlbuf == 0) + { + reading = 1; + rlbuf = edit_line (prompt ? prompt : "", itext); + reading = 0; + rlind = 0; + } + if (rlbuf == 0) + { + eof = 1; + break; + } + c = rlbuf[rlind++]; + } + else + { +#endif + + if (print_ps2) + { + if (ps2 == 0) + ps2 = get_string_value ("PS2"); + fprintf (stderr, "%s", ps2 ? ps2 : ""); + fflush (stderr); + print_ps2 = 0; + } + + reading = 1; + CHECK_ALRM; + errno = 0; + if (unbuffered_read == 2) + retval = posixly_correct ? zreadintr (fd, &c, 1) : zreadn (fd, &c, nchars - nr); + else if (unbuffered_read) + retval = posixly_correct ? zreadintr (fd, &c, 1) : zread (fd, &c, 1); + else + retval = posixly_correct ? zreadcintr (fd, &c) : zreadc (fd, &c); + reading = 0; + + if (retval <= 0) + { + int t; + + t = errno; + if (retval < 0 && errno == EINTR) + { + check_signals (); /* in case we didn't call zread via zreadc */ + lastsig = LASTSIG(); + if (lastsig == 0) + lastsig = trapped_signal_received; +#if 0 + run_pending_traps (); /* because interrupt_immediately is not set */ +#endif + } + else + lastsig = 0; + if (terminating_signal && tty_modified) + ttyrestore (&termsave); /* fix terminal before exiting */ + CHECK_TERMSIG; + eof = 1; + errno = t; /* preserve it for the error message below */ + break; + } + + QUIT; /* in case we didn't call check_signals() */ +#if defined (READLINE) + } +#endif + + if (retval <= 0) /* XXX shouldn't happen */ + CHECK_ALRM; + + /* XXX -- use i + mb_cur_max (at least 4) for multibyte/read_mbchar */ + if (i + (mb_cur_max > 4 ? mb_cur_max : 4) >= size) + { + char *t; + t = (char *)xrealloc (input_string, size += 128); + + /* Only need to change unwind-protect if input_string changes */ + if (t != input_string) + { + input_string = t; + 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) + { + pass_next = 0; + if (c == '\n') + { + if (skip_ctlesc == 0 && i > 0) + i--; /* back up over the CTLESC */ + if (interactive && input_is_tty && raw == 0) + print_ps2 = 1; + } + else + goto add_char; + continue; + } + + /* This may cause problems if IFS contains CTLESC */ + if (c == '\\' && raw == 0) + { + pass_next++; + if (skip_ctlesc == 0) + { + saw_escape++; + input_string[i++] = CTLESC; + } + continue; + } + + if (ignore_delim == 0 && (unsigned char)c == delim) + break; + + if (c == '\0' && delim != '\0') + continue; /* skip NUL bytes in input */ + + if ((skip_ctlesc == 0 && c == CTLESC) || (skip_ctlnul == 0 && c == CTLNUL)) + { + saw_escape++; + input_string[i++] = CTLESC; + } + +add_char: + input_string[i++] = c; + CHECK_ALRM; + +#if defined (HANDLE_MULTIBYTE) + /* XXX - what if C == 127? Can DEL introduce a multibyte sequence? */ + if (mb_cur_max > 1 && is_basic (c) == 0) + { + input_string[i] = '\0'; /* for simplicity and debugging */ + /* If we got input from readline, grab the next multibyte char from + rlbuf. */ +# if defined (READLINE) + if (edit) + { + size_t clen; + clen = mbrlen (rlbuf + rlind - 1, mb_cur_max, (mbstate_t *)NULL); + /* We only deal with valid multibyte sequences longer than one + byte. If we get anything else, we leave the one character + copied and move on to the next. */ + if ((int)clen > 1) + { + memcpy (input_string+i, rlbuf+rlind, clen-1); + i += clen - 1; + rlind += clen - 1; + } + } + else +# endif + if (locale_utf8locale == 0 || ((c & 0x80) != 0)) + i += read_mbchar (fd, input_string, i, c, unbuffered_read); + } +#endif + + nr++; + + if (nchars > 0 && nr >= nchars) + break; + } + input_string[i] = '\0'; + CHECK_ALRM; + +#if defined (READLINE) + if (edit) + free (rlbuf); +#endif + + if (retval < 0) + { + t_errno = errno; + if (errno != EINTR) + builtin_error (_("read error: %d: %s"), fd, strerror (errno)); + run_unwind_frame ("read_builtin"); + return ((t_errno != EINTR) ? EXECUTION_FAILURE : 128+lastsig); + } + + if (tmsec > 0 || tmusec > 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) + ttyrestore (&termsave); + } + else if (silent) + ttyrestore (&termsave); + + if (unbuffered_read == 0) + zsyncfd (fd); + +#if defined (READLINE) + if (save_instream) + rl_instream = save_instream; /* can't portably free it */ +#endif + + discard_unwind_frame ("read_builtin"); + + retval = eof ? EXECUTION_FAILURE : EXECUTION_SUCCESS; + +assign_vars: + +#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); + free (input_string); + return (EXECUTION_FAILURE); + } + + var = find_or_make_array_variable (arrayname, 1); + if (var == 0) + { + free (input_string); + return EXECUTION_FAILURE; /* readonly or noassign */ + } + if (assoc_p (var)) + { + builtin_error (_("%s: cannot convert associative to indexed array"), arrayname); + free (input_string); + return EXECUTION_FAILURE; /* existing associative array */ + } + else if (invisible_p (var)) + VUNSETATTR (var, att_invisible); + array_flush (array_cell (var)); + + alist = list_string (input_string, ifs_chars, 0); + if (alist) + { + if (saw_escape) + dequote_list (alist); + else + word_list_remove_quoted_nulls (alist); + assign_array_var_from_word_list (var, alist, 0); + dispose_words (alist); + } + free (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, 0); + free (t); + } + else + var = bind_variable ("REPLY", input_string, 0); + if (var == 0 || readonly_p (var) || noassign_p (var)) + retval = EXECUTION_FAILURE; + else + 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, vflags) == 0) +#else + if (legal_identifier (varname) == 0) +#endif + { + sh_invalidid (varname); + free (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); + free (t1); + } + else + var = bind_read_variable (varname, t ? t : ""); + } + else + { + t = (char *)0; + var = bind_read_variable (varname, ""); + } + + FREE (t); + if (var == 0) + { + free (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, vflags) == 0) +#else + if (legal_identifier (list->word->word) == 0) +#endif + { + sh_invalidid (list->word->word); + free (orig_input_string); + return (EXECUTION_FAILURE); + } + +#if 0 + /* 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); +#else + /* Check whether or not the number of fields is exactly the same as the + number of variables. */ + tofree = NULL; + if (*input_string) + { + t1 = input_string; + t = get_word_from_string (&input_string, ifs_chars, &e); + if (*input_string == 0) + tofree = input_string = t; + else + { + input_string = strip_trailing_ifs_whitespace (t1, ifs_chars, saw_escape); + tofree = t; + } + } +#endif + + if (saw_escape && input_string && *input_string) + { + t = dequote_string (input_string); + var = bind_read_variable (list->word->word, t); + free (t); + } + else + var = bind_read_variable (list->word->word, input_string ? input_string : ""); + + if (var) + { + stupidly_hack_special_variables (list->word->word); + VUNSETATTR (var, att_invisible); + } + else + retval = EXECUTION_FAILURE; + + FREE (tofree); + free (orig_input_string); + + return (retval); +} + +static SHELL_VAR * +bind_read_variable (name, value) + char *name, *value; +{ + SHELL_VAR *v; + + v = builtin_bind_variable (name, value, 0); + return (v == 0 ? v + : ((readonly_p (v) || noassign_p (v)) ? (SHELL_VAR *)NULL : v)); +} + +#if defined (HANDLE_MULTIBYTE) +static int +read_mbchar (fd, string, ind, ch, unbuffered) + int fd; + char *string; + int ind, ch, unbuffered; +{ + char mbchar[MB_LEN_MAX + 1]; + int i, n, r; + char c; + size_t ret; + mbstate_t ps, ps_back; + wchar_t wc; + + memset (&ps, '\0', sizeof (mbstate_t)); + memset (&ps_back, '\0', sizeof (mbstate_t)); + + mbchar[0] = ch; + i = 1; + for (n = 0; n <= MB_LEN_MAX; n++) + { + ps_back = ps; + ret = mbrtowc (&wc, mbchar, i, &ps); + if (ret == (size_t)-2) + { + ps = ps_back; + + /* We don't want to be interrupted during a multibyte char read */ + if (unbuffered == 2) + r = zreadn (fd, &c, 1); + else if (unbuffered) + r = zread (fd, &c, 1); + else + r = zreadc (fd, &c); + if (r <= 0) + goto mbchar_return; + mbchar[i++] = c; + continue; + } + else if (ret == (size_t)-1 || ret == (size_t)0 || ret > (size_t)0) + break; + } + +mbchar_return: + if (i > 1) /* read a multibyte char */ + /* mbchar[0] is already string[ind-1] */ + for (r = 1; r < i; r++) + string[ind+r-1] = mbchar[r]; + return i - 1; +} +#endif + + +static void +ttyrestore (ttp) + struct ttsave *ttp; +{ + ttsetattr (ttp->fd, &(ttp->attrs)); + tty_modified = 0; +} + +void +read_tty_cleanup () +{ + if (tty_modified) + ttyrestore (&termsave); +} + +int +read_tty_modified () +{ + return (tty_modified); +} + +#if defined (READLINE) +static rl_completion_func_t *old_attempted_completion_function = 0; +static rl_hook_func_t *old_startup_hook; +static char *deftext; + +static void +reset_attempted_completion_function (cp) + char *cp; +{ + if (rl_attempted_completion_function == 0 && old_attempted_completion_function) + rl_attempted_completion_function = old_attempted_completion_function; +} + +static int +set_itext () +{ + int r1, r2; + + r1 = r2 = 0; + if (old_startup_hook) + r1 = (*old_startup_hook) (); + if (deftext) + { + r2 = rl_insert_text (deftext); + deftext = (char *)NULL; + rl_startup_hook = old_startup_hook; + old_startup_hook = (rl_hook_func_t *)NULL; + } + return (r1 || r2); +} + +static char * +edit_line (p, itext) + char *p; + char *itext; +{ + char *ret; + int len; + + if (bash_readline_initialized == 0) + initialize_readline (); + + old_attempted_completion_function = rl_attempted_completion_function; + rl_attempted_completion_function = (rl_completion_func_t *)NULL; + bashline_set_event_hook (); + if (itext) + { + old_startup_hook = rl_startup_hook; + rl_startup_hook = set_itext; + deftext = itext; + } + + ret = readline (p); + + rl_attempted_completion_function = old_attempted_completion_function; + old_attempted_completion_function = (rl_completion_func_t *)NULL; + bashline_reset_event_hook (); + + 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 (); + + /* Save the old delimiter char binding */ + old_newline_ctype = cmap[RETURN].type; + old_newline_func = cmap[RETURN].function; + old_delim_ctype = cmap[c].type; + old_delim_func = cmap[c].function; + + /* Change newline to self-insert */ + cmap[RETURN].type = ISFUNC; + cmap[RETURN].function = rl_insert; + + /* Bind the delimiter character to accept-line. */ + 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/builtins/return.c b/builtins/return.c new file mode 100644 index 0000000..d90286c --- /dev/null +++ b/builtins/return.c @@ -0,0 +1,40 @@ +/* return.c, created from return.def. */ +#line 22 "./return.def" + +#line 36 "./return.def" + +#include + +#if defined (HAVE_UNISTD_H) +# ifdef _MINIX +# include +# endif +# include +#endif + +#include "../bashintl.h" + +#include "../shell.h" +#include "../execute_cmd.h" +#include "common.h" +#include "bashgetopt.h" + +/* If we are executing a user-defined function then exit with the value + specified as an argument. if no argument is given, then the last + exit status is used. */ +int +return_builtin (list) + WORD_LIST *list; +{ + CHECK_HELPOPT (list); + + return_catch_value = get_exitstat (list); + + if (return_catch_flag) + sh_longjmp (return_catch, 1); + else + { + builtin_error (_("can only `return' from a function or sourced script")); + return (EX_USAGE); + } +} diff --git a/builtins/set.c b/builtins/set.c new file mode 100644 index 0000000..e623ccf --- /dev/null +++ b/builtins/set.c @@ -0,0 +1,880 @@ +/* set.c, created from set.def. */ +#line 22 "./set.def" + +#include + +#if defined (HAVE_UNISTD_H) +# ifdef _MINIX +# include +# endif +# include +#endif + +#include + +#include "../bashansi.h" +#include "../bashintl.h" + +#include "../shell.h" +#include "../parser.h" +#include "../flags.h" +#include "common.h" +#include "bashgetopt.h" + +#if defined (READLINE) +# include "../input.h" +# include "../bashline.h" +# include +#endif + +#if defined (HISTORY) +# include "../bashhist.h" +#endif + +#line 153 "./set.def" + +typedef int setopt_set_func_t PARAMS((int, char *)); +typedef int setopt_get_func_t PARAMS((char *)); + +static int find_minus_o_option PARAMS((char *)); + +static void print_minus_o_option PARAMS((char *, int, int)); +static void print_all_shell_variables PARAMS((void)); + +static int set_ignoreeof PARAMS((int, char *)); +static int set_posix_mode PARAMS((int, char *)); + +#if defined (READLINE) +static int set_edit_mode PARAMS((int, char *)); +static int get_edit_mode PARAMS((char *)); +#endif + +#if defined (HISTORY) +static int bash_set_history PARAMS((int, char *)); +#endif + +static const char * const on = "on"; +static const char * const off = "off"; + +static int previous_option_value; + +/* A struct used to match long options for set -o to the corresponding + option letter or internal variable. The functions can be called to + dynamically generate values. If you add a new variable name here + that doesn't have a corresponding single-character option letter, make + sure to set the value appropriately in reset_shell_options. */ +const struct { + char *name; + int letter; + int *variable; + setopt_set_func_t *set_func; + setopt_get_func_t *get_func; +} o_options[] = { + { "allexport", 'a', (int *)NULL, (setopt_set_func_t *)NULL, (setopt_get_func_t *)NULL }, +#if defined (BRACE_EXPANSION) + { "braceexpand",'B', (int *)NULL, (setopt_set_func_t *)NULL, (setopt_get_func_t *)NULL }, +#endif +#if defined (READLINE) + { "emacs", '\0', (int *)NULL, set_edit_mode, get_edit_mode }, +#endif + { "errexit", 'e', (int *)NULL, (setopt_set_func_t *)NULL, (setopt_get_func_t *)NULL }, + { "errtrace", 'E', (int *)NULL, (setopt_set_func_t *)NULL, (setopt_get_func_t *)NULL }, + { "functrace", 'T', (int *)NULL, (setopt_set_func_t *)NULL, (setopt_get_func_t *)NULL }, + { "hashall", 'h', (int *)NULL, (setopt_set_func_t *)NULL, (setopt_get_func_t *)NULL }, +#if defined (BANG_HISTORY) + { "histexpand", 'H', (int *)NULL, (setopt_set_func_t *)NULL, (setopt_get_func_t *)NULL }, +#endif /* BANG_HISTORY */ +#if defined (HISTORY) + { "history", '\0', &enable_history_list, bash_set_history, (setopt_get_func_t *)NULL }, +#endif + { "ignoreeof", '\0', &ignoreeof, set_ignoreeof, (setopt_get_func_t *)NULL }, + { "interactive-comments", '\0', &interactive_comments, (setopt_set_func_t *)NULL, (setopt_get_func_t *)NULL }, + { "keyword", 'k', (int *)NULL, (setopt_set_func_t *)NULL, (setopt_get_func_t *)NULL }, +#if defined (JOB_CONTROL) + { "monitor", 'm', (int *)NULL, (setopt_set_func_t *)NULL, (setopt_get_func_t *)NULL }, +#endif + { "noclobber", 'C', (int *)NULL, (setopt_set_func_t *)NULL, (setopt_get_func_t *)NULL }, + { "noexec", 'n', (int *)NULL, (setopt_set_func_t *)NULL, (setopt_get_func_t *)NULL }, + { "noglob", 'f', (int *)NULL, (setopt_set_func_t *)NULL, (setopt_get_func_t *)NULL }, +#if defined (HISTORY) + { "nolog", '\0', &dont_save_function_defs, (setopt_set_func_t *)NULL, (setopt_get_func_t *)NULL }, +#endif +#if defined (JOB_CONTROL) + { "notify", 'b', (int *)NULL, (setopt_set_func_t *)NULL, (setopt_get_func_t *)NULL }, +#endif /* JOB_CONTROL */ + { "nounset", 'u', (int *)NULL, (setopt_set_func_t *)NULL, (setopt_get_func_t *)NULL }, + { "onecmd", 't', (int *)NULL, (setopt_set_func_t *)NULL, (setopt_get_func_t *)NULL }, + { "physical", 'P', (int *)NULL, (setopt_set_func_t *)NULL, (setopt_get_func_t *)NULL }, + { "pipefail", '\0', &pipefail_opt, (setopt_set_func_t *)NULL, (setopt_get_func_t *)NULL }, + { "posix", '\0', &posixly_correct, set_posix_mode, (setopt_get_func_t *)NULL }, + { "privileged", 'p', (int *)NULL, (setopt_set_func_t *)NULL, (setopt_get_func_t *)NULL }, + { "verbose", 'v', (int *)NULL, (setopt_set_func_t *)NULL, (setopt_get_func_t *)NULL }, +#if defined (READLINE) + { "vi", '\0', (int *)NULL, set_edit_mode, get_edit_mode }, +#endif + { "xtrace", 'x', (int *)NULL, (setopt_set_func_t *)NULL, (setopt_get_func_t *)NULL }, + {(char *)NULL, 0 , (int *)NULL, (setopt_set_func_t *)NULL, (setopt_get_func_t *)NULL }, +}; + +#define N_O_OPTIONS (sizeof (o_options) / sizeof (o_options[0])) + +#define GET_BINARY_O_OPTION_VALUE(i, name) \ + ((o_options[i].get_func) ? (*o_options[i].get_func) (name) \ + : (*o_options[i].variable)) + +#define SET_BINARY_O_OPTION_VALUE(i, onoff, name) \ + ((o_options[i].set_func) ? (*o_options[i].set_func) (onoff, name) \ + : (*o_options[i].variable = (onoff == FLAG_ON))) + +static int +find_minus_o_option (name) + char *name; +{ + register int i; + + for (i = 0; o_options[i].name; i++) + if (STREQ (name, o_options[i].name)) + return i; + return -1; +} + +int +minus_o_option_value (name) + char *name; +{ + register int i; + int *on_or_off; + + i = find_minus_o_option (name); + if (i < 0) + return (-1); + + if (o_options[i].letter) + { + on_or_off = find_flag (o_options[i].letter); + return ((on_or_off == FLAG_UNKNOWN) ? -1 : *on_or_off); + } + else + return (GET_BINARY_O_OPTION_VALUE (i, name)); +} + +#define MINUS_O_FORMAT "%-15s\t%s\n" + +static void +print_minus_o_option (name, value, pflag) + char *name; + int value, pflag; +{ + if (pflag == 0) + printf (MINUS_O_FORMAT, name, value ? on : off); + else + printf ("set %co %s\n", value ? '-' : '+', name); +} + +void +list_minus_o_opts (mode, reusable) + int mode, reusable; +{ + register int i; + int *on_or_off, value; + + for (i = 0; o_options[i].name; i++) + { + if (o_options[i].letter) + { + value = 0; + on_or_off = find_flag (o_options[i].letter); + if (on_or_off == FLAG_UNKNOWN) + on_or_off = &value; + if (mode == -1 || mode == *on_or_off) + print_minus_o_option (o_options[i].name, *on_or_off, reusable); + } + else + { + value = GET_BINARY_O_OPTION_VALUE (i, o_options[i].name); + if (mode == -1 || mode == value) + print_minus_o_option (o_options[i].name, value, reusable); + } + } +} + +char ** +get_minus_o_opts () +{ + char **ret; + int i; + + ret = strvec_create (N_O_OPTIONS + 1); + for (i = 0; o_options[i].name; i++) + ret[i] = o_options[i].name; + ret[i] = (char *)NULL; + return ret; +} + +char * +get_current_options () +{ + char *temp; + int i, posixopts; + + posixopts = num_posix_options (); /* shopts modified by posix mode */ + /* Make the buffer big enough to hold the set -o options and the shopt + options modified by posix mode. */ + temp = (char *)xmalloc (1 + N_O_OPTIONS + posixopts); + for (i = 0; o_options[i].name; i++) + { + if (o_options[i].letter) + temp[i] = *(find_flag (o_options[i].letter)); + else + temp[i] = GET_BINARY_O_OPTION_VALUE (i, o_options[i].name); + } + + /* Add the shell options that are modified by posix mode to the end of the + bitmap. They will be handled in set_current_options() */ + get_posix_options (temp+i); + temp[i+posixopts] = '\0'; + return (temp); +} + +void +set_current_options (bitmap) + const char *bitmap; +{ + int i, v, cv, *on_or_off; + + if (bitmap == 0) + return; + + for (i = 0; o_options[i].name; i++) + { + v = bitmap[i] ? FLAG_ON : FLAG_OFF; + if (o_options[i].letter) + { + /* We should not get FLAG_UNKNOWN here */ + on_or_off = find_flag (o_options[i].letter); + cv = *on_or_off ? FLAG_ON : FLAG_OFF; + if (v != cv) + change_flag (o_options[i].letter, v); + } + else + { + cv = GET_BINARY_O_OPTION_VALUE (i, o_options[i].name); + cv = cv ? FLAG_ON : FLAG_OFF; + if (v != cv) + SET_BINARY_O_OPTION_VALUE (i, v, o_options[i].name); + } + } + + /* Now reset the variables changed by posix mode */ + set_posix_options (bitmap+i); +} + +static int +set_ignoreeof (on_or_off, option_name) + int on_or_off; + char *option_name; +{ + ignoreeof = on_or_off == FLAG_ON; + unbind_variable_noref ("ignoreeof"); + if (ignoreeof) + bind_variable ("IGNOREEOF", "10", 0); + else + unbind_variable_noref ("IGNOREEOF"); + sv_ignoreeof ("IGNOREEOF"); + return 0; +} + +static int +set_posix_mode (on_or_off, option_name) + int on_or_off; + char *option_name; +{ + /* short-circuit on no-op */ + if ((on_or_off == FLAG_ON && posixly_correct) || + (on_or_off == FLAG_OFF && posixly_correct == 0)) + return 0; + + posixly_correct = on_or_off == FLAG_ON; + if (posixly_correct == 0) + unbind_variable_noref ("POSIXLY_CORRECT"); + else + bind_variable ("POSIXLY_CORRECT", "y", 0); + sv_strict_posix ("POSIXLY_CORRECT"); + return (0); +} + +#if defined (READLINE) +/* Magic. This code `knows' how readline handles rl_editing_mode. */ +static int +set_edit_mode (on_or_off, option_name) + int on_or_off; + char *option_name; +{ + int isemacs; + + if (on_or_off == FLAG_ON) + { + rl_variable_bind ("editing-mode", option_name); + + if (interactive) + with_input_from_stdin (); + no_line_editing = 0; + } + else + { + isemacs = rl_editing_mode == 1; + if ((isemacs && *option_name == 'e') || (!isemacs && *option_name == 'v')) + { + if (interactive) + with_input_from_stream (stdin, "stdin"); + no_line_editing = 1; + } + } + return 1-no_line_editing; +} + +static int +get_edit_mode (name) + char *name; +{ + return (*name == 'e' ? no_line_editing == 0 && rl_editing_mode == 1 + : no_line_editing == 0 && rl_editing_mode == 0); +} +#endif /* READLINE */ + +#if defined (HISTORY) +static int +bash_set_history (on_or_off, option_name) + int on_or_off; + char *option_name; +{ + if (on_or_off == FLAG_ON) + { + enable_history_list = 1; + bash_history_enable (); + if (history_lines_this_session == 0) + load_history (); + } + else + { + enable_history_list = 0; + bash_history_disable (); + } + return (1 - enable_history_list); +} +#endif + +int +set_minus_o_option (on_or_off, option_name) + int on_or_off; + char *option_name; +{ + register int i; + + i = find_minus_o_option (option_name); + if (i < 0) + { + sh_invalidoptname (option_name); + return (EX_USAGE); + } + + if (o_options[i].letter == 0) + { + previous_option_value = GET_BINARY_O_OPTION_VALUE (i, o_options[i].name); + SET_BINARY_O_OPTION_VALUE (i, on_or_off, option_name); + return (EXECUTION_SUCCESS); + } + else + { + if ((previous_option_value = change_flag (o_options[i].letter, on_or_off)) == FLAG_ERROR) + { + sh_invalidoptname (option_name); + return (EXECUTION_FAILURE); + } + else + return (EXECUTION_SUCCESS); + } +} + +static void +print_all_shell_variables () +{ + SHELL_VAR **vars; + + vars = all_shell_variables (); + if (vars) + { + print_var_list (vars); + free (vars); + } + + /* POSIX.2 does not allow function names and definitions to be output when + `set' is invoked without options (PASC Interp #202). */ + if (posixly_correct == 0) + { + vars = all_shell_functions (); + if (vars) + { + print_func_list (vars); + free (vars); + } + } +} + +void +set_shellopts () +{ + char *value; + char tflag[N_O_OPTIONS]; + int vsize, i, vptr, *ip, exported; + SHELL_VAR *v; + + for (vsize = i = 0; o_options[i].name; i++) + { + tflag[i] = 0; + if (o_options[i].letter) + { + ip = find_flag (o_options[i].letter); + if (ip && *ip) + { + vsize += strlen (o_options[i].name) + 1; + tflag[i] = 1; + } + } + else if (GET_BINARY_O_OPTION_VALUE (i, o_options[i].name)) + { + vsize += strlen (o_options[i].name) + 1; + tflag[i] = 1; + } + } + + value = (char *)xmalloc (vsize + 1); + + for (i = vptr = 0; o_options[i].name; i++) + { + if (tflag[i]) + { + strcpy (value + vptr, o_options[i].name); + vptr += strlen (o_options[i].name); + value[vptr++] = ':'; + } + } + + if (vptr) + vptr--; /* cut off trailing colon */ + value[vptr] = '\0'; + + v = find_variable ("SHELLOPTS"); + + /* Turn off the read-only attribute so we can bind the new value, and + note whether or not the variable was exported. */ + if (v) + { + VUNSETATTR (v, att_readonly); + exported = exported_p (v); + } + else + exported = 0; + + v = bind_variable ("SHELLOPTS", value, 0); + + /* Turn the read-only attribute back on, and turn off the export attribute + if it was set implicitly by mark_modified_vars and SHELLOPTS was not + exported before we bound the new value. */ + VSETATTR (v, att_readonly); + if (mark_modified_vars && exported == 0 && exported_p (v)) + VUNSETATTR (v, att_exported); + + free (value); +} + +void +parse_shellopts (value) + char *value; +{ + char *vname; + int vptr; + + vptr = 0; + while (vname = extract_colon_unit (value, &vptr)) + { + set_minus_o_option (FLAG_ON, vname); + free (vname); + } +} + +void +initialize_shell_options (no_shellopts) + int no_shellopts; +{ + char *temp; + SHELL_VAR *var; + + if (no_shellopts == 0) + { + var = find_variable ("SHELLOPTS"); + /* set up any shell options we may have inherited. */ + if (var && imported_p (var)) + { + temp = (array_p (var) || assoc_p (var)) ? (char *)NULL : savestring (value_cell (var)); + if (temp) + { + parse_shellopts (temp); + free (temp); + } + } + } + + /* Set up the $SHELLOPTS variable. */ + set_shellopts (); +} + +/* Reset the values of the -o options that are not also shell flags. This is + called from execute_cmd.c:initialize_subshell() when setting up a subshell + to run an executable shell script without a leading `#!'. */ +void +reset_shell_options () +{ + pipefail_opt = 0; + ignoreeof = 0; + +#if defined (STRICT_POSIX) + posixly_correct = 1; +#else + posixly_correct = 0; +#endif +#if defined (HISTORY) + dont_save_function_defs = 0; + remember_on_history = enable_history_list = 1; /* XXX */ +#endif +} + +/* Set some flags from the word values in the input list. If LIST is empty, + then print out the values of the variables instead. If LIST contains + non-flags, then set $1 - $9 to the successive words of LIST. */ +int +set_builtin (list) + WORD_LIST *list; +{ + int on_or_off, flag_name, force_assignment, opts_changed, rv, r; + register char *arg; + char s[3]; + + if (list == 0) + { + print_all_shell_variables (); + return (sh_chkwrite (EXECUTION_SUCCESS)); + } + + /* Check validity of flag arguments. */ + rv = EXECUTION_SUCCESS; + reset_internal_getopt (); + while ((flag_name = internal_getopt (list, optflags)) != -1) + { + switch (flag_name) + { + case 'i': /* don't allow set -i */ + s[0] = list_opttype; + s[1] = 'i'; + s[2] = '\0'; + sh_invalidopt (s); + builtin_usage (); + return (EX_USAGE); + CASE_HELPOPT; + case '?': + builtin_usage (); + return (list_optopt == '?' ? EXECUTION_SUCCESS : EX_USAGE); + default: + break; + } + } + + /* Do the set command. While the list consists of words starting with + '-' or '+' treat them as flags, otherwise, start assigning them to + $1 ... $n. */ + for (force_assignment = opts_changed = 0; list; ) + { + arg = list->word->word; + + /* If the argument is `--' or `-' then signal the end of the list + and remember the remaining arguments. */ + if (arg[0] == '-' && (!arg[1] || (arg[1] == '-' && !arg[2]))) + { + list = list->next; + + /* `set --' unsets the positional parameters. */ + if (arg[1] == '-') + force_assignment = 1; + + /* Until told differently, the old shell behaviour of + `set - [arg ...]' being equivalent to `set +xv [arg ...]' + stands. Posix.2 says the behaviour is marked as obsolescent. */ + else + { + change_flag ('x', '+'); + change_flag ('v', '+'); + opts_changed = 1; + } + + break; + } + + if ((on_or_off = *arg) && (on_or_off == '-' || on_or_off == '+')) + { + while (flag_name = *++arg) + { + if (flag_name == '?') + { + builtin_usage (); + return (EXECUTION_SUCCESS); + } + else if (flag_name == 'o') /* -+o option-name */ + { + char *option_name; + WORD_LIST *opt; + + opt = list->next; + + if (opt == 0) + { + list_minus_o_opts (-1, (on_or_off == '+')); + rv = sh_chkwrite (rv); + continue; + } + + option_name = opt->word->word; + + if (option_name == 0 || *option_name == '\0' || + *option_name == '-' || *option_name == '+') + { + list_minus_o_opts (-1, (on_or_off == '+')); + continue; + } + list = list->next; /* Skip over option name. */ + + opts_changed = 1; + if ((r = set_minus_o_option (on_or_off, option_name)) != EXECUTION_SUCCESS) + { + set_shellopts (); + return (r); + } + } + else if (change_flag (flag_name, on_or_off) == FLAG_ERROR) + { + s[0] = on_or_off; + s[1] = flag_name; + s[2] = '\0'; + sh_invalidopt (s); + builtin_usage (); + set_shellopts (); + return (EXECUTION_FAILURE); + } + opts_changed = 1; + } + } + else + { + break; + } + list = list->next; + } + + /* Assigning $1 ... $n */ + if (list || force_assignment) + remember_args (list, 1); + /* Set up new value of $SHELLOPTS */ + if (opts_changed) + set_shellopts (); + return (rv); +} + +#line 830 "./set.def" + +#define NEXT_VARIABLE() any_failed++; list = list->next; continue; + +int +unset_builtin (list) + WORD_LIST *list; +{ + int unset_function, unset_variable, unset_array, opt, nameref, any_failed; + int global_unset_func, global_unset_var, vflags, valid_id; + char *name, *tname; + + unset_function = unset_variable = unset_array = nameref = any_failed = 0; + global_unset_func = global_unset_var = 0; + + reset_internal_getopt (); + while ((opt = internal_getopt (list, "fnv")) != -1) + { + switch (opt) + { + case 'f': + global_unset_func = 1; + break; + case 'v': + global_unset_var = 1; + break; + case 'n': + nameref = 1; + break; + CASE_HELPOPT; + default: + builtin_usage (); + return (EX_USAGE); + } + } + + list = loptend; + + if (global_unset_func && global_unset_var) + { + builtin_error (_("cannot simultaneously unset a function and a variable")); + return (EXECUTION_FAILURE); + } + else if (unset_function && nameref) + nameref = 0; + +#if defined (ARRAY_VARS) + vflags = assoc_expand_once ? (VA_NOEXPAND|VA_ONEWORD) : 0; +#endif + + while (list) + { + SHELL_VAR *var; + int tem; +#if defined (ARRAY_VARS) + char *t; +#endif + + name = list->word->word; + + unset_function = global_unset_func; + unset_variable = global_unset_var; + +#if defined (ARRAY_VARS) + unset_array = 0; + /* XXX valid array reference second arg was 0 */ + if (!unset_function && nameref == 0 && valid_array_reference (name, vflags)) + { + t = strchr (name, '['); + *t++ = '\0'; + unset_array++; + } +#endif + /* Get error checking out of the way first. The low-level functions + just perform the unset, relying on the caller to verify. */ + valid_id = legal_identifier (name); + + /* Whether or not we are in posix mode, if neither -f nor -v appears, + skip over trying to unset variables with invalid names and just + treat them as potential shell function names. */ + if (global_unset_func == 0 && global_unset_var == 0 && valid_id == 0) + { + unset_variable = unset_array = 0; + unset_function = 1; + } + + /* Bash allows functions with names which are not valid identifiers + to be created when not in posix mode, so check only when in posix + mode when unsetting a function. */ + if (unset_function == 0 && valid_id == 0) + { + sh_invalidid (name); + NEXT_VARIABLE (); + } + + /* Search for functions here if -f supplied or if NAME cannot be a + variable name. */ + var = unset_function ? find_function (name) + : (nameref ? find_variable_last_nameref (name, 0) : find_variable (name)); + + /* Some variables (but not functions yet) cannot be unset, period. */ + if (var && unset_function == 0 && non_unsettable_p (var)) + { + builtin_error (_("%s: cannot unset"), name); + NEXT_VARIABLE (); + } + + /* if we have a nameref we want to use it */ + if (var && unset_function == 0 && nameref == 0 && STREQ (name, name_cell(var)) == 0) + name = name_cell (var); + + /* Posix.2 says try variables first, then functions. If we would + find a function after unsuccessfully searching for a variable, + note that we're acting on a function now as if -f were + supplied. The readonly check below takes care of it. */ + if (var == 0 && nameref == 0 && unset_variable == 0 && unset_function == 0) + { + if (var = find_function (name)) + unset_function = 1; + } + + /* Posix.2 says that unsetting readonly variables is an error. */ + if (var && readonly_p (var)) + { + builtin_error (_("%s: cannot unset: readonly %s"), + var->name, unset_function ? "function" : "variable"); + NEXT_VARIABLE (); + } + + /* Unless the -f option is supplied, the name refers to a variable. */ +#if defined (ARRAY_VARS) + if (var && unset_array) + { + /* Let unbind_array_element decide what to do with non-array vars */ + tem = unbind_array_element (var, t, vflags); /* XXX new third arg */ + if (tem == -2 && array_p (var) == 0 && assoc_p (var) == 0) + { + builtin_error (_("%s: not an array variable"), var->name); + NEXT_VARIABLE (); + } + else if (tem < 0) + any_failed++; + } + else +#endif /* ARRAY_VARS */ + /* If we're trying to unset a nameref variable whose value isn't a set + variable, make sure we still try to unset the nameref's value */ + if (var == 0 && nameref == 0 && unset_function == 0) + { + var = find_variable_last_nameref (name, 0); + if (var && nameref_p (var)) + { +#if defined (ARRAY_VARS) + if (valid_array_reference (nameref_cell (var), 0)) + { + tname = savestring (nameref_cell (var)); + if (var = array_variable_part (tname, 0, &t, (int *)0)) + tem = unbind_array_element (var, t, vflags); /* XXX new third arg */ + free (tname); + } + else +#endif + tem = unbind_variable (nameref_cell (var)); + } + else + tem = unbind_variable (name); + } + else + tem = unset_function ? unbind_func (name) : (nameref ? unbind_nameref (name) : unbind_variable (name)); + + /* This is what Posix.2 says: ``If neither -f nor -v + is specified, the name refers to a variable; if a variable by + that name does not exist, a function by that name, if any, + shall be unset.'' */ + if (tem == -1 && nameref == 0 && unset_function == 0 && unset_variable == 0) + tem = unbind_func (name); + + name = list->word->word; /* reset above for namerefs */ + + /* SUSv3, POSIX.1-2001 say: ``Unsetting a variable or function that + was not previously set shall not be considered an error.'' */ + + if (unset_function == 0) + stupidly_hack_special_variables (name); + + list = list->next; + } + + return (any_failed ? EXECUTION_FAILURE : EXECUTION_SUCCESS); +} diff --git a/builtins/setattr.c b/builtins/setattr.c new file mode 100644 index 0000000..8f2529e --- /dev/null +++ b/builtins/setattr.c @@ -0,0 +1,605 @@ +/* setattr.c, created from setattr.def. */ +#line 22 "./setattr.def" + +#include + +#if defined (HAVE_UNISTD_H) +# ifdef _MINIX +# include +# endif +# include +#endif + +#include +#include "../bashansi.h" +#include "../bashintl.h" + +#include "../shell.h" +#include "../execute_cmd.h" +#include "../flags.h" +#include "common.h" +#include "bashgetopt.h" + +extern sh_builtin_func_t *this_shell_builtin; + +#ifdef ARRAY_VARS +extern int declare_builtin PARAMS((WORD_LIST *)); +#endif + +#define READONLY_OR_EXPORT \ + (this_shell_builtin == readonly_builtin || this_shell_builtin == export_builtin) + +#line 69 "./setattr.def" + +/* For each variable name in LIST, make that variable appear in the + environment passed to simple commands. If there is no LIST, then + print all such variables. An argument of `-n' says to remove the + exported attribute from variables named in LIST. An argument of + -f indicates that the names present in LIST refer to functions. */ +int +export_builtin (list) + register WORD_LIST *list; +{ + return (set_or_show_attributes (list, att_exported, 0)); +} + +#line 103 "./setattr.def" + +/* For each variable name in LIST, make that variable readonly. Given an + empty LIST, print out all existing readonly variables. */ +int +readonly_builtin (list) + register WORD_LIST *list; +{ + return (set_or_show_attributes (list, att_readonly, 0)); +} + +#if defined (ARRAY_VARS) +# define ATTROPTS "aAfnp" +#else +# define ATTROPTS "fnp" +#endif + +/* For each variable name in LIST, make that variable have the specified + ATTRIBUTE. An arg of `-n' says to remove the attribute from the the + remaining names in LIST (doesn't work for readonly). */ +int +set_or_show_attributes (list, attribute, nodefs) + register WORD_LIST *list; + int attribute, nodefs; +{ + register SHELL_VAR *var; + int assign, undo, any_failed, assign_error, opt; + int functions_only, arrays_only, assoc_only; + int aflags; + char *name; +#if defined (ARRAY_VARS) + WORD_LIST *nlist, *tlist; + WORD_DESC *w; + char optw[8]; + int opti; +#endif + + functions_only = arrays_only = assoc_only = 0; + undo = any_failed = assign_error = 0; + /* Read arguments from the front of the list. */ + reset_internal_getopt (); + while ((opt = internal_getopt (list, ATTROPTS)) != -1) + { + switch (opt) + { + case 'n': + undo = 1; + break; + case 'f': + functions_only = 1; + break; +#if defined (ARRAY_VARS) + case 'a': + arrays_only = 1; + break; + case 'A': + assoc_only = 1; + break; +#endif + case 'p': + break; + CASE_HELPOPT; + default: + builtin_usage (); + return (EX_USAGE); + } + } + list = loptend; + + if (list) + { + if (attribute & att_exported) + array_needs_making = 1; + + /* Cannot undo readonly status, silently disallowed. */ + if (undo && (attribute & att_readonly)) + attribute &= ~att_readonly; + + while (list) + { + name = list->word->word; + + if (functions_only) /* xxx -f name */ + { + var = find_function (name); + if (var == 0) + { + builtin_error (_("%s: not a function"), name); + any_failed++; + } + else if ((attribute & att_exported) && undo == 0 && exportable_function_name (name) == 0) + { + builtin_error (_("%s: cannot export"), name); + any_failed++; + } + else + SETVARATTR (var, attribute, undo); + + list = list->next; + continue; + } + + /* xxx [-np] name[=value] */ + assign = assignment (name, 0); + + aflags = 0; + if (assign) + { + name[assign] = '\0'; + if (name[assign - 1] == '+') + { + aflags |= ASS_APPEND; + name[assign - 1] = '\0'; + } + } + + if (legal_identifier (name) == 0) + { + sh_invalidid (name); + if (assign) + assign_error++; + else + any_failed++; + list = list->next; + continue; + } + + if (assign) /* xxx [-np] name=value */ + { + name[assign] = '='; + if (aflags & ASS_APPEND) + name[assign - 1] = '+'; +#if defined (ARRAY_VARS) + /* Let's try something here. Turn readonly -a xxx=yyy into + declare -ra xxx=yyy and see what that gets us. */ + if (arrays_only || assoc_only) + { + tlist = list->next; + list->next = (WORD_LIST *)NULL; + /* Add -g to avoid readonly/export creating local variables: + only local/declare/typeset create local variables */ + opti = 0; + optw[opti++] = '-'; + optw[opti++] = 'g'; + if (attribute & att_readonly) + optw[opti++] = 'r'; + if (attribute & att_exported) + optw[opti++] = 'x'; + if (arrays_only) + optw[opti++] = 'a'; + else + optw[opti++] = 'A'; + optw[opti] = '\0'; + + w = make_word (optw); + nlist = make_word_list (w, list); + + opt = declare_builtin (nlist); + if (opt != EXECUTION_SUCCESS) + assign_error++; + list->next = tlist; + dispose_word (w); + free (nlist); + } + else +#endif + /* This word has already been expanded once with command + and parameter expansion. Call do_assignment_no_expand (), + which does not do command or parameter substitution. If + the assignment is not performed correctly, flag an error. */ + if (do_assignment_no_expand (name) == 0) + assign_error++; + name[assign] = '\0'; + if (aflags & ASS_APPEND) + name[assign - 1] = '\0'; + } + + set_var_attribute (name, attribute, undo); + if (assign) /* restore word */ + { + name[assign] = '='; + if (aflags & ASS_APPEND) + name[assign-1] = '+'; + } + list = list->next; + } + } + else + { + SHELL_VAR **variable_list; + register int i; + + if ((attribute & att_function) || functions_only) + { + variable_list = all_shell_functions (); + if (attribute != att_function) + attribute &= ~att_function; /* so declare -xf works, for example */ + } + else + variable_list = all_shell_variables (); + +#if defined (ARRAY_VARS) + if (attribute & att_array) + { + arrays_only++; + if (attribute != att_array) + attribute &= ~att_array; + } + else if (attribute & att_assoc) + { + assoc_only++; + if (attribute != att_assoc) + attribute &= ~att_assoc; + } +#endif + + if (variable_list) + { + for (i = 0; var = variable_list[i]; i++) + { +#if defined (ARRAY_VARS) + if (arrays_only && array_p (var) == 0) + continue; + else if (assoc_only && assoc_p (var) == 0) + continue; +#endif + + /* If we imported a variable that's not a valid identifier, don't + show it in any lists. */ + if ((var->attributes & (att_invisible|att_imported)) == (att_invisible|att_imported)) + continue; + + if ((var->attributes & attribute)) + { + show_var_attributes (var, READONLY_OR_EXPORT, nodefs); + if (any_failed = sh_chkwrite (any_failed)) + break; + } + } + free (variable_list); + } + } + + return (assign_error ? EX_BADASSIGN + : ((any_failed == 0) ? EXECUTION_SUCCESS + : EXECUTION_FAILURE)); +} + +/* Show all variable variables (v == 1) or functions (v == 0) with + attributes. */ +int +show_all_var_attributes (v, nodefs) + int v, nodefs; +{ + SHELL_VAR **variable_list, *var; + int any_failed; + register int i; + + variable_list = v ? all_shell_variables () : all_shell_functions (); + if (variable_list == 0) + return (EXECUTION_SUCCESS); + + for (i = any_failed = 0; var = variable_list[i]; i++) + { + show_var_attributes (var, READONLY_OR_EXPORT, nodefs); + if (any_failed = sh_chkwrite (any_failed)) + break; + } + free (variable_list); + return (any_failed == 0 ? EXECUTION_SUCCESS : EXECUTION_FAILURE); +} + +/* Show all local variable variables with their attributes. This shows unset + local variables (all_local_variables called with 0 argment). */ +int +show_local_var_attributes (v, nodefs) + int v, nodefs; +{ + SHELL_VAR **variable_list, *var; + int any_failed; + register int i; + + variable_list = all_local_variables (0); + if (variable_list == 0) + return (EXECUTION_SUCCESS); + + for (i = any_failed = 0; var = variable_list[i]; i++) + { + show_var_attributes (var, READONLY_OR_EXPORT, nodefs); + if (any_failed = sh_chkwrite (any_failed)) + break; + } + free (variable_list); + return (any_failed == 0 ? EXECUTION_SUCCESS : EXECUTION_FAILURE); +} + +int +var_attribute_string (var, pattr, flags) + SHELL_VAR *var; + int pattr; + char *flags; /* filled in with attributes */ +{ + int i; + + i = 0; + + /* pattr == 0 means we are called from `declare'. */ + if (pattr == 0 || posixly_correct == 0) + { +#if defined (ARRAY_VARS) + if (array_p (var)) + flags[i++] = 'a'; + + if (assoc_p (var)) + flags[i++] = 'A'; +#endif + + if (function_p (var)) + flags[i++] = 'f'; + + if (integer_p (var)) + flags[i++] = 'i'; + + if (nameref_p (var)) + flags[i++] = 'n'; + + if (readonly_p (var)) + flags[i++] = 'r'; + + if (trace_p (var)) + flags[i++] = 't'; + + if (exported_p (var)) + flags[i++] = 'x'; + + if (capcase_p (var)) + flags[i++] = 'c'; + + if (lowercase_p (var)) + flags[i++] = 'l'; + + if (uppercase_p (var)) + flags[i++] = 'u'; + } + else + { +#if defined (ARRAY_VARS) + if (array_p (var)) + flags[i++] = 'a'; + + if (assoc_p (var)) + flags[i++] = 'A'; +#endif + + if (function_p (var)) + flags[i++] = 'f'; + } + + flags[i] = '\0'; + return i; +} + +/* Show the attributes for shell variable VAR. If NODEFS is non-zero, + don't show function definitions along with the name. If PATTR is + non-zero, it indicates we're being called from `export' or `readonly'. + In POSIX mode, this prints the name of the calling builtin (`export' + or `readonly') instead of `declare', and doesn't print function defs + when called by `export' or `readonly'. */ +int +show_var_attributes (var, pattr, nodefs) + SHELL_VAR *var; + int pattr, nodefs; +{ + char flags[MAX_ATTRIBUTES], *x; + int i; + + i = var_attribute_string (var, pattr, flags); + + /* If we're printing functions with definitions, print the function def + first, then the attributes, instead of printing output that can't be + reused as input to recreate the current state. */ + if (function_p (var) && nodefs == 0 && (pattr == 0 || posixly_correct == 0)) + { + printf ("%s\n", named_function_string (var->name, function_cell (var), FUNC_MULTILINE|FUNC_EXTERNAL)); + nodefs++; + if (pattr == 0 && i == 1 && flags[0] == 'f') + return 0; /* don't print `declare -f name' */ + } + + if (pattr == 0 || posixly_correct == 0) + printf ("declare -%s ", i ? flags : "-"); + else if (i) + printf ("%s -%s ", this_command_name, flags); + else + printf ("%s ", this_command_name); + +#if defined (ARRAY_VARS) + if (invisible_p (var) && (array_p (var) || assoc_p (var))) + printf ("%s\n", var->name); + else if (array_p (var)) + print_array_assignment (var, 0); + else if (assoc_p (var)) + print_assoc_assignment (var, 0); + else +#endif + /* force `readonly' and `export' to not print out function definitions + when in POSIX mode. */ + if (nodefs || (function_p (var) && pattr != 0 && posixly_correct)) + printf ("%s\n", var->name); + else if (function_p (var)) + printf ("%s\n", named_function_string (var->name, function_cell (var), FUNC_MULTILINE|FUNC_EXTERNAL)); + else if (invisible_p (var) || var_isset (var) == 0) + printf ("%s\n", var->name); + else + { + x = sh_double_quote (value_cell (var)); + printf ("%s=%s\n", var->name, x); + free (x); + } + return (0); +} + +int +show_name_attributes (name, nodefs) + char *name; + int nodefs; +{ + SHELL_VAR *var; + + var = find_variable_noref (name); + + if (var) /* show every variable with attributes, even unset ones */ + { + show_var_attributes (var, READONLY_OR_EXPORT, nodefs); + return (0); + } + else + return (1); +} + +int +show_localname_attributes (name, nodefs) + char *name; + int nodefs; +{ + SHELL_VAR *var; + + var = find_variable_noref (name); + + if (var && local_p (var) && var->context == variable_context) /* show every variable with attributes, even unset ones */ + { + show_var_attributes (var, READONLY_OR_EXPORT, nodefs); + return (0); + } + else + return (1); +} + +int +show_func_attributes (name, nodefs) + char *name; + int nodefs; +{ + SHELL_VAR *var; + + var = find_function (name); + + if (var) + { + show_var_attributes (var, READONLY_OR_EXPORT, nodefs); + return (0); + } + else + return (1); +} + +void +set_var_attribute (name, attribute, undo) + char *name; + int attribute, undo; +{ + SHELL_VAR *var, *tv, *v, *refvar; + char *tvalue; + + if (undo) + var = find_variable (name); + else + { + tv = find_tempenv_variable (name); + /* XXX -- need to handle case where tv is a temp variable in a + function-scope context, since function_env has been merged into + the local variables table. */ + if (tv && tempvar_p (tv)) + { + tvalue = var_isset (tv) ? savestring (value_cell (tv)) : savestring (""); + + var = bind_variable (tv->name, tvalue, 0); + if (var == 0) + { + free (tvalue); + return; /* XXX - no error message here */ + } + var->attributes |= tv->attributes & ~att_tempvar; + /* This avoids an error message when propagating a read-only var + later on. */ + if (posixly_correct || shell_compatibility_level <= 44) + { + if (var->context == 0 && (attribute & att_readonly)) + { + /* Don't bother to set the `propagate to the global variables + table' flag if we've just bound the variable in that + table */ + v = find_global_variable (tv->name); + if (v != var) + VSETATTR (tv, att_propagate); + } + else + VSETATTR (tv, att_propagate); + if (var->context != 0) + VSETATTR (var, att_propagate); + } + + SETVARATTR (tv, attribute, undo); /* XXX */ + + stupidly_hack_special_variables (tv->name); + + free (tvalue); + } + else + { + var = find_variable_notempenv (name); + if (var == 0) + { + /* We might have a nameref pointing to something that we can't + resolve to a shell variable. If we do, skip it. We do a little + checking just so we can print an error message. */ + refvar = find_variable_nameref_for_create (name, 0); + if (refvar == INVALID_NAMEREF_VALUE) + return; + /* Otherwise we probably have a nameref pointing to a variable + that hasn't been created yet. bind_variable will take care + of that. */ + } + if (var == 0) + { + var = bind_variable (name, (char *)NULL, 0); + if (var) + VSETATTR (var, att_invisible); + } + else if (var->context != 0) + VSETATTR (var, att_propagate); + } + } + + if (var) + SETVARATTR (var, attribute, undo); + + if (var && (exported_p (var) || (attribute & att_exported))) + array_needs_making++; /* XXX */ +} diff --git a/builtins/shift.c b/builtins/shift.c new file mode 100644 index 0000000..ff6ebca --- /dev/null +++ b/builtins/shift.c @@ -0,0 +1,61 @@ +/* shift.c, created from shift.def. */ +#line 22 "./shift.def" + +#include + +#if defined (HAVE_UNISTD_H) +# ifdef _MINIX +# include +# endif +# include +#endif + +#include "../bashansi.h" +#include "../bashintl.h" + +#include "../shell.h" +#include "common.h" + +#line 49 "./shift.def" + +int print_shift_error; + +/* Shift the arguments ``left''. Shift DOLLAR_VARS down then take one + off of REST_OF_ARGS and place it into DOLLAR_VARS[9]. If LIST has + anything in it, it is a number which says where to start the + shifting. Return > 0 if `times' > $#, otherwise 0. */ +int +shift_builtin (list) + WORD_LIST *list; +{ + intmax_t times; + int itimes, nargs; + + CHECK_HELPOPT (list); + + if (get_numeric_arg (list, 0, ×) == 0) + return (EXECUTION_FAILURE); + + if (times == 0) + return (EXECUTION_SUCCESS); + else if (times < 0) + { + sh_erange (list ? list->word->word : NULL, _("shift count")); + return (EXECUTION_FAILURE); + } + nargs = number_of_args (); + if (times > nargs) + { + if (print_shift_error) + sh_erange (list ? list->word->word : NULL, _("shift count")); + return (EXECUTION_FAILURE); + } + else if (times == nargs) + clear_dollar_vars (); + else + shift_args (itimes = times); + + invalidate_cached_quoted_dollar_at (); + + return (EXECUTION_SUCCESS); +} diff --git a/builtins/shopt.c b/builtins/shopt.c new file mode 100644 index 0000000..0f88f93 --- /dev/null +++ b/builtins/shopt.c @@ -0,0 +1,861 @@ +/* shopt.c, created from shopt.def. */ +#line 22 "./shopt.def" + +#line 43 "./shopt.def" + +#include + +#if defined (HAVE_UNISTD_H) +# ifdef _MINIX +# include +# endif +# include +#endif + +#include + +#include "version.h" + +#include "../bashintl.h" + +#include "../shell.h" +#include "../flags.h" +#include "common.h" +#include "bashgetopt.h" + +#if defined (READLINE) +# include "../bashline.h" +#endif + +#if defined (HISTORY) +# include "../bashhist.h" +#endif + +#define UNSETOPT 0 +#define SETOPT 1 + +#define OPTFMT "%-15s\t%s\n" + +extern int allow_null_glob_expansion, fail_glob_expansion, glob_dot_filenames; +extern int cdable_vars, mail_warning, source_uses_path; +extern int no_exit_on_failed_exec, print_shift_error; +extern int check_hashed_filenames, promptvars; +extern int cdspelling, expand_aliases; +extern int extended_quote; +extern int check_window_size; +extern int glob_ignore_case, match_ignore_case; +extern int hup_on_exit; +extern int xpg_echo; +extern int gnu_error_format; +extern int check_jobs_at_exit; +extern int autocd; +extern int glob_star; +extern int glob_asciirange; +extern int lastpipe_opt; +extern int inherit_errexit; +extern int localvar_inherit; +extern int localvar_unset; + +#if defined (EXTENDED_GLOB) +extern int extended_glob; +#endif + +#if defined (READLINE) +extern int hist_verify, history_reediting, perform_hostname_completion; +extern int no_empty_command_completion; +extern int force_fignore; +extern int dircomplete_spelling, dircomplete_expand; +extern int complete_fullquote; + +extern int enable_hostname_completion PARAMS((int)); +#endif + +#if defined (PROGRAMMABLE_COMPLETION) +extern int prog_completion_enabled; +extern int progcomp_alias; +#endif + +#if defined (DEBUGGER) +extern int debugging_mode; +#endif + +#if defined (ARRAY_VARS) +extern int assoc_expand_once; +extern int array_expand_once; +#endif + +#if defined (SYSLOG_HISTORY) +extern int syslog_history; +#endif + +static void shopt_error PARAMS((char *)); + +static int set_shellopts_after_change PARAMS((char *, int)); +static int set_compatibility_level PARAMS((char *, int)); + +#if defined (RESTRICTED_SHELL) +static int set_restricted_shell PARAMS((char *, int)); +#endif + +#if defined (READLINE) +static int shopt_enable_hostname_completion PARAMS((char *, int)); +static int shopt_set_complete_direxpand PARAMS((char *, int)); +#endif + +static int shopt_set_debug_mode PARAMS((char *, int)); + +static int shopt_login_shell; +static int shopt_compat31; +static int shopt_compat32; +static int shopt_compat40; +static int shopt_compat41; +static int shopt_compat42; +static int shopt_compat43; +static int shopt_compat44; + +typedef int shopt_set_func_t PARAMS((char *, int)); + +/* If you add a new variable name here, make sure to set the default value + appropriately in reset_shopt_options. */ + +static struct { + char *name; + int *value; + shopt_set_func_t *set_func; +} shopt_vars[] = { + { "autocd", &autocd, (shopt_set_func_t *)NULL }, +#if defined (ARRAY_VARS) + { "assoc_expand_once", &assoc_expand_once, (shopt_set_func_t *)NULL }, +#endif + { "cdable_vars", &cdable_vars, (shopt_set_func_t *)NULL }, + { "cdspell", &cdspelling, (shopt_set_func_t *)NULL }, + { "checkhash", &check_hashed_filenames, (shopt_set_func_t *)NULL }, +#if defined (JOB_CONTROL) + { "checkjobs", &check_jobs_at_exit, (shopt_set_func_t *)NULL }, +#endif + { "checkwinsize", &check_window_size, (shopt_set_func_t *)NULL }, +#if defined (HISTORY) + { "cmdhist", &command_oriented_history, (shopt_set_func_t *)NULL }, +#endif + { "compat31", &shopt_compat31, set_compatibility_level }, + { "compat32", &shopt_compat32, set_compatibility_level }, + { "compat40", &shopt_compat40, set_compatibility_level }, + { "compat41", &shopt_compat41, set_compatibility_level }, + { "compat42", &shopt_compat42, set_compatibility_level }, + { "compat43", &shopt_compat43, set_compatibility_level }, + { "compat44", &shopt_compat44, set_compatibility_level }, +#if defined (READLINE) + { "complete_fullquote", &complete_fullquote, (shopt_set_func_t *)NULL}, + { "direxpand", &dircomplete_expand, shopt_set_complete_direxpand }, + { "dirspell", &dircomplete_spelling, (shopt_set_func_t *)NULL }, +#endif + { "dotglob", &glob_dot_filenames, (shopt_set_func_t *)NULL }, + { "execfail", &no_exit_on_failed_exec, (shopt_set_func_t *)NULL }, + { "expand_aliases", &expand_aliases, (shopt_set_func_t *)NULL }, +#if defined (DEBUGGER) + { "extdebug", &debugging_mode, shopt_set_debug_mode }, +#endif +#if defined (EXTENDED_GLOB) + { "extglob", &extended_glob, (shopt_set_func_t *)NULL }, +#endif + { "extquote", &extended_quote, (shopt_set_func_t *)NULL }, + { "failglob", &fail_glob_expansion, (shopt_set_func_t *)NULL }, +#if defined (READLINE) + { "force_fignore", &force_fignore, (shopt_set_func_t *)NULL }, +#endif + { "globasciiranges", &glob_asciirange, (shopt_set_func_t *)NULL }, + { "globstar", &glob_star, (shopt_set_func_t *)NULL }, + { "gnu_errfmt", &gnu_error_format, (shopt_set_func_t *)NULL }, +#if defined (HISTORY) + { "histappend", &force_append_history, (shopt_set_func_t *)NULL }, +#endif +#if defined (READLINE) + { "histreedit", &history_reediting, (shopt_set_func_t *)NULL }, + { "histverify", &hist_verify, (shopt_set_func_t *)NULL }, + { "hostcomplete", &perform_hostname_completion, shopt_enable_hostname_completion }, +#endif + { "huponexit", &hup_on_exit, (shopt_set_func_t *)NULL }, + { "inherit_errexit", &inherit_errexit, (shopt_set_func_t *)NULL }, + { "interactive_comments", &interactive_comments, set_shellopts_after_change }, + { "lastpipe", &lastpipe_opt, (shopt_set_func_t *)NULL }, +#if defined (HISTORY) + { "lithist", &literal_history, (shopt_set_func_t *)NULL }, +#endif + { "localvar_inherit", &localvar_inherit, (shopt_set_func_t *)NULL }, + { "localvar_unset", &localvar_unset, (shopt_set_func_t *)NULL }, + { "login_shell", &shopt_login_shell, set_login_shell }, + { "mailwarn", &mail_warning, (shopt_set_func_t *)NULL }, +#if defined (READLINE) + { "no_empty_cmd_completion", &no_empty_command_completion, (shopt_set_func_t *)NULL }, +#endif + { "nocaseglob", &glob_ignore_case, (shopt_set_func_t *)NULL }, + { "nocasematch", &match_ignore_case, (shopt_set_func_t *)NULL }, + { "nullglob", &allow_null_glob_expansion, (shopt_set_func_t *)NULL }, +#if defined (PROGRAMMABLE_COMPLETION) + { "progcomp", &prog_completion_enabled, (shopt_set_func_t *)NULL }, +# if defined (ALIAS) + { "progcomp_alias", &progcomp_alias, (shopt_set_func_t *)NULL }, +# endif +#endif + { "promptvars", &promptvars, (shopt_set_func_t *)NULL }, +#if defined (RESTRICTED_SHELL) + { "restricted_shell", &restricted_shell, set_restricted_shell }, +#endif + { "shift_verbose", &print_shift_error, (shopt_set_func_t *)NULL }, + { "sourcepath", &source_uses_path, (shopt_set_func_t *)NULL }, +#if defined (SYSLOG_HISTORY) && defined (SYSLOG_SHOPT) + { "syslog_history", &syslog_history, (shopt_set_func_t *)NULL }, +#endif + { "xpg_echo", &xpg_echo, (shopt_set_func_t *)NULL }, + { (char *)0, (int *)0, (shopt_set_func_t *)NULL } +}; + +#define N_SHOPT_OPTIONS (sizeof (shopt_vars) / sizeof (shopt_vars[0])) + +#define GET_SHOPT_OPTION_VALUE(i) (*shopt_vars[i].value) + +static const char * const on = "on"; +static const char * const off = "off"; + +static int find_shopt PARAMS((char *)); +static int toggle_shopts PARAMS((int, WORD_LIST *, int)); +static void print_shopt PARAMS((char *, int, int)); +static int list_shopts PARAMS((WORD_LIST *, int)); +static int list_some_shopts PARAMS((int, int)); +static int list_shopt_o_options PARAMS((WORD_LIST *, int)); +static int list_some_o_options PARAMS((int, int)); +static int set_shopt_o_options PARAMS((int, WORD_LIST *, int)); + +#define SFLAG 0x01 +#define UFLAG 0x02 +#define QFLAG 0x04 +#define OFLAG 0x08 +#define PFLAG 0x10 + +int +shopt_builtin (list) + WORD_LIST *list; +{ + int opt, flags, rval; + + flags = 0; + reset_internal_getopt (); + while ((opt = internal_getopt (list, "psuoq")) != -1) + { + switch (opt) + { + case 's': + flags |= SFLAG; + break; + case 'u': + flags |= UFLAG; + break; + case 'q': + flags |= QFLAG; + break; + case 'o': + flags |= OFLAG; + break; + case 'p': + flags |= PFLAG; + break; + CASE_HELPOPT; + default: + builtin_usage (); + return (EX_USAGE); + } + } + list = loptend; + + if ((flags & (SFLAG|UFLAG)) == (SFLAG|UFLAG)) + { + builtin_error (_("cannot set and unset shell options simultaneously")); + return (EXECUTION_FAILURE); + } + + rval = EXECUTION_SUCCESS; + if ((flags & OFLAG) && ((flags & (SFLAG|UFLAG)) == 0)) /* shopt -o */ + rval = list_shopt_o_options (list, flags); + else if (list && (flags & OFLAG)) /* shopt -so args */ + rval = set_shopt_o_options ((flags & SFLAG) ? FLAG_ON : FLAG_OFF, list, flags & QFLAG); + else if (flags & OFLAG) /* shopt -so */ + rval = list_some_o_options ((flags & SFLAG) ? 1 : 0, flags); + else if (list && (flags & (SFLAG|UFLAG))) /* shopt -su args */ + rval = toggle_shopts ((flags & SFLAG) ? SETOPT : UNSETOPT, list, flags & QFLAG); + else if ((flags & (SFLAG|UFLAG)) == 0) /* shopt [args] */ + rval = list_shopts (list, flags); + else /* shopt -su */ + rval = list_some_shopts ((flags & SFLAG) ? SETOPT : UNSETOPT, flags); + return (rval); +} + +/* Reset the options managed by `shopt' to the values they would have at + shell startup. Variables from shopt_vars. */ +void +reset_shopt_options () +{ + autocd = cdable_vars = cdspelling = 0; + check_hashed_filenames = CHECKHASH_DEFAULT; + check_window_size = CHECKWINSIZE_DEFAULT; + allow_null_glob_expansion = glob_dot_filenames = 0; + no_exit_on_failed_exec = 0; + expand_aliases = 0; + extended_quote = 1; + fail_glob_expansion = 0; + glob_asciirange = GLOBASCII_DEFAULT; + glob_star = 0; + gnu_error_format = 0; + hup_on_exit = 0; + inherit_errexit = 0; + interactive_comments = 1; + lastpipe_opt = 0; + localvar_inherit = localvar_unset = 0; + mail_warning = 0; + glob_ignore_case = match_ignore_case = 0; + print_shift_error = 0; + source_uses_path = promptvars = 1; + +#if defined (JOB_CONTROL) + check_jobs_at_exit = 0; +#endif + +#if defined (EXTENDED_GLOB) + extended_glob = EXTGLOB_DEFAULT; +#endif + +#if defined (ARRAY_VARS) + assoc_expand_once = 0; +#endif + +#if defined (HISTORY) + literal_history = 0; + force_append_history = 0; + command_oriented_history = 1; +#endif + +#if defined (SYSLOG_HISTORY) +# if defined (SYSLOG_SHOPT) + syslog_history = SYSLOG_SHOPT; +# else + syslog_history = 1; +# endif /* SYSLOG_SHOPT */ +#endif + +#if defined (READLINE) + complete_fullquote = 1; + force_fignore = 1; + hist_verify = history_reediting = 0; + perform_hostname_completion = 1; +# if DIRCOMPLETE_EXPAND_DEFAULT + dircomplete_expand = 1; +# else + dircomplete_expand = 0; +#endif + dircomplete_spelling = 0; + no_empty_command_completion = 0; +#endif + +#if defined (PROGRAMMABLE_COMPLETION) + prog_completion_enabled = 1; +# if defined (ALIAS) + progcomp_alias = 0; +# endif +#endif + +#if defined (DEFAULT_ECHO_TO_XPG) || defined (STRICT_POSIX) + xpg_echo = 1; +#else + xpg_echo = 0; +#endif /* DEFAULT_ECHO_TO_XPG */ + + shopt_login_shell = login_shell; +} + +static int +find_shopt (name) + char *name; +{ + int i; + + for (i = 0; shopt_vars[i].name; i++) + if (STREQ (name, shopt_vars[i].name)) + return i; + return -1; +} + +static void +shopt_error (s) + char *s; +{ + builtin_error (_("%s: invalid shell option name"), s); +} + +static int +toggle_shopts (mode, list, quiet) + int mode; + WORD_LIST *list; + int quiet; +{ + WORD_LIST *l; + int ind, rval; + SHELL_VAR *v; + + for (l = list, rval = EXECUTION_SUCCESS; l; l = l->next) + { + ind = find_shopt (l->word->word); + if (ind < 0) + { + shopt_error (l->word->word); + rval = EXECUTION_FAILURE; + } + else + { + *shopt_vars[ind].value = mode; /* 1 for set, 0 for unset */ + if (shopt_vars[ind].set_func) + (*shopt_vars[ind].set_func) (shopt_vars[ind].name, mode); + } + } + + /* Don't set $BASHOPTS here if it hasn't already been initialized */ + if (v = find_variable ("BASHOPTS")) + set_bashopts (); + return (rval); +} + +static void +print_shopt (name, val, flags) + char *name; + int val, flags; +{ + if (flags & PFLAG) + printf ("shopt %s %s\n", val ? "-s" : "-u", name); + else + printf (OPTFMT, name, val ? on : off); +} + +/* List the values of all or any of the `shopt' options. Returns 0 if + all were listed or all variables queried were on; 1 otherwise. */ +static int +list_shopts (list, flags) + WORD_LIST *list; + int flags; +{ + WORD_LIST *l; + int i, val, rval; + + if (list == 0) + { + for (i = 0; shopt_vars[i].name; i++) + { + val = *shopt_vars[i].value; + if ((flags & QFLAG) == 0) + print_shopt (shopt_vars[i].name, val, flags); + } + return (sh_chkwrite (EXECUTION_SUCCESS)); + } + + for (l = list, rval = EXECUTION_SUCCESS; l; l = l->next) + { + i = find_shopt (l->word->word); + if (i < 0) + { + shopt_error (l->word->word); + rval = EXECUTION_FAILURE; + continue; + } + val = *shopt_vars[i].value; + if (val == 0) + rval = EXECUTION_FAILURE; + if ((flags & QFLAG) == 0) + print_shopt (l->word->word, val, flags); + } + + return (sh_chkwrite (rval)); +} + +static int +list_some_shopts (mode, flags) + int mode, flags; +{ + int val, i; + + for (i = 0; shopt_vars[i].name; i++) + { + val = *shopt_vars[i].value; + if (((flags & QFLAG) == 0) && mode == val) + print_shopt (shopt_vars[i].name, val, flags); + } + return (sh_chkwrite (EXECUTION_SUCCESS)); +} + +static int +list_shopt_o_options (list, flags) + WORD_LIST *list; + int flags; +{ + WORD_LIST *l; + int val, rval; + + if (list == 0) + { + if ((flags & QFLAG) == 0) + list_minus_o_opts (-1, (flags & PFLAG)); + return (sh_chkwrite (EXECUTION_SUCCESS)); + } + + for (l = list, rval = EXECUTION_SUCCESS; l; l = l->next) + { + val = minus_o_option_value (l->word->word); + if (val == -1) + { + sh_invalidoptname (l->word->word); + rval = EXECUTION_FAILURE; + continue; + } + if (val == 0) + rval = EXECUTION_FAILURE; + if ((flags & QFLAG) == 0) + { + if (flags & PFLAG) + printf ("set %co %s\n", val ? '-' : '+', l->word->word); + else + printf (OPTFMT, l->word->word, val ? on : off); + } + } + return (sh_chkwrite (rval)); +} + +static int +list_some_o_options (mode, flags) + int mode, flags; +{ + if ((flags & QFLAG) == 0) + list_minus_o_opts (mode, (flags & PFLAG)); + return (sh_chkwrite (EXECUTION_SUCCESS)); +} + +static int +set_shopt_o_options (mode, list, quiet) + int mode; + WORD_LIST *list; + int quiet; +{ + WORD_LIST *l; + int rval; + + for (l = list, rval = EXECUTION_SUCCESS; l; l = l->next) + { + if (set_minus_o_option (mode, l->word->word) == EXECUTION_FAILURE) + rval = EXECUTION_FAILURE; + } + set_shellopts (); + return rval; +} + +/* If we set or unset interactive_comments with shopt, make sure the + change is reflected in $SHELLOPTS. */ +static int +set_shellopts_after_change (option_name, mode) + char *option_name; + int mode; +{ + set_shellopts (); + return (0); +} + +static int +shopt_set_debug_mode (option_name, mode) + char *option_name; + int mode; +{ +#if defined (DEBUGGER) + error_trace_mode = function_trace_mode = debugging_mode; + set_shellopts (); + if (debugging_mode) + init_bash_argv (); +#endif + return (0); +} + +#if defined (READLINE) +static int +shopt_enable_hostname_completion (option_name, mode) + char *option_name; + int mode; +{ + return (enable_hostname_completion (mode)); +} +#endif + +static int +set_compatibility_level (option_name, mode) + char *option_name; + int mode; +{ + int ind; + char *rhs; + + /* If we're setting something, redo some of the work we did above in + toggle_shopt(). Unset everything and reset the appropriate option + based on OPTION_NAME. */ + if (mode) + { + shopt_compat31 = shopt_compat32 = 0; + shopt_compat40 = shopt_compat41 = shopt_compat42 = shopt_compat43 = 0; + shopt_compat44 = 0; + ind = find_shopt (option_name); + *shopt_vars[ind].value = mode; + } + + /* Then set shell_compatibility_level based on what remains */ + if (shopt_compat31) + shell_compatibility_level = 31; + else if (shopt_compat32) + shell_compatibility_level = 32; + else if (shopt_compat40) + shell_compatibility_level = 40; + else if (shopt_compat41) + shell_compatibility_level = 41; + else if (shopt_compat42) + shell_compatibility_level = 42; + else if (shopt_compat43) + shell_compatibility_level = 43; + else if (shopt_compat44) + shell_compatibility_level = 44; + else + shell_compatibility_level = DEFAULT_COMPAT_LEVEL; + + /* Make sure the current compatibility level is reflected in BASH_COMPAT */ + rhs = itos (shell_compatibility_level); + bind_variable ("BASH_COMPAT", rhs, 0); + free (rhs); + + return 0; +} + +/* Set and unset the various compatibility options from the value of + shell_compatibility_level; used by sv_shcompat */ +void +set_compatibility_opts () +{ + shopt_compat31 = shopt_compat32 = 0; + shopt_compat40 = shopt_compat41 = shopt_compat42 = shopt_compat43 = 0; + shopt_compat44 = 0; + switch (shell_compatibility_level) + { + case DEFAULT_COMPAT_LEVEL: + break; + case 44: + shopt_compat44 = 1; break; + case 43: + shopt_compat43 = 1; break; + case 42: + shopt_compat42 = 1; break; + case 41: + shopt_compat41 = 1; break; + case 40: + shopt_compat40 = 1; break; + case 32: + shopt_compat32 = 1; break; + case 31: + shopt_compat31 = 1; break; + } +} + +#if defined (READLINE) +static int +shopt_set_complete_direxpand (option_name, mode) + char *option_name; + int mode; +{ + set_directory_hook (); + return 0; +} +#endif + +#if defined (RESTRICTED_SHELL) +/* Don't allow the value of restricted_shell to be modified. */ + +static int +set_restricted_shell (option_name, mode) + char *option_name; + int mode; +{ + static int save_restricted = -1; + + if (save_restricted == -1) + save_restricted = shell_is_restricted (shell_name); + + restricted_shell = save_restricted; + return (0); +} +#endif /* RESTRICTED_SHELL */ + +/* Not static so shell.c can call it to initialize shopt_login_shell */ +int +set_login_shell (option_name, mode) + char *option_name; + int mode; +{ + shopt_login_shell = login_shell != 0; + return (0); +} + +char ** +get_shopt_options () +{ + char **ret; + int n, i; + + n = sizeof (shopt_vars) / sizeof (shopt_vars[0]); + ret = strvec_create (n + 1); + for (i = 0; shopt_vars[i].name; i++) + ret[i] = savestring (shopt_vars[i].name); + ret[i] = (char *)NULL; + return ret; +} + +/* + * External interface for other parts of the shell. NAME is a string option; + * MODE is 0 if we want to unset an option; 1 if we want to set an option. + * REUSABLE is 1 if we want to print output in a form that may be reused. + */ +int +shopt_setopt (name, mode) + char *name; + int mode; +{ + WORD_LIST *wl; + int r; + + wl = add_string_to_list (name, (WORD_LIST *)NULL); + r = toggle_shopts (mode, wl, 0); + dispose_words (wl); + return r; +} + +int +shopt_listopt (name, reusable) + char *name; + int reusable; +{ + int i; + + if (name == 0) + return (list_shopts ((WORD_LIST *)NULL, reusable ? PFLAG : 0)); + + i = find_shopt (name); + if (i < 0) + { + shopt_error (name); + return (EXECUTION_FAILURE); + } + + print_shopt (name, *shopt_vars[i].value, reusable ? PFLAG : 0); + return (sh_chkwrite (EXECUTION_SUCCESS)); +} + +void +set_bashopts () +{ + char *value; + char tflag[N_SHOPT_OPTIONS]; + int vsize, i, vptr, *ip, exported; + SHELL_VAR *v; + + for (vsize = i = 0; shopt_vars[i].name; i++) + { + tflag[i] = 0; + if (GET_SHOPT_OPTION_VALUE (i)) + { + vsize += strlen (shopt_vars[i].name) + 1; + tflag[i] = 1; + } + } + + value = (char *)xmalloc (vsize + 1); + + for (i = vptr = 0; shopt_vars[i].name; i++) + { + if (tflag[i]) + { + strcpy (value + vptr, shopt_vars[i].name); + vptr += strlen (shopt_vars[i].name); + value[vptr++] = ':'; + } + } + + if (vptr) + vptr--; /* cut off trailing colon */ + value[vptr] = '\0'; + + v = find_variable ("BASHOPTS"); + + /* Turn off the read-only attribute so we can bind the new value, and + note whether or not the variable was exported. */ + if (v) + { + VUNSETATTR (v, att_readonly); + exported = exported_p (v); + } + else + exported = 0; + + v = bind_variable ("BASHOPTS", value, 0); + + /* Turn the read-only attribute back on, and turn off the export attribute + if it was set implicitly by mark_modified_vars and SHELLOPTS was not + exported before we bound the new value. */ + VSETATTR (v, att_readonly); + if (mark_modified_vars && exported == 0 && exported_p (v)) + VUNSETATTR (v, att_exported); + + free (value); +} + +void +parse_bashopts (value) + char *value; +{ + char *vname; + int vptr, ind; + + vptr = 0; + while (vname = extract_colon_unit (value, &vptr)) + { + ind = find_shopt (vname); + if (ind >= 0) + { + *shopt_vars[ind].value = 1; + if (shopt_vars[ind].set_func) + (*shopt_vars[ind].set_func) (shopt_vars[ind].name, 1); + } + free (vname); + } +} + +void +initialize_bashopts (no_bashopts) + int no_bashopts; +{ + char *temp; + SHELL_VAR *var; + + if (no_bashopts == 0) + { + var = find_variable ("BASHOPTS"); + /* set up any shell options we may have inherited. */ + if (var && imported_p (var)) + { + temp = (array_p (var) || assoc_p (var)) ? (char *)NULL : savestring (value_cell (var)); + if (temp) + { + parse_bashopts (temp); + free (temp); + } + } + } + + /* Set up the $BASHOPTS variable. */ + set_bashopts (); +} diff --git a/builtins/source.c b/builtins/source.c new file mode 100644 index 0000000..3faba82 --- /dev/null +++ b/builtins/source.c @@ -0,0 +1,154 @@ +/* source.c, created from source.def. */ +#line 22 "./source.def" + +#line 37 "./source.def" + +#line 53 "./source.def" + +#include + +#include "../bashtypes.h" +#include "posixstat.h" +#include "filecntl.h" +#if ! defined(_MINIX) && defined (HAVE_SYS_FILE_H) +# include +#endif +#include + +#if defined (HAVE_UNISTD_H) +# include +#endif + +#include "../bashansi.h" +#include "../bashintl.h" + +#include "../shell.h" +#include "../execute_cmd.h" +#include "../flags.h" +#include "../findcmd.h" +#include "common.h" +#include "bashgetopt.h" +#include "../trap.h" + +#if !defined (errno) +extern int errno; +#endif /* !errno */ + +static void maybe_pop_dollar_vars PARAMS((void)); + +/* If non-zero, `.' uses $PATH to look up the script to be sourced. */ +int source_uses_path = 1; + +/* If non-zero, `.' looks in the current directory if the filename argument + is not found in the $PATH. */ +int source_searches_cwd = 1; + +/* If this . script is supplied arguments, we save the dollar vars and + replace them with the script arguments for the duration of the script's + execution. If the script does not change the dollar vars, we restore + what we saved. If the dollar vars are changed in the script, and we are + not executing a shell function, we leave the new values alone and free + the saved values. */ +static void +maybe_pop_dollar_vars () +{ + if (variable_context == 0 && (dollar_vars_changed () & ARGS_SETBLTIN)) + dispose_saved_dollar_vars (); + else + pop_dollar_vars (); + if (debugging_mode) + pop_args (); /* restore BASH_ARGC and BASH_ARGV */ + set_dollar_vars_unchanged (); + invalidate_cached_quoted_dollar_at (); /* just invalidate to be safe */ +} + +/* Read and execute commands from the file passed as argument. Guess what. + This cannot be done in a subshell, since things like variable assignments + take place in there. So, I open the file, place it into a large string, + close the file, and then execute the string. */ +int +source_builtin (list) + WORD_LIST *list; +{ + int result; + char *filename, *debug_trap, *x; + + if (no_options (list)) + return (EX_USAGE); + list = loptend; + + if (list == 0) + { + builtin_error (_("filename argument required")); + builtin_usage (); + return (EX_USAGE); + } + +#if defined (RESTRICTED_SHELL) + if (restricted && strchr (list->word->word, '/')) + { + sh_restricted (list->word->word); + return (EXECUTION_FAILURE); + } +#endif + + filename = (char *)NULL; + /* XXX -- should this be absolute_pathname? */ + if (posixly_correct && strchr (list->word->word, '/')) + filename = savestring (list->word->word); + else if (absolute_pathname (list->word->word)) + filename = savestring (list->word->word); + else if (source_uses_path) + filename = find_path_file (list->word->word); + if (filename == 0) + { + if (source_searches_cwd == 0) + { + x = printable_filename (list->word->word, 0); + builtin_error (_("%s: file not found"), x); + if (x != list->word->word) + free (x); + if (posixly_correct && interactive_shell == 0 && executing_command_builtin == 0) + { + last_command_exit_value = EXECUTION_FAILURE; + jump_to_top_level (EXITPROG); + } + return (EXECUTION_FAILURE); + } + else + filename = savestring (list->word->word); + } + + begin_unwind_frame ("source"); + add_unwind_protect (xfree, filename); + + if (list->next) + { + push_dollar_vars (); + add_unwind_protect ((Function *)maybe_pop_dollar_vars, (char *)NULL); + if (debugging_mode || shell_compatibility_level <= 44) + init_bash_argv (); /* Initialize BASH_ARGV and BASH_ARGC */ + remember_args (list->next, 1); + if (debugging_mode) + push_args (list->next); /* Update BASH_ARGV and BASH_ARGC */ + } + set_dollar_vars_unchanged (); + + /* Don't inherit the DEBUG trap unless function_trace_mode (overloaded) + is set. XXX - should sourced files inherit the RETURN trap? Functions + don't. */ + debug_trap = TRAP_STRING (DEBUG_TRAP); + if (debug_trap && function_trace_mode == 0) + { + debug_trap = savestring (debug_trap); + add_unwind_protect (xfree, debug_trap); + add_unwind_protect (maybe_set_debug_trap, debug_trap); + restore_default_signal (DEBUG_TRAP); + } + + result = source_file (filename, (list && list->next)); + + run_unwind_frame ("source"); + + return (result); +} diff --git a/builtins/suspend.c b/builtins/suspend.c new file mode 100644 index 0000000..6fcc97b --- /dev/null +++ b/builtins/suspend.c @@ -0,0 +1,95 @@ +/* suspend.c, created from suspend.def. */ +#line 22 "./suspend.def" + +#line 38 "./suspend.def" + +#include + +#if defined (JOB_CONTROL) +#if defined (HAVE_UNISTD_H) +# ifdef _MINIX +# include +# endif +# include +#endif + +#include "../bashtypes.h" +#include +#include "../bashintl.h" +#include "../shell.h" +#include "../jobs.h" +#include "common.h" +#include "bashgetopt.h" + +static sighandler suspend_continue PARAMS((int)); + +static SigHandler *old_cont; +#if 0 +static SigHandler *old_stop; +#endif + +/* Continue handler. */ +static sighandler +suspend_continue (sig) + int sig; +{ + set_signal_handler (SIGCONT, old_cont); +#if 0 + set_signal_handler (SIGSTOP, old_stop); +#endif + SIGRETURN (0); +} + +/* Suspending the shell. If -f is the arg, then do the suspend + no matter what. Otherwise, complain if a login shell. */ +int +suspend_builtin (list) + WORD_LIST *list; +{ + int opt, force; + + reset_internal_getopt (); + force = 0; + while ((opt = internal_getopt (list, "f")) != -1) + switch (opt) + { + case 'f': + force++; + break; + CASE_HELPOPT; + default: + builtin_usage (); + return (EX_USAGE); + } + + list = loptend; + + if (job_control == 0) + { + sh_nojobs (_("cannot suspend")); + return (EXECUTION_FAILURE); + } + + if (force == 0) + { + no_args (list); + + if (login_shell) + { + builtin_error (_("cannot suspend a login shell")); + return (EXECUTION_FAILURE); + } + } + + /* XXX - should we put ourselves back into the original pgrp now? If so, + call end_job_control() here and do the right thing in suspend_continue + (that is, call restart_job_control()). */ + old_cont = (SigHandler *)set_signal_handler (SIGCONT, suspend_continue); +#if 0 + old_stop = (SigHandler *)set_signal_handler (SIGSTOP, SIG_DFL); +#endif + killpg (shell_pgrp, SIGSTOP); + return (EXECUTION_SUCCESS); +} + +#endif /* JOB_CONTROL */ diff --git a/builtins/test.c b/builtins/test.c new file mode 100644 index 0000000..4b38a56 --- /dev/null +++ b/builtins/test.c @@ -0,0 +1,52 @@ +/* test.c, created from test.def. */ +#line 22 "./test.def" + +#line 104 "./test.def" + +#line 114 "./test.def" + +#include + +#if defined (HAVE_UNISTD_H) +# ifdef _MINIX +# include +# endif +# include +#endif + +#include "../bashansi.h" +#include "../bashintl.h" + +#include "../shell.h" +#include "../execute_cmd.h" +#include "../test.h" +#include "common.h" + +/* TEST/[ builtin. */ +int +test_builtin (list) + WORD_LIST *list; +{ + char **argv; + int argc, result; + + /* We let Matthew Bradburn and Kevin Braunsdorf's code do the + actual test command. So turn the list of args into an array + of strings, since that is what their code wants. */ + if (list == 0) + { + if (this_command_name[0] == '[' && !this_command_name[1]) + { + builtin_error (_("missing `]'")); + return (EX_BADUSAGE); + } + + return (EXECUTION_FAILURE); + } + + argv = make_builtin_argv (list, &argc); + result = test_command (argc, argv); + free ((char *)argv); + + return (result); +} diff --git a/builtins/times.c b/builtins/times.c new file mode 100644 index 0000000..4e8b490 --- /dev/null +++ b/builtins/times.c @@ -0,0 +1,90 @@ +/* times.c, created from times.def. */ +#line 22 "./times.def" + +#line 34 "./times.def" + +#include + +#if defined (HAVE_UNISTD_H) +# ifdef _MINIX +# include +# endif +# include +#endif + +#include +#include "../bashtypes.h" +#include "../shell.h" + +#include + +#if defined (HAVE_SYS_TIMES_H) +# include +#endif /* HAVE_SYS_TIMES_H */ + +#if defined (HAVE_SYS_RESOURCE_H) && !defined (RLIMTYPE) +# include +#endif + +#include "common.h" + +/* Print the totals for system and user time used. */ +int +times_builtin (list) + WORD_LIST *list; +{ +#if defined (HAVE_GETRUSAGE) && defined (HAVE_TIMEVAL) && defined (RUSAGE_SELF) + struct rusage self, kids; + + USE_VAR(list); + + if (no_options (list)) + return (EX_USAGE); + + getrusage (RUSAGE_SELF, &self); + getrusage (RUSAGE_CHILDREN, &kids); /* terminated child processes */ + + print_timeval (stdout, &self.ru_utime); + putchar (' '); + print_timeval (stdout, &self.ru_stime); + putchar ('\n'); + print_timeval (stdout, &kids.ru_utime); + putchar (' '); + print_timeval (stdout, &kids.ru_stime); + putchar ('\n'); + +#else +# if defined (HAVE_TIMES) + /* This uses the POSIX.1/XPG5 times(2) interface, which fills in a + `struct tms' with values of type clock_t. */ + struct tms t; + + USE_VAR(list); + + if (no_options (list)) + return (EX_USAGE); + + times (&t); + + print_clock_t (stdout, t.tms_utime); + putchar (' '); + print_clock_t (stdout, t.tms_stime); + putchar ('\n'); + print_clock_t (stdout, t.tms_cutime); + putchar (' '); + print_clock_t (stdout, t.tms_cstime); + putchar ('\n'); + +# else /* !HAVE_TIMES */ + + USE_VAR(list); + + if (no_options (list)) + return (EX_USAGE); + printf ("0.00 0.00\n0.00 0.00\n"); + +# endif /* HAVE_TIMES */ +#endif /* !HAVE_TIMES */ + + return (sh_chkwrite (EXECUTION_SUCCESS)); +} diff --git a/builtins/tmpbuiltins.c b/builtins/tmpbuiltins.c new file mode 100644 index 0000000..5bc61ab --- /dev/null +++ b/builtins/tmpbuiltins.c @@ -0,0 +1,2088 @@ +/* builtins.c -- the built in shell commands. */ + +/* This file is manufactured by ./mkbuiltins, and should not be + edited by hand. See the source to mkbuiltins for details. */ + +/* Copyright (C) 1987-2015 Free Software Foundation, Inc. + + This file is part of GNU Bash, the Bourne Again SHell. + + Bash is free software: you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation, either version 3 of the License, or + (at your option) any later version. + + Bash is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with Bash. If not, see . +*/ + +/* The list of shell builtins. Each element is name, function, flags, + long-doc, short-doc. The long-doc field contains a pointer to an array + of help lines. The function takes a WORD_LIST *; the first word in the + list is the first arg to the command. The list has already had word + expansion performed. + + Functions which need to look at only the simple commands (e.g. + the enable_builtin ()), should ignore entries where + (array[i].function == (sh_builtin_func_t *)NULL). Such entries are for + the list of shell reserved control structures, like `if' and `while'. + The end of the list is denoted with a NULL name field. */ + +/* TRANSLATORS: Please do not translate command names in descriptions */ + +#include "../builtins.h" +#include "tmpbuiltins.h" +#include "bashintl.h" + +struct builtin static_shell_builtins[] = { +#if defined (ALIAS) + { "alias", (sh_builtin_func_t *)0x0, BUILTIN_ENABLED | STATIC_BUILTIN | ASSIGNMENT_BUILTIN | POSIX_BUILTIN, alias_doc, + N_("alias [-p] [name[=value] ... ]"), "alias" }, +#endif /* ALIAS */ +#if defined (ALIAS) + { "unalias", (sh_builtin_func_t *)0x0, BUILTIN_ENABLED | STATIC_BUILTIN | POSIX_BUILTIN, unalias_doc, + N_("unalias [-a] name [name ...]"), "unalias" }, +#endif /* ALIAS */ +#if defined (READLINE) + { "bind", (sh_builtin_func_t *)0x0, BUILTIN_ENABLED | STATIC_BUILTIN, bind_doc, + N_("bind [-lpsvPSVX] [-m keymap] [-f filename] [-q name] [-u name] [-r keyseq] [-x keyseq:shell-command] [keyseq:readline-function or readline-command]"), "bind" }, +#endif /* READLINE */ + { "break", (sh_builtin_func_t *)0x0, BUILTIN_ENABLED | STATIC_BUILTIN | SPECIAL_BUILTIN, break_doc, + N_("break [n]"), "break" }, + { "continue", (sh_builtin_func_t *)0x0, BUILTIN_ENABLED | STATIC_BUILTIN | SPECIAL_BUILTIN, continue_doc, + N_("continue [n]"), "continue" }, + { "builtin", (sh_builtin_func_t *)0x0, BUILTIN_ENABLED | STATIC_BUILTIN, builtin_doc, + N_("builtin [shell-builtin [arg ...]]"), "builtin" }, +#if defined (DEBUGGER) + { "caller", (sh_builtin_func_t *)0x0, BUILTIN_ENABLED | STATIC_BUILTIN, caller_doc, + N_("caller [expr]"), "caller" }, +#endif /* DEBUGGER */ + { "cd", (sh_builtin_func_t *)0x0, BUILTIN_ENABLED | STATIC_BUILTIN | POSIX_BUILTIN, cd_doc, + N_("cd [-L|[-P [-e]] [-@]] [dir]"), "cd" }, + { "pwd", (sh_builtin_func_t *)0x0, BUILTIN_ENABLED | STATIC_BUILTIN | POSIX_BUILTIN, pwd_doc, + N_("pwd [-LP]"), "pwd" }, + { ":", (sh_builtin_func_t *)0x0, BUILTIN_ENABLED | STATIC_BUILTIN | SPECIAL_BUILTIN, colon_doc, + ":", "colon" }, + { "true", (sh_builtin_func_t *)0x0, BUILTIN_ENABLED | STATIC_BUILTIN | POSIX_BUILTIN, true_doc, + "true", "true" }, + { "false", (sh_builtin_func_t *)0x0, BUILTIN_ENABLED | STATIC_BUILTIN | POSIX_BUILTIN, false_doc, + "false", "false" }, + { "command", (sh_builtin_func_t *)0x0, BUILTIN_ENABLED | STATIC_BUILTIN | POSIX_BUILTIN, command_doc, + N_("command [-pVv] command [arg ...]"), "command" }, + { "declare", (sh_builtin_func_t *)0x0, BUILTIN_ENABLED | STATIC_BUILTIN | ASSIGNMENT_BUILTIN | LOCALVAR_BUILTIN, declare_doc, + N_("declare [-aAfFgiIlnrtux] [-p] [name[=value] ...]"), "declare" }, + { "typeset", (sh_builtin_func_t *)0x0, BUILTIN_ENABLED | STATIC_BUILTIN | ASSIGNMENT_BUILTIN | LOCALVAR_BUILTIN, typeset_doc, + N_("typeset [-aAfFgiIlnrtux] [-p] name[=value] ..."), "typeset" }, + { "local", (sh_builtin_func_t *)0x0, BUILTIN_ENABLED | STATIC_BUILTIN | ASSIGNMENT_BUILTIN | LOCALVAR_BUILTIN, local_doc, + N_("local [option] name[=value] ..."), "local" }, +#if defined (V9_ECHO) + { "echo", (sh_builtin_func_t *)0x0, BUILTIN_ENABLED | STATIC_BUILTIN, echo_doc, + N_("echo [-neE] [arg ...]"), "echo" }, +#endif /* V9_ECHO */ +#if !defined (V9_ECHO) + { "echo", (sh_builtin_func_t *)0x0, BUILTIN_ENABLED | STATIC_BUILTIN, echo_doc, + N_("echo [-n] [arg ...]"), "echo" }, +#endif /* !V9_ECHO */ + { "enable", (sh_builtin_func_t *)0x0, BUILTIN_ENABLED | STATIC_BUILTIN, enable_doc, + N_("enable [-a] [-dnps] [-f filename] [name ...]"), "enable" }, + { "eval", (sh_builtin_func_t *)0x0, BUILTIN_ENABLED | STATIC_BUILTIN | SPECIAL_BUILTIN, eval_doc, + N_("eval [arg ...]"), "eval" }, + { "getopts", (sh_builtin_func_t *)0x0, BUILTIN_ENABLED | STATIC_BUILTIN | POSIX_BUILTIN, getopts_doc, + N_("getopts optstring name [arg ...]"), "getopts" }, + { "exec", (sh_builtin_func_t *)0x0, BUILTIN_ENABLED | STATIC_BUILTIN | SPECIAL_BUILTIN, exec_doc, + N_("exec [-cl] [-a name] [command [argument ...]] [redirection ...]"), "exec" }, + { "exit", (sh_builtin_func_t *)0x0, BUILTIN_ENABLED | STATIC_BUILTIN | SPECIAL_BUILTIN, exit_doc, + N_("exit [n]"), "exit" }, + { "logout", (sh_builtin_func_t *)0x0, BUILTIN_ENABLED | STATIC_BUILTIN, logout_doc, + N_("logout [n]"), "logout" }, +#if defined (HISTORY) + { "fc", (sh_builtin_func_t *)0x0, BUILTIN_ENABLED | STATIC_BUILTIN | POSIX_BUILTIN, fc_doc, + N_("fc [-e ename] [-lnr] [first] [last] or fc -s [pat=rep] [command]"), "fc" }, +#endif /* HISTORY */ +#if defined (JOB_CONTROL) + { "fg", (sh_builtin_func_t *)0x0, BUILTIN_ENABLED | STATIC_BUILTIN | POSIX_BUILTIN, fg_doc, + N_("fg [job_spec]"), "fg" }, +#endif /* JOB_CONTROL */ +#if defined (JOB_CONTROL) + { "bg", (sh_builtin_func_t *)0x0, BUILTIN_ENABLED | STATIC_BUILTIN | POSIX_BUILTIN, bg_doc, + N_("bg [job_spec ...]"), "bg" }, +#endif /* JOB_CONTROL */ + { "hash", (sh_builtin_func_t *)0x0, BUILTIN_ENABLED | STATIC_BUILTIN, hash_doc, + N_("hash [-lr] [-p pathname] [-dt] [name ...]"), "hash" }, +#if defined (HELP_BUILTIN) + { "help", (sh_builtin_func_t *)0x0, BUILTIN_ENABLED | STATIC_BUILTIN, help_doc, + N_("help [-dms] [pattern ...]"), "help" }, +#endif /* HELP_BUILTIN */ +#if defined (HISTORY) + { "history", (sh_builtin_func_t *)0x0, BUILTIN_ENABLED | STATIC_BUILTIN, history_doc, + N_("history [-c] [-d offset] [n] or history -anrw [filename] or history -ps arg [arg...]"), "history" }, +#endif /* HISTORY */ +#if defined (JOB_CONTROL) + { "jobs", (sh_builtin_func_t *)0x0, BUILTIN_ENABLED | STATIC_BUILTIN | POSIX_BUILTIN, jobs_doc, + N_("jobs [-lnprs] [jobspec ...] or jobs -x command [args]"), "jobs" }, +#endif /* JOB_CONTROL */ +#if defined (JOB_CONTROL) + { "disown", (sh_builtin_func_t *)0x0, BUILTIN_ENABLED | STATIC_BUILTIN, disown_doc, + N_("disown [-h] [-ar] [jobspec ... | pid ...]"), "disown" }, +#endif /* JOB_CONTROL */ + { "kill", (sh_builtin_func_t *)0x0, BUILTIN_ENABLED | STATIC_BUILTIN | POSIX_BUILTIN, kill_doc, + N_("kill [-s sigspec | -n signum | -sigspec] pid | jobspec ... or kill -l [sigspec]"), "kill" }, + { "let", (sh_builtin_func_t *)0x0, BUILTIN_ENABLED | STATIC_BUILTIN, let_doc, + N_("let arg [arg ...]"), "let" }, + { "read", (sh_builtin_func_t *)0x0, BUILTIN_ENABLED | STATIC_BUILTIN | POSIX_BUILTIN, read_doc, + N_("read [-ers] [-a array] [-d delim] [-i text] [-n nchars] [-N nchars] [-p prompt] [-t timeout] [-u fd] [name ...]"), "read" }, + { "return", (sh_builtin_func_t *)0x0, BUILTIN_ENABLED | STATIC_BUILTIN | SPECIAL_BUILTIN, return_doc, + N_("return [n]"), "return" }, + { "set", (sh_builtin_func_t *)0x0, BUILTIN_ENABLED | STATIC_BUILTIN | SPECIAL_BUILTIN, set_doc, + N_("set [-abefhkmnptuvxBCHP] [-o option-name] [--] [arg ...]"), "set" }, + { "unset", (sh_builtin_func_t *)0x0, BUILTIN_ENABLED | STATIC_BUILTIN | SPECIAL_BUILTIN, unset_doc, + N_("unset [-f] [-v] [-n] [name ...]"), "unset" }, + { "export", (sh_builtin_func_t *)0x0, BUILTIN_ENABLED | STATIC_BUILTIN | SPECIAL_BUILTIN | ASSIGNMENT_BUILTIN, export_doc, + N_("export [-fn] [name[=value] ...] or export -p"), "export" }, + { "readonly", (sh_builtin_func_t *)0x0, BUILTIN_ENABLED | STATIC_BUILTIN | SPECIAL_BUILTIN | ASSIGNMENT_BUILTIN, readonly_doc, + N_("readonly [-aAf] [name[=value] ...] or readonly -p"), "readonly" }, + { "shift", (sh_builtin_func_t *)0x0, BUILTIN_ENABLED | STATIC_BUILTIN | SPECIAL_BUILTIN, shift_doc, + N_("shift [n]"), "shift" }, + { "source", (sh_builtin_func_t *)0x0, BUILTIN_ENABLED | STATIC_BUILTIN | SPECIAL_BUILTIN, source_doc, + N_("source filename [arguments]"), "source" }, + { ".", (sh_builtin_func_t *)0x0, BUILTIN_ENABLED | STATIC_BUILTIN | SPECIAL_BUILTIN, dot_doc, + N_(". filename [arguments]"), "dot" }, +#if defined (JOB_CONTROL) + { "suspend", (sh_builtin_func_t *)0x0, BUILTIN_ENABLED | STATIC_BUILTIN, suspend_doc, + N_("suspend [-f]"), "suspend" }, +#endif /* JOB_CONTROL */ + { "test", (sh_builtin_func_t *)0x0, BUILTIN_ENABLED | STATIC_BUILTIN, test_doc, + N_("test [expr]"), "test" }, + { "[", (sh_builtin_func_t *)0x0, BUILTIN_ENABLED | STATIC_BUILTIN, test_bracket_doc, + N_("[ arg... ]"), "test_bracket" }, + { "times", (sh_builtin_func_t *)0x0, BUILTIN_ENABLED | STATIC_BUILTIN | SPECIAL_BUILTIN, times_doc, + "times", "times" }, + { "trap", (sh_builtin_func_t *)0x0, BUILTIN_ENABLED | STATIC_BUILTIN | SPECIAL_BUILTIN, trap_doc, + N_("trap [-lp] [[arg] signal_spec ...]"), "trap" }, + { "type", (sh_builtin_func_t *)0x0, BUILTIN_ENABLED | STATIC_BUILTIN, type_doc, + N_("type [-afptP] name [name ...]"), "type" }, +#if !defined (_MINIX) + { "ulimit", (sh_builtin_func_t *)0x0, BUILTIN_ENABLED | STATIC_BUILTIN, ulimit_doc, + N_("ulimit [-SHabcdefiklmnpqrstuvxPT] [limit]"), "ulimit" }, +#endif /* !_MINIX */ + { "umask", (sh_builtin_func_t *)0x0, BUILTIN_ENABLED | STATIC_BUILTIN | POSIX_BUILTIN, umask_doc, + N_("umask [-p] [-S] [mode]"), "umask" }, +#if defined (JOB_CONTROL) + { "wait", (sh_builtin_func_t *)0x0, BUILTIN_ENABLED | STATIC_BUILTIN | POSIX_BUILTIN, wait_doc, + N_("wait [-fn] [-p var] [id ...]"), "wait" }, +#endif /* JOB_CONTROL */ +#if !defined (JOB_CONTROL) + { "wait", (sh_builtin_func_t *)0x0, BUILTIN_ENABLED | STATIC_BUILTIN | POSIX_BUILTIN, wait_doc, + N_("wait [pid ...]"), "wait" }, +#endif /* !JOB_CONTROL */ + { "for", (sh_builtin_func_t *)0x0, BUILTIN_ENABLED | STATIC_BUILTIN, for_doc, + N_("for NAME [in WORDS ... ] ; do COMMANDS; done"), "for" }, + { "for ((", (sh_builtin_func_t *)0x0, BUILTIN_ENABLED | STATIC_BUILTIN, arith_for_doc, + N_("for (( exp1; exp2; exp3 )); do COMMANDS; done"), "arith_for" }, + { "select", (sh_builtin_func_t *)0x0, BUILTIN_ENABLED | STATIC_BUILTIN, select_doc, + N_("select NAME [in WORDS ... ;] do COMMANDS; done"), "select" }, + { "time", (sh_builtin_func_t *)0x0, BUILTIN_ENABLED | STATIC_BUILTIN, time_doc, + N_("time [-p] pipeline"), "time" }, + { "case", (sh_builtin_func_t *)0x0, BUILTIN_ENABLED | STATIC_BUILTIN, case_doc, + N_("case WORD in [PATTERN [| PATTERN]...) COMMANDS ;;]... esac"), "case" }, + { "if", (sh_builtin_func_t *)0x0, BUILTIN_ENABLED | STATIC_BUILTIN, if_doc, + N_("if COMMANDS; then COMMANDS; [ elif COMMANDS; then COMMANDS; ]... [ else COMMANDS; ] fi"), "if" }, + { "while", (sh_builtin_func_t *)0x0, BUILTIN_ENABLED | STATIC_BUILTIN, while_doc, + N_("while COMMANDS; do COMMANDS; done"), "while" }, + { "until", (sh_builtin_func_t *)0x0, BUILTIN_ENABLED | STATIC_BUILTIN, until_doc, + N_("until COMMANDS; do COMMANDS; done"), "until" }, + { "coproc", (sh_builtin_func_t *)0x0, BUILTIN_ENABLED | STATIC_BUILTIN, coproc_doc, + N_("coproc [NAME] command [redirections]"), "coproc" }, + { "function", (sh_builtin_func_t *)0x0, BUILTIN_ENABLED | STATIC_BUILTIN, function_doc, + N_("function name { COMMANDS ; } or name () { COMMANDS ; }"), "function" }, + { "{ ... }", (sh_builtin_func_t *)0x0, BUILTIN_ENABLED | STATIC_BUILTIN, grouping_braces_doc, + N_("{ COMMANDS ; }"), "grouping_braces" }, + { "%", (sh_builtin_func_t *)0x0, BUILTIN_ENABLED | STATIC_BUILTIN, fg_percent_doc, + N_("job_spec [&]"), "fg_percent" }, + { "(( ... ))", (sh_builtin_func_t *)0x0, BUILTIN_ENABLED | STATIC_BUILTIN, arith_doc, + N_("(( expression ))"), "arith" }, + { "[[ ... ]]", (sh_builtin_func_t *)0x0, BUILTIN_ENABLED | STATIC_BUILTIN, conditional_doc, + N_("[[ expression ]]"), "conditional" }, + { "variables", (sh_builtin_func_t *)0x0, BUILTIN_ENABLED | STATIC_BUILTIN, variable_help_doc, + N_("variables - Names and meanings of some shell variables"), "variable_help" }, +#if defined (PUSHD_AND_POPD) + { "pushd", (sh_builtin_func_t *)0x0, BUILTIN_ENABLED | STATIC_BUILTIN, pushd_doc, + N_("pushd [-n] [+N | -N | dir]"), "pushd" }, +#endif /* PUSHD_AND_POPD */ +#if defined (PUSHD_AND_POPD) + { "popd", (sh_builtin_func_t *)0x0, BUILTIN_ENABLED | STATIC_BUILTIN, popd_doc, + N_("popd [-n] [+N | -N]"), "popd" }, +#endif /* PUSHD_AND_POPD */ +#if defined (PUSHD_AND_POPD) + { "dirs", (sh_builtin_func_t *)0x0, BUILTIN_ENABLED | STATIC_BUILTIN, dirs_doc, + N_("dirs [-clpv] [+N] [-N]"), "dirs" }, +#endif /* PUSHD_AND_POPD */ + { "shopt", (sh_builtin_func_t *)0x0, BUILTIN_ENABLED | STATIC_BUILTIN, shopt_doc, + N_("shopt [-pqsu] [-o] [optname ...]"), "shopt" }, + { "printf", (sh_builtin_func_t *)0x0, BUILTIN_ENABLED | STATIC_BUILTIN, printf_doc, + N_("printf [-v var] format [arguments]"), "printf" }, +#if defined (PROGRAMMABLE_COMPLETION) + { "complete", (sh_builtin_func_t *)0x0, BUILTIN_ENABLED | STATIC_BUILTIN, complete_doc, + N_("complete [-abcdefgjksuv] [-pr] [-DEI] [-o option] [-A action] [-G globpat] [-W wordlist] [-F function] [-C command] [-X filterpat] [-P prefix] [-S suffix] [name ...]"), "complete" }, +#endif /* PROGRAMMABLE_COMPLETION */ +#if defined (PROGRAMMABLE_COMPLETION) + { "compgen", (sh_builtin_func_t *)0x0, BUILTIN_ENABLED | STATIC_BUILTIN, compgen_doc, + N_("compgen [-abcdefgjksuv] [-o option] [-A action] [-G globpat] [-W wordlist] [-F function] [-C command] [-X filterpat] [-P prefix] [-S suffix] [word]"), "compgen" }, +#endif /* PROGRAMMABLE_COMPLETION */ +#if defined (PROGRAMMABLE_COMPLETION) + { "compopt", (sh_builtin_func_t *)0x0, BUILTIN_ENABLED | STATIC_BUILTIN, compopt_doc, + N_("compopt [-o|+o option] [-DEI] [name ...]"), "compopt" }, +#endif /* PROGRAMMABLE_COMPLETION */ + { "mapfile", (sh_builtin_func_t *)0x0, BUILTIN_ENABLED | STATIC_BUILTIN, mapfile_doc, + N_("mapfile [-d delim] [-n count] [-O origin] [-s count] [-t] [-u fd] [-C callback] [-c quantum] [array]"), "mapfile" }, + { "readarray", (sh_builtin_func_t *)0x0, BUILTIN_ENABLED | STATIC_BUILTIN, readarray_doc, + N_("readarray [-d delim] [-n count] [-O origin] [-s count] [-t] [-u fd] [-C callback] [-c quantum] [array]"), "readarray" }, + { (char *)0x0, (sh_builtin_func_t *)0x0, 0, (char **)0x0, (char *)0x0, (char *)0x0 } +}; + +struct builtin *shell_builtins = static_shell_builtins; +struct builtin *current_builtin; + +int num_shell_builtins = + sizeof (static_shell_builtins) / sizeof (struct builtin) - 1; +#if defined (ALIAS) +char * const alias_doc[] = { +#if defined (HELP_BUILTIN) +N_("Define or display aliases.\n\ + \n\ + Without arguments, `alias' prints the list of aliases in the reusable\n\ + form `alias NAME=VALUE' on standard output.\n\ + \n\ + Otherwise, an alias is defined for each NAME whose VALUE is given.\n\ + A trailing space in VALUE causes the next word to be checked for\n\ + alias substitution when the alias is expanded.\n\ + \n\ + Options:\n\ + -p print all defined aliases in a reusable format\n\ + \n\ + Exit Status:\n\ + alias returns true unless a NAME is supplied for which no alias has been\n\ + defined."), +#endif /* HELP_BUILTIN */ + (char *)NULL +}; +#endif /* ALIAS */ +#if defined (ALIAS) +char * const unalias_doc[] = { +#if defined (HELP_BUILTIN) +N_("Remove each NAME from the list of defined aliases.\n\ + \n\ + Options:\n\ + -a remove all alias definitions\n\ + \n\ + Return success unless a NAME is not an existing alias."), +#endif /* HELP_BUILTIN */ + (char *)NULL +}; +#endif /* ALIAS */ +#if defined (READLINE) +char * const bind_doc[] = { +#if defined (HELP_BUILTIN) +N_("Set Readline key bindings and variables.\n\ + \n\ + Bind a key sequence to a Readline function or a macro, or set a\n\ + Readline variable. The non-option argument syntax is equivalent to\n\ + that found in ~/.inputrc, but must be passed as a single argument:\n\ + e.g., bind '\"\\C-x\\C-r\": re-read-init-file'.\n\ + \n\ + Options:\n\ + -m keymap Use KEYMAP as the keymap for the duration of this\n\ + command. Acceptable keymap names are emacs,\n\ + emacs-standard, emacs-meta, emacs-ctlx, vi, vi-move,\n\ + vi-command, and vi-insert.\n\ + -l List names of functions.\n\ + -P List function names and bindings.\n\ + -p List functions and bindings in a form that can be\n\ + reused as input.\n\ + -S List key sequences that invoke macros and their values\n\ + -s List key sequences that invoke macros and their values\n\ + in a form that can be reused as input.\n\ + -V List variable names and values\n\ + -v List variable names and values in a form that can\n\ + be reused as input.\n\ + -q function-name Query about which keys invoke the named function.\n\ + -u function-name Unbind all keys which are bound to the named function.\n\ + -r keyseq Remove the binding for KEYSEQ.\n\ + -f filename Read key bindings from FILENAME.\n\ + -x keyseq:shell-command Cause SHELL-COMMAND to be executed when\n\ + KEYSEQ is entered.\n\ + -X List key sequences bound with -x and associated commands\n\ + in a form that can be reused as input.\n\ + \n\ + Exit Status:\n\ + bind returns 0 unless an unrecognized option is given or an error occurs."), +#endif /* HELP_BUILTIN */ + (char *)NULL +}; +#endif /* READLINE */ +char * const break_doc[] = { +#if defined (HELP_BUILTIN) +N_("Exit for, while, or until loops.\n\ + \n\ + Exit a FOR, WHILE or UNTIL loop. If N is specified, break N enclosing\n\ + loops.\n\ + \n\ + Exit Status:\n\ + The exit status is 0 unless N is not greater than or equal to 1."), +#endif /* HELP_BUILTIN */ + (char *)NULL +}; +char * const continue_doc[] = { +#if defined (HELP_BUILTIN) +N_("Resume for, while, or until loops.\n\ + \n\ + Resumes the next iteration of the enclosing FOR, WHILE or UNTIL loop.\n\ + If N is specified, resumes the Nth enclosing loop.\n\ + \n\ + Exit Status:\n\ + The exit status is 0 unless N is not greater than or equal to 1."), +#endif /* HELP_BUILTIN */ + (char *)NULL +}; +char * const builtin_doc[] = { +#if defined (HELP_BUILTIN) +N_("Execute shell builtins.\n\ + \n\ + Execute SHELL-BUILTIN with arguments ARGs without performing command\n\ + lookup. This is useful when you wish to reimplement a shell builtin\n\ + as a shell function, but need to execute the builtin within the function.\n\ + \n\ + Exit Status:\n\ + Returns the exit status of SHELL-BUILTIN, or false if SHELL-BUILTIN is\n\ + not a shell builtin."), +#endif /* HELP_BUILTIN */ + (char *)NULL +}; +#if defined (DEBUGGER) +char * const caller_doc[] = { +#if defined (HELP_BUILTIN) +N_("Return the context of the current subroutine call.\n\ + \n\ + Without EXPR, returns \"$line $filename\". With EXPR, returns\n\ + \"$line $subroutine $filename\"; this extra information can be used to\n\ + provide a stack trace.\n\ + \n\ + The value of EXPR indicates how many call frames to go back before the\n\ + current one; the top frame is frame 0.\n\ + \n\ + Exit Status:\n\ + Returns 0 unless the shell is not executing a shell function or EXPR\n\ + is invalid."), +#endif /* HELP_BUILTIN */ + (char *)NULL +}; +#endif /* DEBUGGER */ +char * const cd_doc[] = { +#if defined (HELP_BUILTIN) +N_("Change the shell working directory.\n\ + \n\ + Change the current directory to DIR. The default DIR is the value of the\n\ + HOME shell variable.\n\ + \n\ + The variable CDPATH defines the search path for the directory containing\n\ + DIR. Alternative directory names in CDPATH are separated by a colon (:).\n\ + A null directory name is the same as the current directory. If DIR begins\n\ + with a slash (/), then CDPATH is not used.\n\ + \n\ + If the directory is not found, and the shell option `cdable_vars' is set,\n\ + the word is assumed to be a variable name. If that variable has a value,\n\ + its value is used for DIR.\n\ + \n\ + Options:\n\ + -L force symbolic links to be followed: resolve symbolic\n\ + links in DIR after processing instances of `..'\n\ + -P use the physical directory structure without following\n\ + symbolic links: resolve symbolic links in DIR before\n\ + processing instances of `..'\n\ + -e if the -P option is supplied, and the current working\n\ + directory cannot be determined successfully, exit with\n\ + a non-zero status\n\ + -@ on systems that support it, present a file with extended\n\ + attributes as a directory containing the file attributes\n\ + \n\ + The default is to follow symbolic links, as if `-L' were specified.\n\ + `..' is processed by removing the immediately previous pathname component\n\ + back to a slash or the beginning of DIR.\n\ + \n\ + Exit Status:\n\ + Returns 0 if the directory is changed, and if $PWD is set successfully when\n\ + -P is used; non-zero otherwise."), +#endif /* HELP_BUILTIN */ + (char *)NULL +}; +char * const pwd_doc[] = { +#if defined (HELP_BUILTIN) +N_("Print the name of the current working directory.\n\ + \n\ + Options:\n\ + -L print the value of $PWD if it names the current working\n\ + directory\n\ + -P print the physical directory, without any symbolic links\n\ + \n\ + By default, `pwd' behaves as if `-L' were specified.\n\ + \n\ + Exit Status:\n\ + Returns 0 unless an invalid option is given or the current directory\n\ + cannot be read."), +#endif /* HELP_BUILTIN */ + (char *)NULL +}; +char * const colon_doc[] = { +#if defined (HELP_BUILTIN) +N_("Null command.\n\ + \n\ + No effect; the command does nothing.\n\ + \n\ + Exit Status:\n\ + Always succeeds."), +#endif /* HELP_BUILTIN */ + (char *)NULL +}; +char * const true_doc[] = { +#if defined (HELP_BUILTIN) +N_("Return a successful result.\n\ + \n\ + Exit Status:\n\ + Always succeeds."), +#endif /* HELP_BUILTIN */ + (char *)NULL +}; +char * const false_doc[] = { +#if defined (HELP_BUILTIN) +N_("Return an unsuccessful result.\n\ + \n\ + Exit Status:\n\ + Always fails."), +#endif /* HELP_BUILTIN */ + (char *)NULL +}; +char * const command_doc[] = { +#if defined (HELP_BUILTIN) +N_("Execute a simple command or display information about commands.\n\ + \n\ + Runs COMMAND with ARGS suppressing shell function lookup, or display\n\ + information about the specified COMMANDs. Can be used to invoke commands\n\ + on disk when a function with the same name exists.\n\ + \n\ + Options:\n\ + -p use a default value for PATH that is guaranteed to find all of\n\ + the standard utilities\n\ + -v print a description of COMMAND similar to the `type' builtin\n\ + -V print a more verbose description of each COMMAND\n\ + \n\ + Exit Status:\n\ + Returns exit status of COMMAND, or failure if COMMAND is not found."), +#endif /* HELP_BUILTIN */ + (char *)NULL +}; +char * const declare_doc[] = { +#if defined (HELP_BUILTIN) +N_("Set variable values and attributes.\n\ + \n\ + Declare variables and give them attributes. If no NAMEs are given,\n\ + display the attributes and values of all variables.\n\ + \n\ + Options:\n\ + -f restrict action or display to function names and definitions\n\ + -F restrict display to function names only (plus line number and\n\ + source file when debugging)\n\ + -g create global variables when used in a shell function; otherwise\n\ + ignored\n\ + -I if creating a local variable, inherit the attributes and value\n\ + of a variable with the same name at a previous scope\n\ + -p display the attributes and value of each NAME\n\ + \n\ + Options which set attributes:\n\ + -a to make NAMEs indexed arrays (if supported)\n\ + -A to make NAMEs associative arrays (if supported)\n\ + -i to make NAMEs have the `integer' attribute\n\ + -l to convert the value of each NAME to lower case on assignment\n\ + -n make NAME a reference to the variable named by its value\n\ + -r to make NAMEs readonly\n\ + -t to make NAMEs have the `trace' attribute\n\ + -u to convert the value of each NAME to upper case on assignment\n\ + -x to make NAMEs export\n\ + \n\ + Using `+' instead of `-' turns off the given attribute.\n\ + \n\ + Variables with the integer attribute have arithmetic evaluation (see\n\ + the `let' command) performed when the variable is assigned a value.\n\ + \n\ + When used in a function, `declare' makes NAMEs local, as with the `local'\n\ + command. The `-g' option suppresses this behavior.\n\ + \n\ + Exit Status:\n\ + Returns success unless an invalid option is supplied or a variable\n\ + assignment error occurs."), +#endif /* HELP_BUILTIN */ + (char *)NULL +}; +char * const typeset_doc[] = { +#if defined (HELP_BUILTIN) +N_("Set variable values and attributes.\n\ + \n\ + A synonym for `declare'. See `help declare'."), +#endif /* HELP_BUILTIN */ + (char *)NULL +}; +char * const local_doc[] = { +#if defined (HELP_BUILTIN) +N_("Define local variables.\n\ + \n\ + Create a local variable called NAME, and give it VALUE. OPTION can\n\ + be any option accepted by `declare'.\n\ + \n\ + Local variables can only be used within a function; they are visible\n\ + only to the function where they are defined and its children.\n\ + \n\ + Exit Status:\n\ + Returns success unless an invalid option is supplied, a variable\n\ + assignment error occurs, or the shell is not executing a function."), +#endif /* HELP_BUILTIN */ + (char *)NULL +}; +#if defined (V9_ECHO) +char * const echo_doc[] = { +#if defined (HELP_BUILTIN) +N_("Write arguments to the standard output.\n\ + \n\ + Display the ARGs, separated by a single space character and followed by a\n\ + newline, on the standard output.\n\ + \n\ + Options:\n\ + -n do not append a newline\n\ + -e enable interpretation of the following backslash escapes\n\ + -E explicitly suppress interpretation of backslash escapes\n\ + \n\ + `echo' interprets the following backslash-escaped characters:\n\ + \\a alert (bell)\n\ + \\b backspace\n\ + \\c suppress further output\n\ + \\e escape character\n\ + \\E escape character\n\ + \\f form feed\n\ + \\n new line\n\ + \\r carriage return\n\ + \\t horizontal tab\n\ + \\v vertical tab\n\ + \\\\ backslash\n\ + \\0nnn the character whose ASCII code is NNN (octal). NNN can be\n\ + 0 to 3 octal digits\n\ + \\xHH the eight-bit character whose value is HH (hexadecimal). HH\n\ + can be one or two hex digits\n\ + \\uHHHH the Unicode character whose value is the hexadecimal value HHHH.\n\ + HHHH can be one to four hex digits.\n\ + \\UHHHHHHHH the Unicode character whose value is the hexadecimal value\n\ + HHHHHHHH. HHHHHHHH can be one to eight hex digits.\n\ + \n\ + Exit Status:\n\ + Returns success unless a write error occurs."), +#endif /* HELP_BUILTIN */ + (char *)NULL +}; +#endif /* V9_ECHO */ +#if !defined (V9_ECHO) +char * const echo_doc[] = { +#if defined (HELP_BUILTIN) +N_("Write arguments to the standard output.\n\ + \n\ + Display the ARGs on the standard output followed by a newline.\n\ + \n\ + Options:\n\ + -n do not append a newline\n\ + \n\ + Exit Status:\n\ + Returns success unless a write error occurs."), +#endif /* HELP_BUILTIN */ + (char *)NULL +}; +#endif /* !V9_ECHO */ +char * const enable_doc[] = { +#if defined (HELP_BUILTIN) +N_("Enable and disable shell builtins.\n\ + \n\ + Enables and disables builtin shell commands. Disabling allows you to\n\ + execute a disk command which has the same name as a shell builtin\n\ + without using a full pathname.\n\ + \n\ + Options:\n\ + -a print a list of builtins showing whether or not each is enabled\n\ + -n disable each NAME or display a list of disabled builtins\n\ + -p print the list of builtins in a reusable format\n\ + -s print only the names of Posix `special' builtins\n\ + \n\ + Options controlling dynamic loading:\n\ + -f Load builtin NAME from shared object FILENAME\n\ + -d Remove a builtin loaded with -f\n\ + \n\ + Without options, each NAME is enabled.\n\ + \n\ + To use the `test' found in $PATH instead of the shell builtin\n\ + version, type `enable -n test'.\n\ + \n\ + Exit Status:\n\ + Returns success unless NAME is not a shell builtin or an error occurs."), +#endif /* HELP_BUILTIN */ + (char *)NULL +}; +char * const eval_doc[] = { +#if defined (HELP_BUILTIN) +N_("Execute arguments as a shell command.\n\ + \n\ + Combine ARGs into a single string, use the result as input to the shell,\n\ + and execute the resulting commands.\n\ + \n\ + Exit Status:\n\ + Returns exit status of command or success if command is null."), +#endif /* HELP_BUILTIN */ + (char *)NULL +}; +char * const getopts_doc[] = { +#if defined (HELP_BUILTIN) +N_("Parse option arguments.\n\ + \n\ + Getopts is used by shell procedures to parse positional parameters\n\ + as options.\n\ + \n\ + OPTSTRING contains the option letters to be recognized; if a letter\n\ + is followed by a colon, the option is expected to have an argument,\n\ + which should be separated from it by white space.\n\ + \n\ + Each time it is invoked, getopts will place the next option in the\n\ + shell variable $name, initializing name if it does not exist, and\n\ + the index of the next argument to be processed into the shell\n\ + variable OPTIND. OPTIND is initialized to 1 each time the shell or\n\ + a shell script is invoked. When an option requires an argument,\n\ + getopts places that argument into the shell variable OPTARG.\n\ + \n\ + getopts reports errors in one of two ways. If the first character\n\ + of OPTSTRING is a colon, getopts uses silent error reporting. In\n\ + this mode, no error messages are printed. If an invalid option is\n\ + seen, getopts places the option character found into OPTARG. If a\n\ + required argument is not found, getopts places a ':' into NAME and\n\ + sets OPTARG to the option character found. If getopts is not in\n\ + silent mode, and an invalid option is seen, getopts places '?' into\n\ + NAME and unsets OPTARG. If a required argument is not found, a '?'\n\ + is placed in NAME, OPTARG is unset, and a diagnostic message is\n\ + printed.\n\ + \n\ + If the shell variable OPTERR has the value 0, getopts disables the\n\ + printing of error messages, even if the first character of\n\ + OPTSTRING is not a colon. OPTERR has the value 1 by default.\n\ + \n\ + Getopts normally parses the positional parameters, but if arguments\n\ + are supplied as ARG values, they are parsed instead.\n\ + \n\ + Exit Status:\n\ + Returns success if an option is found; fails if the end of options is\n\ + encountered or an error occurs."), +#endif /* HELP_BUILTIN */ + (char *)NULL +}; +char * const exec_doc[] = { +#if defined (HELP_BUILTIN) +N_("Replace the shell with the given command.\n\ + \n\ + Execute COMMAND, replacing this shell with the specified program.\n\ + ARGUMENTS become the arguments to COMMAND. If COMMAND is not specified,\n\ + any redirections take effect in the current shell.\n\ + \n\ + Options:\n\ + -a name pass NAME as the zeroth argument to COMMAND\n\ + -c execute COMMAND with an empty environment\n\ + -l place a dash in the zeroth argument to COMMAND\n\ + \n\ + If the command cannot be executed, a non-interactive shell exits, unless\n\ + the shell option `execfail' is set.\n\ + \n\ + Exit Status:\n\ + Returns success unless COMMAND is not found or a redirection error occurs."), +#endif /* HELP_BUILTIN */ + (char *)NULL +}; +char * const exit_doc[] = { +#if defined (HELP_BUILTIN) +N_("Exit the shell.\n\ + \n\ + Exits the shell with a status of N. If N is omitted, the exit status\n\ + is that of the last command executed."), +#endif /* HELP_BUILTIN */ + (char *)NULL +}; +char * const logout_doc[] = { +#if defined (HELP_BUILTIN) +N_("Exit a login shell.\n\ + \n\ + Exits a login shell with exit status N. Returns an error if not executed\n\ + in a login shell."), +#endif /* HELP_BUILTIN */ + (char *)NULL +}; +#if defined (HISTORY) +char * const fc_doc[] = { +#if defined (HELP_BUILTIN) +N_("Display or execute commands from the history list.\n\ + \n\ + fc is used to list or edit and re-execute commands from the history list.\n\ + FIRST and LAST can be numbers specifying the range, or FIRST can be a\n\ + string, which means the most recent command beginning with that\n\ + string.\n\ + \n\ + Options:\n\ + -e ENAME select which editor to use. Default is FCEDIT, then EDITOR,\n\ + then vi\n\ + -l list lines instead of editing\n\ + -n omit line numbers when listing\n\ + -r reverse the order of the lines (newest listed first)\n\ + \n\ + With the `fc -s [pat=rep ...] [command]' format, COMMAND is\n\ + re-executed after the substitution OLD=NEW is performed.\n\ + \n\ + A useful alias to use with this is r='fc -s', so that typing `r cc'\n\ + runs the last command beginning with `cc' and typing `r' re-executes\n\ + the last command.\n\ + \n\ + Exit Status:\n\ + Returns success or status of executed command; non-zero if an error occurs."), +#endif /* HELP_BUILTIN */ + (char *)NULL +}; +#endif /* HISTORY */ +#if defined (JOB_CONTROL) +char * const fg_doc[] = { +#if defined (HELP_BUILTIN) +N_("Move job to the foreground.\n\ + \n\ + Place the job identified by JOB_SPEC in the foreground, making it the\n\ + current job. If JOB_SPEC is not present, the shell's notion of the\n\ + current job is used.\n\ + \n\ + Exit Status:\n\ + Status of command placed in foreground, or failure if an error occurs."), +#endif /* HELP_BUILTIN */ + (char *)NULL +}; +#endif /* JOB_CONTROL */ +#if defined (JOB_CONTROL) +char * const bg_doc[] = { +#if defined (HELP_BUILTIN) +N_("Move jobs to the background.\n\ + \n\ + Place the jobs identified by each JOB_SPEC in the background, as if they\n\ + had been started with `&'. If JOB_SPEC is not present, the shell's notion\n\ + of the current job is used.\n\ + \n\ + Exit Status:\n\ + Returns success unless job control is not enabled or an error occurs."), +#endif /* HELP_BUILTIN */ + (char *)NULL +}; +#endif /* JOB_CONTROL */ +char * const hash_doc[] = { +#if defined (HELP_BUILTIN) +N_("Remember or display program locations.\n\ + \n\ + Determine and remember the full pathname of each command NAME. If\n\ + no arguments are given, information about remembered commands is displayed.\n\ + \n\ + Options:\n\ + -d forget the remembered location of each NAME\n\ + -l display in a format that may be reused as input\n\ + -p pathname use PATHNAME as the full pathname of NAME\n\ + -r forget all remembered locations\n\ + -t print the remembered location of each NAME, preceding\n\ + each location with the corresponding NAME if multiple\n\ + NAMEs are given\n\ + Arguments:\n\ + NAME Each NAME is searched for in $PATH and added to the list\n\ + of remembered commands.\n\ + \n\ + Exit Status:\n\ + Returns success unless NAME is not found or an invalid option is given."), +#endif /* HELP_BUILTIN */ + (char *)NULL +}; +#if defined (HELP_BUILTIN) +char * const help_doc[] = { +#if defined (HELP_BUILTIN) +N_("Display information about builtin commands.\n\ + \n\ + Displays brief summaries of builtin commands. If PATTERN is\n\ + specified, gives detailed help on all commands matching PATTERN,\n\ + otherwise the list of help topics is printed.\n\ + \n\ + Options:\n\ + -d output short description for each topic\n\ + -m display usage in pseudo-manpage format\n\ + -s output only a short usage synopsis for each topic matching\n\ + PATTERN\n\ + \n\ + Arguments:\n\ + PATTERN Pattern specifying a help topic\n\ + \n\ + Exit Status:\n\ + Returns success unless PATTERN is not found or an invalid option is given."), +#endif /* HELP_BUILTIN */ + (char *)NULL +}; +#endif /* HELP_BUILTIN */ +#if defined (HISTORY) +char * const history_doc[] = { +#if defined (HELP_BUILTIN) +N_("Display or manipulate the history list.\n\ + \n\ + Display the history list with line numbers, prefixing each modified\n\ + entry with a `*'. An argument of N lists only the last N entries.\n\ + \n\ + Options:\n\ + -c clear the history list by deleting all of the entries\n\ + -d offset delete the history entry at position OFFSET. Negative\n\ + offsets count back from the end of the history list\n\ + \n\ + -a append history lines from this session to the history file\n\ + -n read all history lines not already read from the history file\n\ + and append them to the history list\n\ + -r read the history file and append the contents to the history\n\ + list\n\ + -w write the current history to the history file\n\ + \n\ + -p perform history expansion on each ARG and display the result\n\ + without storing it in the history list\n\ + -s append the ARGs to the history list as a single entry\n\ + \n\ + If FILENAME is given, it is used as the history file. Otherwise,\n\ + if HISTFILE has a value, that is used, else ~/.bash_history.\n\ + \n\ + If the HISTTIMEFORMAT variable is set and not null, its value is used\n\ + as a format string for strftime(3) to print the time stamp associated\n\ + with each displayed history entry. No time stamps are printed otherwise.\n\ + \n\ + Exit Status:\n\ + Returns success unless an invalid option is given or an error occurs."), +#endif /* HELP_BUILTIN */ + (char *)NULL +}; +#endif /* HISTORY */ +#if defined (JOB_CONTROL) +char * const jobs_doc[] = { +#if defined (HELP_BUILTIN) +N_("Display status of jobs.\n\ + \n\ + Lists the active jobs. JOBSPEC restricts output to that job.\n\ + Without options, the status of all active jobs is displayed.\n\ + \n\ + Options:\n\ + -l lists process IDs in addition to the normal information\n\ + -n lists only processes that have changed status since the last\n\ + notification\n\ + -p lists process IDs only\n\ + -r restrict output to running jobs\n\ + -s restrict output to stopped jobs\n\ + \n\ + If -x is supplied, COMMAND is run after all job specifications that\n\ + appear in ARGS have been replaced with the process ID of that job's\n\ + process group leader.\n\ + \n\ + Exit Status:\n\ + Returns success unless an invalid option is given or an error occurs.\n\ + If -x is used, returns the exit status of COMMAND."), +#endif /* HELP_BUILTIN */ + (char *)NULL +}; +#endif /* JOB_CONTROL */ +#if defined (JOB_CONTROL) +char * const disown_doc[] = { +#if defined (HELP_BUILTIN) +N_("Remove jobs from current shell.\n\ + \n\ + Removes each JOBSPEC argument from the table of active jobs. Without\n\ + any JOBSPECs, the shell uses its notion of the current job.\n\ + \n\ + Options:\n\ + -a remove all jobs if JOBSPEC is not supplied\n\ + -h mark each JOBSPEC so that SIGHUP is not sent to the job if the\n\ + shell receives a SIGHUP\n\ + -r remove only running jobs\n\ + \n\ + Exit Status:\n\ + Returns success unless an invalid option or JOBSPEC is given."), +#endif /* HELP_BUILTIN */ + (char *)NULL +}; +#endif /* JOB_CONTROL */ +char * const kill_doc[] = { +#if defined (HELP_BUILTIN) +N_("Send a signal to a job.\n\ + \n\ + Send the processes identified by PID or JOBSPEC the signal named by\n\ + SIGSPEC or SIGNUM. If neither SIGSPEC nor SIGNUM is present, then\n\ + SIGTERM is assumed.\n\ + \n\ + Options:\n\ + -s sig SIG is a signal name\n\ + -n sig SIG is a signal number\n\ + -l list the signal names; if arguments follow `-l' they are\n\ + assumed to be signal numbers for which names should be listed\n\ + -L synonym for -l\n\ + \n\ + Kill is a shell builtin for two reasons: it allows job IDs to be used\n\ + instead of process IDs, and allows processes to be killed if the limit\n\ + on processes that you can create is reached.\n\ + \n\ + Exit Status:\n\ + Returns success unless an invalid option is given or an error occurs."), +#endif /* HELP_BUILTIN */ + (char *)NULL +}; +char * const let_doc[] = { +#if defined (HELP_BUILTIN) +N_("Evaluate arithmetic expressions.\n\ + \n\ + Evaluate each ARG as an arithmetic expression. Evaluation is done in\n\ + fixed-width integers with no check for overflow, though division by 0\n\ + is trapped and flagged as an error. The following list of operators is\n\ + grouped into levels of equal-precedence operators. The levels are listed\n\ + in order of decreasing precedence.\n\ + \n\ + id++, id-- variable post-increment, post-decrement\n\ + ++id, --id variable pre-increment, pre-decrement\n\ + -, + unary minus, plus\n\ + !, ~ logical and bitwise negation\n\ + ** exponentiation\n\ + *, /, % multiplication, division, remainder\n\ + +, - addition, subtraction\n\ + <<, >> left and right bitwise shifts\n\ + <=, >=, <, > comparison\n\ + ==, != equality, inequality\n\ + & bitwise AND\n\ + ^ bitwise XOR\n\ + | bitwise OR\n\ + && logical AND\n\ + || logical OR\n\ + expr ? expr : expr\n\ + conditional operator\n\ + =, *=, /=, %=,\n\ + +=, -=, <<=, >>=,\n\ + &=, ^=, |= assignment\n\ + \n\ + Shell variables are allowed as operands. The name of the variable\n\ + is replaced by its value (coerced to a fixed-width integer) within\n\ + an expression. The variable need not have its integer attribute\n\ + turned on to be used in an expression.\n\ + \n\ + Operators are evaluated in order of precedence. Sub-expressions in\n\ + parentheses are evaluated first and may override the precedence\n\ + rules above.\n\ + \n\ + Exit Status:\n\ + If the last ARG evaluates to 0, let returns 1; let returns 0 otherwise."), +#endif /* HELP_BUILTIN */ + (char *)NULL +}; +char * const read_doc[] = { +#if defined (HELP_BUILTIN) +N_("Read a line from the standard input and split it into fields.\n\ + \n\ + Reads a single line from the standard input, or from file descriptor FD\n\ + if the -u option is supplied. The line is split into fields as with word\n\ + splitting, and the first word is assigned to the first NAME, the second\n\ + word to the second NAME, and so on, with any leftover words assigned to\n\ + the last NAME. Only the characters found in $IFS are recognized as word\n\ + delimiters.\n\ + \n\ + If no NAMEs are supplied, the line read is stored in the REPLY variable.\n\ + \n\ + Options:\n\ + -a array assign the words read to sequential indices of the array\n\ + variable ARRAY, starting at zero\n\ + -d delim continue until the first character of DELIM is read, rather\n\ + than newline\n\ + -e use Readline to obtain the line\n\ + -i text use TEXT as the initial text for Readline\n\ + -n nchars return after reading NCHARS characters rather than waiting\n\ + for a newline, but honor a delimiter if fewer than\n\ + NCHARS characters are read before the delimiter\n\ + -N nchars return only after reading exactly NCHARS characters, unless\n\ + EOF is encountered or read times out, ignoring any\n\ + delimiter\n\ + -p prompt output the string PROMPT without a trailing newline before\n\ + attempting to read\n\ + -r do not allow backslashes to escape any characters\n\ + -s do not echo input coming from a terminal\n\ + -t timeout time out and return failure if a complete line of\n\ + input is not read within TIMEOUT seconds. The value of the\n\ + TMOUT variable is the default timeout. TIMEOUT may be a\n\ + fractional number. If TIMEOUT is 0, read returns\n\ + immediately, without trying to read any data, returning\n\ + success only if input is available on the specified\n\ + file descriptor. The exit status is greater than 128\n\ + if the timeout is exceeded\n\ + -u fd read from file descriptor FD instead of the standard input\n\ + \n\ + Exit Status:\n\ + The return code is zero, unless end-of-file is encountered, read times out\n\ + (in which case it's greater than 128), a variable assignment error occurs,\n\ + or an invalid file descriptor is supplied as the argument to -u."), +#endif /* HELP_BUILTIN */ + (char *)NULL +}; +char * const return_doc[] = { +#if defined (HELP_BUILTIN) +N_("Return from a shell function.\n\ + \n\ + Causes a function or sourced script to exit with the return value\n\ + specified by N. If N is omitted, the return status is that of the\n\ + last command executed within the function or script.\n\ + \n\ + Exit Status:\n\ + Returns N, or failure if the shell is not executing a function or script."), +#endif /* HELP_BUILTIN */ + (char *)NULL +}; +char * const set_doc[] = { +#if defined (HELP_BUILTIN) +N_("Set or unset values of shell options and positional parameters.\n\ + \n\ + Change the value of shell attributes and positional parameters, or\n\ + display the names and values of shell variables.\n\ + \n\ + Options:\n\ + -a Mark variables which are modified or created for export.\n\ + -b Notify of job termination immediately.\n\ + -e Exit immediately if a command exits with a non-zero status.\n\ + -f Disable file name generation (globbing).\n\ + -h Remember the location of commands as they are looked up.\n\ + -k All assignment arguments are placed in the environment for a\n\ + command, not just those that precede the command name.\n\ + -m Job control is enabled.\n\ + -n Read commands but do not execute them.\n\ + -o option-name\n\ + Set the variable corresponding to option-name:\n\ + allexport same as -a\n\ + braceexpand same as -B\n\ + emacs use an emacs-style line editing interface\n\ + errexit same as -e\n\ + errtrace same as -E\n\ + functrace same as -T\n\ + hashall same as -h\n\ + histexpand same as -H\n\ + history enable command history\n\ + ignoreeof the shell will not exit upon reading EOF\n\ + interactive-comments\n\ + allow comments to appear in interactive commands\n\ + keyword same as -k\n\ + monitor same as -m\n\ + noclobber same as -C\n\ + noexec same as -n\n\ + noglob same as -f\n\ + nolog currently accepted but ignored\n\ + notify same as -b\n\ + nounset same as -u\n\ + onecmd same as -t\n\ + physical same as -P\n\ + pipefail the return value of a pipeline is the status of\n\ + the last command to exit with a non-zero status,\n\ + or zero if no command exited with a non-zero status\n\ + posix change the behavior of bash where the default\n\ + operation differs from the Posix standard to\n\ + match the standard\n\ + privileged same as -p\n\ + verbose same as -v\n\ + vi use a vi-style line editing interface\n\ + xtrace same as -x\n\ + -p Turned on whenever the real and effective user ids do not match.\n\ + Disables processing of the $ENV file and importing of shell\n\ + functions. Turning this option off causes the effective uid and\n\ + gid to be set to the real uid and gid.\n\ + -t Exit after reading and executing one command.\n\ + -u Treat unset variables as an error when substituting.\n\ + -v Print shell input lines as they are read.\n\ + -x Print commands and their arguments as they are executed.\n\ + -B the shell will perform brace expansion\n\ + -C If set, disallow existing regular files to be overwritten\n\ + by redirection of output.\n\ + -E If set, the ERR trap is inherited by shell functions.\n\ + -H Enable ! style history substitution. This flag is on\n\ + by default when the shell is interactive.\n\ + -P If set, do not resolve symbolic links when executing commands\n\ + such as cd which change the current directory.\n\ + -T If set, the DEBUG and RETURN traps are inherited by shell functions.\n\ + -- Assign any remaining arguments to the positional parameters.\n\ + If there are no remaining arguments, the positional parameters\n\ + are unset.\n\ + - Assign any remaining arguments to the positional parameters.\n\ + The -x and -v options are turned off.\n\ + \n\ + Using + rather than - causes these flags to be turned off. The\n\ + flags can also be used upon invocation of the shell. The current\n\ + set of flags may be found in $-. The remaining n ARGs are positional\n\ + parameters and are assigned, in order, to $1, $2, .. $n. If no\n\ + ARGs are given, all shell variables are printed.\n\ + \n\ + Exit Status:\n\ + Returns success unless an invalid option is given."), +#endif /* HELP_BUILTIN */ + (char *)NULL +}; +char * const unset_doc[] = { +#if defined (HELP_BUILTIN) +N_("Unset values and attributes of shell variables and functions.\n\ + \n\ + For each NAME, remove the corresponding variable or function.\n\ + \n\ + Options:\n\ + -f treat each NAME as a shell function\n\ + -v treat each NAME as a shell variable\n\ + -n treat each NAME as a name reference and unset the variable itself\n\ + rather than the variable it references\n\ + \n\ + Without options, unset first tries to unset a variable, and if that fails,\n\ + tries to unset a function.\n\ + \n\ + Some variables cannot be unset; also see `readonly'.\n\ + \n\ + Exit Status:\n\ + Returns success unless an invalid option is given or a NAME is read-only."), +#endif /* HELP_BUILTIN */ + (char *)NULL +}; +char * const export_doc[] = { +#if defined (HELP_BUILTIN) +N_("Set export attribute for shell variables.\n\ + \n\ + Marks each NAME for automatic export to the environment of subsequently\n\ + executed commands. If VALUE is supplied, assign VALUE before exporting.\n\ + \n\ + Options:\n\ + -f refer to shell functions\n\ + -n remove the export property from each NAME\n\ + -p display a list of all exported variables and functions\n\ + \n\ + An argument of `--' disables further option processing.\n\ + \n\ + Exit Status:\n\ + Returns success unless an invalid option is given or NAME is invalid."), +#endif /* HELP_BUILTIN */ + (char *)NULL +}; +char * const readonly_doc[] = { +#if defined (HELP_BUILTIN) +N_("Mark shell variables as unchangeable.\n\ + \n\ + Mark each NAME as read-only; the values of these NAMEs may not be\n\ + changed by subsequent assignment. If VALUE is supplied, assign VALUE\n\ + before marking as read-only.\n\ + \n\ + Options:\n\ + -a refer to indexed array variables\n\ + -A refer to associative array variables\n\ + -f refer to shell functions\n\ + -p display a list of all readonly variables or functions,\n\ + depending on whether or not the -f option is given\n\ + \n\ + An argument of `--' disables further option processing.\n\ + \n\ + Exit Status:\n\ + Returns success unless an invalid option is given or NAME is invalid."), +#endif /* HELP_BUILTIN */ + (char *)NULL +}; +char * const shift_doc[] = { +#if defined (HELP_BUILTIN) +N_("Shift positional parameters.\n\ + \n\ + Rename the positional parameters $N+1,$N+2 ... to $1,$2 ... If N is\n\ + not given, it is assumed to be 1.\n\ + \n\ + Exit Status:\n\ + Returns success unless N is negative or greater than $#."), +#endif /* HELP_BUILTIN */ + (char *)NULL +}; +char * const source_doc[] = { +#if defined (HELP_BUILTIN) +N_("Execute commands from a file in the current shell.\n\ + \n\ + Read and execute commands from FILENAME in the current shell. The\n\ + entries in $PATH are used to find the directory containing FILENAME.\n\ + If any ARGUMENTS are supplied, they become the positional parameters\n\ + when FILENAME is executed.\n\ + \n\ + Exit Status:\n\ + Returns the status of the last command executed in FILENAME; fails if\n\ + FILENAME cannot be read."), +#endif /* HELP_BUILTIN */ + (char *)NULL +}; +char * const dot_doc[] = { +#if defined (HELP_BUILTIN) +N_("Execute commands from a file in the current shell.\n\ + \n\ + Read and execute commands from FILENAME in the current shell. The\n\ + entries in $PATH are used to find the directory containing FILENAME.\n\ + If any ARGUMENTS are supplied, they become the positional parameters\n\ + when FILENAME is executed.\n\ + \n\ + Exit Status:\n\ + Returns the status of the last command executed in FILENAME; fails if\n\ + FILENAME cannot be read."), +#endif /* HELP_BUILTIN */ + (char *)NULL +}; +#if defined (JOB_CONTROL) +char * const suspend_doc[] = { +#if defined (HELP_BUILTIN) +N_("Suspend shell execution.\n\ + \n\ + Suspend the execution of this shell until it receives a SIGCONT signal.\n\ + Unless forced, login shells cannot be suspended.\n\ + \n\ + Options:\n\ + -f force the suspend, even if the shell is a login shell\n\ + \n\ + Exit Status:\n\ + Returns success unless job control is not enabled or an error occurs."), +#endif /* HELP_BUILTIN */ + (char *)NULL +}; +#endif /* JOB_CONTROL */ +char * const test_doc[] = { +#if defined (HELP_BUILTIN) +N_("Evaluate conditional expression.\n\ + \n\ + Exits with a status of 0 (true) or 1 (false) depending on\n\ + the evaluation of EXPR. Expressions may be unary or binary. Unary\n\ + expressions are often used to examine the status of a file. There\n\ + are string operators and numeric comparison operators as well.\n\ + \n\ + The behavior of test depends on the number of arguments. Read the\n\ + bash manual page for the complete specification.\n\ + \n\ + File operators:\n\ + \n\ + -a FILE True if file exists.\n\ + -b FILE True if file is block special.\n\ + -c FILE True if file is character special.\n\ + -d FILE True if file is a directory.\n\ + -e FILE True if file exists.\n\ + -f FILE True if file exists and is a regular file.\n\ + -g FILE True if file is set-group-id.\n\ + -h FILE True if file is a symbolic link.\n\ + -L FILE True if file is a symbolic link.\n\ + -k FILE True if file has its `sticky' bit set.\n\ + -p FILE True if file is a named pipe.\n\ + -r FILE True if file is readable by you.\n\ + -s FILE True if file exists and is not empty.\n\ + -S FILE True if file is a socket.\n\ + -t FD True if FD is opened on a terminal.\n\ + -u FILE True if the file is set-user-id.\n\ + -w FILE True if the file is writable by you.\n\ + -x FILE True if the file is executable by you.\n\ + -O FILE True if the file is effectively owned by you.\n\ + -G FILE True if the file is effectively owned by your group.\n\ + -N FILE True if the file has been modified since it was last read.\n\ + \n\ + FILE1 -nt FILE2 True if file1 is newer than file2 (according to\n\ + modification date).\n\ + \n\ + FILE1 -ot FILE2 True if file1 is older than file2.\n\ + \n\ + FILE1 -ef FILE2 True if file1 is a hard link to file2.\n\ + \n\ + String operators:\n\ + \n\ + -z STRING True if string is empty.\n\ + \n\ + -n STRING\n\ + STRING True if string is not empty.\n\ + \n\ + STRING1 = STRING2\n\ + True if the strings are equal.\n\ + STRING1 != STRING2\n\ + True if the strings are not equal.\n\ + STRING1 < STRING2\n\ + True if STRING1 sorts before STRING2 lexicographically.\n\ + STRING1 > STRING2\n\ + True if STRING1 sorts after STRING2 lexicographically.\n\ + \n\ + Other operators:\n\ + \n\ + -o OPTION True if the shell option OPTION is enabled.\n\ + -v VAR True if the shell variable VAR is set.\n\ + -R VAR True if the shell variable VAR is set and is a name\n\ + reference.\n\ + ! EXPR True if expr is false.\n\ + EXPR1 -a EXPR2 True if both expr1 AND expr2 are true.\n\ + EXPR1 -o EXPR2 True if either expr1 OR expr2 is true.\n\ + \n\ + arg1 OP arg2 Arithmetic tests. OP is one of -eq, -ne,\n\ + -lt, -le, -gt, or -ge.\n\ + \n\ + Arithmetic binary operators return true if ARG1 is equal, not-equal,\n\ + less-than, less-than-or-equal, greater-than, or greater-than-or-equal\n\ + than ARG2.\n\ + \n\ + Exit Status:\n\ + Returns success if EXPR evaluates to true; fails if EXPR evaluates to\n\ + false or an invalid argument is given."), +#endif /* HELP_BUILTIN */ + (char *)NULL +}; +char * const test_bracket_doc[] = { +#if defined (HELP_BUILTIN) +N_("Evaluate conditional expression.\n\ + \n\ + This is a synonym for the \"test\" builtin, but the last argument must\n\ + be a literal `]', to match the opening `['."), +#endif /* HELP_BUILTIN */ + (char *)NULL +}; +char * const times_doc[] = { +#if defined (HELP_BUILTIN) +N_("Display process times.\n\ + \n\ + Prints the accumulated user and system times for the shell and all of its\n\ + child processes.\n\ + \n\ + Exit Status:\n\ + Always succeeds."), +#endif /* HELP_BUILTIN */ + (char *)NULL +}; +char * const trap_doc[] = { +#if defined (HELP_BUILTIN) +N_("Trap signals and other events.\n\ + \n\ + Defines and activates handlers to be run when the shell receives signals\n\ + or other conditions.\n\ + \n\ + ARG is a command to be read and executed when the shell receives the\n\ + signal(s) SIGNAL_SPEC. If ARG is absent (and a single SIGNAL_SPEC\n\ + is supplied) or `-', each specified signal is reset to its original\n\ + value. If ARG is the null string each SIGNAL_SPEC is ignored by the\n\ + shell and by the commands it invokes.\n\ + \n\ + If a SIGNAL_SPEC is EXIT (0) ARG is executed on exit from the shell. If\n\ + a SIGNAL_SPEC is DEBUG, ARG is executed before every simple command. If\n\ + a SIGNAL_SPEC is RETURN, ARG is executed each time a shell function or a\n\ + script run by the . or source builtins finishes executing. A SIGNAL_SPEC\n\ + of ERR means to execute ARG each time a command's failure would cause the\n\ + shell to exit when the -e option is enabled.\n\ + \n\ + If no arguments are supplied, trap prints the list of commands associated\n\ + with each signal.\n\ + \n\ + Options:\n\ + -l print a list of signal names and their corresponding numbers\n\ + -p display the trap commands associated with each SIGNAL_SPEC\n\ + \n\ + Each SIGNAL_SPEC is either a signal name in or a signal number.\n\ + Signal names are case insensitive and the SIG prefix is optional. A\n\ + signal may be sent to the shell with \"kill -signal $$\".\n\ + \n\ + Exit Status:\n\ + Returns success unless a SIGSPEC is invalid or an invalid option is given."), +#endif /* HELP_BUILTIN */ + (char *)NULL +}; +char * const type_doc[] = { +#if defined (HELP_BUILTIN) +N_("Display information about command type.\n\ + \n\ + For each NAME, indicate how it would be interpreted if used as a\n\ + command name.\n\ + \n\ + Options:\n\ + -a display all locations containing an executable named NAME;\n\ + includes aliases, builtins, and functions, if and only if\n\ + the `-p' option is not also used\n\ + -f suppress shell function lookup\n\ + -P force a PATH search for each NAME, even if it is an alias,\n\ + builtin, or function, and returns the name of the disk file\n\ + that would be executed\n\ + -p returns either the name of the disk file that would be executed,\n\ + or nothing if `type -t NAME' would not return `file'\n\ + -t output a single word which is one of `alias', `keyword',\n\ + `function', `builtin', `file' or `', if NAME is an alias,\n\ + shell reserved word, shell function, shell builtin, disk file,\n\ + or not found, respectively\n\ + \n\ + Arguments:\n\ + NAME Command name to be interpreted.\n\ + \n\ + Exit Status:\n\ + Returns success if all of the NAMEs are found; fails if any are not found."), +#endif /* HELP_BUILTIN */ + (char *)NULL +}; +#if !defined (_MINIX) +char * const ulimit_doc[] = { +#if defined (HELP_BUILTIN) +N_("Modify shell resource limits.\n\ + \n\ + Provides control over the resources available to the shell and processes\n\ + it creates, on systems that allow such control.\n\ + \n\ + Options:\n\ + -S use the `soft' resource limit\n\ + -H use the `hard' resource limit\n\ + -a all current limits are reported\n\ + -b the socket buffer size\n\ + -c the maximum size of core files created\n\ + -d the maximum size of a process's data segment\n\ + -e the maximum scheduling priority (`nice')\n\ + -f the maximum size of files written by the shell and its children\n\ + -i the maximum number of pending signals\n\ + -k the maximum number of kqueues allocated for this process\n\ + -l the maximum size a process may lock into memory\n\ + -m the maximum resident set size\n\ + -n the maximum number of open file descriptors\n\ + -p the pipe buffer size\n\ + -q the maximum number of bytes in POSIX message queues\n\ + -r the maximum real-time scheduling priority\n\ + -s the maximum stack size\n\ + -t the maximum amount of cpu time in seconds\n\ + -u the maximum number of user processes\n\ + -v the size of virtual memory\n\ + -x the maximum number of file locks\n\ + -P the maximum number of pseudoterminals\n\ + -R the maximum time a real-time process can run before blocking\n\ + -T the maximum number of threads\n\ + \n\ + Not all options are available on all platforms.\n\ + \n\ + If LIMIT is given, it is the new value of the specified resource; the\n\ + special LIMIT values `soft', `hard', and `unlimited' stand for the\n\ + current soft limit, the current hard limit, and no limit, respectively.\n\ + Otherwise, the current value of the specified resource is printed. If\n\ + no option is given, then -f is assumed.\n\ + \n\ + Values are in 1024-byte increments, except for -t, which is in seconds,\n\ + -p, which is in increments of 512 bytes, and -u, which is an unscaled\n\ + number of processes.\n\ + \n\ + Exit Status:\n\ + Returns success unless an invalid option is supplied or an error occurs."), +#endif /* HELP_BUILTIN */ + (char *)NULL +}; +#endif /* !_MINIX */ +char * const umask_doc[] = { +#if defined (HELP_BUILTIN) +N_("Display or set file mode mask.\n\ + \n\ + Sets the user file-creation mask to MODE. If MODE is omitted, prints\n\ + the current value of the mask.\n\ + \n\ + If MODE begins with a digit, it is interpreted as an octal number;\n\ + otherwise it is a symbolic mode string like that accepted by chmod(1).\n\ + \n\ + Options:\n\ + -p if MODE is omitted, output in a form that may be reused as input\n\ + -S makes the output symbolic; otherwise an octal number is output\n\ + \n\ + Exit Status:\n\ + Returns success unless MODE is invalid or an invalid option is given."), +#endif /* HELP_BUILTIN */ + (char *)NULL +}; +#if defined (JOB_CONTROL) +char * const wait_doc[] = { +#if defined (HELP_BUILTIN) +N_("Wait for job completion and return exit status.\n\ + \n\ + Waits for each process identified by an ID, which may be a process ID or a\n\ + job specification, and reports its termination status. If ID is not\n\ + given, waits for all currently active child processes, and the return\n\ + status is zero. If ID is a job specification, waits for all processes\n\ + in that job's pipeline.\n\ + \n\ + If the -n option is supplied, waits for a single job from the list of IDs,\n\ + or, if no IDs are supplied, for the next job to complete and returns its\n\ + exit status.\n\ + \n\ + If the -p option is supplied, the process or job identifier of the job\n\ + for which the exit status is returned is assigned to the variable VAR\n\ + named by the option argument. The variable will be unset initially, before\n\ + any assignment. This is useful only when the -n option is supplied.\n\ + \n\ + If the -f option is supplied, and job control is enabled, waits for the\n\ + specified ID to terminate, instead of waiting for it to change status.\n\ + \n\ + Exit Status:\n\ + Returns the status of the last ID; fails if ID is invalid or an invalid\n\ + option is given, or if -n is supplied and the shell has no unwaited-for\n\ + children."), +#endif /* HELP_BUILTIN */ + (char *)NULL +}; +#endif /* JOB_CONTROL */ +#if !defined (JOB_CONTROL) +char * const wait_doc[] = { +#if defined (HELP_BUILTIN) +N_("Wait for process completion and return exit status.\n\ + \n\ + Waits for each process specified by a PID and reports its termination status.\n\ + If PID is not given, waits for all currently active child processes,\n\ + and the return status is zero. PID must be a process ID.\n\ + \n\ + Exit Status:\n\ + Returns the status of the last PID; fails if PID is invalid or an invalid\n\ + option is given."), +#endif /* HELP_BUILTIN */ + (char *)NULL +}; +#endif /* !JOB_CONTROL */ +char * const for_doc[] = { +#if defined (HELP_BUILTIN) +N_("Execute commands for each member in a list.\n\ + \n\ + The `for' loop executes a sequence of commands for each member in a\n\ + list of items. If `in WORDS ...;' is not present, then `in \"$@\"' is\n\ + assumed. For each element in WORDS, NAME is set to that element, and\n\ + the COMMANDS are executed.\n\ + \n\ + Exit Status:\n\ + Returns the status of the last command executed."), +#endif /* HELP_BUILTIN */ + (char *)NULL +}; +char * const arith_for_doc[] = { +#if defined (HELP_BUILTIN) +N_("Arithmetic for loop.\n\ + \n\ + Equivalent to\n\ + (( EXP1 ))\n\ + while (( EXP2 )); do\n\ + COMMANDS\n\ + (( EXP3 ))\n\ + done\n\ + EXP1, EXP2, and EXP3 are arithmetic expressions. If any expression is\n\ + omitted, it behaves as if it evaluates to 1.\n\ + \n\ + Exit Status:\n\ + Returns the status of the last command executed."), +#endif /* HELP_BUILTIN */ + (char *)NULL +}; +char * const select_doc[] = { +#if defined (HELP_BUILTIN) +N_("Select words from a list and execute commands.\n\ + \n\ + The WORDS are expanded, generating a list of words. The\n\ + set of expanded words is printed on the standard error, each\n\ + preceded by a number. If `in WORDS' is not present, `in \"$@\"'\n\ + is assumed. The PS3 prompt is then displayed and a line read\n\ + from the standard input. If the line consists of the number\n\ + corresponding to one of the displayed words, then NAME is set\n\ + to that word. If the line is empty, WORDS and the prompt are\n\ + redisplayed. If EOF is read, the command completes. Any other\n\ + value read causes NAME to be set to null. The line read is saved\n\ + in the variable REPLY. COMMANDS are executed after each selection\n\ + until a break command is executed.\n\ + \n\ + Exit Status:\n\ + Returns the status of the last command executed."), +#endif /* HELP_BUILTIN */ + (char *)NULL +}; +char * const time_doc[] = { +#if defined (HELP_BUILTIN) +N_("Report time consumed by pipeline's execution.\n\ + \n\ + Execute PIPELINE and print a summary of the real time, user CPU time,\n\ + and system CPU time spent executing PIPELINE when it terminates.\n\ + \n\ + Options:\n\ + -p print the timing summary in the portable Posix format\n\ + \n\ + The value of the TIMEFORMAT variable is used as the output format.\n\ + \n\ + Exit Status:\n\ + The return status is the return status of PIPELINE."), +#endif /* HELP_BUILTIN */ + (char *)NULL +}; +char * const case_doc[] = { +#if defined (HELP_BUILTIN) +N_("Execute commands based on pattern matching.\n\ + \n\ + Selectively execute COMMANDS based upon WORD matching PATTERN. The\n\ + `|' is used to separate multiple patterns.\n\ + \n\ + Exit Status:\n\ + Returns the status of the last command executed."), +#endif /* HELP_BUILTIN */ + (char *)NULL +}; +char * const if_doc[] = { +#if defined (HELP_BUILTIN) +N_("Execute commands based on conditional.\n\ + \n\ + The `if COMMANDS' list is executed. If its exit status is zero, then the\n\ + `then COMMANDS' list is executed. Otherwise, each `elif COMMANDS' list is\n\ + executed in turn, and if its exit status is zero, the corresponding\n\ + `then COMMANDS' list is executed and the if command completes. Otherwise,\n\ + the `else COMMANDS' list is executed, if present. The exit status of the\n\ + entire construct is the exit status of the last command executed, or zero\n\ + if no condition tested true.\n\ + \n\ + Exit Status:\n\ + Returns the status of the last command executed."), +#endif /* HELP_BUILTIN */ + (char *)NULL +}; +char * const while_doc[] = { +#if defined (HELP_BUILTIN) +N_("Execute commands as long as a test succeeds.\n\ + \n\ + Expand and execute COMMANDS as long as the final command in the\n\ + `while' COMMANDS has an exit status of zero.\n\ + \n\ + Exit Status:\n\ + Returns the status of the last command executed."), +#endif /* HELP_BUILTIN */ + (char *)NULL +}; +char * const until_doc[] = { +#if defined (HELP_BUILTIN) +N_("Execute commands as long as a test does not succeed.\n\ + \n\ + Expand and execute COMMANDS as long as the final command in the\n\ + `until' COMMANDS has an exit status which is not zero.\n\ + \n\ + Exit Status:\n\ + Returns the status of the last command executed."), +#endif /* HELP_BUILTIN */ + (char *)NULL +}; +char * const coproc_doc[] = { +#if defined (HELP_BUILTIN) +N_("Create a coprocess named NAME.\n\ + \n\ + Execute COMMAND asynchronously, with the standard output and standard\n\ + input of the command connected via a pipe to file descriptors assigned\n\ + to indices 0 and 1 of an array variable NAME in the executing shell.\n\ + The default NAME is \"COPROC\".\n\ + \n\ + Exit Status:\n\ + The coproc command returns an exit status of 0."), +#endif /* HELP_BUILTIN */ + (char *)NULL +}; +char * const function_doc[] = { +#if defined (HELP_BUILTIN) +N_("Define shell function.\n\ + \n\ + Create a shell function named NAME. When invoked as a simple command,\n\ + NAME runs COMMANDs in the calling shell's context. When NAME is invoked,\n\ + the arguments are passed to the function as $1...$n, and the function's\n\ + name is in $FUNCNAME.\n\ + \n\ + Exit Status:\n\ + Returns success unless NAME is readonly."), +#endif /* HELP_BUILTIN */ + (char *)NULL +}; +char * const grouping_braces_doc[] = { +#if defined (HELP_BUILTIN) +N_("Group commands as a unit.\n\ + \n\ + Run a set of commands in a group. This is one way to redirect an\n\ + entire set of commands.\n\ + \n\ + Exit Status:\n\ + Returns the status of the last command executed."), +#endif /* HELP_BUILTIN */ + (char *)NULL +}; +char * const fg_percent_doc[] = { +#if defined (HELP_BUILTIN) +N_("Resume job in foreground.\n\ + \n\ + Equivalent to the JOB_SPEC argument to the `fg' command. Resume a\n\ + stopped or background job. JOB_SPEC can specify either a job name\n\ + or a job number. Following JOB_SPEC with a `&' places the job in\n\ + the background, as if the job specification had been supplied as an\n\ + argument to `bg'.\n\ + \n\ + Exit Status:\n\ + Returns the status of the resumed job."), +#endif /* HELP_BUILTIN */ + (char *)NULL +}; +char * const arith_doc[] = { +#if defined (HELP_BUILTIN) +N_("Evaluate arithmetic expression.\n\ + \n\ + The EXPRESSION is evaluated according to the rules for arithmetic\n\ + evaluation. Equivalent to `let \"EXPRESSION\"'.\n\ + \n\ + Exit Status:\n\ + Returns 1 if EXPRESSION evaluates to 0; returns 0 otherwise."), +#endif /* HELP_BUILTIN */ + (char *)NULL +}; +char * const conditional_doc[] = { +#if defined (HELP_BUILTIN) +N_("Execute conditional command.\n\ + \n\ + Returns a status of 0 or 1 depending on the evaluation of the conditional\n\ + expression EXPRESSION. Expressions are composed of the same primaries used\n\ + by the `test' builtin, and may be combined using the following operators:\n\ + \n\ + ( EXPRESSION ) Returns the value of EXPRESSION\n\ + ! EXPRESSION True if EXPRESSION is false; else false\n\ + EXPR1 && EXPR2 True if both EXPR1 and EXPR2 are true; else false\n\ + EXPR1 || EXPR2 True if either EXPR1 or EXPR2 is true; else false\n\ + \n\ + When the `==' and `!=' operators are used, the string to the right of\n\ + the operator is used as a pattern and pattern matching is performed.\n\ + When the `=~' operator is used, the string to the right of the operator\n\ + is matched as a regular expression.\n\ + \n\ + The && and || operators do not evaluate EXPR2 if EXPR1 is sufficient to\n\ + determine the expression's value.\n\ + \n\ + Exit Status:\n\ + 0 or 1 depending on value of EXPRESSION."), +#endif /* HELP_BUILTIN */ + (char *)NULL +}; +char * const variable_help_doc[] = { +#if defined (HELP_BUILTIN) +N_("Common shell variable names and usage.\n\ + \n\ + BASH_VERSION Version information for this Bash.\n\ + CDPATH A colon-separated list of directories to search\n\ + for directories given as arguments to `cd'.\n\ + GLOBIGNORE A colon-separated list of patterns describing filenames to\n\ + be ignored by pathname expansion.\n\ + HISTFILE The name of the file where your command history is stored.\n\ + HISTFILESIZE The maximum number of lines this file can contain.\n\ + HISTSIZE The maximum number of history lines that a running\n\ + shell can access.\n\ + HOME The complete pathname to your login directory.\n\ + HOSTNAME The name of the current host.\n\ + HOSTTYPE The type of CPU this version of Bash is running under.\n\ + IGNOREEOF Controls the action of the shell on receipt of an EOF\n\ + character as the sole input. If set, then the value\n\ + of it is the number of EOF characters that can be seen\n\ + in a row on an empty line before the shell will exit\n\ + (default 10). When unset, EOF signifies the end of input.\n\ + MACHTYPE A string describing the current system Bash is running on.\n\ + MAILCHECK How often, in seconds, Bash checks for new mail.\n\ + MAILPATH A colon-separated list of filenames which Bash checks\n\ + for new mail.\n\ + OSTYPE The version of Unix this version of Bash is running on.\n\ + PATH A colon-separated list of directories to search when\n\ + looking for commands.\n\ + PROMPT_COMMAND A command to be executed before the printing of each\n\ + primary prompt.\n\ + PS1 The primary prompt string.\n\ + PS2 The secondary prompt string.\n\ + PWD The full pathname of the current directory.\n\ + SHELLOPTS A colon-separated list of enabled shell options.\n\ + TERM The name of the current terminal type.\n\ + TIMEFORMAT The output format for timing statistics displayed by the\n\ + `time' reserved word.\n\ + auto_resume Non-null means a command word appearing on a line by\n\ + itself is first looked for in the list of currently\n\ + stopped jobs. If found there, that job is foregrounded.\n\ + A value of `exact' means that the command word must\n\ + exactly match a command in the list of stopped jobs. A\n\ + value of `substring' means that the command word must\n\ + match a substring of the job. Any other value means that\n\ + the command must be a prefix of a stopped job.\n\ + histchars Characters controlling history expansion and quick\n\ + substitution. The first character is the history\n\ + substitution character, usually `!'. The second is\n\ + the `quick substitution' character, usually `^'. The\n\ + third is the `history comment' character, usually `#'.\n\ + HISTIGNORE A colon-separated list of patterns used to decide which\n\ + commands should be saved on the history list.\n\ +"), +#endif /* HELP_BUILTIN */ + (char *)NULL +}; +#if defined (PUSHD_AND_POPD) +char * const pushd_doc[] = { +#if defined (HELP_BUILTIN) +N_("Add directories to stack.\n\ + \n\ + Adds a directory to the top of the directory stack, or rotates\n\ + the stack, making the new top of the stack the current working\n\ + directory. With no arguments, exchanges the top two directories.\n\ + \n\ + Options:\n\ + -n Suppresses the normal change of directory when adding\n\ + directories to the stack, so only the stack is manipulated.\n\ + \n\ + Arguments:\n\ + +N Rotates the stack so that the Nth directory (counting\n\ + from the left of the list shown by `dirs', starting with\n\ + zero) is at the top.\n\ + \n\ + -N Rotates the stack so that the Nth directory (counting\n\ + from the right of the list shown by `dirs', starting with\n\ + zero) is at the top.\n\ + \n\ + dir Adds DIR to the directory stack at the top, making it the\n\ + new current working directory.\n\ + \n\ + The `dirs' builtin displays the directory stack.\n\ + \n\ + Exit Status:\n\ + Returns success unless an invalid argument is supplied or the directory\n\ + change fails."), +#endif /* HELP_BUILTIN */ + (char *)NULL +}; +#endif /* PUSHD_AND_POPD */ +#if defined (PUSHD_AND_POPD) +char * const popd_doc[] = { +#if defined (HELP_BUILTIN) +N_("Remove directories from stack.\n\ + \n\ + Removes entries from the directory stack. With no arguments, removes\n\ + the top directory from the stack, and changes to the new top directory.\n\ + \n\ + Options:\n\ + -n Suppresses the normal change of directory when removing\n\ + directories from the stack, so only the stack is manipulated.\n\ + \n\ + Arguments:\n\ + +N Removes the Nth entry counting from the left of the list\n\ + shown by `dirs', starting with zero. For example: `popd +0'\n\ + removes the first directory, `popd +1' the second.\n\ + \n\ + -N Removes the Nth entry counting from the right of the list\n\ + shown by `dirs', starting with zero. For example: `popd -0'\n\ + removes the last directory, `popd -1' the next to last.\n\ + \n\ + The `dirs' builtin displays the directory stack.\n\ + \n\ + Exit Status:\n\ + Returns success unless an invalid argument is supplied or the directory\n\ + change fails."), +#endif /* HELP_BUILTIN */ + (char *)NULL +}; +#endif /* PUSHD_AND_POPD */ +#if defined (PUSHD_AND_POPD) +char * const dirs_doc[] = { +#if defined (HELP_BUILTIN) +N_("Display directory stack.\n\ + \n\ + Display the list of currently remembered directories. Directories\n\ + find their way onto the list with the `pushd' command; you can get\n\ + back up through the list with the `popd' command.\n\ + \n\ + Options:\n\ + -c clear the directory stack by deleting all of the elements\n\ + -l do not print tilde-prefixed versions of directories relative\n\ + to your home directory\n\ + -p print the directory stack with one entry per line\n\ + -v print the directory stack with one entry per line prefixed\n\ + with its position in the stack\n\ + \n\ + Arguments:\n\ + +N Displays the Nth entry counting from the left of the list\n\ + shown by dirs when invoked without options, starting with\n\ + zero.\n\ + \n\ + -N Displays the Nth entry counting from the right of the list\n\ + shown by dirs when invoked without options, starting with\n\ + zero.\n\ + \n\ + Exit Status:\n\ + Returns success unless an invalid option is supplied or an error occurs."), +#endif /* HELP_BUILTIN */ + (char *)NULL +}; +#endif /* PUSHD_AND_POPD */ +char * const shopt_doc[] = { +#if defined (HELP_BUILTIN) +N_("Set and unset shell options.\n\ + \n\ + Change the setting of each shell option OPTNAME. Without any option\n\ + arguments, list each supplied OPTNAME, or all shell options if no\n\ + OPTNAMEs are given, with an indication of whether or not each is set.\n\ + \n\ + Options:\n\ + -o restrict OPTNAMEs to those defined for use with `set -o'\n\ + -p print each shell option with an indication of its status\n\ + -q suppress output\n\ + -s enable (set) each OPTNAME\n\ + -u disable (unset) each OPTNAME\n\ + \n\ + Exit Status:\n\ + Returns success if OPTNAME is enabled; fails if an invalid option is\n\ + given or OPTNAME is disabled."), +#endif /* HELP_BUILTIN */ + (char *)NULL +}; +char * const printf_doc[] = { +#if defined (HELP_BUILTIN) +N_("Formats and prints ARGUMENTS under control of the FORMAT.\n\ + \n\ + Options:\n\ + -v var assign the output to shell variable VAR rather than\n\ + display it on the standard output\n\ + \n\ + FORMAT is a character string which contains three types of objects: plain\n\ + characters, which are simply copied to standard output; character escape\n\ + sequences, which are converted and copied to the standard output; and\n\ + format specifications, each of which causes printing of the next successive\n\ + argument.\n\ + \n\ + In addition to the standard format specifications described in printf(1),\n\ + printf interprets:\n\ + \n\ + %b expand backslash escape sequences in the corresponding argument\n\ + %q quote the argument in a way that can be reused as shell input\n\ + %(fmt)T output the date-time string resulting from using FMT as a format\n\ + string for strftime(3)\n\ + \n\ + The format is re-used as necessary to consume all of the arguments. If\n\ + there are fewer arguments than the format requires, extra format\n\ + specifications behave as if a zero value or null string, as appropriate,\n\ + had been supplied.\n\ + \n\ + Exit Status:\n\ + Returns success unless an invalid option is given or a write or assignment\n\ + error occurs."), +#endif /* HELP_BUILTIN */ + (char *)NULL +}; +#if defined (PROGRAMMABLE_COMPLETION) +char * const complete_doc[] = { +#if defined (HELP_BUILTIN) +N_("Specify how arguments are to be completed by Readline.\n\ + \n\ + For each NAME, specify how arguments are to be completed. If no options\n\ + are supplied, existing completion specifications are printed in a way that\n\ + allows them to be reused as input.\n\ + \n\ + Options:\n\ + -p print existing completion specifications in a reusable format\n\ + -r remove a completion specification for each NAME, or, if no\n\ + NAMEs are supplied, all completion specifications\n\ + -D apply the completions and actions as the default for commands\n\ + without any specific completion defined\n\ + -E apply the completions and actions to \"empty\" commands --\n\ + completion attempted on a blank line\n\ + -I apply the completions and actions to the initial (usually the\n\ + command) word\n\ + \n\ + When completion is attempted, the actions are applied in the order the\n\ + uppercase-letter options are listed above. If multiple options are supplied,\n\ + the -D option takes precedence over -E, and both take precedence over -I.\n\ + \n\ + Exit Status:\n\ + Returns success unless an invalid option is supplied or an error occurs."), +#endif /* HELP_BUILTIN */ + (char *)NULL +}; +#endif /* PROGRAMMABLE_COMPLETION */ +#if defined (PROGRAMMABLE_COMPLETION) +char * const compgen_doc[] = { +#if defined (HELP_BUILTIN) +N_("Display possible completions depending on the options.\n\ + \n\ + Intended to be used from within a shell function generating possible\n\ + completions. If the optional WORD argument is supplied, matches against\n\ + WORD are generated.\n\ + \n\ + Exit Status:\n\ + Returns success unless an invalid option is supplied or an error occurs."), +#endif /* HELP_BUILTIN */ + (char *)NULL +}; +#endif /* PROGRAMMABLE_COMPLETION */ +#if defined (PROGRAMMABLE_COMPLETION) +char * const compopt_doc[] = { +#if defined (HELP_BUILTIN) +N_("Modify or display completion options.\n\ + \n\ + Modify the completion options for each NAME, or, if no NAMEs are supplied,\n\ + the completion currently being executed. If no OPTIONs are given, print\n\ + the completion options for each NAME or the current completion specification.\n\ + \n\ + Options:\n\ + -o option Set completion option OPTION for each NAME\n\ + -D Change options for the \"default\" command completion\n\ + -E Change options for the \"empty\" command completion\n\ + -I Change options for completion on the initial word\n\ + \n\ + Using `+o' instead of `-o' turns off the specified option.\n\ + \n\ + Arguments:\n\ + \n\ + Each NAME refers to a command for which a completion specification must\n\ + have previously been defined using the `complete' builtin. If no NAMEs\n\ + are supplied, compopt must be called by a function currently generating\n\ + completions, and the options for that currently-executing completion\n\ + generator are modified.\n\ + \n\ + Exit Status:\n\ + Returns success unless an invalid option is supplied or NAME does not\n\ + have a completion specification defined."), +#endif /* HELP_BUILTIN */ + (char *)NULL +}; +#endif /* PROGRAMMABLE_COMPLETION */ +char * const mapfile_doc[] = { +#if defined (HELP_BUILTIN) +N_("Read lines from the standard input into an indexed array variable.\n\ + \n\ + Read lines from the standard input into the indexed array variable ARRAY, or\n\ + from file descriptor FD if the -u option is supplied. The variable MAPFILE\n\ + is the default ARRAY.\n\ + \n\ + Options:\n\ + -d delim Use DELIM to terminate lines, instead of newline\n\ + -n count Copy at most COUNT lines. If COUNT is 0, all lines are copied\n\ + -O origin Begin assigning to ARRAY at index ORIGIN. The default index is 0\n\ + -s count Discard the first COUNT lines read\n\ + -t Remove a trailing DELIM from each line read (default newline)\n\ + -u fd Read lines from file descriptor FD instead of the standard input\n\ + -C callback Evaluate CALLBACK each time QUANTUM lines are read\n\ + -c quantum Specify the number of lines read between each call to\n\ + CALLBACK\n\ + \n\ + Arguments:\n\ + ARRAY Array variable name to use for file data\n\ + \n\ + If -C is supplied without -c, the default quantum is 5000. When\n\ + CALLBACK is evaluated, it is supplied the index of the next array\n\ + element to be assigned and the line to be assigned to that element\n\ + as additional arguments.\n\ + \n\ + If not supplied with an explicit origin, mapfile will clear ARRAY before\n\ + assigning to it.\n\ + \n\ + Exit Status:\n\ + Returns success unless an invalid option is given or ARRAY is readonly or\n\ + not an indexed array."), +#endif /* HELP_BUILTIN */ + (char *)NULL +}; +char * const readarray_doc[] = { +#if defined (HELP_BUILTIN) +N_("Read lines from a file into an array variable.\n\ + \n\ + A synonym for `mapfile'."), +#endif /* HELP_BUILTIN */ + (char *)NULL +}; diff --git a/builtins/tmpbuiltins.h b/builtins/tmpbuiltins.h new file mode 100644 index 0000000..b2ac3aa --- /dev/null +++ b/builtins/tmpbuiltins.h @@ -0,0 +1,188 @@ +/* tmpbuiltins.h - The list of builtins found in libbuiltins.a. */ +#if defined (ALIAS) +extern int alias_builtin PARAMS((WORD_LIST *)); +extern char * const alias_doc[]; +#endif /* ALIAS */ +#if defined (ALIAS) +extern int unalias_builtin PARAMS((WORD_LIST *)); +extern char * const unalias_doc[]; +#endif /* ALIAS */ +#if defined (READLINE) +extern int bind_builtin PARAMS((WORD_LIST *)); +extern char * const bind_doc[]; +#endif /* READLINE */ +extern int break_builtin PARAMS((WORD_LIST *)); +extern char * const break_doc[]; +extern int continue_builtin PARAMS((WORD_LIST *)); +extern char * const continue_doc[]; +extern int builtin_builtin PARAMS((WORD_LIST *)); +extern char * const builtin_doc[]; +#if defined (DEBUGGER) +extern int caller_builtin PARAMS((WORD_LIST *)); +extern char * const caller_doc[]; +#endif /* DEBUGGER */ +extern int cd_builtin PARAMS((WORD_LIST *)); +extern char * const cd_doc[]; +extern int pwd_builtin PARAMS((WORD_LIST *)); +extern char * const pwd_doc[]; +extern int colon_builtin PARAMS((WORD_LIST *)); +extern char * const colon_doc[]; +extern int colon_builtin PARAMS((WORD_LIST *)); +extern char * const true_doc[]; +extern int false_builtin PARAMS((WORD_LIST *)); +extern char * const false_doc[]; +extern int command_builtin PARAMS((WORD_LIST *)); +extern char * const command_doc[]; +extern int declare_builtin PARAMS((WORD_LIST *)); +extern char * const declare_doc[]; +extern int declare_builtin PARAMS((WORD_LIST *)); +extern char * const typeset_doc[]; +extern int local_builtin PARAMS((WORD_LIST *)); +extern char * const local_doc[]; +#if defined (V9_ECHO) +extern int echo_builtin PARAMS((WORD_LIST *)); +extern char * const echo_doc[]; +#endif /* V9_ECHO */ +#if !defined (V9_ECHO) +extern int echo_builtin PARAMS((WORD_LIST *)); +extern char * const echo_doc[]; +#endif /* !V9_ECHO */ +extern int enable_builtin PARAMS((WORD_LIST *)); +extern char * const enable_doc[]; +extern int eval_builtin PARAMS((WORD_LIST *)); +extern char * const eval_doc[]; +extern int getopts_builtin PARAMS((WORD_LIST *)); +extern char * const getopts_doc[]; +extern int exec_builtin PARAMS((WORD_LIST *)); +extern char * const exec_doc[]; +extern int exit_builtin PARAMS((WORD_LIST *)); +extern char * const exit_doc[]; +extern int logout_builtin PARAMS((WORD_LIST *)); +extern char * const logout_doc[]; +#if defined (HISTORY) +extern int fc_builtin PARAMS((WORD_LIST *)); +extern char * const fc_doc[]; +#endif /* HISTORY */ +#if defined (JOB_CONTROL) +extern int fg_builtin PARAMS((WORD_LIST *)); +extern char * const fg_doc[]; +#endif /* JOB_CONTROL */ +#if defined (JOB_CONTROL) +extern int bg_builtin PARAMS((WORD_LIST *)); +extern char * const bg_doc[]; +#endif /* JOB_CONTROL */ +extern int hash_builtin PARAMS((WORD_LIST *)); +extern char * const hash_doc[]; +#if defined (HELP_BUILTIN) +extern int help_builtin PARAMS((WORD_LIST *)); +extern char * const help_doc[]; +#endif /* HELP_BUILTIN */ +#if defined (HISTORY) +extern int history_builtin PARAMS((WORD_LIST *)); +extern char * const history_doc[]; +#endif /* HISTORY */ +#if defined (JOB_CONTROL) +extern int jobs_builtin PARAMS((WORD_LIST *)); +extern char * const jobs_doc[]; +#endif /* JOB_CONTROL */ +#if defined (JOB_CONTROL) +extern int disown_builtin PARAMS((WORD_LIST *)); +extern char * const disown_doc[]; +#endif /* JOB_CONTROL */ +extern int kill_builtin PARAMS((WORD_LIST *)); +extern char * const kill_doc[]; +extern int let_builtin PARAMS((WORD_LIST *)); +extern char * const let_doc[]; +extern int read_builtin PARAMS((WORD_LIST *)); +extern char * const read_doc[]; +extern int return_builtin PARAMS((WORD_LIST *)); +extern char * const return_doc[]; +extern int set_builtin PARAMS((WORD_LIST *)); +extern char * const set_doc[]; +extern int unset_builtin PARAMS((WORD_LIST *)); +extern char * const unset_doc[]; +extern int export_builtin PARAMS((WORD_LIST *)); +extern char * const export_doc[]; +extern int readonly_builtin PARAMS((WORD_LIST *)); +extern char * const readonly_doc[]; +extern int shift_builtin PARAMS((WORD_LIST *)); +extern char * const shift_doc[]; +extern int source_builtin PARAMS((WORD_LIST *)); +extern char * const source_doc[]; +extern int source_builtin PARAMS((WORD_LIST *)); +extern char * const dot_doc[]; +#if defined (JOB_CONTROL) +extern int suspend_builtin PARAMS((WORD_LIST *)); +extern char * const suspend_doc[]; +#endif /* JOB_CONTROL */ +extern int test_builtin PARAMS((WORD_LIST *)); +extern char * const test_doc[]; +extern int test_builtin PARAMS((WORD_LIST *)); +extern char * const test_bracket_doc[]; +extern int times_builtin PARAMS((WORD_LIST *)); +extern char * const times_doc[]; +extern int trap_builtin PARAMS((WORD_LIST *)); +extern char * const trap_doc[]; +extern int type_builtin PARAMS((WORD_LIST *)); +extern char * const type_doc[]; +#if !defined (_MINIX) +extern int ulimit_builtin PARAMS((WORD_LIST *)); +extern char * const ulimit_doc[]; +#endif /* !_MINIX */ +extern int umask_builtin PARAMS((WORD_LIST *)); +extern char * const umask_doc[]; +#if defined (JOB_CONTROL) +extern int wait_builtin PARAMS((WORD_LIST *)); +extern char * const wait_doc[]; +#endif /* JOB_CONTROL */ +#if !defined (JOB_CONTROL) +extern int wait_builtin PARAMS((WORD_LIST *)); +extern char * const wait_doc[]; +#endif /* !JOB_CONTROL */ +extern char * const for_doc[]; +extern char * const arith_for_doc[]; +extern char * const select_doc[]; +extern char * const time_doc[]; +extern char * const case_doc[]; +extern char * const if_doc[]; +extern char * const while_doc[]; +extern char * const until_doc[]; +extern char * const coproc_doc[]; +extern char * const function_doc[]; +extern char * const grouping_braces_doc[]; +extern char * const fg_percent_doc[]; +extern char * const arith_doc[]; +extern char * const conditional_doc[]; +extern char * const variable_help_doc[]; +#if defined (PUSHD_AND_POPD) +extern int pushd_builtin PARAMS((WORD_LIST *)); +extern char * const pushd_doc[]; +#endif /* PUSHD_AND_POPD */ +#if defined (PUSHD_AND_POPD) +extern int popd_builtin PARAMS((WORD_LIST *)); +extern char * const popd_doc[]; +#endif /* PUSHD_AND_POPD */ +#if defined (PUSHD_AND_POPD) +extern int dirs_builtin PARAMS((WORD_LIST *)); +extern char * const dirs_doc[]; +#endif /* PUSHD_AND_POPD */ +extern int shopt_builtin PARAMS((WORD_LIST *)); +extern char * const shopt_doc[]; +extern int printf_builtin PARAMS((WORD_LIST *)); +extern char * const printf_doc[]; +#if defined (PROGRAMMABLE_COMPLETION) +extern int complete_builtin PARAMS((WORD_LIST *)); +extern char * const complete_doc[]; +#endif /* PROGRAMMABLE_COMPLETION */ +#if defined (PROGRAMMABLE_COMPLETION) +extern int compgen_builtin PARAMS((WORD_LIST *)); +extern char * const compgen_doc[]; +#endif /* PROGRAMMABLE_COMPLETION */ +#if defined (PROGRAMMABLE_COMPLETION) +extern int compopt_builtin PARAMS((WORD_LIST *)); +extern char * const compopt_doc[]; +#endif /* PROGRAMMABLE_COMPLETION */ +extern int mapfile_builtin PARAMS((WORD_LIST *)); +extern char * const mapfile_doc[]; +extern int mapfile_builtin PARAMS((WORD_LIST *)); +extern char * const readarray_doc[]; diff --git a/builtins/trap.c b/builtins/trap.c new file mode 100644 index 0000000..cfabbad --- /dev/null +++ b/builtins/trap.c @@ -0,0 +1,260 @@ +/* trap.c, created from trap.def. */ +#line 22 "./trap.def" + +#line 58 "./trap.def" + +#include + +#if defined (HAVE_UNISTD_H) +# ifdef _MINIX +# include +# endif +# include +#endif + +#include "../bashtypes.h" +#include +#include +#include "../bashansi.h" + +#include "../shell.h" +#include "../trap.h" +#include "common.h" +#include "bashgetopt.h" + +static void showtrap PARAMS((int, int)); +static int display_traps PARAMS((WORD_LIST *, int)); + +/* The trap command: + + trap + trap + trap -l + trap -p [sigspec ...] + trap [--] + + Set things up so that ARG is executed when SIGNAL(s) N is received. + If ARG is the empty string, then ignore the SIGNAL(s). If there is + no ARG, then set the trap for SIGNAL(s) to its original value. Just + plain "trap" means to print out the list of commands associated with + each signal number. Single arg of "-l" means list the signal names. */ + +/* Possible operations to perform on the list of signals.*/ +#define SET 0 /* Set this signal to first_arg. */ +#define REVERT 1 /* Revert to this signals original value. */ +#define IGNORE 2 /* Ignore this signal. */ + +int +trap_builtin (list) + WORD_LIST *list; +{ + int list_signal_names, display, result, opt; + + list_signal_names = display = 0; + result = EXECUTION_SUCCESS; + + reset_internal_getopt (); + while ((opt = internal_getopt (list, "lp")) != -1) + { + switch (opt) + { + case 'l': + list_signal_names++; + break; + case 'p': + display++; + break; + CASE_HELPOPT; + default: + builtin_usage (); + return (EX_USAGE); + } + } + list = loptend; + + opt = DSIG_NOCASE|DSIG_SIGPREFIX; /* flags for decode_signal */ + + if (list_signal_names) + return (sh_chkwrite (display_signal_list ((WORD_LIST *)NULL, 1))); + else if (display || list == 0) + { + initialize_terminating_signals (); + get_all_original_signals (); + return (sh_chkwrite (display_traps (list, display && posixly_correct))); + } + else + { + char *first_arg; + int operation, sig, first_signal; + + operation = SET; + first_arg = list->word->word; + first_signal = first_arg && *first_arg && all_digits (first_arg) && signal_object_p (first_arg, opt); + + /* Backwards compatibility. XXX - question about whether or not we + should throw an error if an all-digit argument doesn't correspond + to a valid signal number (e.g., if it's `50' on a system with only + 32 signals). */ + if (first_signal) + operation = REVERT; + /* When in posix mode, the historical behavior of looking for a + missing first argument is disabled. To revert to the original + signal handling disposition, use `-' as the first argument. */ + else if (posixly_correct == 0 && first_arg && *first_arg && + (*first_arg != '-' || first_arg[1]) && + signal_object_p (first_arg, opt) && list->next == 0) + operation = REVERT; + else + { + list = list->next; + if (list == 0) + { + builtin_usage (); + return (EX_USAGE); + } + else if (*first_arg == '\0') + operation = IGNORE; + else if (first_arg[0] == '-' && !first_arg[1]) + operation = REVERT; + } + + /* If we're in a command substitution, we haven't freed the trap strings + (though we reset the signal handlers). If we're setting a trap to + handle a signal here, free the rest of the trap strings since they + don't apply any more. */ + if (subshell_environment & SUBSHELL_RESETTRAP) + { + free_trap_strings (); + subshell_environment &= ~SUBSHELL_RESETTRAP; + } + + while (list) + { + sig = decode_signal (list->word->word, opt); + + if (sig == NO_SIG) + { + sh_invalidsig (list->word->word); + result = EXECUTION_FAILURE; + } + else + { + switch (operation) + { + case SET: + set_signal (sig, first_arg); + break; + + case REVERT: + restore_default_signal (sig); + + /* Signals that the shell treats specially need special + handling. */ + switch (sig) + { + case SIGINT: + /* XXX - should we do this if original disposition + was SIG_IGN? */ + if (interactive) + set_signal_handler (SIGINT, sigint_sighandler); + /* special cases for interactive == 0 */ + else if (interactive_shell && (sourcelevel||running_trap||parse_and_execute_level)) + set_signal_handler (SIGINT, sigint_sighandler); + else + set_signal_handler (SIGINT, termsig_sighandler); + break; + + case SIGQUIT: + /* Always ignore SIGQUIT. */ + set_signal_handler (SIGQUIT, SIG_IGN); + break; + case SIGTERM: +#if defined (JOB_CONTROL) + case SIGTTIN: + case SIGTTOU: + case SIGTSTP: +#endif /* JOB_CONTROL */ + if (interactive) + set_signal_handler (sig, SIG_IGN); + break; + } + break; + + case IGNORE: + ignore_signal (sig); + break; + } + } + list = list->next; + } + } + + return (result); +} + +static void +showtrap (i, show_default) + int i, show_default; +{ + char *t, *p, *sn; + + p = trap_list[i]; + if (p == (char *)DEFAULT_SIG && signal_is_hard_ignored (i) == 0) + { + if (show_default) + t = "-"; + else + return; + } + else if (signal_is_hard_ignored (i)) + t = (char *)NULL; + else + t = (p == (char *)IGNORE_SIG) ? (char *)NULL : sh_single_quote (p); + + sn = signal_name (i); + /* Make sure that signals whose names are unknown (for whatever reason) + are printed as signal numbers. */ + if (STREQN (sn, "SIGJUNK", 7) || STREQN (sn, "unknown", 7)) + printf ("trap -- %s %d\n", t ? t : "''", i); + else if (posixly_correct) + { + if (STREQN (sn, "SIG", 3)) + printf ("trap -- %s %s\n", t ? t : "''", sn+3); + else + printf ("trap -- %s %s\n", t ? t : "''", sn); + } + else + printf ("trap -- %s %s\n", t ? t : "''", sn); + + if (show_default == 0) + FREE (t); +} + +static int +display_traps (list, show_all) + WORD_LIST *list; + int show_all; +{ + int result, i; + + if (list == 0) + { + for (i = 0; i < BASH_NSIG; i++) + showtrap (i, show_all); + return (EXECUTION_SUCCESS); + } + + for (result = EXECUTION_SUCCESS; list; list = list->next) + { + i = decode_signal (list->word->word, DSIG_NOCASE|DSIG_SIGPREFIX); + if (i == NO_SIG) + { + sh_invalidsig (list->word->word); + result = EXECUTION_FAILURE; + } + else + showtrap (i, show_all); + } + + return (result); +} diff --git a/builtins/type.c b/builtins/type.c new file mode 100644 index 0000000..5c6b76b --- /dev/null +++ b/builtins/type.c @@ -0,0 +1,373 @@ +/* type.c, created from type.def. */ +#line 22 "./type.def" + +#line 52 "./type.def" + +#include + +#include "../bashtypes.h" +#include "posixstat.h" + +#if defined (HAVE_UNISTD_H) +# include +#endif + +#include +#include "../bashansi.h" +#include "../bashintl.h" + +#include "../shell.h" +#include "../parser.h" +#include "../execute_cmd.h" +#include "../findcmd.h" +#include "../hashcmd.h" + +#if defined (ALIAS) +#include "../alias.h" +#endif /* ALIAS */ + +#include "common.h" +#include "bashgetopt.h" + +extern int find_reserved_word PARAMS((char *)); + +/* For each word in LIST, find out what the shell is going to do with + it as a simple command. i.e., which file would this shell use to + execve, or if it is a builtin command, or an alias. Possible flag + arguments: + -t Returns the "type" of the object, one of + `alias', `keyword', `function', `builtin', + or `file'. + + -p Returns the pathname of the file if -type is + a file. + + -a Returns all occurrences of words, whether they + be a filename in the path, alias, function, + or builtin. + + -f Suppress shell function lookup, like `command'. + + -P Force a path search even in the presence of other + definitions. + + Order of evaluation: + alias + keyword + function + builtin + file + */ + +int +type_builtin (list) + WORD_LIST *list; +{ + int dflags, any_failed, opt; + WORD_LIST *this; + + if (list == 0) + return (EXECUTION_SUCCESS); + + dflags = CDESC_SHORTDESC; /* default */ + any_failed = 0; + + /* Handle the obsolescent `-type', `-path', and `-all' by prescanning + the arguments and converting those options to the form that + internal_getopt recognizes. Converts `--type', `--path', and `--all' + also. THIS SHOULD REALLY GO AWAY. */ + for (this = list; this && this->word->word[0] == '-'; this = this->next) + { + char *flag = &(this->word->word[1]); + + if (STREQ (flag, "type") || STREQ (flag, "-type")) + { + this->word->word[1] = 't'; + this->word->word[2] = '\0'; + } + else if (STREQ (flag, "path") || STREQ (flag, "-path")) + { + this->word->word[1] = 'p'; + this->word->word[2] = '\0'; + } + else if (STREQ (flag, "all") || STREQ (flag, "-all")) + { + this->word->word[1] = 'a'; + this->word->word[2] = '\0'; + } + } + + reset_internal_getopt (); + while ((opt = internal_getopt (list, "afptP")) != -1) + { + switch (opt) + { + case 'a': + dflags |= CDESC_ALL; + break; + case 'f': + dflags |= CDESC_NOFUNCS; + break; + case 'p': + dflags |= CDESC_PATH_ONLY; + dflags &= ~(CDESC_TYPE|CDESC_SHORTDESC); + break; + case 't': + dflags |= CDESC_TYPE; + dflags &= ~(CDESC_PATH_ONLY|CDESC_SHORTDESC); + break; + case 'P': /* shorthand for type -ap */ + dflags |= (CDESC_PATH_ONLY|CDESC_FORCE_PATH); + dflags &= ~(CDESC_TYPE|CDESC_SHORTDESC); + break; + CASE_HELPOPT; + default: + builtin_usage (); + return (EX_USAGE); + } + } + list = loptend; + + while (list) + { + int found; + + found = describe_command (list->word->word, dflags); + + if (!found && (dflags & (CDESC_PATH_ONLY|CDESC_TYPE)) == 0) + sh_notfound (list->word->word); + + any_failed += found == 0; + list = list->next; + } + + opt = (any_failed == 0) ? EXECUTION_SUCCESS : EXECUTION_FAILURE; + return (sh_chkwrite (opt)); +} + +/* + * Describe COMMAND as required by the type and command builtins. + * + * Behavior is controlled by DFLAGS. Flag values are + * CDESC_ALL print all descriptions of a command + * CDESC_SHORTDESC print the description for type and command -V + * CDESC_REUSABLE print in a format that may be reused as input + * CDESC_TYPE print the type for type -t + * CDESC_PATH_ONLY print the path for type -p + * CDESC_FORCE_PATH force a path search for type -P + * CDESC_NOFUNCS skip function lookup for type -f + * CDESC_ABSPATH convert to absolute path, no ./ prefix + * CDESC_STDPATH command -p standard path list + * + * CDESC_ALL says whether or not to look for all occurrences of COMMAND, or + * return after finding it once. + */ +int +describe_command (command, dflags) + char *command; + int dflags; +{ + int found, i, found_file, f, all; + char *full_path, *x, *pathlist; + SHELL_VAR *func; +#if defined (ALIAS) + alias_t *alias; +#endif + + all = (dflags & CDESC_ALL) != 0; + found = found_file = 0; + full_path = (char *)NULL; + +#if defined (ALIAS) + /* Command is an alias? */ + if (((dflags & CDESC_FORCE_PATH) == 0) && expand_aliases && (alias = find_alias (command))) + { + if (dflags & CDESC_TYPE) + puts ("alias"); + else if (dflags & CDESC_SHORTDESC) + printf (_("%s is aliased to `%s'\n"), command, alias->value); + else if (dflags & CDESC_REUSABLE) + { + x = sh_single_quote (alias->value); + printf ("alias %s=%s\n", command, x); + free (x); + } + + found = 1; + + if (all == 0) + return (1); + } +#endif /* ALIAS */ + + /* Command is a shell reserved word? */ + if (((dflags & CDESC_FORCE_PATH) == 0) && (i = find_reserved_word (command)) >= 0) + { + if (dflags & CDESC_TYPE) + puts ("keyword"); + else if (dflags & CDESC_SHORTDESC) + printf (_("%s is a shell keyword\n"), command); + else if (dflags & CDESC_REUSABLE) + printf ("%s\n", command); + + found = 1; + + if (all == 0) + return (1); + } + + /* Command is a function? */ + if (((dflags & (CDESC_FORCE_PATH|CDESC_NOFUNCS)) == 0) && (func = find_function (command))) + { + if (dflags & CDESC_TYPE) + puts ("function"); + else if (dflags & CDESC_SHORTDESC) + { + char *result; + + printf (_("%s is a function\n"), command); + + /* We're blowing away THE_PRINTED_COMMAND here... */ + + result = named_function_string (command, function_cell (func), FUNC_MULTILINE|FUNC_EXTERNAL); + printf ("%s\n", result); + } + else if (dflags & CDESC_REUSABLE) + printf ("%s\n", command); + + found = 1; + + if (all == 0) + return (1); + } + + /* Command is a builtin? */ + if (((dflags & CDESC_FORCE_PATH) == 0) && find_shell_builtin (command)) + { + if (dflags & CDESC_TYPE) + puts ("builtin"); + else if (dflags & CDESC_SHORTDESC) + { + if (posixly_correct && find_special_builtin (command) != 0) + printf (_("%s is a special shell builtin\n"), command); + else + printf (_("%s is a shell builtin\n"), command); + } + else if (dflags & CDESC_REUSABLE) + printf ("%s\n", command); + + found = 1; + + if (all == 0) + return (1); + } + + /* Command is a disk file? */ + /* If the command name given is already an absolute command, just + check to see if it is executable. */ + if (absolute_program (command)) + { + f = file_status (command); + if (f & FS_EXECABLE) + { + if (dflags & CDESC_TYPE) + puts ("file"); + else if (dflags & CDESC_SHORTDESC) + printf (_("%s is %s\n"), command, command); + else if (dflags & (CDESC_REUSABLE|CDESC_PATH_ONLY)) + printf ("%s\n", command); + + /* There's no use looking in the hash table or in $PATH, + because they're not consulted when an absolute program + name is supplied. */ + return (1); + } + } + + /* If the user isn't doing "-a", then we might care about + whether the file is present in our hash table. */ + if (all == 0 || (dflags & CDESC_FORCE_PATH)) + { + if (full_path = phash_search (command)) + { + if (dflags & CDESC_TYPE) + puts ("file"); + else if (dflags & CDESC_SHORTDESC) + printf (_("%s is hashed (%s)\n"), command, full_path); + else if (dflags & (CDESC_REUSABLE|CDESC_PATH_ONLY)) + printf ("%s\n", full_path); + + free (full_path); + return (1); + } + } + + /* Now search through $PATH. */ + while (1) + { + if (dflags & CDESC_STDPATH) /* command -p, all cannot be non-zero */ + { + pathlist = conf_standard_path (); + full_path = find_in_path (command, pathlist, FS_EXEC_PREFERRED|FS_NODIRS); + free (pathlist); + /* Will only go through this once, since all == 0 if STDPATH set */ + } + else if (all == 0) + full_path = find_user_command (command); + else + full_path = user_command_matches (command, FS_EXEC_ONLY, found_file); /* XXX - should that be FS_EXEC_PREFERRED? */ + + if (full_path == 0) + break; + + /* If we found the command as itself by looking through $PATH, it + probably doesn't exist. Check whether or not the command is an + executable file. If it's not, don't report a match. This is + the default posix mode behavior */ + if (STREQ (full_path, command) || posixly_correct) + { + f = file_status (full_path); + if ((f & FS_EXECABLE) == 0) + { + free (full_path); + full_path = (char *)NULL; + if (all == 0) + break; + } + else if (ABSPATH (full_path)) + ; /* placeholder; don't need to do anything yet */ + else if (dflags & (CDESC_REUSABLE|CDESC_PATH_ONLY|CDESC_SHORTDESC)) + { + f = MP_DOCWD | ((dflags & CDESC_ABSPATH) ? MP_RMDOT : 0); + x = sh_makepath ((char *)NULL, full_path, f); + free (full_path); + full_path = x; + } + } + /* If we require a full path and don't have one, make one */ + else if ((dflags & CDESC_ABSPATH) && ABSPATH (full_path) == 0) + { + x = sh_makepath ((char *)NULL, full_path, MP_DOCWD|MP_RMDOT); + free (full_path); + full_path = x; + } + + found_file++; + found = 1; + + if (dflags & CDESC_TYPE) + puts ("file"); + else if (dflags & CDESC_SHORTDESC) + printf (_("%s is %s\n"), command, full_path); + else if (dflags & (CDESC_REUSABLE|CDESC_PATH_ONLY)) + printf ("%s\n", full_path); + + free (full_path); + full_path = (char *)NULL; + + if (all == 0) + break; + } + + return (found); +} diff --git a/builtins/ulimit.c b/builtins/ulimit.c new file mode 100644 index 0000000..7e986d8 --- /dev/null +++ b/builtins/ulimit.c @@ -0,0 +1,732 @@ +/* ulimit.c, created from ulimit.def. */ +#line 22 "./ulimit.def" + +#line 73 "./ulimit.def" + +#if !defined (_MINIX) + +#include + +#include "../bashtypes.h" +#if defined (HAVE_SYS_PARAM_H) +# include +#endif + +#if defined (HAVE_UNISTD_H) +# include +#endif + +#include +#include + +#include "../bashintl.h" + +#include "../shell.h" +#include "common.h" +#include "bashgetopt.h" +#include "pipesize.h" + +#if !defined (errno) +extern int errno; +#endif + +/* For some reason, HPUX chose to make these definitions visible only if + _KERNEL is defined, so we define _KERNEL before including + and #undef it afterward. */ +#if defined (HAVE_RESOURCE) +# include +# if defined (HPUX) && defined (RLIMIT_NEEDS_KERNEL) +# define _KERNEL +# endif +# include +# if defined (HPUX) && defined (RLIMIT_NEEDS_KERNEL) +# undef _KERNEL +# endif +#elif defined (HAVE_SYS_TIMES_H) +# include +#endif + +#if defined (HAVE_LIMITS_H) +# include +#endif + +/* Check for the most basic symbols. If they aren't present, this + system's isn't very useful to us. */ +#if !defined (RLIMIT_FSIZE) || !defined (HAVE_GETRLIMIT) +# undef HAVE_RESOURCE +#endif + +#if !defined (HAVE_RESOURCE) && defined (HAVE_ULIMIT_H) +# include +#endif + +#if !defined (RLIMTYPE) +# define RLIMTYPE long +# define string_to_rlimtype(s) strtol(s, (char **)NULL, 10) +# define print_rlimtype(num, nl) printf ("%ld%s", num, nl ? "\n" : "") +#endif + +/* Alternate names */ + +/* Some systems use RLIMIT_NOFILE, others use RLIMIT_OFILE */ +#if defined (HAVE_RESOURCE) && defined (RLIMIT_OFILE) && !defined (RLIMIT_NOFILE) +# define RLIMIT_NOFILE RLIMIT_OFILE +#endif /* HAVE_RESOURCE && RLIMIT_OFILE && !RLIMIT_NOFILE */ + +#if defined (HAVE_RESOURCE) && defined (RLIMIT_POSIXLOCKS) && !defined (RLIMIT_LOCKS) +# define RLIMIT_LOCKS RLIMIT_POSIXLOCKS +#endif /* HAVE_RESOURCE && RLIMIT_POSIXLOCKS && !RLIMIT_LOCKS */ + +/* Some systems have these, some do not. */ +#ifdef RLIMIT_FSIZE +# define RLIMIT_FILESIZE RLIMIT_FSIZE +#else +# define RLIMIT_FILESIZE 256 +#endif + +#define RLIMIT_PIPESIZE 257 + +#ifdef RLIMIT_NOFILE +# define RLIMIT_OPENFILES RLIMIT_NOFILE +#else +# define RLIMIT_OPENFILES 258 +#endif + +#ifdef RLIMIT_VMEM +# define RLIMIT_VIRTMEM RLIMIT_VMEM +# define RLIMIT_VMBLKSZ 1024 +#else +# ifdef RLIMIT_AS +# define RLIMIT_VIRTMEM RLIMIT_AS +# define RLIMIT_VMBLKSZ 1024 +# else +# define RLIMIT_VIRTMEM 259 +# define RLIMIT_VMBLKSZ 1 +# endif +#endif + +#ifdef RLIMIT_NPROC +# define RLIMIT_MAXUPROC RLIMIT_NPROC +#else +# define RLIMIT_MAXUPROC 260 +#endif + +#if !defined (RLIMIT_PTHREAD) && defined (RLIMIT_NTHR) +# define RLIMIT_PTHREAD RLIMIT_NTHR +#endif + +#if !defined (RLIM_INFINITY) +# define RLIM_INFINITY 0x7fffffff +#endif + +#if !defined (RLIM_SAVED_CUR) +# define RLIM_SAVED_CUR RLIM_INFINITY +#endif + +#if !defined (RLIM_SAVED_MAX) +# define RLIM_SAVED_MAX RLIM_INFINITY +#endif + +#define LIMIT_HARD 0x01 +#define LIMIT_SOFT 0x02 + +/* "Blocks" are defined as 512 bytes when in Posix mode and 1024 bytes + otherwise. */ +#define POSIXBLK -2 + +#define BLOCKSIZE(x) (((x) == POSIXBLK) ? (posixly_correct ? 512 : 1024) : (x)) + +static int _findlim PARAMS((int)); + +static int ulimit_internal PARAMS((int, char *, int, int)); + +static int get_limit PARAMS((int, RLIMTYPE *, RLIMTYPE *)); +static int set_limit PARAMS((int, RLIMTYPE, int)); + +static void printone PARAMS((int, RLIMTYPE, int)); +static void print_all_limits PARAMS((int)); + +static int set_all_limits PARAMS((int, RLIMTYPE)); + +static int filesize PARAMS((RLIMTYPE *)); +static int pipesize PARAMS((RLIMTYPE *)); +static int getmaxuprc PARAMS((RLIMTYPE *)); +static int getmaxvm PARAMS((RLIMTYPE *, RLIMTYPE *)); + +typedef struct { + int option; /* The ulimit option for this limit. */ + int parameter; /* Parameter to pass to get_limit (). */ + int block_factor; /* Blocking factor for specific limit. */ + const char * const description; /* Descriptive string to output. */ + const char * const units; /* scale */ +} RESOURCE_LIMITS; + +static RESOURCE_LIMITS limits[] = { +#ifdef RLIMIT_NPTS + { 'P', RLIMIT_NPTS, 1, "number of pseudoterminals", (char *)NULL }, +#endif +#ifdef RLIMIT_RTTIME + { 'R', RLIMIT_RTTIME, 1, "real-time non-blocking time", "microseconds" }, +#endif +#ifdef RLIMIT_PTHREAD + { 'T', RLIMIT_PTHREAD, 1, "number of threads", (char *)NULL }, +#endif +#ifdef RLIMIT_SBSIZE + { 'b', RLIMIT_SBSIZE, 1, "socket buffer size", "bytes" }, +#endif +#ifdef RLIMIT_CORE + { 'c', RLIMIT_CORE, POSIXBLK, "core file size", "blocks" }, +#endif +#ifdef RLIMIT_DATA + { 'd', RLIMIT_DATA, 1024, "data seg size", "kbytes" }, +#endif +#ifdef RLIMIT_NICE + { 'e', RLIMIT_NICE, 1, "scheduling priority", (char *)NULL }, +#endif + { 'f', RLIMIT_FILESIZE, POSIXBLK, "file size", "blocks" }, +#ifdef RLIMIT_SIGPENDING + { 'i', RLIMIT_SIGPENDING, 1, "pending signals", (char *)NULL }, +#endif +#ifdef RLIMIT_KQUEUES + { 'k', RLIMIT_KQUEUES, 1, "max kqueues", (char *)NULL }, +#endif +#ifdef RLIMIT_MEMLOCK + { 'l', RLIMIT_MEMLOCK, 1024, "max locked memory", "kbytes" }, +#endif +#ifdef RLIMIT_RSS + { 'm', RLIMIT_RSS, 1024, "max memory size", "kbytes" }, +#endif /* RLIMIT_RSS */ + { 'n', RLIMIT_OPENFILES, 1, "open files", (char *)NULL}, + { 'p', RLIMIT_PIPESIZE, 512, "pipe size", "512 bytes" }, +#ifdef RLIMIT_MSGQUEUE + { 'q', RLIMIT_MSGQUEUE, 1, "POSIX message queues", "bytes" }, +#endif +#ifdef RLIMIT_RTPRIO + { 'r', RLIMIT_RTPRIO, 1, "real-time priority", (char *)NULL }, +#endif +#ifdef RLIMIT_STACK + { 's', RLIMIT_STACK, 1024, "stack size", "kbytes" }, +#endif +#ifdef RLIMIT_CPU + { 't', RLIMIT_CPU, 1, "cpu time", "seconds" }, +#endif /* RLIMIT_CPU */ + { 'u', RLIMIT_MAXUPROC, 1, "max user processes", (char *)NULL }, +#if defined (HAVE_RESOURCE) + { 'v', RLIMIT_VIRTMEM, RLIMIT_VMBLKSZ, "virtual memory", "kbytes" }, +#endif +#ifdef RLIMIT_SWAP + { 'w', RLIMIT_SWAP, 1024, "swap size", "kbytes" }, +#endif +#ifdef RLIMIT_LOCKS + { 'x', RLIMIT_LOCKS, 1, "file locks", (char *)NULL }, +#endif + { -1, -1, -1, (char *)NULL, (char *)NULL } +}; +#define NCMDS (sizeof(limits) / sizeof(limits[0])) + +typedef struct _cmd { + int cmd; + char *arg; +} ULCMD; + +static ULCMD *cmdlist; +static int ncmd; +static int cmdlistsz; + +#if !defined (HAVE_RESOURCE) && !defined (HAVE_ULIMIT) +long +ulimit (cmd, newlim) + int cmd; + long newlim; +{ + errno = EINVAL; + return -1; +} +#endif /* !HAVE_RESOURCE && !HAVE_ULIMIT */ + +static int +_findlim (opt) + int opt; +{ + register int i; + + for (i = 0; limits[i].option > 0; i++) + if (limits[i].option == opt) + return i; + return -1; +} + +static char optstring[4 + 2 * NCMDS]; + +/* Report or set limits associated with certain per-process resources. + See the help documentation in builtins.c for a full description. */ +int +ulimit_builtin (list) + register WORD_LIST *list; +{ + register char *s; + int c, limind, mode, opt, all_limits; + + mode = 0; + + all_limits = 0; + + /* Idea stolen from pdksh -- build option string the first time called. */ + if (optstring[0] == 0) + { + s = optstring; + *s++ = 'a'; *s++ = 'S'; *s++ = 'H'; + for (c = 0; limits[c].option > 0; c++) + { + *s++ = limits[c].option; + *s++ = ';'; + } + *s = '\0'; + } + + /* Initialize the command list. */ + if (cmdlistsz == 0) + cmdlist = (ULCMD *)xmalloc ((cmdlistsz = 16) * sizeof (ULCMD)); + ncmd = 0; + + reset_internal_getopt (); + while ((opt = internal_getopt (list, optstring)) != -1) + { + switch (opt) + { + case 'a': + all_limits++; + break; + + /* -S and -H are modifiers, not real options. */ + case 'S': + mode |= LIMIT_SOFT; + break; + + case 'H': + mode |= LIMIT_HARD; + break; + + CASE_HELPOPT; + case '?': + builtin_usage (); + return (EX_USAGE); + + default: + if (ncmd >= cmdlistsz) + cmdlist = (ULCMD *)xrealloc (cmdlist, (cmdlistsz *= 2) * sizeof (ULCMD)); + cmdlist[ncmd].cmd = opt; + cmdlist[ncmd++].arg = list_optarg; + break; + } + } + list = loptend; + + if (all_limits) + { +#ifdef NOTYET + if (list) /* setting */ + { + if (STREQ (list->word->word, "unlimited") == 0) + { + builtin_error (_("%s: invalid limit argument"), list->word->word); + return (EXECUTION_FAILURE); + } + return (set_all_limits (mode == 0 ? LIMIT_SOFT|LIMIT_HARD : mode, RLIM_INFINITY)); + } +#endif + print_all_limits (mode == 0 ? LIMIT_SOFT : mode); + return (sh_chkwrite (EXECUTION_SUCCESS)); + } + + /* default is `ulimit -f' */ + if (ncmd == 0) + { + cmdlist[ncmd].cmd = 'f'; + /* `ulimit something' is same as `ulimit -f something' */ + cmdlist[ncmd++].arg = list ? list->word->word : (char *)NULL; + if (list) + list = list->next; + } + + /* verify each command in the list. */ + for (c = 0; c < ncmd; c++) + { + limind = _findlim (cmdlist[c].cmd); + if (limind == -1) + { + builtin_error (_("`%c': bad command"), cmdlist[c].cmd); + return (EX_USAGE); + } + } + + for (c = 0; c < ncmd; c++) + if (ulimit_internal (cmdlist[c].cmd, cmdlist[c].arg, mode, ncmd > 1) == EXECUTION_FAILURE) + return (EXECUTION_FAILURE); + + return (EXECUTION_SUCCESS); +} + +static int +ulimit_internal (cmd, cmdarg, mode, multiple) + int cmd; + char *cmdarg; + int mode, multiple; +{ + int opt, limind, setting; + int block_factor; + RLIMTYPE soft_limit, hard_limit, real_limit, limit; + + setting = cmdarg != 0; + limind = _findlim (cmd); + if (mode == 0) + mode = setting ? (LIMIT_HARD|LIMIT_SOFT) : LIMIT_SOFT; + opt = get_limit (limind, &soft_limit, &hard_limit); + if (opt < 0) + { + builtin_error (_("%s: cannot get limit: %s"), limits[limind].description, + strerror (errno)); + return (EXECUTION_FAILURE); + } + + if (setting == 0) /* print the value of the specified limit */ + { + printone (limind, (mode & LIMIT_SOFT) ? soft_limit : hard_limit, multiple); + return (EXECUTION_SUCCESS); + } + + /* Setting the limit. */ + if (STREQ (cmdarg, "hard")) + real_limit = hard_limit; + else if (STREQ (cmdarg, "soft")) + real_limit = soft_limit; + else if (STREQ (cmdarg, "unlimited")) + real_limit = RLIM_INFINITY; + else if (all_digits (cmdarg)) + { + limit = string_to_rlimtype (cmdarg); + block_factor = BLOCKSIZE(limits[limind].block_factor); + real_limit = limit * block_factor; + + if ((real_limit / block_factor) != limit) + { + sh_erange (cmdarg, _("limit")); + return (EXECUTION_FAILURE); + } + } + else + { + sh_invalidnum (cmdarg); + return (EXECUTION_FAILURE); + } + + if (set_limit (limind, real_limit, mode) < 0) + { + builtin_error (_("%s: cannot modify limit: %s"), limits[limind].description, + strerror (errno)); + return (EXECUTION_FAILURE); + } + + return (EXECUTION_SUCCESS); +} + +static int +get_limit (ind, softlim, hardlim) + int ind; + RLIMTYPE *softlim, *hardlim; +{ + RLIMTYPE value; +#if defined (HAVE_RESOURCE) + struct rlimit limit; +#endif + + if (limits[ind].parameter >= 256) + { + switch (limits[ind].parameter) + { + case RLIMIT_FILESIZE: + if (filesize (&value) < 0) + return -1; + break; + case RLIMIT_PIPESIZE: + if (pipesize (&value) < 0) + return -1; + break; + case RLIMIT_OPENFILES: + value = (RLIMTYPE)getdtablesize (); + break; + case RLIMIT_VIRTMEM: + return (getmaxvm (softlim, hardlim)); + case RLIMIT_MAXUPROC: + if (getmaxuprc (&value) < 0) + return -1; + break; + default: + errno = EINVAL; + return -1; + } + *softlim = *hardlim = value; + return (0); + } + else + { +#if defined (HAVE_RESOURCE) + if (getrlimit (limits[ind].parameter, &limit) < 0) + return -1; + *softlim = limit.rlim_cur; + *hardlim = limit.rlim_max; +# if defined (HPUX9) + if (limits[ind].parameter == RLIMIT_FILESIZE) + { + *softlim *= 512; + *hardlim *= 512; /* Ugh. */ + } + else +# endif /* HPUX9 */ + return 0; +#else + errno = EINVAL; + return -1; +#endif + } +} + +static int +set_limit (ind, newlim, mode) + int ind; + RLIMTYPE newlim; + int mode; +{ +#if defined (HAVE_RESOURCE) + struct rlimit limit; + RLIMTYPE val; +#endif + + if (limits[ind].parameter >= 256) + switch (limits[ind].parameter) + { + case RLIMIT_FILESIZE: +#if !defined (HAVE_RESOURCE) + return (ulimit (2, newlim / 512L)); +#else + errno = EINVAL; + return -1; +#endif + + case RLIMIT_OPENFILES: +#if defined (HAVE_SETDTABLESIZE) +# if defined (__CYGWIN__) + /* Grrr... Cygwin declares setdtablesize as void. */ + setdtablesize (newlim); + return 0; +# else + return (setdtablesize (newlim)); +# endif +#endif + case RLIMIT_PIPESIZE: + case RLIMIT_VIRTMEM: + case RLIMIT_MAXUPROC: + default: + errno = EINVAL; + return -1; + } + else + { +#if defined (HAVE_RESOURCE) + if (getrlimit (limits[ind].parameter, &limit) < 0) + return -1; +# if defined (HPUX9) + if (limits[ind].parameter == RLIMIT_FILESIZE) + newlim /= 512; /* Ugh. */ +# endif /* HPUX9 */ + val = (current_user.euid != 0 && newlim == RLIM_INFINITY && + (mode & LIMIT_HARD) == 0 && /* XXX -- test */ + (limit.rlim_cur <= limit.rlim_max)) + ? limit.rlim_max : newlim; + if (mode & LIMIT_SOFT) + limit.rlim_cur = val; + if (mode & LIMIT_HARD) + limit.rlim_max = val; + + return (setrlimit (limits[ind].parameter, &limit)); +#else + errno = EINVAL; + return -1; +#endif + } +} + +static int +getmaxvm (softlim, hardlim) + RLIMTYPE *softlim, *hardlim; +{ +#if defined (HAVE_RESOURCE) + struct rlimit datalim, stacklim; + + if (getrlimit (RLIMIT_DATA, &datalim) < 0) + return -1; + + if (getrlimit (RLIMIT_STACK, &stacklim) < 0) + return -1; + + /* Protect against overflow. */ + *softlim = (datalim.rlim_cur / 1024L) + (stacklim.rlim_cur / 1024L); + *hardlim = (datalim.rlim_max / 1024L) + (stacklim.rlim_max / 1024L); + return 0; +#else + errno = EINVAL; + return -1; +#endif /* HAVE_RESOURCE */ +} + +static int +filesize(valuep) + RLIMTYPE *valuep; +{ +#if !defined (HAVE_RESOURCE) + long result; + if ((result = ulimit (1, 0L)) < 0) + return -1; + else + *valuep = (RLIMTYPE) result * 512; + return 0; +#else + errno = EINVAL; + return -1; +#endif +} + +static int +pipesize (valuep) + RLIMTYPE *valuep; +{ +#if defined (PIPE_BUF) + /* This is defined on Posix systems. */ + *valuep = (RLIMTYPE) PIPE_BUF; + return 0; +#else +# if defined (_POSIX_PIPE_BUF) + *valuep = (RLIMTYPE) _POSIX_PIPE_BUF; + return 0; +# else +# if defined (PIPESIZE) + /* This is defined by running a program from the Makefile. */ + *valuep = (RLIMTYPE) PIPESIZE; + return 0; +# else + errno = EINVAL; + return -1; +# endif /* PIPESIZE */ +# endif /* _POSIX_PIPE_BUF */ +#endif /* PIPE_BUF */ +} + +static int +getmaxuprc (valuep) + RLIMTYPE *valuep; +{ + long maxchild; + + maxchild = getmaxchild (); + if (maxchild < 0) + { + errno = EINVAL; + return -1; + } + else + { + *valuep = (RLIMTYPE) maxchild; + return 0; + } +} + +static void +print_all_limits (mode) + int mode; +{ + register int i; + RLIMTYPE softlim, hardlim; + + if (mode == 0) + mode |= LIMIT_SOFT; + + for (i = 0; limits[i].option > 0; i++) + { + if (get_limit (i, &softlim, &hardlim) == 0) + printone (i, (mode & LIMIT_SOFT) ? softlim : hardlim, 1); + else if (errno != EINVAL) + builtin_error ("%s: cannot get limit: %s", limits[i].description, + strerror (errno)); + } +} + +static void +printone (limind, curlim, pdesc) + int limind; + RLIMTYPE curlim; + int pdesc; +{ + char unitstr[64]; + int factor; + + factor = BLOCKSIZE(limits[limind].block_factor); + if (pdesc) + { + if (limits[limind].units) + sprintf (unitstr, "(%s, -%c) ", limits[limind].units, limits[limind].option); + else + sprintf (unitstr, "(-%c) ", limits[limind].option); + + printf ("%-20s %20s", limits[limind].description, unitstr); + } + if (curlim == RLIM_INFINITY) + puts ("unlimited"); + else if (curlim == RLIM_SAVED_MAX) + puts ("hard"); + else if (curlim == RLIM_SAVED_CUR) + puts ("soft"); + else + print_rlimtype ((curlim / factor), 1); +} + +/* Set all limits to NEWLIM. NEWLIM currently must be RLIM_INFINITY, which + causes all limits to be set as high as possible depending on mode (like + csh `unlimit'). Returns -1 if NEWLIM is invalid, 0 if all limits + were set successfully, and 1 if at least one limit could not be set. + + To raise all soft limits to their corresponding hard limits, use + ulimit -S -a unlimited + To attempt to raise all hard limits to infinity (superuser-only), use + ulimit -H -a unlimited + To attempt to raise all soft and hard limits to infinity, use + ulimit -a unlimited +*/ + +static int +set_all_limits (mode, newlim) + int mode; + RLIMTYPE newlim; +{ + register int i; + int retval = 0; + + if (newlim != RLIM_INFINITY) + { + errno = EINVAL; + return -1; + } + + if (mode == 0) + mode = LIMIT_SOFT|LIMIT_HARD; + + for (retval = i = 0; limits[i].option > 0; i++) + if (set_limit (i, newlim, mode) < 0) + { + builtin_error (_("%s: cannot modify limit: %s"), limits[i].description, + strerror (errno)); + retval = 1; + } + return retval; +} + +#endif /* !_MINIX */ diff --git a/builtins/umask.c b/builtins/umask.c new file mode 100644 index 0000000..84a92ca --- /dev/null +++ b/builtins/umask.c @@ -0,0 +1,281 @@ +/* umask.c, created from umask.def. */ +#line 22 "./umask.def" + +#line 41 "./umask.def" + +#include + +#include "../bashtypes.h" +#include "filecntl.h" +#if ! defined(_MINIX) && defined (HAVE_SYS_FILE_H) +# include +#endif + +#if defined (HAVE_UNISTD_H) +#include +#endif + +#include +#include + +#include "../bashintl.h" + +#include "../shell.h" +#include "posixstat.h" +#include "common.h" +#include "bashgetopt.h" + +/* **************************************************************** */ +/* */ +/* UMASK Builtin and Helpers */ +/* */ +/* **************************************************************** */ + +static void print_symbolic_umask PARAMS((mode_t)); +static int symbolic_umask PARAMS((WORD_LIST *)); + +/* Set or display the mask used by the system when creating files. Flag + of -S means display the umask in a symbolic mode. */ +int +umask_builtin (list) + WORD_LIST *list; +{ + int print_symbolically, opt, umask_value, pflag; + mode_t umask_arg; + + print_symbolically = pflag = 0; + reset_internal_getopt (); + while ((opt = internal_getopt (list, "Sp")) != -1) + { + switch (opt) + { + case 'S': + print_symbolically++; + break; + case 'p': + pflag++; + break; + CASE_HELPOPT; + default: + builtin_usage (); + return (EX_USAGE); + } + } + + list = loptend; + + if (list) + { + if (DIGIT (*list->word->word)) + { + umask_value = read_octal (list->word->word); + + /* Note that other shells just let you set the umask to zero + by specifying a number out of range. This is a problem + with those shells. We don't change the umask if the input + is lousy. */ + if (umask_value == -1) + { + sh_erange (list->word->word, _("octal number")); + return (EXECUTION_FAILURE); + } + } + else + { + umask_value = symbolic_umask (list); + if (umask_value == -1) + return (EXECUTION_FAILURE); + } + umask_arg = (mode_t)umask_value; + umask (umask_arg); + if (print_symbolically) + print_symbolic_umask (umask_arg); + } + else /* Display the UMASK for this user. */ + { + umask_arg = umask (022); + umask (umask_arg); + + if (pflag) + printf ("umask%s ", (print_symbolically ? " -S" : "")); + if (print_symbolically) + print_symbolic_umask (umask_arg); + else + printf ("%04lo\n", (unsigned long)umask_arg); + } + + return (sh_chkwrite (EXECUTION_SUCCESS)); +} + +/* Print the umask in a symbolic form. In the output, a letter is + printed if the corresponding bit is clear in the umask. */ +static void +#if defined (__STDC__) +print_symbolic_umask (mode_t um) +#else +print_symbolic_umask (um) + mode_t um; +#endif +{ + char ubits[4], gbits[4], obits[4]; /* u=rwx,g=rwx,o=rwx */ + int i; + + i = 0; + if ((um & S_IRUSR) == 0) + ubits[i++] = 'r'; + if ((um & S_IWUSR) == 0) + ubits[i++] = 'w'; + if ((um & S_IXUSR) == 0) + ubits[i++] = 'x'; + ubits[i] = '\0'; + + i = 0; + if ((um & S_IRGRP) == 0) + gbits[i++] = 'r'; + if ((um & S_IWGRP) == 0) + gbits[i++] = 'w'; + if ((um & S_IXGRP) == 0) + gbits[i++] = 'x'; + gbits[i] = '\0'; + + i = 0; + if ((um & S_IROTH) == 0) + obits[i++] = 'r'; + if ((um & S_IWOTH) == 0) + obits[i++] = 'w'; + if ((um & S_IXOTH) == 0) + obits[i++] = 'x'; + obits[i] = '\0'; + + printf ("u=%s,g=%s,o=%s\n", ubits, gbits, obits); +} + +int +parse_symbolic_mode (mode, initial_bits) + char *mode; + int initial_bits; +{ + int who, op, perm, bits, c; + char *s; + + for (s = mode, bits = initial_bits;;) + { + who = op = perm = 0; + + /* Parse the `who' portion of the symbolic mode clause. */ + while (member (*s, "agou")) + { + switch (c = *s++) + { + case 'u': + who |= S_IRWXU; + continue; + case 'g': + who |= S_IRWXG; + continue; + case 'o': + who |= S_IRWXO; + continue; + case 'a': + who |= S_IRWXU | S_IRWXG | S_IRWXO; + continue; + default: + break; + } + } + + /* The operation is now sitting in *s. */ + op = *s++; + switch (op) + { + case '+': + case '-': + case '=': + break; + default: + builtin_error (_("`%c': invalid symbolic mode operator"), op); + return (-1); + } + + /* Parse out the `perm' section of the symbolic mode clause. */ + while (member (*s, "rwx")) + { + c = *s++; + + switch (c) + { + case 'r': + perm |= S_IRUGO; + break; + case 'w': + perm |= S_IWUGO; + break; + case 'x': + perm |= S_IXUGO; + break; + } + } + + /* Now perform the operation or return an error for a + bad permission string. */ + if (!*s || *s == ',') + { + if (who) + perm &= who; + + switch (op) + { + case '+': + bits |= perm; + break; + case '-': + bits &= ~perm; + break; + case '=': + if (who == 0) + who = S_IRWXU | S_IRWXG | S_IRWXO; + bits &= ~who; + bits |= perm; + break; + + /* No other values are possible. */ + } + + if (*s == '\0') + break; + else + s++; /* skip past ',' */ + } + else + { + builtin_error (_("`%c': invalid symbolic mode character"), *s); + return (-1); + } + } + + return (bits); +} + +/* Set the umask from a symbolic mode string similar to that accepted + by chmod. If the -S argument is given, then print the umask in a + symbolic form. */ +static int +symbolic_umask (list) + WORD_LIST *list; +{ + int um, bits; + + /* Get the initial umask. Don't change it yet. */ + um = umask (022); + umask (um); + + /* All work is done with the complement of the umask -- it's + more intuitive and easier to deal with. It is complemented + again before being returned. */ + bits = parse_symbolic_mode (list->word->word, ~um & 0777); + if (bits == -1) + return (-1); + + um = ~bits & 0777; + return (um); +} diff --git a/builtins/wait.c b/builtins/wait.c new file mode 100644 index 0000000..ce7d44c --- /dev/null +++ b/builtins/wait.c @@ -0,0 +1,303 @@ +/* wait.c, created from wait.def. */ +#line 51 "./wait.def" + +#line 66 "./wait.def" + +#include + +#include "../bashtypes.h" +#include + +#if defined (HAVE_UNISTD_H) +# include +#endif + +#include + +#include "../bashansi.h" + +#include "../shell.h" +#include "../execute_cmd.h" +#include "../jobs.h" +#include "../trap.h" +#include "../sig.h" +#include "common.h" +#include "bashgetopt.h" + +extern int wait_signal_received; + +procenv_t wait_intr_buf; +int wait_intr_flag; + +static int set_waitlist PARAMS((WORD_LIST *)); +static void unset_waitlist PARAMS((void)); + +/* Wait for the pid in LIST to stop or die. If no arguments are given, then + wait for all of the active background processes of the shell and return + 0. If a list of pids or job specs are given, return the exit status of + the last one waited for. */ + +#define WAIT_RETURN(s) \ + do \ + { \ + wait_signal_received = 0; \ + wait_intr_flag = 0; \ + return (s);\ + } \ + while (0) + +int +wait_builtin (list) + WORD_LIST *list; +{ + int status, code, opt, nflag, wflags; + char *vname; + SHELL_VAR *pidvar; + struct procstat pstat; + + USE_VAR(list); + + nflag = wflags = 0; + vname = NULL; + pidvar = (SHELL_VAR *)NULL; + reset_internal_getopt (); + while ((opt = internal_getopt (list, "fnp:")) != -1) + { + switch (opt) + { +#if defined (JOB_CONTROL) + case 'n': + nflag = 1; + break; + case 'f': + wflags |= JWAIT_FORCE; + break; + case 'p': + vname = list_optarg; + break; +#endif + CASE_HELPOPT; + default: + builtin_usage (); + return (EX_USAGE); + } + } + list = loptend; + + /* Sanity-check variable name if -p supplied. */ + if (vname) + { +#if defined (ARRAY_VARS) + int arrayflags; + + arrayflags = assoc_expand_once ? (VA_NOEXPAND|VA_ONEWORD) : 0; + if (legal_identifier (vname) == 0 && valid_array_reference (vname, arrayflags) == 0) +#else + if (legal_identifier (vname) == 0) +#endif + { + sh_invalidid (vname); + WAIT_RETURN (EXECUTION_FAILURE); + } + if (builtin_unbind_variable (vname) == -2) + WAIT_RETURN (EXECUTION_FAILURE); + } + + /* POSIX.2 says: When the shell is waiting (by means of the wait utility) + for asynchronous commands to complete, the reception of a signal for + which a trap has been set shall cause the wait utility to return + immediately with an exit status greater than 128, after which the trap + associated with the signal shall be taken. + + We handle SIGINT here; it's the only one that needs to be treated + specially (I think), since it's handled specially in {no,}jobs.c. */ + wait_intr_flag = 1; + code = setjmp_sigs (wait_intr_buf); + + if (code) + { + last_command_exit_signal = wait_signal_received; + status = 128 + wait_signal_received; + wait_sigint_cleanup (); + WAIT_RETURN (status); + } + + opt = first_pending_trap (); +#if defined (SIGCHLD) + /* We special case SIGCHLD when not in posix mode because we don't break + out of the wait even when the signal is trapped; we run the trap after + the wait completes. See how it's handled in jobs.c:waitchld(). */ + if (opt == SIGCHLD && posixly_correct == 0) + opt = next_pending_trap (opt+1); +#endif + if (opt != -1) + { + last_command_exit_signal = wait_signal_received = opt; + status = opt + 128; + WAIT_RETURN (status); + } + + /* We support jobs or pids. + wait [pid-or-job ...] */ + +#if defined (JOB_CONTROL) + if (nflag) + { + if (list) + { + opt = set_waitlist (list); + if (opt == 0) + WAIT_RETURN (127); + wflags |= JWAIT_WAITING; + } + + status = wait_for_any_job (wflags, &pstat); + if (status < 0) + status = 127; + + if (vname && status >= 0) + bind_var_to_int (vname, pstat.pid); + if (list) + unset_waitlist (); + WAIT_RETURN (status); + } +#endif + + /* But wait without any arguments means to wait for all of the shell's + currently active background processes. */ + if (list == 0) + { + wait_for_background_pids (&pstat); + if (vname) + bind_var_to_int (vname, pstat.pid); + WAIT_RETURN (EXECUTION_SUCCESS); + } + + status = EXECUTION_SUCCESS; + while (list) + { + pid_t pid; + char *w; + intmax_t pid_value; + + w = list->word->word; + if (DIGIT (*w)) + { + if (legal_number (w, &pid_value) && pid_value == (pid_t)pid_value) + { + pid = (pid_t)pid_value; + status = wait_for_single_pid (pid, wflags|JWAIT_PERROR); + pstat.pid = pid; + pstat.status = status; + } + else + { + sh_badpid (w); + pstat.pid = NO_PID; + pstat.status = 127; + WAIT_RETURN (EXECUTION_FAILURE); + } + } +#if defined (JOB_CONTROL) + else if (*w && *w == '%') + /* Must be a job spec. Check it out. */ + { + int job; + sigset_t set, oset; + + BLOCK_CHILD (set, oset); + job = get_job_spec (list); + + if (INVALID_JOB (job)) + { + if (job != DUP_JOB) + sh_badjob (list->word->word); + UNBLOCK_CHILD (oset); + status = 127; /* As per Posix.2, section 4.70.2 */ + pstat.pid = NO_PID; + pstat.status = status; + list = list->next; + continue; + } + + /* Job spec used. Wait for the last pid in the pipeline. */ + UNBLOCK_CHILD (oset); + status = wait_for_job (job, wflags, &pstat); + } +#endif /* JOB_CONTROL */ + else + { + sh_badpid (w); + pstat.pid = NO_PID; + pstat.status = 127; + status = EXECUTION_FAILURE; + } + + /* Don't waste time with a longjmp. */ + if (wait_signal_received) + { + last_command_exit_signal = wait_signal_received; + status = 128 + wait_signal_received; + wait_sigint_cleanup (); + WAIT_RETURN (status); + } + + list = list->next; + } + + WAIT_RETURN (status); +} + +#if defined (JOB_CONTROL) +/* Take each valid pid or jobspec in LIST and mark the corresponding job as + J_WAITING, so wait -n knows which jobs to wait for. Return the number of + jobs we found. */ +static int +set_waitlist (list) + WORD_LIST *list; +{ + sigset_t set, oset; + int job, r, njob; + intmax_t pid; + WORD_LIST *l; + + BLOCK_CHILD (set, oset); + njob = 0; + for (l = list; l; l = l->next) + { + job = NO_JOB; + job = (l && legal_number (l->word->word, &pid) && pid == (pid_t) pid) + ? get_job_by_pid ((pid_t) pid, 0, 0) + : get_job_spec (l); + if (job == NO_JOB || jobs == 0 || INVALID_JOB (job)) + { + sh_badjob (l->word->word); + continue; + } + /* We don't check yet to see if one of the desired jobs has already + terminated, but we could. We wait until wait_for_any_job(). This + has the advantage of validating all the arguments. */ + if ((jobs[job]->flags & J_WAITING) == 0) + { + njob++; + jobs[job]->flags |= J_WAITING; + } + } + UNBLOCK_CHILD (oset); + return (njob); +} + +/* Clean up after a call to wait -n jobs */ +static void +unset_waitlist () +{ + int i; + sigset_t set, oset; + + BLOCK_CHILD (set, oset); + for (i = 0; i < js.j_jobslots; i++) + if (jobs[i] && (jobs[i]->flags & J_WAITING)) + jobs[i]->flags &= ~J_WAITING; + UNBLOCK_CHILD (oset); +} +#endif diff --git a/config-top.h b/config-top.h index 735f75e..90a7dc1 100644 --- a/config-top.h +++ b/config-top.h @@ -173,7 +173,7 @@ #define SOURCENEST_MAX 0 /* Define to use libc mktemp/mkstemp instead of replacements in lib/sh/tmpfile.c */ -#define USE_MKTEMP +// #define USE_MKTEMP #define USE_MKSTEMP #define USE_MKDTEMP diff --git a/config.h b/config.h new file mode 100644 index 0000000..298d93c --- /dev/null +++ b/config.h @@ -0,0 +1,1236 @@ +/* config.h. Generated from config.h.in by configure. */ +/* config.h -- Configuration file for bash. */ + +/* Copyright (C) 1987-2009,2011-2012,2013-2019 Free Software Foundation, Inc. + + This file is part of GNU Bash, the Bourne Again SHell. + + Bash is free software: you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation, either version 3 of the License, or + (at your option) any later version. + + Bash is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with Bash. If not, see . +*/ + +#ifndef _CONFIG_H_ +#define _CONFIG_H_ + +/* Template settings for autoconf */ + +#define __EXTENSIONS__ 1 +#define _ALL_SOURCE 1 +#define _GNU_SOURCE 1 +/* #undef _POSIX_SOURCE */ +/* #undef _POSIX_1_SOURCE */ +#define _POSIX_PTHREAD_SEMANTICS 1 +#define _TANDEM_SOURCE 1 +/* #undef _MINIX */ + +/* Configuration feature settings controllable by autoconf. */ + +/* Define JOB_CONTROL if your operating system supports + BSD-like job control. */ +#define JOB_CONTROL 1 + +/* Define ALIAS if you want the alias features. */ +#define ALIAS 1 + +/* Define PUSHD_AND_POPD if you want those commands to be compiled in. + (Also the `dirs' commands.) */ +#define PUSHD_AND_POPD 1 + +/* Define BRACE_EXPANSION if you want curly brace expansion a la Csh: + foo{a,b} -> fooa foob. Even if this is compiled in (the default) you + can turn it off at shell startup with `-nobraceexpansion', or during + shell execution with `set +o braceexpand'. */ +#define BRACE_EXPANSION 1 + +/* Define READLINE to get the nifty/glitzy editing features. + This is on by default. You can turn it off interactively + with the -nolineediting flag. */ +#define READLINE 1 + +/* Define BANG_HISTORY if you want to have Csh style "!" history expansion. + This is unrelated to READLINE. */ +#define BANG_HISTORY 1 + +/* Define HISTORY if you want to have access to previously typed commands. + + If both HISTORY and READLINE are defined, you can get at the commands + with line editing commands, and you can directly manipulate the history + from the command line. + + If only HISTORY is defined, the `fc' and `history' builtins are + available. */ +#define HISTORY 1 + +/* Define this if you want completion that puts all alternatives into + a brace expansion shell expression. */ +#if defined (BRACE_EXPANSION) && defined (READLINE) +# define BRACE_COMPLETION +#endif /* BRACE_EXPANSION */ + +/* Define DEFAULT_ECHO_TO_XPG if you want the echo builtin to interpret + the backslash-escape characters by default, like the XPG Single Unix + Specification V2 for echo. + This requires that V9_ECHO be defined. */ +/* #undef DEFAULT_ECHO_TO_XPG */ + +/* Define HELP_BUILTIN if you want the `help' shell builtin and the long + documentation strings compiled into the shell. */ +#define HELP_BUILTIN 1 + +/* Define RESTRICTED_SHELL if you want the generated shell to have the + ability to be a restricted one. The shell thus generated can become + restricted by being run with the name "rbash", or by setting the -r + flag. */ +#define RESTRICTED_SHELL 1 + +/* Define DISABLED_BUILTINS if you want "builtin foo" to always run the + shell builtin "foo", even if it has been disabled with "enable -n foo". */ +/* #undef DISABLED_BUILTINS */ + +/* Define PROCESS_SUBSTITUTION if you want the K*rn shell-like process + substitution features "<(file)". */ +/* Right now, you cannot do this on machines without fully operational + FIFO support. This currently include NeXT and Alliant. */ +#define PROCESS_SUBSTITUTION 1 + +/* Define PROMPT_STRING_DECODE if you want the backslash-escaped special + characters in PS1 and PS2 expanded. Variable expansion will still be + performed. */ +#define PROMPT_STRING_DECODE 1 + +/* Define SELECT_COMMAND if you want the Korn-shell style `select' command: + select word in word_list; do command_list; done */ +#define SELECT_COMMAND 1 + +/* Define COMMAND_TIMING of you want the ksh-style `time' reserved word and + the ability to time pipelines, functions, and builtins. */ +#define COMMAND_TIMING 1 + +/* Define ARRAY_VARS if you want ksh-style one-dimensional array variables. */ +#define ARRAY_VARS 1 + +/* Define DPAREN_ARITHMETIC if you want the ksh-style ((...)) arithmetic + evaluation command. */ +#define DPAREN_ARITHMETIC 1 + +/* Define EXTENDED_GLOB if you want the ksh-style [*+@?!](patlist) extended + pattern matching. */ +#define EXTENDED_GLOB 1 + +/* Define EXTGLOB_DEFAULT to the value you'd like the extglob shell option + to have by default */ +#define EXTGLOB_DEFAULT 0 + +/* Define COND_COMMAND if you want the ksh-style [[...]] conditional + command. */ +#define COND_COMMAND 1 + +/* Define COND_REGEXP if you want extended regular expression matching and the + =~ binary operator in the [[...]] conditional command. */ +#define COND_REGEXP 1 + +/* Define COPROCESS_SUPPORT if you want support for ksh-like coprocesses and + the `coproc' reserved word */ +#define COPROCESS_SUPPORT 1 + +/* Define ARITH_FOR_COMMAND if you want the ksh93-style + for (( init; test; step )) do list; done + arithmetic for command. */ +#define ARITH_FOR_COMMAND 1 + +/* Define NETWORK_REDIRECTIONS if you want /dev/(tcp|udp)/host/port to open + socket connections when used in redirections */ +#define NETWORK_REDIRECTIONS 1 + +/* Define PROGRAMMABLE_COMPLETION for the programmable completion features + and the complete builtin. */ +#define PROGRAMMABLE_COMPLETION 1 + +/* Define NO_MULTIBYTE_SUPPORT to not compile in support for multibyte + characters, even if the OS supports them. */ +/* #undef NO_MULTIBYTE_SUPPORT */ + +/* Define DEBUGGER if you want to compile in some features used only by the + bash debugger. */ +#define DEBUGGER 1 + +/* Define STRICT_POSIX if you want bash to be strictly posix.2 conformant by + default (except for echo; that is controlled separately). */ +/* #undef STRICT_POSIX */ + +/* Define MEMSCRAMBLE if you want the bash malloc and free to scramble + memory contents on malloc() and free(). */ +#define MEMSCRAMBLE 1 + +/* Define for case-modifying variable attributes; variables modified on + assignment */ +#define CASEMOD_ATTRS 1 + +/* Define for case-modifying word expansions */ +#define CASEMOD_EXPANSIONS 1 + +/* Define to make the `direxpand' shopt option enabled by default. */ +/* #undef DIRCOMPLETE_EXPAND_DEFAULT */ + +/* Define to make the `globasciiranges' shopt option enabled by default. */ +#define GLOBASCII_DEFAULT 1 + +/* Define to allow functions to be imported from the environment. */ +#define FUNCTION_IMPORT 1 + +/* Define AFS if you are using Transarc's AFS. */ +/* #undef AFS */ + +/* #undef ENABLE_NLS */ + +/* End of configuration settings controllable by autoconf. */ +/* Other settable options appear in config-top.h. */ + +#include "config-top.h" + +/* Beginning of autoconf additions. */ + +/* Characteristics of the C compiler */ +/* #undef const */ + +/* #undef inline */ + +#define restrict __restrict + +/* #undef volatile */ + +/* Define if cpp supports the ANSI-C stringizing `#' operator */ +#define HAVE_STRINGIZE 1 + +/* Define if the compiler supports `long double' variables. */ +#define HAVE_LONG_DOUBLE 1 + +#define PROTOTYPES 1 +#define __PROTOTYPES 1 + +/* #undef __CHAR_UNSIGNED__ */ + +/* Define if the compiler supports `long long' variables. */ +#define HAVE_LONG_LONG 1 + +#define HAVE_UNSIGNED_LONG_LONG 1 + +/* The number of bytes in a int. */ +#define SIZEOF_INT 4 + +/* The number of bytes in a long. */ +#define SIZEOF_LONG 8 + +/* The number of bytes in a pointer to char. */ +#define SIZEOF_CHAR_P 8 + +/* The number of bytes in a double (hopefully 8). */ +#define SIZEOF_DOUBLE 8 + +/* The number of bytes in an `intmax_t'. */ +#define SIZEOF_INTMAX_T 8 + +/* The number of bytes in a `long long', if we have one. */ +#define SIZEOF_LONG_LONG 8 + +/* The number of bytes in a `wchar_t', if supported */ +#define SIZEOF_WCHAR_T 4 + +/* System paths */ + +#define DEFAULT_MAIL_DIRECTORY "/var/mail" + +/* Characteristics of the system's header files and libraries that affect + the compilation environment. */ + +/* Define if the system does not provide POSIX.1 features except + with this defined. */ +/* #undef _POSIX_1_SOURCE */ + +/* Define if you need to in order for stat and other things to work. */ +/* #undef _POSIX_SOURCE */ + +/* Define to use GNU libc extensions */ +#define _GNU_SOURCE 1 + +/* Define if you have the ANSI C header files. */ +#define STDC_HEADERS 1 + +/* Memory management functions. */ + +/* Define if using the bash version of malloc in lib/malloc/malloc.c */ +/* #undef USING_BASH_MALLOC */ + +/* #undef DISABLE_MALLOC_WRAPPERS */ + +/* Define if using alloca.c. */ +/* #undef C_ALLOCA */ + +/* Define to one of _getb67, GETB67, getb67 for Cray-2 and Cray-YMP systems. + This function is required for alloca.c support on those systems. */ +/* #undef CRAY_STACKSEG_END */ + +/* Define if you have alloca, as a function or macro. */ +#define HAVE_ALLOCA 1 + +/* Define if you have and it should be used (not on Ultrix). */ +#define HAVE_ALLOCA_H 1 + +/* Define if major/minor/makedev is defined in */ +/* #undef MAJOR_IN_MAKEDEV */ + +/* Define if major/minor/makedev is defined in */ +#define MAJOR_IN_SYSMACROS 1 + +/* SYSTEM TYPES */ + +/* Define to `long' if doesn't define. */ +/* #undef off_t */ + +/* Define to `int' if doesn't define. */ +/* #undef mode_t */ + +/* Define to `int' if doesn't define. */ +/* #undef sigset_t */ + +/* Define to `int' if doesn't define. */ +/* #undef pid_t */ + +/* Define to `short' if doesn't define. */ +#define bits16_t short + +/* Define to `unsigned short' if doesn't define. */ +#define u_bits16_t unsigned short + +/* Define to `int' if doesn't define. */ +#define bits32_t int + +/* Define to `unsigned int' if doesn't define. */ +#define u_bits32_t unsigned int + +/* Define to `double' if doesn't define. */ +#define bits64_t char * + +/* Define to `unsigned int' if doesn't define. */ +/* #undef u_int */ + +/* Define to `unsigned long' if doesn't define. */ +/* #undef u_long */ + +/* Define to `int' if doesn't define. */ +/* #undef ptrdiff_t */ + +/* Define to `unsigned' if doesn't define. */ +/* #undef size_t */ + +/* Define to `int' if doesn't define. */ +/* #undef ssize_t */ + +/* Define to `long' if doesn't define. */ +/* #undef intmax_t */ + +/* Define to `unsigned long' if doesn't define. */ +/* #undef uintmax_t */ + +/* Define to integer type wide enough to hold a pointer if doesn't define. */ +/* #undef uintptr_t */ + +/* Define to `int' if doesn't define. */ +/* #undef uid_t */ + +/* Define to `long' if doesn't define. */ +/* #undef clock_t */ + +/* Define to `long' if doesn't define. */ +/* #undef time_t */ + +/* Define to `int' if doesn't define. */ +/* #undef gid_t */ + +/* Define to `unsigned int' if doesn't define. */ +/* #undef socklen_t */ + +/* Define to `int' if doesn't define. */ +/* #undef sig_atomic_t */ + +#define HAVE_MBSTATE_T 1 + +/* Define if you have quad_t in . */ +#define HAVE_QUAD_T 1 + +/* Define if you have wchar_t in . */ +#define HAVE_WCHAR_T 1 + +/* Define if you have wctype_t in . */ +#define HAVE_WCTYPE_T 1 + +/* Define if you have wint_t in . */ +#define HAVE_WINT_T 1 + +#define RLIMTYPE rlim_t + +/* Define to the type of elements in the array set by `getgroups'. + Usually this is either `int' or `gid_t'. */ +#define GETGROUPS_T gid_t + +/* Characteristics of the machine archictecture. */ + +/* If using the C implementation of alloca, define if you know the + direction of stack growth for your system; otherwise it will be + automatically deduced at run-time. + STACK_DIRECTION > 0 => grows toward higher addresses + STACK_DIRECTION < 0 => grows toward lower addresses + STACK_DIRECTION = 0 => direction of growth unknown + */ +/* #undef STACK_DIRECTION */ + +/* Define if the machine architecture is big-endian. */ +/* #undef WORDS_BIGENDIAN */ + +/* Check for the presence of certain non-function symbols in the system + libraries. */ + +/* Define if `sys_siglist' is declared by or . */ +#define HAVE_DECL_SYS_SIGLIST 0 +/* #undef SYS_SIGLIST_DECLARED */ + +/* Define if `_sys_siglist' is declared by or . */ +/* #undef UNDER_SYS_SIGLIST_DECLARED */ + +/* #undef HAVE_SYS_SIGLIST */ + +/* #undef HAVE_UNDER_SYS_SIGLIST */ + +#define HAVE_SYS_ERRLIST 1 + +/* #undef HAVE_TZNAME */ +/* #undef HAVE_DECL_TZNAME */ + +/* Characteristics of some of the system structures. */ + +#define HAVE_STRUCT_DIRENT_D_INO 1 + +#define HAVE_STRUCT_DIRENT_D_FILENO 1 + +/* #undef HAVE_STRUCT_DIRENT_D_NAMLEN */ + +/* #undef TIOCSTAT_IN_SYS_IOCTL */ + +#define FIONREAD_IN_SYS_IOCTL 1 + +#define GWINSZ_IN_SYS_IOCTL 1 + +#define STRUCT_WINSIZE_IN_SYS_IOCTL 1 + +/* #undef TM_IN_SYS_TIME */ + +/* #undef STRUCT_WINSIZE_IN_TERMIOS */ + +/* #undef SPEED_T_IN_SYS_TYPES */ + +#define TERMIOS_LDISC 1 + +#define TERMIO_LDISC 1 + +#define HAVE_STRUCT_STAT_ST_BLOCKS 1 + +#define HAVE_STRUCT_TM_TM_ZONE 1 +#define HAVE_TM_ZONE 1 + +#define HAVE_TIMEVAL 1 + +#define HAVE_STRUCT_TIMEZONE 1 + +#define WEXITSTATUS_OFFSET 8 + +#define HAVE_STRUCT_TIMESPEC 1 +#define TIME_H_DEFINES_STRUCT_TIMESPEC 1 +/* #undef SYS_TIME_H_DEFINES_STRUCT_TIMESPEC */ +/* #undef PTHREAD_H_DEFINES_STRUCT_TIMESPEC */ + +#define HAVE_STRUCT_STAT_ST_ATIM_TV_NSEC 1 +#define TYPEOF_STRUCT_STAT_ST_ATIM_IS_STRUCT_TIMESPEC 1 +/* #undef HAVE_STRUCT_STAT_ST_ATIMESPEC_TV_NSEC */ +/* #undef HAVE_STRUCT_STAT_ST_ATIMENSEC */ +/* #undef HAVE_STRUCT_STAT_ST_ATIM_ST__TIM_TV_NSEC */ + +/* Characteristics of definitions in the system header files. */ + +#define HAVE_GETPW_DECLS 1 + +/* #undef HAVE_RESOURCE */ + +/* #undef HAVE_LIBC_FNM_EXTMATCH */ + +/* Define if you have and it defines AUDIT_USER_TTY */ +#define HAVE_DECL_AUDIT_USER_TTY 1 + +#define HAVE_DECL_CONFSTR 1 + +#define HAVE_DECL_PRINTF 1 + +#define HAVE_DECL_SBRK 1 + +#define HAVE_DECL_STRCPY 1 + +#define HAVE_DECL_STRSIGNAL 1 + +#define HAVE_DECL_STRTOLD 1 + +/* #undef PRI_MACROS_BROKEN */ + +/* #undef STRTOLD_BROKEN */ + +/* Define if WCONTINUED is defined in system headers, but rejected by waitpid */ +/* #undef WCONTINUED_BROKEN */ + +/* These are checked with BASH_CHECK_DECL */ + +#define HAVE_DECL_STRTOIMAX 1 +#define HAVE_DECL_STRTOL 1 +#define HAVE_DECL_STRTOLL 1 +#define HAVE_DECL_STRTOUL 1 +#define HAVE_DECL_STRTOULL 1 +#define HAVE_DECL_STRTOUMAX 1 + +/* Characteristics of system calls and C library functions. */ + +/* Define if the `getpgrp' function takes no argument. */ +#define GETPGRP_VOID 1 + +/* #undef NAMED_PIPES_MISSING */ + +/* #undef OPENDIR_NOT_ROBUST */ + +#define PGRP_PIPE 1 + +/* Define if the setvbuf function takes the buffering type as its second + argument and the buffer pointer as the third, as on System V + before release 3. */ +/* #undef SETVBUF_REVERSED */ + +/* #undef STAT_MACROS_BROKEN */ + +#define ULIMIT_MAXFDS 1 + +#define CAN_REDEFINE_GETENV 1 + +#define HAVE_STD_PUTENV 1 + +#define HAVE_STD_UNSETENV 1 + +#define HAVE_PRINTF_A_FORMAT 1 + +#define CTYPE_NON_ASCII 1 + +/* Define if you have and nl_langinfo(CODESET). */ +#define HAVE_LANGINFO_CODESET 1 + +/* Characteristics of properties exported by the kernel. */ + +/* Define if the kernel can exec files beginning with #! */ +#define HAVE_HASH_BANG_EXEC 1 + +/* Define if you have the /dev/fd devices to map open files into the file system. */ +#define HAVE_DEV_FD 1 + +/* Defined to /dev/fd or /proc/self/fd (linux). */ +#define DEV_FD_PREFIX "/dev/fd/" + +/* Define if you have the /dev/stdin device. */ +#define HAVE_DEV_STDIN 1 + +/* The type of iconv's `inbuf' argument */ +#define ICONV_CONST + +/* Type and behavior of signal handling functions. */ + +/* Define as the return type of signal handlers (int or void). */ +#define RETSIGTYPE void + +/* Define if return type of signal handlers is void */ +#define VOID_SIGHANDLER 1 + +/* #undef MUST_REINSTALL_SIGHANDLERS */ + +/* #undef HAVE_BSD_SIGNALS */ + +#define HAVE_POSIX_SIGNALS 1 + +/* #undef HAVE_USG_SIGHOLD */ + +/* #undef UNUSABLE_RT_SIGNALS */ + +/* Presence of system and C library functions. */ + +/* Define if you have the arc4random function. */ +/* #undef HAVE_ARC4RANDOM */ + +/* Define if you have the asprintf function. */ +#define HAVE_ASPRINTF 1 + +/* Define if you have the bcopy function. */ +#define HAVE_BCOPY 1 + +/* Define if you have the bzero function. */ +#define HAVE_BZERO 1 + +/* Define if you have the chown function. */ +#define HAVE_CHOWN 1 + +/* Define if you have the confstr function. */ +#define HAVE_CONFSTR 1 + +/* Define if you have the dlclose function. */ +#define HAVE_DLCLOSE 1 + +/* Define if you have the dlopen function. */ +#define HAVE_DLOPEN 1 + +/* Define if you have the dlsym function. */ +#define HAVE_DLSYM 1 + +/* Define if you don't have vprintf but do have _doprnt. */ +/* #undef HAVE_DOPRNT */ + +/* Define if you have the dprintf function. */ +#define HAVE_DPRINTF 1 + +/* Define if you have the dup2 function. */ +#define HAVE_DUP2 1 + +/* Define if you have the eaccess function. */ +/* #undef HAVE_EACCESS */ + +/* Define if you have the faccessat function. */ +#define HAVE_FACCESSAT 1 + +/* Define if you have the fcntl function. */ +#define HAVE_FCNTL 1 + +/* Define if you have the fnmatch function. */ +#define HAVE_FNMATCH 1 + +/* Can fnmatch be used as a fallback to match [=equiv=] with collation weights? */ +#define FNMATCH_EQUIV_FALLBACK 1 + +/* Define if you have the fpurge/__fpurge function. */ +#define HAVE_FPURGE 1 +/* #undef HAVE___FPURGE */ +#define HAVE_DECL_FPURGE 0 + +/* Define if you have the getaddrinfo function. */ +#define HAVE_GETADDRINFO 1 + +/* Define if you have the getcwd function. */ +#define HAVE_GETCWD 1 + +/* Define if you have the getentropy function. */ +#define HAVE_GETENTROPY 1 + +/* Define if you have the getdtablesize function. */ +/* #undef HAVE_GETDTABLESIZE */ + +/* Define if you have the getgroups function. */ +#define HAVE_GETGROUPS 1 + +/* Define if you have the gethostbyname function. */ +#define HAVE_GETHOSTBYNAME 1 + +/* Define if you have the gethostname function. */ +#define HAVE_GETHOSTNAME 1 + +/* Define if you have the getpagesize function. */ +#define HAVE_GETPAGESIZE 1 + +/* Define if you have the getpeername function. */ +#define HAVE_GETPEERNAME 1 + +/* Define if you have the getpwent function. */ +#define HAVE_GETPWENT 1 + +/* Define if you have the getpwnam function. */ +#define HAVE_GETPWNAM 1 + +/* Define if you have the getpwuid function. */ +#define HAVE_GETPWUID 1 + +/* Define if you have the getrandom function. */ +#define HAVE_GETRANDOM 1 + +/* Define if you have the getrlimit function. */ +#define HAVE_GETRLIMIT 1 + +/* Define if you have the getrusage function. */ +#define HAVE_GETRUSAGE 1 + +/* Define if you have the getservbyname function. */ +#define HAVE_GETSERVBYNAME 1 + +/* Define if you have the getservent function. */ +#define HAVE_GETSERVENT 1 + +/* Define if you have the gettimeofday function. */ +#define HAVE_GETTIMEOFDAY 1 + +/* Define if you have the getwd function. */ +/* #undef HAVE_GETWD */ + +/* Define if you have the iconv function. */ +#define HAVE_ICONV 1 + +/* Define if you have the imaxdiv function. */ +#define HAVE_IMAXDIV 1 + +/* Define if you have the inet_aton function. */ +#define HAVE_INET_ATON 1 + +/* Define if you have the isascii function. */ +#define HAVE_ISASCII 1 + +/* Define if you have the isblank function. */ +#define HAVE_ISBLANK 1 + +/* Define if you have the isgraph function. */ +#define HAVE_ISGRAPH 1 + +/* Define if you have the isprint function. */ +#define HAVE_ISPRINT 1 + +/* Define if you have the isspace function. */ +#define HAVE_ISSPACE 1 + +/* Define if you have the iswctype function. */ +#define HAVE_ISWCTYPE 1 + +/* Define if you have the iswlower function. */ +#define HAVE_ISWLOWER 1 + +/* Define if you have the iswupper function. */ +#define HAVE_ISWUPPER 1 + +/* Define if you have the isxdigit function. */ +#define HAVE_ISXDIGIT 1 + +/* Define if you have the kill function. */ +#define HAVE_KILL 1 + +/* Define if you have the killpg function. */ +#define HAVE_KILLPG 1 + +/* Define if you have the lstat function. */ +#define HAVE_LSTAT 1 + +/* Define if you have the locale_charset function. */ +/* #undef HAVE_LOCALE_CHARSET */ + +/* Define if you have the mbrlen function. */ +#define HAVE_MBRLEN 1 + +/* Define if you have the mbrtowc function. */ +#define HAVE_MBRTOWC 1 + +/* Define if you have the mbscasecmp function. */ +/* #undef HAVE_MBSCASECMP */ + +/* Define if you have the mbschr function. */ +/* #undef HAVE_MBSCHR */ + +/* Define if you have the mbscmp function. */ +/* #undef HAVE_MBSCMP */ + +/* Define if you have the mbsnrtowcs function. */ +#define HAVE_MBSNRTOWCS 1 + +/* Define if you have the mbsrtowcs function. */ +#define HAVE_MBSRTOWCS 1 + +/* Define if you have the memmove function. */ +#define HAVE_MEMMOVE 1 + +/* Define if you have the memset function. */ +#define HAVE_MEMSET 1 + +/* Define if you have the mkdtemp function. */ +#define HAVE_MKDTEMP 1 + +/* Define if you have the mkfifo function. */ +#define HAVE_MKFIFO 1 + +/* Define if you have the mkstemp function. */ +#define HAVE_MKSTEMP 1 + +/* Define if you have the pathconf function. */ +#define HAVE_PATHCONF 1 + +/* Define if you have the pselect function. */ +#define HAVE_PSELECT 1 + +/* Define if you have the putenv function. */ +#define HAVE_PUTENV 1 + +/* Define if you have the raise function. */ +#define HAVE_RAISE 1 + +/* Define if you have the random function. */ +#define HAVE_RANDOM 1 + +/* Define if you have the readlink function. */ +#define HAVE_READLINK 1 + +/* Define if you have the regcomp function. */ +#define HAVE_REGCOMP 1 + +/* Define if you have the regexec function. */ +#define HAVE_REGEXEC 1 + +/* Define if you have the rename function. */ +#define HAVE_RENAME 1 + +/* Define if you have the sbrk function. */ +#define HAVE_SBRK 1 + +/* Define if you have the select function. */ +#define HAVE_SELECT 1 + +/* Define if you have the setdtablesize function. */ +/* #undef HAVE_SETDTABLESIZE */ + +/* Define if you have the setenv function. */ +#define HAVE_SETENV 1 + +/* Define if you have the setitimer function. */ +#define HAVE_SETITIMER 1 + +/* Define if you have the setlinebuf function. */ +#define HAVE_SETLINEBUF 1 + +/* Define if you have the setlocale function. */ +#define HAVE_SETLOCALE 1 + +/* Define if you have the setostype function. */ +/* #undef HAVE_SETOSTYPE */ + +/* Define if you have the setregid function. */ +/* #undef HAVE_SETREGID */ +#define HAVE_DECL_SETREGID 1 + +/* Define if you have the setregid function. */ +#define HAVE_SETRESGID 1 +/* #undef HAVE_DECL_SETRESGID */ + +/* Define if you have the setresuid function. */ +#define HAVE_SETRESUID 1 +/* #undef HAVE_DECL_SETRESUID */ + +/* Define if you have the setvbuf function. */ +#define HAVE_SETVBUF 1 + +/* Define if you have the siginterrupt function. */ +#define HAVE_SIGINTERRUPT 1 + +/* Define if you have the POSIX.1-style sigsetjmp function. */ +#define HAVE_POSIX_SIGSETJMP 1 + +/* Define if you have the snprintf function. */ +#define HAVE_SNPRINTF 1 + +/* Define if you have the strcasecmp function. */ +#define HAVE_STRCASECMP 1 + +/* Define if you have the strcasestr function. */ +#define HAVE_STRCASESTR 1 + +/* Define if you have the strchr function. */ +#define HAVE_STRCHR 1 + +/* Define if you have the strchrnul function. */ +#define HAVE_STRCHRNUL 1 + +/* Define if you have the strcoll function. */ +#define HAVE_STRCOLL 1 + +/* Define if you have the strerror function. */ +#define HAVE_STRERROR 1 + +/* Define if you have the strftime function. */ +#define HAVE_STRFTIME 1 + +/* Define if you have the strnlen function. */ +#define HAVE_STRNLEN 1 + +/* Define if you have the strpbrk function. */ +#define HAVE_STRPBRK 1 + +/* Define if you have the strstr function. */ +#define HAVE_STRSTR 1 + +/* Define if you have the strtod function. */ +#define HAVE_STRTOD 1 + +/* Define if you have the strtoimax function. */ +#define HAVE_STRTOIMAX 1 + +/* Define if you have the strtol function. */ +#define HAVE_STRTOL 1 + +/* Define if you have the strtoll function. */ +#define HAVE_STRTOLL 1 + +/* Define if you have the strtoul function. */ +#define HAVE_STRTOUL 1 + +/* Define if you have the strtoull function. */ +#define HAVE_STRTOULL 1 + +/* Define if you have the strtoumax function. */ +#define HAVE_STRTOUMAX 1 + +/* Define if you have the strsignal function or macro. */ +#define HAVE_STRSIGNAL 1 + +/* Define if you have the sysconf function. */ +#define HAVE_SYSCONF 1 + +/* Define if you have the syslog function. */ +#define HAVE_SYSLOG 1 + +/* Define if you have the tcgetattr function. */ +#define HAVE_TCGETATTR 1 + +/* Define if you have the tcgetpgrp function. */ +#define HAVE_TCGETPGRP 1 + +/* Define if you have the times function. */ +#define HAVE_TIMES 1 + +/* Define if you have the towlower function. */ +#define HAVE_TOWLOWER 1 + +/* Define if you have the towupper function. */ +#define HAVE_TOWUPPER 1 + +/* Define if you have the ttyname function. */ +#define HAVE_TTYNAME 1 + +/* Define if you have the tzset function. */ +#define HAVE_TZSET 1 + +/* Define if you have the ulimit function. */ +#define HAVE_ULIMIT 1 + +/* Define if you have the uname function. */ +#define HAVE_UNAME 1 + +/* Define if you have the unsetenv function. */ +#define HAVE_UNSETENV 1 + +/* Define if you have the vasprintf function. */ +#define HAVE_VASPRINTF 1 + +/* Define if you have the vprintf function. */ +#define HAVE_VPRINTF 1 + +/* Define if you have the vsnprintf function. */ +#define HAVE_VSNPRINTF 1 + +/* Define if you have the waitpid function. */ +#define HAVE_WAITPID 1 + +/* Define if you have the wait3 function. */ +#define HAVE_WAIT3 1 + +/* Define if you have the wcrtomb function. */ +#define HAVE_WCRTOMB 1 + +/* Define if you have the wcscoll function. */ +#define HAVE_WCSCOLL 1 + +/* Define if you have the wcsdup function. */ +#define HAVE_WCSDUP 1 + +/* Define if you have the wctype function. */ +#define HAVE_WCTYPE 1 + +/* Define if you have the wcswidth function. */ +#define HAVE_WCSWIDTH 1 + +/* Define if you have the wcwidth function. */ +#define HAVE_WCWIDTH 1 + +/* and if it works */ +/* #undef WCWIDTH_BROKEN */ + +/* Presence of certain system include files. */ + +/* Define if you have the header file. */ +#define HAVE_ARPA_INET_H 1 + +/* Define if you have the header file. */ +#define HAVE_DIRENT_H 1 + +/* Define if you have the header file. */ +#define HAVE_DLFCN_H 1 + +/* Define if you have the header file. */ +#define HAVE_GRP_H 1 + +/* Define if you have the header file. */ +#define HAVE_INTTYPES_H 1 + +/* Define if you have the header file. */ +#define HAVE_LANGINFO_H 1 + +/* Define if you have the header file. */ +#define HAVE_LIBAUDIT_H 1 + +/* Define if you have the header file. */ +/* #undef HAVE_LIBINTL_H */ + +/* Define if you have the header file. */ +#define HAVE_LIMITS_H 1 + +/* Define if you have the header file. */ +#define HAVE_LOCALE_H 1 + +/* Define if you have the header file. */ +/* #undef HAVE_MBSTR_H */ + +/* Define if you have the header file. */ +/* #undef HAVE_NDIR_H */ + +/* Define if you have the header file. */ +#define HAVE_NETDB_H 1 + +/* Define if you have the header file. */ +#define HAVE_NETINET_IN_H 1 + +/* Define if you have the header file. */ +#define HAVE_PWD_H 1 + +/* Define if you have the header file. */ +#define HAVE_REGEX_H 1 + +/* Define if you have the header file. */ +#define HAVE_STDLIB_H 1 + +/* Define if you have the header file. */ +#define HAVE_STDARG_H 1 + +/* Define if you have the header file. */ +#define HAVE_STRING_H 1 + +/* Define if you have the header file. */ +#define HAVE_STRINGS_H 1 + +/* Define if you have the header file. */ +#define HAVE_MEMORY_H 1 + +/* Define if you have the header file. */ +#define HAVE_STDBOOL_H 1 + +/* Define if you have the header file. */ +#define HAVE_STDDEF_H 1 + +/* Define if you have the header file. */ +#define HAVE_STDINT_H 1 + +/* Define if you have the header file. */ +#define HAVE_SYSLOG_H 1 + +/* Define if you have the header file. */ +/* #undef HAVE_SYS_DIR_H */ + +/* Define if you have the header file. */ +#define HAVE_SYS_FILE_H 1 + +/* Define if you have the header file. */ +#define HAVE_SYS_IOCTL_H 1 + +/* Define if you have the header file. */ +#define HAVE_SYS_MMAN_H 1 + +/* Define if you have the header file. */ +/* #undef HAVE_SYS_NDIR_H */ + +/* Define if you have the header file. */ +#define HAVE_SYS_PARAM_H 1 + +/* Define if you have the header file. */ +/* #undef HAVE_SYS_PTE_H */ + +/* Define if you have the header file. */ +/* #undef HAVE_SYS_PTEM_H */ + +/* Define if you have the header file. */ +#define HAVE_SYS_RANDOM_H 1 + +/* Define if you have the header file. */ +#define HAVE_SYS_RESOURCE_H 1 + +/* Define if you have the header file. */ +#define HAVE_SYS_SELECT_H 1 + +/* Define if you have the header file. */ +#define HAVE_SYS_SOCKET_H 1 + +/* Define if you have the header file. */ +#define HAVE_SYS_STAT_H 1 + +/* Define if you have the header file. */ +/* #undef HAVE_SYS_STREAM_H */ + +/* Define if you have */ +#define HAVE_SYS_TIME_H 1 + +#define TIME_WITH_SYS_TIME 1 + +/* Define if you have */ +#define HAVE_SYS_TIMES_H 1 + +/* Define if you have the header file. */ +#define HAVE_SYS_TYPES_H 1 + +/* Define if you have that is POSIX.1 compatible. */ +#define HAVE_SYS_WAIT_H 1 + +/* Define if you have the header file. */ +/* #undef HAVE_TERMCAP_H */ + +/* Define if you have the header file. */ +#define HAVE_TERMIO_H 1 + +/* Define if you have the header file. */ +#define HAVE_TERMIOS_H 1 + +/* Define if you have the header file. */ +#define HAVE_ULIMIT_H 1 + +/* Define if you have the header file. */ +#define HAVE_UNISTD_H 1 + +/* Define if you have the header file. */ +/* #undef HAVE_VARARGS_H */ + +/* Define if you have the header file. */ +#define HAVE_WCHAR_H 1 + +/* Define if you have the header file. */ +#define HAVE_WCTYPE_H 1 + +/* Presence of certain system libraries. */ + +#define HAVE_LIBDL 1 + +/* #undef HAVE_LIBSUN */ + +/* #undef HAVE_LIBSOCKET */ + +/* Are we running the GNU C library, version 2.1 or later? */ +/* #undef GLIBC21 */ + +/* Are we running SVR5 (UnixWare 7)? */ +/* #undef SVR5 */ + +/* Are we running SVR4.2? */ +/* #undef SVR4_2 */ + +/* Are we running some version of SVR4? */ +/* #undef SVR4 */ + +/* Define if job control is unusable or unsupported. */ +/* #undef JOB_CONTROL_MISSING */ + +/* Do we need to define _KERNEL to get the RLIMIT_* defines from + ? */ +/* #undef RLIMIT_NEEDS_KERNEL */ + +/* Number of bits in a file offset, on hosts where this is settable. */ +/* #undef _FILE_OFFSET_BITS */ + +/* Define for large files on AIX-style hosts. */ +/* #undef _LARGE_FILES */ + +/* Do strcoll(3) and strcmp(3) give different results in the default locale? */ +/* #undef STRCOLL_BROKEN */ + +/* #undef DUP2_BROKEN */ + +/* #undef GETCWD_BROKEN */ + +/* #undef DEV_FD_STAT_BROKEN */ + +/* Additional defines for configuring lib/intl, maintained by autoscan/autoheader */ + +/* Define if you have the header file. */ +#define HAVE_ARGZ_H 1 + +/* Define if you have the header file. */ +#define HAVE_ERRNO_H 1 + +/* Define if you have the header file. */ +#define HAVE_FCNTL_H 1 + +/* Define if you have the header file. */ +#define HAVE_MALLOC_H 1 + +/* Define if you have the header file. */ +#define HAVE_STDIO_EXT_H 1 + +/* Define if you have the `dcgettext' function. */ +#define HAVE_DCGETTEXT 1 + +/* Define if you have the `localeconv' function. */ +#define HAVE_LOCALECONV 1 + +/* Define if your system has a working `malloc' function. */ +/* #undef HAVE_MALLOC */ + +/* Define if you have the `mempcpy' function. */ +#define HAVE_MEMPCPY 1 + +/* Define if you have a working `mmap' system call. */ +#define HAVE_MMAP 1 + +/* Define if you have the `mremap' function. */ +#define HAVE_MREMAP 1 + +/* Define if you have the `munmap' function. */ +#define HAVE_MUNMAP 1 + +/* Define if you have the `nl_langinfo' function. */ +/* #undef HAVE_NL_LANGINFO */ + +/* Define if you have the `stpcpy' function. */ +#define HAVE_STPCPY 1 + +/* Define if you have the `strcspn' function. */ +#define HAVE_STRCSPN 1 + +/* Define if you have the `strdup' function. */ +#define HAVE_STRDUP 1 + +/* Define if you have the `__argz_count' function. */ +#define HAVE___ARGZ_COUNT 1 + +/* Define if you have the `__argz_next' function. */ +#define HAVE___ARGZ_NEXT 1 + +/* Define if you have the `__argz_stringify' function. */ +#define HAVE___ARGZ_STRINGIFY 1 + +/* End additions for lib/intl */ + +#include "config-bot.h" + +#endif /* _CONFIG_H_ */ diff --git a/doc/article.ps b/doc/article.ps index adbeba0..e69de29 100644 --- a/doc/article.ps +++ b/doc/article.ps @@ -1,1442 +0,0 @@ -%!PS-Adobe-3.0 -%%Creator: groff version 1.19.2 -%%CreationDate: Tue Oct 22 11:07:52 2013 -%%DocumentNeededResources: font Times-Bold -%%+ font Times-Italic -%%+ font Times-Roman -%%+ font Courier -%%DocumentSuppliedResources: procset grops 1.19 2 -%%Pages: 11 -%%PageOrder: Ascend -%%DocumentMedia: Default 612 792 0 () () -%%Orientation: Portrait -%%EndComments -%%BeginDefaults -%%PageMedia: Default -%%EndDefaults -%%BeginProlog -%%BeginResource: procset grops 1.19 2 -%!PS-Adobe-3.0 Resource-ProcSet -/setpacking where{ -pop -currentpacking -true setpacking -}if -/grops 120 dict dup begin -/SC 32 def -/A/show load def -/B{0 SC 3 -1 roll widthshow}bind def -/C{0 exch ashow}bind def -/D{0 exch 0 SC 5 2 roll awidthshow}bind def -/E{0 rmoveto show}bind def -/F{0 rmoveto 0 SC 3 -1 roll widthshow}bind def -/G{0 rmoveto 0 exch ashow}bind def -/H{0 rmoveto 0 exch 0 SC 5 2 roll awidthshow}bind def -/I{0 exch rmoveto show}bind def -/J{0 exch rmoveto 0 SC 3 -1 roll widthshow}bind def -/K{0 exch rmoveto 0 exch ashow}bind def -/L{0 exch rmoveto 0 exch 0 SC 5 2 roll awidthshow}bind def -/M{rmoveto show}bind def -/N{rmoveto 0 SC 3 -1 roll widthshow}bind def -/O{rmoveto 0 exch ashow}bind def -/P{rmoveto 0 exch 0 SC 5 2 roll awidthshow}bind def -/Q{moveto show}bind def -/R{moveto 0 SC 3 -1 roll widthshow}bind def -/S{moveto 0 exch ashow}bind def -/T{moveto 0 exch 0 SC 5 2 roll awidthshow}bind def -/SF{ -findfont exch -[exch dup 0 exch 0 exch neg 0 0]makefont -dup setfont -[exch/setfont cvx]cvx bind def -}bind def -/MF{ -findfont -[5 2 roll -0 3 1 roll -neg 0 0]makefont -dup setfont -[exch/setfont cvx]cvx bind def -}bind def -/level0 0 def -/RES 0 def -/PL 0 def -/LS 0 def -/MANUAL{ -statusdict begin/manualfeed true store end -}bind def -/PLG{ -gsave newpath clippath pathbbox grestore -exch pop add exch pop -}bind def -/BP{ -/level0 save def -1 setlinecap -1 setlinejoin -72 RES div dup scale -LS{ -90 rotate -}{ -0 PL translate -}ifelse -1 -1 scale -}bind def -/EP{ -level0 restore -showpage -}def -/DA{ -newpath arcn stroke -}bind def -/SN{ -transform -.25 sub exch .25 sub exch -round .25 add exch round .25 add exch -itransform -}bind def -/DL{ -SN -moveto -SN -lineto stroke -}bind def -/DC{ -newpath 0 360 arc closepath -}bind def -/TM matrix def -/DE{ -TM currentmatrix pop -translate scale newpath 0 0 .5 0 360 arc closepath -TM setmatrix -}bind def -/RC/rcurveto load def -/RL/rlineto load def -/ST/stroke load def -/MT/moveto load def -/CL/closepath load def -/Fr{ -setrgbcolor fill -}bind def -/setcmykcolor where{ -pop -/Fk{ -setcmykcolor fill -}bind def -}if -/Fg{ -setgray fill -}bind def -/FL/fill load def -/LW/setlinewidth load def -/Cr/setrgbcolor load def -/setcmykcolor where{ -pop -/Ck/setcmykcolor load def -}if -/Cg/setgray load def -/RE{ -findfont -dup maxlength 1 index/FontName known not{1 add}if dict begin -{ -1 index/FID ne{def}{pop pop}ifelse -}forall -/Encoding exch def -dup/FontName exch def -currentdict end definefont pop -}bind def -/DEFS 0 def -/EBEGIN{ -moveto -DEFS begin -}bind def -/EEND/end load def -/CNT 0 def -/level1 0 def -/PBEGIN{ -/level1 save def -translate -div 3 1 roll div exch scale -neg exch neg exch translate -0 setgray -0 setlinecap -1 setlinewidth -0 setlinejoin -10 setmiterlimit -[]0 setdash -/setstrokeadjust where{ -pop -false setstrokeadjust -}if -/setoverprint where{ -pop -false setoverprint -}if -newpath -/CNT countdictstack def -userdict begin -/showpage{}def -/setpagedevice{}def -}bind def -/PEND{ -countdictstack CNT sub{end}repeat -level1 restore -}bind def -end def -/setpacking where{ -pop -setpacking -}if -%%EndResource -%%EndProlog -%%BeginSetup -%%BeginFeature: *PageSize Default -<< /PageSize [ 612 792 ] /ImagingBBox null >> setpagedevice -%%EndFeature -%%IncludeResource: font Times-Bold -%%IncludeResource: font Times-Italic -%%IncludeResource: font Times-Roman -%%IncludeResource: font Courier -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 -/.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 -/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 -/P/Q/R/S/T/U/V/W/X/Y/Z/bracketleft/backslash/bracketright/circumflex -/underscore/quoteleft/a/b/c/d/e/f/g/h/i/j/k/l/m/n/o/p/q/r/s/t/u/v/w/x/y -/z/braceleft/bar/braceright/tilde/.notdef/quotesinglbase/guillemotleft -/guillemotright/bullet/florin/fraction/perthousand/dagger/daggerdbl -/endash/emdash/ff/fi/fl/ffi/ffl/dotlessi/dotlessj/grave/hungarumlaut -/dotaccent/breve/caron/ring/ogonek/quotedblleft/quotedblright/oe/lslash -/quotedblbase/OE/Lslash/.notdef/exclamdown/cent/sterling/currency/yen -/brokenbar/section/dieresis/copyright/ordfeminine/guilsinglleft -/logicalnot/minus/registered/macron/degree/plusminus/twosuperior -/threesuperior/acute/mu/paragraph/periodcentered/cedilla/onesuperior -/ordmasculine/guilsinglright/onequarter/onehalf/threequarters -/questiondown/Agrave/Aacute/Acircumflex/Atilde/Adieresis/Aring/AE -/Ccedilla/Egrave/Eacute/Ecircumflex/Edieresis/Igrave/Iacute/Icircumflex -/Idieresis/Eth/Ntilde/Ograve/Oacute/Ocircumflex/Otilde/Odieresis -/multiply/Oslash/Ugrave/Uacute/Ucircumflex/Udieresis/Yacute/Thorn -/germandbls/agrave/aacute/acircumflex/atilde/adieresis/aring/ae/ccedilla -/egrave/eacute/ecircumflex/edieresis/igrave/iacute/icircumflex/idieresis -/eth/ntilde/ograve/oacute/ocircumflex/otilde/odieresis/divide/oslash -/ugrave/uacute/ucircumflex/udieresis/yacute/thorn/ydieresis]def -/Courier@0 ENC0/Courier RE/Times-Roman@0 ENC0/Times-Roman RE -/Times-Italic@0 ENC0/Times-Italic RE/Times-Bold@0 ENC0/Times-Bold RE -%%EndSetup -%%Page: 1 1 -%%BeginPageSetup -BP -%%EndPageSetup -/F0 12/Times-Bold@0 SF(Bash \255 The GNU shell*)227.904 123 Q/F1 10 -/Times-Italic@0 SF(Chet Rame)263.85 159 Q(y)-.3 E(Case W)221.72 171 Q -(estern Reserve Univer)-.92 E(sity)-.1 E -.15(ch)250.425 183 S -(et@po.cwru.edu).15 E/F2 10/Times-Bold@0 SF 2.5(1. Intr)72 219 R -(oduction)-.18 E(Bash)97 234.6 Q/F3 10/Times-Roman@0 SF .904 -(is the shell, or command language interpreter)3.404 F 3.404(,t)-.4 G -.904(hat will appear in the GNU operating system.)-3.404 F 1.075 -(The name is an acron)72 246.6 R 1.075(ym for the \231Bourne-Ag)-.15 F -1.075(ain SHell\232, a pun on Ste)-.05 F 1.375 -.15(ve B)-.25 H 1.075 -(ourne, the author of the direct).15 F .206(ancestor of the current)72 -258.6 R/F4 8/Times-Roman@0 SF(UNIX)2.706 E F3 2.706C(hell)-2.706 E -F1(/bin/sh)2.706 E F3 2.706(,w)C .205(hich appeared in the Se)-2.706 F --.15(ve)-.25 G .205(nth Edition Bell Labs Research v).15 F(er)-.15 E(-) --.2 E(sion of)72 270.6 Q/F5 9/Times-Roman@0 SF(UNIX)2.5 E F3(.)A .387 -(Bash is an)97 286.2 R F2(sh)2.887 E F3 .387 -(\255compatible shell that incorporates useful features from the K)B -.388(orn shell \()-.35 F F2(ksh)A F3 2.888(\)a)C .388(nd the C)-2.888 F -.023(shell \()72 298.2 R F2(csh)A F3 .023 -(\), described later in this article.)B .022 -(It is ultimately intended to be a conformant implementation of the) -5.022 F 3.568(IEEE POSIX Shell and Utilities speci\214cation \(IEEE W)72 -310.2 R 3.568(orking Group 1003.2\).)-.8 F 3.569(It of)8.569 F 3.569 -(fers functional)-.25 F(impro)72 322.2 Q -.15(ve)-.15 G(ments o).15 E --.15(ve)-.15 G 2.5(rs).15 G 2.5(hf)-2.5 G(or both interacti)-2.5 E .3 --.15(ve a)-.25 H(nd programming use.).15 E .697 -(While the GNU operating system will most lik)97 337.8 R .697 -(ely include a v)-.1 F .697(ersion of the Berk)-.15 F(ele)-.1 E 3.197 -(ys)-.15 G .696(hell csh, Bash)-3.197 F .015(will be the def)72 349.8 R -.015(ault shell.)-.1 F(Lik)5.015 E 2.515(eo)-.1 G .015(ther GNU softw) --2.515 F .016(are, Bash is quite portable.)-.1 F .016 -(It currently runs on nearly e)5.016 F -.15(ve)-.25 G(ry).15 E -.15(ve) -72 361.8 S .523(rsion of).15 F F4(UNIX)3.023 E F3 .523(and a fe)3.023 F -3.023(wo)-.25 G .523 -(ther operating systems \255 an independently-supported port e)-3.023 F -.523(xists for OS/2, and)-.15 F .706 -(there are rumors of ports to DOS and W)72 373.8 R(indo)-.4 E .706 -(ws NT)-.25 F 5.706(.P)-.74 G .706(orts to)-5.706 F F5(UNIX)3.206 E F3 -(-lik)A 3.206(es)-.1 G .706(ystems such as QNX and Minix)-3.206 F -(are part of the distrib)72 385.8 Q(ution.)-.2 E .405 -(The original author of Bash w)97 401.4 R .405(as Brian F)-.1 F .405 -(ox, an emplo)-.15 F .405(yee of the Free Softw)-.1 F .405(are F)-.1 F -2.905(oundation. The)-.15 F(cur)2.905 E(-)-.2 E(rent de)72 413.4 Q -.15 -(ve)-.25 G(loper and maintainer is Chet Rame).15 E 1.3 -.65(y, a v)-.15 -H(olunteer who w).45 E(orks at Case W)-.1 E(estern Reserv)-.8 E 2.5(eU) --.15 G(ni)-2.5 E -.15(ve)-.25 G(rsity).15 E(.)-.65 E F2 2.5(2. What')72 -437.4 R 2.5(sP)-.37 G(OSIX, anyway?)-2.5 E F1(POSIX)97 453 Q F3 .343 -(is a name originally coined by Richard Stallman for a f)2.843 F .343 -(amily of open system standards based)-.1 F(on)72 465 Q F5(UNIX)3.24 E -F3 5.74(.T)C .74(here are a number of aspects of)-5.74 F F5(UNIX)3.24 E -F3 .74(under consideration for standardization, from the basic)3.24 F -.192(system services at the system call and C library le)72 477 R -.15 -(ve)-.25 G 2.692(lt).15 G 2.692(oa)-2.692 G .192 -(pplications and tools to system administration and)-2.692 F 2.5 -(management. Each)72 489 R(area of standardization is assigned to a w) -2.5 E(orking group in the 1003 series.)-.1 E 2.814 -(The POSIX Shell and Utilities standard has been de)97 504.6 R -.15(ve) --.25 G 2.814(loped by IEEE W).15 F 2.813(orking Group 1003.2)-.8 F .254 -(\(POSIX.2\).\210 It concentrates on the command interpreter interf)72 -516.6 R .253(ace and utility programs commonly e)-.1 F -.15(xe)-.15 G -(cuted).15 E 1.112(from the command line or by other programs.)72 528.6 -R 1.112(An initial v)6.112 F 1.113 -(ersion of the standard has been appro)-.15 F -.15(ve)-.15 G 3.613(da) -.15 G(nd)-3.613 E .365(published by the IEEE, and w)72 540.6 R .365 -(ork is currently underw)-.1 F .365(ay to update it.)-.1 F .365 -(There are four primary areas of w)5.365 F(ork)-.1 E -(in the 1003.2 standard:)72 552.6 Q 21.5<8341>72 568.2 S .835 -(spects of the shell')-21.5 F 3.335(ss)-.55 G .835 -(yntax and command language.)-3.335 F 3.335(An)5.835 G .835 -(umber of special b)-3.335 F .835(uiltins such as)-.2 F F2(cd)3.335 E F3 -(and)3.335 E F2(exec)97 580.2 Q F3 .545(are being speci\214ed as part o\ -f the shell, since their functionality usually cannot be implemented) -3.046 F(by a separate e)97 592.2 Q -.15(xe)-.15 G(cutable;).15 E 21.5 -<8341>72 607.8 S .926 -(set of utilities to be called by shell scripts and applications.) --18.074 F .927(Examples are programs lik)5.927 F(e)-.1 E F1 .927 -(sed, tr)3.427 F(,)-1.11 E F3(and)97 619.8 Q F1(awk.)2.797 E F3 .297 -(Utilities commonly implemented as shell b)5.297 F .296 -(uiltins are described in this section, such as)-.2 F F2(test)2.796 E F3 -(and)97 631.8 Q F2(kill)3.422 E F3 5.922(.A)C 3.422(ne)-5.922 G .922 -(xpansion of this section')-3.572 F 3.423(ss)-.55 G .923 -(cope, termed the User Portability Extension, or UPE, has)-3.423 F -(standardized interacti)97 643.8 Q .3 -.15(ve p)-.25 H(rograms such as) -.15 E F1(vi)2.5 E F3(and)2.5 E F1(mailx;)2.5 E F3 21.5<8341>72 659.4 S -.288(group of functional interf)-18.712 F .287(aces to services pro)-.1 -F .287(vided by the shell, such as the traditional)-.15 F/F6 10 -/Courier@0 SF(system\(\))2.787 E F3 3.289(Cl)97 671.4 S .789 -(ibrary function.)-3.289 F .789(There are functions to perform shell w) -5.789 F .789(ord e)-.1 F .79(xpansions, perform \214lename e)-.15 F -(xpan-)-.15 E 3.624(sion \()97 683.4 R F1(globbing)A F3 3.624 -(\), obtain v)B 3.624(alues of POSIX.2 system con\214guration v)-.25 F -3.623(ariables, retrie)-.25 F 3.923 -.15(ve v)-.25 H 3.623(alues of)-.1 -F .32 LW 144 691.4 72 691.4 DL F4(*An earlier v)72 703.2 Q -(ersion of this article appeared in The Linux Journal.)-.12 E(\210IEEE,) -72 715 Q/F7 8/Times-Italic@0 SF 1.231(IEEE Standar)3.231 F 3.231(df) --.296 G 1.231(or Information T)-3.231 F(ec)-.736 E(hnolo)-.12 E 1.231 -(gy -- P)-.08 F 1.231(ortable Oper)-.64 F 1.232 -(ating System Interface \(POSIX\) P)-.12 F 1.232(art 2:)-.64 F -(Shell and Utilities)72 725 Q F4 2(,1)C(992.)-2 E 0 Cg EP -%%Page: 2 2 -%%BeginPageSetup -BP -%%EndPageSetup -/F0 10/Times-Roman@0 SF(-2-)282.17 48 Q(en)97 84 Q(vironment v)-.4 E -(ariables \()-.25 E/F1 10/Courier@0 SF(getenv\(\))A F0 -(\), and other services;).833 E 21.5<8341>72 99.6 S(suite of \231de)-19 -E -.15(ve)-.25 G(lopment\232 utilities such as).15 E/F2 10 -/Times-Italic@0 SF(c89)2.5 E F0(\(the POSIX.2 v)2.5 E(ersion of)-.15 E -F2(cc)2.5 E F0(\), and)A F2(yacc.)2.5 E F0 .483 -(Bash is concerned with the aspects of the shell')97 115.2 R 2.983(sb) --.55 G(eha)-2.983 E .484(vior de\214ned by POSIX.2.)-.2 F .484 -(The shell command)5.484 F 1.439 -(language has of course been standardized, including the basic \215o)72 -127.2 R 3.938(wc)-.25 G 1.438(ontrol and program e)-3.938 F -.15(xe)-.15 -G 1.438(cution con-).15 F 1.284 -(structs, I/O redirection and pipelining, ar)72 139.2 R 1.284 -(gument handling, v)-.18 F 1.284(ariable e)-.25 F 1.284 -(xpansion, and quoting.)-.15 F(The)6.285 E F2(special)3.785 E F0 -.2(bu) -72 151.2 S .676 -(iltins, which must be implemented as part of the shell to pro).2 F .676 -(vide the desired functionality)-.15 F 3.176(,a)-.65 G .676 -(re speci\214ed)-3.176 F .7(as being part of the shell; e)72 163.2 R .7 -(xamples of these are)-.15 F/F3 10/Times-Bold@0 SF -2.3 -.15(ev a)3.201 -H(l).15 E F0(and)3.201 E F3(export)3.201 E F0 5.701(.O)C .701 -(ther utilities appear in the sections of)-5.701 F .256(POSIX.2 not de) -72 175.2 R -.2(vo)-.25 G .256(ted to the shell which are commonly \(and\ - in some cases must be\) implemented as b).2 F(uiltin)-.2 E .213 -(commands, such as)72 187.2 R F3 -.18(re)2.713 G(ad).18 E F0(and)2.713 E -F3(test)2.713 E F0 5.213(.P)C .213 -(OSIX.2 also speci\214es aspects of the shell')-5.213 F 2.713(si)-.55 G -(nteracti)-2.713 E .513 -.15(ve b)-.25 H(eha).15 E .214(vior as part)-.2 -F .598(of the UPE, including job control and command line editing.)72 -199.2 R .598(Interestingly enough, only)5.598 F F2(vi)3.098 E F0 .598 -(-style line edit-)B(ing commands ha)72 211.2 Q .3 -.15(ve b)-.2 H -(een standardized;).15 E F2(emacs)2.5 E F0 -(editing commands were left out due to objections.)2.5 E 1.128 -(While POSIX.2 includes much of what the shell has traditionally pro)97 -226.8 R 1.129(vided, some important things)-.15 F(ha)72 238.8 Q .344 --.15(ve b)-.2 H .044(een omitted as being \231be).15 F .044 -(yond its scope.)-.15 F 5.043<9a54>-.7 G .043 -(here is, for instance, no mention of a dif)-5.043 F .043 -(ference between a)-.25 F F2(lo)72 250.8 Q(gin)-.1 E F0 1.445 -(shell and an)3.945 F 3.945(yo)-.15 G 1.445(ther interacti)-3.945 F -1.745 -.15(ve s)-.25 H 1.446 -(hell \(since POSIX.2 does not specify a login program\).).15 F 1.446 -(No \214x)6.446 F(ed)-.15 E(startup \214les are de\214ned, either \255 \ -the standard does not mention)72 262.8 Q F2(.pr)2.5 E(o\214le)-.45 E F0 -(.)A F3 2.5(3. Basic)72 286.8 R(Bash featur)2.5 E(es)-.18 E F0 1.448 -(Since the Bourne shell pro)97 302.4 R 1.448 -(vides Bash with most of its philosophical underpinnings, Bash inherits) --.15 F .64(most of its features and functionality from sh.)72 314.4 R -.641(Bash implements all of the traditional sh \215o)5.641 F 3.141(wc) --.25 G .641(ontrol con-)-3.141 F .8(structs \()72 326.4 R F2(for)A F0(,) -A F2(if)3.3 E F0(,)A F2(while)3.3 E F0 3.3(,e)C 3.3(tc.\). All)-3.3 F -.799(of the Bourne shell b)3.3 F .799 -(uiltins, including those not speci\214ed in the POSIX.2)-.2 F .536 -(standard, appear in Bash.)72 338.4 R(Shell)5.536 E F2(functions)3.036 E -F0 3.036(,i)C .536(ntroduced in the SVR2 v)-3.036 F .537 -(ersion of the Bourne shell, are similar)-.15 F .779 -(to shell scripts, b)72 350.4 R .779 -(ut are de\214ned using a special syntax and are e)-.2 F -.15(xe)-.15 G -.779(cuted in the same process as the calling).15 F 2.841(shell. Bash)72 -362.4 R .341(has shell functions which beha)2.841 F .641 -.15(ve i)-.2 H -2.841(naf).15 G .341(ashion upw)-2.941 F .342 -(ard-compatible with sh functions.)-.1 F .342(There are)5.342 F 1.447 -(certain shell v)72 374.4 R 1.446 -(ariables that Bash interprets in the same w)-.25 F 1.446 -(ay as sh, such as)-.1 F F3(PS1)3.946 E F0(,)A F3(IFS)3.946 E F0 3.946 -(,a)C(nd)-3.946 E F3 -.74(PA)3.946 G(TH)-.21 E F0 6.446(.B)C(ash)-6.446 -E 1.423(implements essentially the same grammar)72 386.4 R 3.924(,p)-.4 -G 1.424(arameter and v)-3.924 F 1.424(ariable e)-.25 F 1.424 -(xpansion semantics, redirection, and)-.15 F 1.06 -(quoting as the Bourne shell.)72 398.4 R 1.06(Where dif)6.06 F 1.06 -(ferences appear between the POSIX.2 standard and traditional sh)-.25 F -(beha)72 410.4 Q(vior)-.2 E 2.5(,B)-.4 G(ash follo)-2.5 E(ws POSIX.)-.25 -E 1.608(The K)97 426 R 1.608(orn Shell \()-.35 F F3(ksh)A F0 4.108(\)i)C -4.108(sad)-4.108 G 1.608(escendant of the Bourne shell written at A) --4.108 F 1.609(T&T Bell Laboratories by)-1.11 F(Da)72 438 Q 1.059(vid K) --.2 F 3.559(orn\207. It)-.35 F(pro)3.559 E 1.059 -(vides a number of useful features that POSIX and Bash ha)-.15 F 1.359 --.15(ve a)-.2 H 3.558(dopted. Man).15 F 3.558(yo)-.15 G 3.558(ft)-3.558 -G(he)-3.558 E(interacti)72 450 Q 1.312 -.15(ve f)-.25 H 1.012 -(acilities in POSIX.2 ha).05 F 1.312 -.15(ve t)-.2 H 1.012 -(heir roots in the ksh: for e).15 F 1.013 -(xample, the POSIX and ksh job control)-.15 F -.1(fa)72 462 S .513 -(cilities are nearly identical. Bash includes features from the K).1 F -.513(orn Shell for both interacti)-.35 F .813 -.15(ve u)-.25 H .513 -(se and shell).15 F 3.905(programming. F)72 474 R 1.405 -(or programming, Bash pro)-.15 F 1.405(vides v)-.15 F 1.405 -(ariables such as)-.25 F F3(RANDOM)3.905 E F0(and)3.905 E F3(REPL)3.905 -E(Y)-.92 E F0 3.905(,t)C(he)-3.905 E F3(typeset)3.905 E F0 -.2(bu)72 486 -S .398(iltin, the ability to remo).2 F .698 -.15(ve s)-.15 H .398 -(ubstrings from v).15 F .398 -(ariables based on patterns, and shell arithmetic.)-.25 F F3(RANDOM) -5.397 E F0 -.15(ex)72 498 S .489 -(pands to a random number each time it is referenced; assigning a v).15 -F .49(alue to)-.25 F F3(RANDOM)2.99 E F0 .49(seeds the random)2.99 F -.055(number generator)72 510 R(.)-.55 E F3(REPL)5.055 E(Y)-.92 E F0 .054 -(is the def)2.554 F .054(ault v)-.1 F .054(ariable used by the)-.25 F F3 --.18(re)2.554 G(ad).18 E F0 -.2(bu)2.554 G .054(iltin when no v).2 F -.054(ariable names are sup-)-.25 F .742(plied as ar)72 522 R 3.243 -(guments. The)-.18 F F3(typeset)3.243 E F0 -.2(bu)3.243 G .743 -(iltin is used to de\214ne v).2 F .743(ariables and gi)-.25 F 1.043 -.15 -(ve t)-.25 H .743(hem attrib).15 F .743(utes such as)-.2 F F3 -.18(re) -3.243 G(ad-).18 E(only)72 534 Q F0 5.512(.B)C .512(ash arithmetic allo) --5.512 F .512(ws the e)-.25 F -.25(va)-.25 G .511(luation of an e).25 F -.511(xpression and the substitution of the result.)-.15 F .511(Shell v) -5.511 F(ari-)-.25 E .222 -(ables may be used as operands, and the result of an e)72 546 R .222 -(xpression may be assigned to a v)-.15 F 2.722(ariable. Nearly)-.25 F -.222(all of)2.722 F(the operators from the C language are a)72 558 Q --.25(va)-.2 G(ilable, with the same precedence rules:).25 E F1 6($e)97 -576 S(cho $\(\(3 + 5 * 32\)\))-6 E(163)97 588 Q F0 -.15(Fo)72 609.6 S -3.24(ri).15 G(nteracti)-3.24 E 1.04 -.15(ve u)-.25 H .74 -(se, Bash implements ksh-style aliases and b).15 F .74(uiltins such as) --.2 F F3(fc)3.24 E F0 .74(\(discussed belo)3.24 F .74(w\) and)-.25 F F3 -(jobs)3.24 E F0(.)A .291(Bash aliases allo)72 621.6 R 2.791(was)-.25 G -.291(tring to be substituted for a command name.)-2.791 F(The)5.291 E -2.791(yc)-.15 G .291(an be used to create a mnemonic)-2.791 F .568 -(for a)72 633.6 R/F4 9/Times-Roman@0 SF(UNIX)3.068 E F0 .568 -(command name \()3.068 F F1 .568(alias del=rm)B F0 .568(\), to e)B .567 -(xpand a single w)-.15 F .567(ord to a comple)-.1 F 3.067(xc)-.15 G .567 -(ommand \()-3.067 F F1(alias)A .255 -(news='xterm -g 80x45 -title trn -e trn -e -S1 -N &')72 645.6 R F0 .255 -(\), or to ensure that a command)B(is in)72 657.6 Q -.2(vo)-.4 G -.1(ke) -.2 G 2.5(dw).1 G(ith a basic set of options \()-2.5 E F1 -(alias ls="/bin/ls -F")A F0(\).)A .293(The C shell \()97 673.2 R F3(csh) -A F0 .293(\)\207, originally written by Bill Jo)B 2.792(yw)-.1 G .292 -(hile at Berk)-2.792 F(ele)-.1 E 1.592 -.65(y, i)-.15 H 2.792(sw).65 G -.292(idely used and quite popular)-2.792 F 1.499(for its interacti)72 -685.2 R 1.799 -.15(ve f)-.25 H 3.999(acilities. Bash).05 F 1.499 -(includes a csh-compatible history e)3.999 F 1.5 -(xpansion mechanism \(\231! history\232\),)-.15 F .019(brace e)72 697.2 -R .018(xpansion, access to a stack of directories via the)-.15 F F3 -(pushd)2.518 E F0(,)A F3(popd)2.518 E F0 2.518(,a)C(nd)-2.518 E F3(dirs) -2.518 E F0 -.2(bu)2.518 G .018(iltins, and tilde e).2 F(xpansion,)-.15 E -1.293(to generate users' home directories.)72 709.2 R -.35(Ti)6.294 G -1.294(lde e).35 F 1.294(xpansion has also been adopted by both the K) --.15 F 1.294(orn Shell and)-.35 F .32 LW 144 717.2 72 717.2 DL/F5 8 -/Times-Roman@0 SF(\207Morris Bolsk)72 727.2 Q 2(ya)-.12 G(nd Da)-2 E -(vid K)-.16 E(orn,)-.28 E/F6 8/Times-Italic@0 SF(The K)2 E -(ornShell Command and Pr)-.32 E -.08(og)-.36 G -.12(ra).08 G -(mming Langua).12 E -.08(ge)-.08 G F5 2(,P).08 G(rentice Hall, 1989.)-2 -E 0 Cg EP -%%Page: 3 3 -%%BeginPageSetup -BP -%%EndPageSetup -/F0 10/Times-Roman@0 SF(-3-)282.17 48 Q(POSIX.2.)72 84 Q .148 -(There were certain areas in which POSIX.2 felt standardization w)97 -99.6 R .149(as necessary)-.1 F 2.649(,b)-.65 G .149(ut no e)-2.849 F -.149(xisting imple-)-.15 F 1.598(mentation pro)72 111.6 R 1.598 -(vided the proper beha)-.15 F(vior)-.2 E 6.598(.T)-.55 G 1.598(he w) --6.598 F 1.597(orking group in)-.1 F -.15(ve)-.4 G 1.597 -(nted and standardized functionality in).15 F .674 -(these areas, which Bash implements.)72 123.6 R(The)5.674 E/F1 10 -/Times-Bold@0 SF(command)3.174 E F0 -.2(bu)3.174 G .674(iltin w).2 F -.674(as in)-.1 F -.15(ve)-.4 G .674 -(nted so that shell functions could be).15 F .996(written to replace b) -72 135.6 R .996(uiltins; it mak)-.2 F .996(es the capabilities of the b) --.1 F .995(uiltin a)-.2 F -.25(va)-.2 G .995(ilable to the function.).25 -F .995(The reserv)5.995 F(ed)-.15 E -.1(wo)72 147.6 S 1.731 -(rd \231!\232 w).1 F 1.731(as added to ne)-.1 F -.05(ga)-.15 G 1.731 -(te the return v).05 F 1.731(alue of a command or pipeline; it w)-.25 F -1.732(as nearly impossible to)-.1 F -.15(ex)72 159.6 S .286 -(press \231if not x\232 cleanly using the sh language.).15 F .286 -(There e)5.286 F .286(xist multiple incompatible implementations of the) --.15 F F1(test)72 171.6 Q F0 -.2(bu)3.163 G .663 -(iltin, which tests \214les for type and other attrib).2 F .664 -(utes and performs arithmetic and string comparisons.)-.2 F .5 -(POSIX considered none of these correct, so the standard beha)72 183.6 R -.5(vior w)-.2 F .5(as speci\214ed in terms of the number of)-.1 F(ar)72 -195.6 Q .412(guments to the command.)-.18 F .412(POSIX.2 dictates e) -5.412 F .412(xactly what will happen when four or fe)-.15 F .412(wer ar) --.25 F .412(guments are)-.18 F(gi)72 207.6 Q -.15(ve)-.25 G 5.01(nt).15 -G(o)-5.01 E F1(test)5.01 E F0 5.01(,a)C 2.51(nd lea)-5.01 F -.15(ve)-.2 -G 5.01(st).15 G 2.51(he beha)-5.01 F 2.51(vior unde\214ned when more ar) --.2 F 2.51(guments are supplied.)-.18 F 2.51(Bash uses the)7.51 F -(POSIX.2 algorithm, which w)72 219.6 Q(as concei)-.1 E -.15(ve)-.25 G -2.5(db).15 G 2.5(yD)-2.5 G -.2(av)-2.5 G(id K).2 E(orn.)-.35 E F1 2.5 -(3.1. F)72 243.6 R(eatur)-.25 E(es not in the Bour)-.18 E(ne Shell)-.15 -E F0 .718(There are a number of minor dif)97 259.2 R .719 -(ferences between Bash and the v)-.25 F .719 -(ersion of sh present on most other)-.15 F -.15(ve)72 271.2 S .874 -(rsions of).15 F/F2 9/Times-Roman@0 SF(UNIX)3.374 E F0 5.873(.T)C .873 -(he majority of these are due to the POSIX standard, b)-5.873 F .873 -(ut some are the result of Bash)-.2 F .386 -(adopting features from other shells.)72 283.2 R -.15(Fo)5.386 G 2.886 -(ri).15 G .386(nstance, Bash includes the ne)-2.886 F 2.886<7799>-.25 G -.386(!\232 reserv)-2.886 F .386(ed w)-.15 F .386(ord, the)-.1 F F1 -(command)2.886 E F0 -.2(bu)72 295.2 S .116(iltin, the ability of the).2 -F F1 -.18(re)2.616 G(ad).18 E F0 -.2(bu)2.615 G .115 -(iltin to correctly return a line ending with a backslash, symbolic ar) -.2 F(guments)-.18 E .798(to the)72 307.2 R F1(umask)3.298 E F0 -.2(bu) -3.298 G .798(iltin, v).2 F .798(ariable substring remo)-.25 F -.25(va) --.15 G .798(l, a w).25 F .799(ay to get the length of a v)-.1 F .799 -(ariable, and the ne)-.25 F 3.299(wa)-.25 G(lgo-)-3.299 E(rithm for the) -72 319.2 Q F1(test)2.5 E F0 -.2(bu)2.5 G -(iltin from the POSIX.2 standard, none of which appear in sh.).2 E 1.225 -(Bash also implements the \231$\(...\)\232 command substitution syntax,\ - which supersedes the sh `...` con-)97 334.8 R 2.851(struct. The)72 -346.8 R .351(\231$\(...\)\232 construct e)2.851 F .351(xpands to the ou\ -tput of the command contained within the parentheses, with)-.15 F .664 -(trailing ne)72 358.8 R .664(wlines remo)-.25 F -.15(ve)-.15 G 3.164 -(d. The).15 F .664(sh syntax is accepted for backw)3.164 F .664 -(ards compatibility)-.1 F 3.164(,b)-.65 G .664 -(ut the \231$\(...\)\232 form is)-3.364 F(preferred because its quoting\ - rules are much simpler and it is easier to nest.)72 370.8 Q .772 -(The Bourne shell does not pro)97 386.4 R .772 -(vide such features as brace e)-.15 F .772 -(xpansion, the ability to de\214ne a v)-.15 F(ariable)-.25 E .283 -(and a function with the same name, local v)72 398.4 R .282 -(ariables in shell functions, the ability to enable and disable indi-) --.25 F 1.532(vidual b)72 410.4 R 1.532 -(uiltins or write a function to replace a b)-.2 F 1.533 -(uiltin, or a means to e)-.2 F 1.533(xport a shell function to a child) --.15 F(process.)72 422.4 Q .32 -(Bash has closed a long-standing shell security hole by not using the)97 -438 R F1($IFS)2.82 E F0 -.25(va)2.82 G .32(riable to split each w).25 F -(ord)-.1 E 1.254(read by the shell, b)72 450 R 1.254 -(ut splitting only the results of e)-.2 F 1.255 -(xpansion \(ksh and the 4.4 BSD sh ha)-.15 F 1.555 -.15(ve \214)-.2 H --.15(xe).15 G 3.755(dt).15 G 1.255(his as)-3.755 F 2.907(well\). Useful) -72 462 R(beha)2.907 E .407(vior such as a means to abort e)-.2 F -.15 -(xe)-.15 G .407(cution of a script read with the \231.).15 F 2.906<9a63> --.7 G .406(ommand using the)-2.906 F F1 -.18(re)72 474 S(tur).18 E(n) --.15 E F0 -.2(bu)2.742 G .242(iltin or automatically e).2 F .242 -(xporting v)-.15 F .243(ariables in the shell')-.25 F 2.743(se)-.55 G --.4(nv)-2.743 G .243(ironment to children is also not present).4 F .969 -(in the Bourne shell.)72 486 R .968(Bash pro)5.968 F .968 -(vides a much more po)-.15 F .968(werful en)-.25 F .968 -(vironment for both interacti)-.4 F 1.268 -.15(ve u)-.25 H .968 -(se and pro-).15 F(gramming.)72 498 Q F1 2.5(4. Bash-speci\214c)72 522 R --.25(Fe)2.5 G(atur).25 E(es)-.18 E F0 .491(This section details a fe)97 -537.6 R 2.991(wo)-.25 G 2.991(ft)-2.991 G .491(he features which mak) --2.991 F 2.991(eB)-.1 G .491(ash unique.)-2.991 F .492(Most of them pro) -5.491 F .492(vide impro)-.15 F -.15(ve)-.15 G(d).15 E(interacti)72 549.6 -Q 1.182 -.15(ve u)-.25 H .882(se, b).15 F .882(ut a fe)-.2 F 3.382(wp) --.25 G .882(rogramming impro)-3.382 F -.15(ve)-.15 G .882 -(ments are present as well.).15 F .882(Full descriptions of these fea-) -5.882 F(tures can be found in the Bash documentation.)72 561.6 Q F1 2.5 -(4.1. Startup)72 585.6 R(Files)2.5 E F0 .161(Bash e)97 601.2 R -.15(xe) --.15 G .161(cutes startup \214les dif).15 F .161 -(ferently than other shells.)-.25 F .162(The Bash beha)5.161 F .162 -(vior is a compromise between)-.2 F .29 -(the csh principle of startup \214les with \214x)72 613.2 R .29 -(ed names e)-.15 F -.15(xe)-.15 G .29 -(cuted for each shell and the sh \231minimalist\232 beha).15 F(vior)-.2 -E(.)-.55 E 2.955(An interacti)72 625.2 R 3.255 -.15(ve i)-.25 H 2.955 -(nstance of Bash started as a login shell reads and e).15 F -.15(xe)-.15 -G(cutes).15 E/F3 10/Times-Italic@0 SF(~/.bash_pr)5.456 E(o\214le)-.45 E -F0 2.956(\(the \214le)5.456 F .954(.bash_pro\214le in the user')72 637.2 -R 3.454(sh)-.55 G .953(ome directory\), if it e)-3.454 F 3.453 -(xists. An)-.15 F(interacti)3.453 E 1.253 -.15(ve n)-.25 H .953 -(on-login shell reads and e).15 F -.15(xe)-.15 G(cutes).15 E F3 -(~/.bashr)72 649.2 Q(c)-.37 E F0 5.641(.A)C(non-interacti)-2.5 E .942 --.15(ve s)-.25 H .642(hell \(one be).15 F .642(gun to e)-.15 F -.15(xe) --.15 G .642(cute a shell script, for e).15 F .642 -(xample\) reads no \214x)-.15 F .642(ed startup)-.15 F .342(\214le, b)72 -661.2 R .342(ut uses the v)-.2 F .342(alue of the v)-.25 F(ariable)-.25 -E F1($ENV)2.842 E F0 2.841(,i)C 2.841(fs)-2.841 G .341 -(et, as the name of a startup \214le.)-2.841 F .341 -(The ksh practice of read-)5.341 F(ing)72 673.2 Q F1($ENV)3.114 E F0 -.614(for e)3.114 F -.15(ve)-.25 G .614(ry shell, with the accompan).15 F -.615(ying dif)-.15 F .615(\214culty of de\214ning the proper v)-.25 F -.615(ariables and functions)-.25 F .721(for interacti)72 685.2 R 1.021 --.15(ve a)-.25 H .721(nd non-interacti).15 F 1.021 -.15(ve s)-.25 H .721 -(hells or ha).15 F .721(ving the \214le read only for interacti)-.2 F -1.02 -.15(ve s)-.25 H .72(hells, w).15 F .72(as considered)-.1 F .158 -(too comple)72 697.2 R 2.658(x. Ease)-.15 F .158(of use w)2.658 F .158 -(on out here.)-.1 F(Interestingly)5.158 E 2.658(,t)-.65 G .158(he ne) --2.658 F .159(xt release of ksh will change to reading)-.15 F F1($ENV) -2.659 E .32 LW 144 705.2 72 705.2 DL/F4 8/Times-Roman@0 SF .559 -(\207Bill Jo)72 715.2 R 1.599 -.52(y, A)-.08 H 2.559(nI).52 G .559 -(ntroduction to the C Shell,)-2.559 F/F5 8/Times-Italic@0 SF .558 -(UNIX User')2.558 F 2.558(sS)-.32 G .558(upplementary Documents)-2.558 F -F4 2.558(,U)C(ni)-2.558 E -.12(ve)-.2 G .558(rsity of California at).12 -F(Berk)72 725.2 Q(ele)-.08 E 1.04 -.52(y, 1)-.12 H(986.).52 E 0 Cg EP -%%Page: 4 4 -%%BeginPageSetup -BP -%%EndPageSetup -/F0 10/Times-Roman@0 SF(-4-)282.17 48 Q(only for interacti)72 84 Q .3 --.15(ve s)-.25 H(hells.).15 E/F1 10/Times-Bold@0 SF 2.5(4.2. New)72 108 -R(Builtin Commands)2.5 E F0 1.02(There are a fe)97 123.6 R 3.52(wb)-.25 -G 1.02(uiltins which are ne)-3.72 F 3.52(wo)-.25 G 3.52(rh)-3.52 G -2.25 --.2(av e)-3.52 H 1.02(been e)3.72 F 1.02(xtended in Bash.)-.15 F(The) -6.02 E F1(enable)3.52 E F0 -.2(bu)3.52 G 1.02(iltin allo).2 F(ws)-.25 E --.2(bu)72 135.6 S .824(iltin commands to be turned on and of).2 F 3.324 -(fa)-.25 G(rbitrarily)-3.324 E 5.824(.T)-.65 G 3.324(ou)-6.624 G .824 -(se the v)-3.324 F .824(ersion of)-.15 F/F2 10/Times-Italic@0 SF(ec) -3.324 E(ho)-.15 E F0 .825(found in a user')3.324 F 3.325(ss)-.55 G -(earch)-3.325 E .625(path rather than the Bash b)72 147.6 R(uiltin,)-.2 -E/F3 10/Courier@0 SF .625(enable -n echo)3.125 F F0(suf)3.125 E 3.125 -(\214ces. The)-.25 F F1(help)3.124 E F0 -.2(bu)3.124 G .624(iltin pro).2 -F .624(vides quick synopses)-.15 F .703(of the shell f)72 159.6 R .704 -(acilities without requiring access to a manual page.)-.1 F F1(Builtin) -5.704 E F0 .704(is similar to)3.204 F F1(command)3.204 E F0 .704 -(in that it)3.204 F .342(bypasses shell functions and directly e)72 -171.6 R -.15(xe)-.15 G .342(cutes b).15 F .342(uiltin commands.)-.2 F -.342(Access to a csh-style stack of directories)5.342 F .072(is pro)72 -183.6 R .073(vided via the)-.15 F F1(pushd)2.573 E F0(,)A F1(popd)2.573 -E F0 2.573(,a)C(nd)-2.573 E F1(dirs)2.573 E F0 -.2(bu)2.573 G(iltins.).2 -E F1(Pushd)5.073 E F0(and)2.573 E F1(popd)2.573 E F0 .073 -(insert and remo)2.573 F .373 -.15(ve d)-.15 H .073(irectories from the) -.15 F 2.858(stack, respecti)72 195.6 R -.15(ve)-.25 G(ly).15 E 5.358(,a) --.65 G(nd)-5.358 E F1(dirs)5.358 E F0 2.858(lists the stack contents.) -5.358 F 2.858(On systems that allo)7.858 F 5.358<778c>-.25 G 2.857 -(ne-grained control of)-5.358 F 1.339(resources, the)72 207.6 R F1 -(ulimit)3.839 E F0 -.2(bu)3.839 G 1.339 -(iltin can be used to tune these settings.).2 F F1(Ulimit)6.34 E F0 -(allo)3.84 E 1.34(ws a user to control, among)-.25 F 1.086 -(other things, whether core dumps are to be generated, ho)72 219.6 R -3.586(wm)-.25 G 1.086(uch memory the shell or a child process is)-3.586 -F(allo)72 231.6 Q .496(wed to allocate, and ho)-.25 F 2.996(wl)-.25 G -(ar)-2.996 E .496(ge a \214le created by a child process can gro)-.18 F -4.296 -.65(w. T)-.25 H(he).65 E F1(suspend)2.996 E F0 .497(command will) -2.997 F .744(stop the shell process when job control is acti)72 243.6 R --.15(ve)-.25 G 3.243(;m).15 G .743(ost other shells do not allo)-3.243 F -3.243(wt)-.25 G(hemselv)-3.243 E .743(es to be stopped)-.15 F(lik)72 -255.6 Q 2.717(et)-.1 G(hat.)-2.717 E F1 -.74(Ty)5.217 G(pe,).74 E F0 -.217(the Bash answer to)2.717 F F1(which)2.717 E F0(and)2.717 E F1 -(whence,)2.717 E F0(sho)2.717 E .218(ws what will happen when a w)-.25 F -.218(ord is typed as a)-.1 F(command:)72 267.6 Q F3 6($t)97 285.6 S -(ype export)-6 E(export is a shell builtin)97 297.6 Q 6($t)97 309.6 S -(ype -t export)-6 E(builtin)97 321.6 Q 6($t)97 333.6 S(ype bash)-6 E -(bash is /bin/bash)97 345.6 Q 6($t)97 357.6 S(ype cd)-6 E -(cd is a function)97 369.6 Q(cd \(\))97 381.6 Q({)97 393.6 Q -(builtin cd ${1+"$@"} && xtitle $HOST: $PWD)121 405.6 Q(})97 417.6 Q F0 --1.11(Va)72 439.2 S .682(rious modes tell what a command w)1.11 F .681 -(ord is \(reserv)-.1 F .681(ed w)-.15 F .681(ord, alias, function, b)-.1 -F .681(uiltin, or \214le\) or which v)-.2 F(er)-.15 E(-)-.2 E 1.15 -(sion of a command will be e)72 451.2 R -.15(xe)-.15 G 1.15 -(cuted based on a user').15 F 3.65(ss)-.55 G 1.15(earch path.)-3.65 F -1.15(Some of this functionality has been)6.15 F -(adopted by POSIX.2 and folded into the)72 463.2 Q F1(command)2.5 E F0 -(utility)2.5 E(.)-.65 E F1 2.5(4.3. Editing)72 487.2 R(and Completion) -2.5 E F0 .682(One area in which Bash shines is command line editing.)97 -502.8 R .682(Bash uses the)5.682 F F2 -.37(re)3.182 G(adline).37 E F0 -.681(library to read and)3.181 F .942(edit lines when interacti)72 514.8 -R -.15(ve)-.25 G 5.942(.R).15 G .942(eadline is a po)-5.942 F .942 -(werful and \215e)-.25 F .942(xible input f)-.15 F .943 -(acility that a user can con\214gure to)-.1 F(indi)72 526.8 Q .732 -(vidual tastes.)-.25 F .732(It allo)5.732 F .732(ws lines to be edited \ -using either emacs or vi commands, where those commands)-.25 F .2 -(are appropriate.)72 538.8 R .2 -(The full capability of emacs is not present \255 there is no w)5.2 F .2 -(ay to e)-.1 F -.15(xe)-.15 G .2(cute a named command).15 F 1.15 -(with M-x, for instance \255 b)72 550.8 R 1.15(ut the e)-.2 F 1.149 -(xisting commands are more than adequate.)-.15 F 1.149 -(The vi mode is compliant)6.149 F -(with the command line editing standardized by POSIX.2.)72 562.8 Q 1.69 -(Readline is fully customizable.)97 578.4 R 1.691 -(In addition to the basic commands and k)6.69 F 1.991 -.15(ey b)-.1 H -1.691(indings, the library).15 F(allo)72 590.4 Q .028 -(ws users to de\214ne additional k)-.25 F .327 -.15(ey b)-.1 H .027 -(indings using a startup \214le.).15 F(The)5.027 E F2(inputr)2.527 E(c) --.37 E F0 .027(\214le, which def)2.527 F .027(aults to the \214le)-.1 F -F2(~/.inputr)72 602.4 Q(c)-.37 E F0 3.002(,i)C 3.002(sr)-3.002 G .503(e\ -ad each time readline initializes, permitting users to maintain a consi\ -stent interf)-3.002 F .503(ace across a)-.1 F .893(set of programs.)72 -614.4 R .893(Readline includes an e)5.893 F .893(xtensible interf)-.15 F -.892(ace, so each program using the library can add its)-.1 F -.25(ow)72 -626.4 S 3.56(nb).25 G 1.06(indable commands and program-speci\214c k) --3.56 F 1.361 -.15(ey b)-.1 H 3.561(indings. Bash).15 F 1.061 -(uses this f)3.561 F 1.061(acility to add bindings that)-.1 F -(perform history e)72 638.4 Q(xpansion or shell w)-.15 E(ord e)-.1 E -(xpansions on the current input line.)-.15 E .707 -(Readline interprets a number of v)97 654 R .706 -(ariables which further tune its beha)-.25 F(vior)-.2 E 5.706(.V)-.55 G -.706(ariables e)-6.816 F .706(xist to control)-.15 F .157 -(whether or not eight-bit characters are directly read as input or con) -72 666 R -.15(ve)-.4 G .158(rted to meta-pre\214x).15 F .158(ed k)-.15 F -.458 -.15(ey s)-.1 H .158(equences \(a).15 F(meta-pre\214x)72 678 Q .082 -(ed k)-.15 F .382 -.15(ey s)-.1 H .081(equence consists of the characte\ -r with the eighth bit zeroed, preceded by the).15 F F2(meta-pr)2.581 E -(e\214x)-.37 E F0(character)72 690 Q 3.233(,u)-.4 G .733 -(sually escape, which selects an alternate k)-3.233 F -.15(ey)-.1 G .734 -(map\), to decide whether to output characters with).15 F .624 -(the eighth bit set directly or as a meta-pre\214x)72 702 R .624(ed k) --.15 F .924 -.15(ey s)-.1 H .623 -(equence, whether or not to wrap to a ne).15 F 3.123(ws)-.25 G .623 -(creen line)-3.123 F 1.196 -(when a line being edited is longer than the screen width, the k)72 714 -R -.15(ey)-.1 G 1.196(map to which subsequent k).15 F 1.496 -.15(ey b) --.1 H(indings).15 E .531(should apply)72 726 R 3.031(,o)-.65 G 3.031(re) --3.031 G -.15(ve)-3.281 G 3.031(nw).15 G .531 -(hat happens when readline w)-3.031 F .531(ants to ring the terminal') --.1 F 3.03(sb)-.55 G 3.03(ell. All)-3.03 F .53(of these v)3.03 F -(ariables)-.25 E 0 Cg EP -%%Page: 5 5 -%%BeginPageSetup -BP -%%EndPageSetup -/F0 10/Times-Roman@0 SF(-5-)282.17 48 Q -(can be set in the inputrc \214le.)72 84 Q .284 -(The startup \214le understands a set of C preprocessor)97 99.6 R(-lik) --.2 E 2.785(ec)-.1 G .285(onditional constructs which allo)-2.785 F -2.785(wv)-.25 G(ariables)-3.035 E .12(or k)72 111.6 R .42 -.15(ey b)-.1 -H .119(indings to be assigned based on the application using readline, \ -the terminal currently being used, or).15 F .338(the editing mode.)72 -123.6 R .338(Users can add program-speci\214c bindings to mak)5.338 F -2.838(et)-.1 G .338(heir li)-2.838 F -.15(ve)-.25 G 2.838(se).15 G 2.838 -(asier: I)-2.838 F(ha)2.838 E .639 -.15(ve b)-.2 H .339(indings that).15 -F(let me edit the v)72 135.6 Q(alue of)-.25 E/F1 10/Times-Bold@0 SF($P) -2.5 E -.95(AT)-.74 G(H).95 E F0(and double-quote the current or pre)2.5 -E(vious w)-.25 E(ord:)-.1 E/F2 10/Courier@0 SF 6(#M)97 153.6 S -(acros that are convenient for shell interaction)-6 E($if Bash)97 165.6 -Q 6(#e)97 177.6 S(dit the path)-6 E -("\\C-xp": "PATH=${PATH}\\e\\C-e\\C-a\\ef\\C-f")97 189.6 Q 6(#p)97 201.6 -S(repare to type a quoted word -- insert open and close double)-6 E 6 -(#q)97 213.6 S(uotes and move to just after the open quote)-6 E -("\\C-x\\"": "\\"\\"\\C-b")97 225.6 Q 6(#Q)97 237.6 S -(uote the current or previous word)-6 E("\\C-xq": "\\eb\\"\\ef\\"")97 -249.6 Q($endif)97 261.6 Q F0 .322(There is a readline command to re-rea\ -d the \214le, so users can edit the \214le, change some bindings, and b\ -e)72 283.2 R(gin)-.15 E(to use them almost immediately)72 295.2 Q(.)-.65 -E .518(Bash implements the)97 310.8 R F1(bind)3.018 E F0 -.2(bu)3.018 G -.518(iltin for more dynamic control of readline than the startup \214le\ - permits.).2 F F1(Bind)72 322.8 Q F0 .25(is used in se)2.75 F -.15(ve) --.25 G .25(ral w).15 F 2.75(ays. In)-.1 F/F3 10/Times-Italic@0 SF(list) -2.75 E F0 .25(mode, it can display the current k)2.75 F .55 -.15(ey b) --.1 H .25(indings, list all the readline edit-).15 F .149(ing directi)72 -334.8 R -.15(ve)-.25 G 2.649(sa).15 G -.25(va)-2.849 G .149 -(ilable for binding, list which k).25 F -.15(ey)-.1 G 2.649(si).15 G --1.9 -.4(nv o)-2.649 H .349 -.1(ke a g).4 H -2.15 -.25(iv e).1 H 2.65 -(nd).25 G(irecti)-2.65 E -.15(ve)-.25 G 2.65(,o).15 G 2.65(ro)-2.65 G -.15(utput the current set of k)-2.65 F -.15(ey)-.1 G .042(bindings in a\ - format that can be incorporated directly into an inputrc \214le.)72 -346.8 R(In)5.041 E F3(batc)2.541 E(h)-.15 E F0 .041 -(mode, it reads a series of)2.541 F -.1(ke)72 358.8 S 2.858(yb)-.05 G -.359(indings directly from a \214le and passes them to readline.)-2.858 -F .359(In its most common usage,)5.359 F F1(bind)2.859 E F0(tak)2.859 E -.359(es a sin-)-.1 F 1.117(gle string and passes it directly to readlin\ -e, which interprets the line as if it had just been read from the)72 -370.8 R(inputrc \214le.)72 382.8 Q(Both k)5 E .3 -.15(ey b)-.1 H -(indings and v).15 E(ariable assignments may appear in the string gi) --.25 E -.15(ve)-.25 G 2.5(nt).15 G(o)-2.5 E F1(bind)2.5 E F0(.)A .53 -(The readline library also pro)97 398.4 R .53(vides an interf)-.15 F .53 -(ace for)-.1 F F3(wor)3.03 E 3.03(dc)-.37 G(ompletion)-3.03 E F0 5.53 -(.W)C .53(hen the)-5.53 F F3(completion)3.03 E F0(character)3.03 E 1.261 -(\(usually T)72 410.4 R 1.261(AB\) is typed, readline looks at the w) --.93 F 1.26(ord currently being entered and computes the set of \214le-) --.1 F .523(names of which the current w)72 422.4 R .523(ord is a v)-.1 F -.523(alid pre\214x.)-.25 F .524 -(If there is only one possible completion, the rest of the)5.523 F .358 -(characters are inserted directly)72 434.4 R 2.858(,o)-.65 G .358(therw\ -ise the common pre\214x of the set of \214lenames is added to the curre\ -nt)-2.858 F -.1(wo)72 446.4 S 3.199(rd. A).1 F .699(second T)3.199 F -.699(AB character entered immediately after a non-unique completion cau\ -ses readline to list)-.93 F 1.814 -(the possible completions; there is an option to ha)72 458.4 R 2.113 --.15(ve t)-.2 H 1.813(he list displayed immediately).15 F 6.813(.R)-.65 -G 1.813(eadline pro)-6.813 F(vides)-.15 E .482 -(hooks so that applications can pro)72 470.4 R .482 -(vide speci\214c types of completion before the def)-.15 F .483 -(ault \214lename completion)-.1 F .132(is attempted.)72 482.4 R .132 -(This is quite \215e)5.132 F .132 -(xible, though it is not completely user)-.15 F 2.632 -(-programmable. Bash,)-.2 F .132(for e)2.632 F .132(xample, can)-.15 F -.37(complete \214lenames, command names \(including aliases, b)72 494.4 -R .37(uiltins, shell reserv)-.2 F .37(ed w)-.15 F .37 -(ords, shell functions, and)-.1 F -.15(exe)72 506.4 S .424 -(cutables found in the \214le system\), shell v).15 F .424 -(ariables, usernames, and hostnames.)-.25 F .423 -(It uses a set of heuristics)5.424 F(that, while not perfect, is genera\ -lly quite good at determining what type of completion to attempt.)72 -518.4 Q F1 2.5(4.4. History)72 542.4 R F0 .144 -(Access to the list of commands pre)97 558 R .144(viously entered \(the) --.25 F F3 .144(command history)2.644 F F0 2.644(\)i)C 2.644(sp)-2.644 G -(ro)-2.644 E .144(vided jointly by Bash)-.15 F .078 -(and the readline library)72 570 R 5.077(.B)-.65 G .077(ash pro)-5.077 F -.077(vides v)-.15 F .077(ariables \()-.25 F F1($HISTFILE)A F0(,)A F1 -($HISTSIZE)2.577 E F0 2.577(,a)C(nd)-2.577 E F1($HISTCONTR)2.577 E(OL) --.3 E F0 2.577(\)a)C(nd)-2.577 E(the)72 582 Q F1(history)2.759 E F0(and) -2.759 E F1(fc)2.759 E F0 -.2(bu)2.759 G .259 -(iltins to manipulate the history list.).2 F .26(The v)5.259 F .26 -(alue of)-.25 F F1($HISTFILE)2.76 E F0 .26(speci\214es the \214le where) -2.76 F .49(Bash writes the command history on e)72 594 R .489 -(xit and reads it on startup.)-.15 F F1($HISTSIZE)5.489 E F0 .489 -(is used to limit the number)2.989 F .642(of commands sa)72 606 R -.15 -(ve)-.2 G 3.142(di).15 G 3.142(nt)-3.142 G .642(he history)-3.142 F(.) --.65 E F1($HISTCONTR)5.642 E(OL)-.3 E F0(pro)3.142 E .642 -(vides a crude form of control o)-.15 F -.15(ve)-.15 G 3.142(rw).15 G -.642(hich com-)-3.142 F .025(mands are sa)72 618 R -.15(ve)-.2 G 2.525 -(do).15 G 2.525(nt)-2.525 G .025(he history list: a v)-2.525 F .025 -(alue of)-.25 F F3(ignor)2.525 E(espace)-.37 E F0 .025(means to not sa) -2.525 F .324 -.15(ve c)-.2 H .024(ommands which be).15 F .024 -(gin with a)-.15 F .927(space; a v)72 630 R .927(alue of)-.25 F F3 -(ignor)3.427 E(edups)-.37 E F0 .927(means to not sa)3.427 F 1.228 -.15 -(ve c)-.2 H .928(ommands identical to the last command sa).15 F -.15(ve) --.2 G(d.).15 E F1($HIST)5.928 E(-)-.92 E(CONTR)72 642 Q(OL)-.3 E F0 -.1 -(wa)3.778 G 3.778(sn).1 G(amed)-3.778 E F1($history_contr)3.778 E(ol) --.18 E F0 1.278(in earlier v)3.778 F 1.278 -(ersions of Bash; the old name is still accepted for)-.15 F(backw)72 654 -Q .575(ards compatibility)-.1 F 5.575(.T)-.65 G(he)-5.575 E F1(history) -3.075 E F0 .575 -(command can read or write \214les containing the history list and dis-) -3.075 F .167(play the current list contents.)72 666 R(The)5.167 E F1(fc) -2.667 E F0 -.2(bu)2.667 G .167(iltin, adopted from POSIX.2 and the K).2 -F .167(orn Shell, allo)-.35 F .167(ws display and)-.25 F(re-e)72 678 Q --.15(xe)-.15 G .58 -(cution, with optional editing, of commands from the history list.).15 F -.58(The readline library of)5.58 F .58(fers a set of)-.25 F 1.255(comma\ -nds to search the history list for a portion of the current input line \ -or a string typed by the user)72 690 R(.)-.55 E(Finally)72 702 Q 2.535 -(,t)-.65 G(he)-2.535 E F3(history)2.535 E F0(library)2.535 E 2.535(,g) --.65 G .036(enerally incorporated directly into the readline library) --2.535 F 2.536(,i)-.65 G .036(mplements a f)-2.536 F .036(acility for) --.1 F 1.023(history recall, e)72 714 R 1.022(xpansion, and re-e)-.15 F --.15(xe)-.15 G 1.022(cution of pre).15 F 1.022(vious commands v)-.25 F -1.022(ery similar to csh \(\231bang history\232, so)-.15 F -(called because the e)72 726 Q -(xclamation point introduces a history substitution\):)-.15 E 0 Cg EP -%%Page: 6 6 -%%BeginPageSetup -BP -%%EndPageSetup -/F0 10/Times-Roman@0 SF(-6-)282.17 48 Q/F1 10/Courier@0 SF 6($e)97 84 S -(cho a b c d e)-6 E 6(abcde)97 96 S 6($!)97 108 S 6(!fghi)-6 G -(echo a b c d e f g h i)97 120 Q 6(abcdefghi)97 132 S 6($!)97 144 S(-2) --6 E(echo a b c d e)97 156 Q 6(abcde)97 168 S 6($e)97 180 S(cho !-2:1-4) --6 E(echo a b c d)97 192 Q 6(abcd)97 204 S F0 1.456 -(The command history is only sa)72 225.6 R -.15(ve)-.2 G 3.957(dw).15 G -1.457(hen the shell is interacti)-3.957 F -.15(ve)-.25 G 3.957(,s).15 G -3.957(oi)-3.957 G 3.957(ti)-3.957 G 3.957(sn)-3.957 G 1.457(ot a)-3.957 -F -.25(va)-.2 G 1.457(ilable for use by shell).25 F(scripts.)72 237.6 Q -/F2 10/Times-Bold@0 SF 2.5(4.5. New)72 261.6 R(Shell V)2.5 E(ariables) --.92 E F0 .59(There are a number of con)97 277.2 R -.15(ve)-.4 G .589 -(nience v).15 F .589(ariables that Bash interprets to mak)-.25 F 3.089 -(el)-.1 G .589(ife easier)-3.089 F 5.589(.T)-.55 G .589(hese include) --5.589 F F2(FIGNORE)72 289.2 Q F0 3.973(,w)C 1.473 -(hich is a set of \214lename suf)-3.973 F<8c78>-.25 E 1.474 -(es identifying \214les to e)-.15 F 1.474 -(xclude when completing \214lenames;)-.15 F F2(HOSTTYPE)72 301.2 Q F0 -2.932(,w)C .432 -(hich is automatically set to a string describing the type of hardw) --2.932 F .431(are on which Bash is cur)-.1 F(-)-.2 E .335(rently e)72 -313.2 R -.15(xe)-.15 G(cuting;).15 E F2(command_oriented_history)2.835 E -F0 2.835(,w)C .335(hich directs Bash to sa)-2.835 F .635 -.15(ve a)-.2 H -.336(ll lines of a multiple-line com-).15 F 1.071(mand such as a)72 -325.2 R/F3 10/Times-Italic@0 SF(while)3.571 E F0(or)3.571 E F3(for)3.571 -E F0 1.071(loop in a single history entry)3.571 F 3.57(,a)-.65 G(llo) --3.57 E 1.07(wing easy re-editing; and)-.25 F F2(IGNOREEOF)3.57 E F0(,)A -.747(whose v)72 337.2 R .747(alue indicates the number of consecuti)-.25 -F 1.047 -.15(ve E)-.25 H .747(OF characters that an interacti).15 F -1.048 -.15(ve s)-.25 H .748(hell will read before).15 F -.15(ex)72 349.2 -S 1.432(iting \255 an easy w).15 F 1.432(ay to k)-.1 F 1.432 -(eep yourself from being logged out accidentally)-.1 F 6.432(.T)-.65 G -(he)-6.432 E F2(auto_r)3.932 E(esume)-.18 E F0 -.25(va)3.932 G(riable) -.25 E .571(alters the w)72 361.2 R .571 -(ay the shell treats simple command names: if job control is acti)-.1 F --.15(ve)-.25 G 3.071(,a).15 G .571(nd this v)-3.071 F .571 -(ariable is set, sin-)-.25 F(gle-w)72 373.2 Q .239(ord simple commands \ -without redirections cause the shell to \214rst look for and restart a \ -suspended job)-.1 F(with that name before starting a ne)72 385.2 Q 2.5 -(wp)-.25 G(rocess.)-2.5 E F2 2.5(4.6. Brace)72 409.2 R(Expansion)2.5 E -F0 .653(Since sh of)97 424.8 R .653(fers no con)-.25 F -.15(ve)-.4 G -.653(nient w).15 F .653 -(ay to generate arbitrary strings that share a common pre\214x or suf) --.1 F<8c78>-.25 E 2.124(\(\214lename e)72 436.8 R 2.124 -(xpansion requires that the \214lenames e)-.15 F 2.123 -(xist\), Bash implements)-.15 F F3(br)4.623 E 2.123(ace e)-.15 F -(xpansion)-.2 E F0 4.623(,ac)C(apability)-4.623 E(pick)72 448.8 Q .773 -(ed up from csh.)-.1 F .774(Brace e)5.773 F .774 -(xpansion is similar to \214lename e)-.15 F .774(xpansion, b)-.15 F .774 -(ut the strings generated need not)-.2 F 1.211(correspond to e)72 460.8 -R 1.211(xisting \214les.)-.15 F 3.711(Ab)6.211 G 1.211(race e)-3.711 F -1.211(xpression consists of an optional)-.15 F F3(pr)3.71 E(eamble)-.37 -E F0 3.71(,f)C(ollo)-3.71 E 1.21(wed by a pair of)-.25 F 2.938 -(braces enclosing a series of comma-separated strings, and an optional) -72 472.8 R F3(postamble)5.438 E F0 7.938(.T)C 2.938(he preamble is) --7.938 F(prepended to each string within the braces, and the postamble \ -is then appended to each resulting string:)72 484.8 Q F1 6($e)97 502.8 S -(cho a{d,c,b}e)-6 E(ade ace abe)97 514.8 Q F0 .306(As this e)72 536.4 R -.306(xample demonstrates, the results of brace e)-.15 F .305 -(xpansion are not sorted, as the)-.15 F 2.805(ya)-.15 G .305 -(re by \214lename e)-2.805 F(xpan-)-.15 E(sion.)72 548.4 Q F2 2.5 -(4.7. Pr)72 572.4 R(ocess Substitution)-.18 E F0 .457 -(On systems that can support it, Bash pro)97 588 R .457(vides a f)-.15 F -.457(acility kno)-.1 F .458(wn as)-.25 F F3(pr)2.958 E .458 -(ocess substitution)-.45 F F0 5.458(.P)C .458(rocess sub-)-5.458 F .347 -(stitution is similar to command substitution in that its speci\214cati\ -on includes a command to e)72 600 R -.15(xe)-.15 G .346(cute, b).15 F -.346(ut the)-.2 F .181(shell does not collect the command')72 612 R -2.681(so)-.55 G .181(utput and insert it into the command line.)-2.681 F -(Rather)5.181 E 2.681(,B)-.4 G .182(ash opens a pipe)-2.681 F 1.861 -(to the command, which is run in the background.)72 624 R 1.861 -(The shell uses named pipes \(FIFOs\) or the)6.861 F F3(/de)4.361 E -(v/fd)-.15 E F0 .961(method of naming open \214les to e)72 636 R .962(x\ -pand the process substitution to a \214lename which connects to the pip\ -e)-.15 F .104(when opened.)72 648 R .103 -(This \214lename becomes the result of the e)5.104 F 2.603 -(xpansion. Process)-.15 F .103(substitution can be used to com-)2.603 F -(pare the outputs of tw)72 660 Q 2.5(od)-.1 G(if)-2.5 E(ferent v)-.25 E -(ersions of an application as part of a re)-.15 E(gression test:)-.15 E -F1 6($c)97 678 S(mp <\(old_prog\) <\(new_prog\))-6 E 0 Cg EP -%%Page: 7 7 -%%BeginPageSetup -BP -%%EndPageSetup -/F0 10/Times-Roman@0 SF(-7-)282.17 48 Q/F1 10/Times-Bold@0 SF 2.5 -(4.8. Pr)72 84 R(ompt Customization)-.18 E F0 2.229 -(One of the more popular interacti)97 99.6 R 2.529 -.15(ve f)-.25 H -2.229(eatures that Bash pro).15 F 2.23 -(vides is the ability to customize the)-.15 F 3.234(prompt. Both)72 -111.6 R F1($PS1)3.234 E F0(and)3.234 E F1($PS2,)3.234 E F0 .734 -(the primary and secondary prompts, are e)3.234 F .733 -(xpanded before being displayed.)-.15 F -.15(Pa)72 123.6 S .804 -(rameter and v).15 F .804(ariable e)-.25 F .805 -(xpansion is performed when the prompt string is e)-.15 F .805 -(xpanded, so an)-.15 F 3.305(ys)-.15 G .805(hell v)-3.305 F(ariable)-.25 -E .729(can be put into the prompt \(e.g.,)72 135.6 R F1($SHL)3.228 E(VL) --.92 E F0 3.228(,w)C .728(hich indicates ho)-3.228 F 3.228(wd)-.25 G -.728(eeply the current shell is nested\).)-3.228 F(Bash)5.728 E 1.895(s\ -pecially interprets characters in the prompt string preceded by a backs\ -lash.)72 147.6 R 1.895(Some of these backslash)6.895 F .874 -(escapes are replaced with the current time, the date, the current w)72 -159.6 R .874(orking directory)-.1 F 3.373(,t)-.65 G .873 -(he username, and the)-3.373 F .78 -(command number or history number of the command being entered.)72 171.6 -R .781(There is e)5.781 F -.15(ve)-.25 G 3.281(nab).15 G .781 -(ackslash escape to)-3.281 F .007 -(cause the shell to change its prompt when running as root after an)72 -183.6 R/F2 10/Times-Italic@0 SF(su)2.507 E F0 5.007(.B)C .007 -(efore printing each primary prompt,)-5.007 F .305(Bash e)72 195.6 R -.305(xpands the v)-.15 F(ariable)-.25 E F1($PR)2.805 E(OMPT_COMMAND)-.3 -E F0 .305(and, if it has a v)2.805 F .306(alue, e)-.25 F -.15(xe)-.15 G -.306(cutes the e).15 F .306(xpanded v)-.15 F .306(alue as)-.25 F 3.735 -(ac)72 207.6 S 1.235(ommand, allo)-3.735 F 1.234 -(wing additional prompt customization.)-.25 F -.15(Fo)6.234 G 3.734(re) -.15 G 1.234(xample, this assignment causes the current)-3.884 F(user)72 -219.6 Q 2.917(,t)-.4 G .417 -(he current host, the time, the last component of the current w)-2.917 F -.417(orking directory)-.1 F 2.917(,t)-.65 G .418(he le)-2.917 F -.15(ve) --.25 G 2.918(lo).15 G 2.918(fs)-2.918 G .418(hell nest-)-2.918 F(ing, a\ -nd the history number of the current command to be embedded into the pr\ -imary prompt:)72 231.6 Q/F3 10/Courier@0 SF 6($P)97 249.6 S -(S1='\\u@\\h [\\t] \\W\($SHLVL:\\!\)\\$ ')-6 E -(chet@odin [21:03:44] documentation\(2:636\)$ cd ..)97 261.6 Q -(chet@odin [21:03:54] src\(2:637\)$)97 273.6 Q F0 .146(The string being\ - assigned is surrounded by single quotes so that if it is e)72 295.2 R -.146(xported, the v)-.15 F .146(alue of)-.25 F F1($SHL)2.646 E(VL)-.92 E -F0(will)2.646 E(be updated by a child shell:)72 307.2 Q F3 -(chet@odin [21:17:35] src\(2:638\)$ export PS1)97 325.2 Q -(chet@odin [21:17:40] src\(2:639\)$ bash)97 337.2 Q -(chet@odin [21:17:46] src\(3:696\)$)97 349.2 Q F0 -(The \\$ escape is displayed as \231)72 370.8 Q F1($)A F0 2.5<9a77>C -(hen running as a normal user)-2.5 E 2.5(,b)-.4 G(ut as \231)-2.7 E F1 -(#)A F0 2.5<9a77>C(hen running as root.)-2.5 E F1 2.5(4.9. File)72 394.8 -R(System V)2.5 E(iews)-.37 E F0 .029(Since Berk)97 410.4 R(ele)-.1 E -2.529(yi)-.15 G .029 -(ntroduced symbolic links in 4.2 BSD, one of their most anno)-2.529 F -.03(ying properties has been)-.1 F .764(the \231w)72 422.4 R .764 -(arping\232 to a completely dif)-.1 F .764 -(ferent area of the \214le system when using)-.25 F F1(cd)3.263 E F0 -3.263(,a)C .763(nd the resultant non-intu-)-3.263 F(iti)72 434.4 Q .704 --.15(ve b)-.25 H(eha).15 E .405(vior of \231)-.2 F F1 .405(cd ..)B F0 -2.905(\232. The)B/F4 9/Times-Roman@0 SF(UNIX)2.905 E F0 -.1(ke)2.905 G -.405(rnel treats symbolic links).1 F F2(physically)2.905 E F0 5.405(.W)C -.405(hen the k)-5.405 F .405(ernel is translating)-.1 F 3.223(ap)72 -446.4 S .723(athname in which one component is a symbolic link, it repl\ -aces all or part of the pathname while pro-)-3.223 F .668 -(cessing the link.)72 458.4 R .668 -(If the contents of the symbolic link be)5.668 F .669 -(gin with a slash, the k)-.15 F .669(ernel replaces the pathname)-.1 F -.219(entirely; if not, the link contents replace the current component.) -72 470.4 R .219(In either case, the symbolic link is visible.)5.219 F -.058(If the link v)72 482.4 R .058(alue is an absolute pathname, the us\ -er \214nds himself in a completely dif)-.25 F .059 -(ferent part of the \214le sys-)-.25 F(tem.)72 494.4 Q .704(Bash pro)97 -510 R .704(vides a)-.15 F F2(lo)3.203 E(gical)-.1 E F0(vie)3.203 E 3.203 -(wo)-.25 G 3.203(ft)-3.203 G .703(he \214le system.)-3.203 F .703 -(In this def)5.703 F .703(ault mode, command and \214lename com-)-.1 F -.522(pletion and b)72 522 R .522(uiltin commands such as)-.2 F F1(cd) -3.022 E F0(and)3.022 E F1(pushd)3.022 E F0 .522 -(which change the current w)3.022 F .522(orking directory transpar)-.1 F -(-)-.2 E .127(ently follo)72 534 R 2.627(ws)-.25 G .127 -(ymbolic links as if the)-2.627 F 2.627(yw)-.15 G .127(ere directories.) --2.627 F(The)5.126 E F1($PWD)2.626 E F0 -.25(va)2.626 G .126 -(riable, which holds the shell').25 F 2.626(si)-.55 G .126(dea of)-2.626 -F .366(the current w)72 546 R .366(orking directory)-.1 F 2.866(,d)-.65 -G .367 -(epends on the path used to reach the directory rather than its ph) --2.866 F .367(ysical loca-)-.05 F -(tion in the local \214le system hierarch)72 558 Q 3.8 -.65(y. F)-.05 H -(or e).5 E(xample:)-.15 E F3 6($c)97 576 S 6(d/)-6 G(usr/local/bin)-6 E -6($e)97 588 S(cho $PWD)-6 E(/usr/local/bin)97 600 Q 6($p)97 612 S(wd)-6 -E(/usr/local/bin)97 624 Q 6($/)97 636 S(bin/pwd)-6 E -(/net/share/sun4/local/bin)97 648 Q 6($c)97 660 S 6(d.)-6 G(.)-6 E 6($p) -97 672 S(wd)-6 E(/usr/local)97 684 Q 6($/)97 696 S(bin/pwd)-6 E -(/net/share/sun4/local)97 708 Q 6($c)97 720 S 6(d.)-6 G(.)-6 E 0 Cg EP -%%Page: 8 8 -%%BeginPageSetup -BP -%%EndPageSetup -/F0 10/Times-Roman@0 SF(-8-)282.17 48 Q/F1 10/Courier@0 SF 6($p)97 84 S -(wd)-6 E(/usr)97 96 Q 6($/)97 108 S(bin/pwd)-6 E(/usr)97 120 Q F0 .3(On\ -e problem with this, of course, arises when programs that do not unders\ -tand the shell')72 141.6 R 2.8(sl)-.55 G .3(ogical notion of)-2.8 F .217 -(the \214le system interpret \231..)72 153.6 R 2.718<9a64>-.7 G(if) --2.718 E(ferently)-.25 E 5.218(.T)-.65 G .218 -(his generally happens when Bash completes \214lenames containing)-5.218 -F(\231..)72 165.6 Q 3.384<9a61>-.7 G .884 -(ccording to a logical hierarch)-3.384 F 3.384(yw)-.05 G .884 -(hich does not correspond to their ph)-3.384 F .883(ysical location.) --.05 F -.15(Fo)5.883 G 3.383(ru).15 G .883(sers who)-3.383 F -(\214nd this troublesome, a corresponding)72 177.6 Q/F2 10 -/Times-Italic@0 SF(physical)2.5 E F0(vie)2.5 E 2.5(wo)-.25 G 2.5(ft)-2.5 -G(he \214le system is a)-2.5 E -.25(va)-.2 G(ilable:).25 E F1 6($c)97 -195.6 S 6(d/)-6 G(usr/local/bin)-6 E 6($p)97 207.6 S(wd)-6 E -(/usr/local/bin)97 219.6 Q 6($s)97 231.6 S(et -o physical)-6 E 6($p)97 -243.6 S(wd)-6 E(/net/share/sun4/local/bin)97 255.6 Q/F3 10/Times-Bold@0 -SF 2.5(4.10. Inter)72 285.6 R(nationalization)-.15 E F0 .145 -(One of the most signi\214cant impro)97 301.2 R -.15(ve)-.15 G .145 -(ments in v).15 F .145(ersion 1.13 of Bash w)-.15 F .145 -(as the change to \231eight-bit clean-)-.1 F 2.933(liness\232. Pre)72 -313.2 R .433(vious v)-.25 F .432 -(ersions used the eighth bit of characters to mark whether or not the) --.15 F 2.932(yw)-.15 G .432(ere quoted when)-2.932 F 1.495(performing w) -72 325.2 R 1.495(ord e)-.1 F 3.995(xpansions. While)-.15 F 1.495 -(this did not af)3.995 F 1.496 -(fect the majority of users, most of whom used only)-.25 F(se)72 337.2 Q --.15(ve)-.25 G 1.236(n-bit ASCII characters, some found it con\214ning.) -.15 F(Be)6.236 E 1.236(ginning with v)-.15 F 1.236 -(ersion 1.13, Bash implemented a)-.15 F(dif)72 349.2 Q .02(ferent quoti\ -ng mechanism that did not alter the eighth bit of characters.)-.25 F -.021(This allo)5.021 F .021(wed Bash to manipulate)-.25 F .427 -(\214les with \231odd\232 characters in their names, b)72 361.2 R .427 -(ut did nothing to help users enter those names, so v)-.2 F .426 -(ersion 1.13)-.15 F 1.458 -(introduced changes to readline that made it eight-bit clean as well.)72 -373.2 R 1.458(Options e)6.458 F 1.458(xist that force readline to)-.15 F -.744(attach no special signi\214cance to characters with the eighth bit\ - set \(the def)72 385.2 R .744(ault beha)-.1 F .744(vior is to con)-.2 F --.15(ve)-.4 G .744(rt these).15 F .641(characters to meta-pre\214x)72 -397.2 R .641(ed k)-.15 F .941 -.15(ey s)-.1 H .642 -(equences\) and to output these characters without con).15 F -.15(ve)-.4 -G .642(rsion to meta-pre-).15 F<8c78>72 409.2 Q .008(ed sequences.)-.15 -F .007(These changes, along with the e)5.007 F .007(xpansion of k)-.15 F --.15(ey)-.1 G .007(maps to a full eight bits, enable readline to).15 F --.1(wo)72 421.2 S(rk with most of the ISO-8859 f).1 E -(amily of character sets, used by man)-.1 E 2.5(yE)-.15 G -(uropean countries.)-2.5 E F3 2.5(4.11. POSIX)72 445.2 R(Mode)2.5 E F0 -.584(Although Bash is intended to be POSIX.2 conformant, there are area\ -s in which the def)97 460.8 R .584(ault beha)-.1 F(vior)-.2 E .463 -(is not compatible with the standard.)72 472.8 R -.15(Fo)5.463 G 2.962 -(ru).15 G .462(sers who wish to operate in a strict POSIX.2 en)-2.962 F -.462(vironment, Bash)-.4 F .505(implements a)72 484.8 R F2 .505 -(POSIX mode)3.005 F F0 5.505(.W)C .505(hen this mode is acti)-5.505 F --.15(ve)-.25 G 3.005(,B).15 G .505(ash modi\214es its def)-3.005 F .505 -(ault operation where it dif)-.1 F(fers)-.25 E .267 -(from POSIX.2 to match the standard.)72 496.8 R .266 -(POSIX mode is entered when Bash is started with the)5.267 F F3(-posix) -2.766 E F0(option.)2.766 E .149(This feature is also a)72 508.8 R -.25 -(va)-.2 G .149(ilable as an option to the).25 F F3(set)2.649 E F0 -.2 -(bu)2.649 G(iltin,).2 E F3 .149(set -o posix)2.649 F F0 5.149(.F)C .149 -(or compatibility with other GNU)-5.299 F(softw)72 520.8 Q 4.02(are tha\ -t attempts to be POSIX.2 compliant, Bash also enters POSIX mode if the \ -v)-.1 F(ariable)-.25 E F3($POSIXL)72 532.8 Q(Y_CORRECT)-.92 E F0 5.824 -(is set when Bash is started or assigned a v)8.324 F 5.825 -(alue during e)-.25 F -.15(xe)-.15 G(cution.).15 E F3($POSIX_PED)72 -544.8 Q(ANTIC)-.35 E F0 .27 -(is accepted as well, to be compatible with some older GNU utilities.) -2.77 F .27(When Bash is)5.27 F .506(started in POSIX mode, for e)72 -556.8 R .506(xample, it sources the \214le named by the v)-.15 F .507 -(alue of)-.25 F F3($ENV)3.007 E F0 .507(rather than the \231nor)3.007 F -(-)-.2 E(mal\232 startup \214les, and does not allo)72 568.8 Q 2.5(wr) --.25 G(eserv)-2.5 E(ed w)-.15 E(ords to be aliased.)-.1 E F3 2.5(5. New) -72 592.8 R -.25(Fe)2.5 G(atur).25 E(es and Futur)-.18 E 2.5(eP)-.18 G -(lans)-2.5 E F0 1.632(There are se)97 608.4 R -.15(ve)-.25 G 1.632 -(ral features introduced in the current v).15 F 1.631(ersion of Bash, v) --.15 F 1.631(ersion 1.14, and a number)-.15 F .241 -(under consideration for future releases.)72 620.4 R .242 -(This section will brie\215y detail the ne)5.242 F 2.742(wf)-.25 G .242 -(eatures in v)-2.742 F .242(ersion 1.14 and)-.15 F(describe se)72 632.4 -Q -.15(ve)-.25 G(ral features that may appear in later v).15 E(ersions.) --.15 E F3 2.5(5.1. New)72 656.4 R -.25(Fe)2.5 G(atur).25 E -(es in Bash-1.14)-.18 E F0 .884(The ne)97 672 R 3.384(wf)-.25 G .884 -(eatures a)-3.384 F -.25(va)-.2 G .884(ilable in Bash-1.14 answer se).25 -F -.15(ve)-.25 G .883(ral of the most common requests for enhance-).15 F -2.931(ments. Most)72 684 R(notably)2.931 E 2.931(,t)-.65 G .432(here is\ - a mechanism for including non-visible character sequences in prompts, \ -such)-2.931 F .136 -(as those which cause a terminal to print characters in dif)72 696 R -.135(ferent colors or in standout mode.)-.25 F .135(There w)5.135 F .135 -(as noth-)-.1 F .558(ing pre)72 708 R -.15(ve)-.25 G .558 -(nting the use of these sequences in earlier v).15 F .559(ersions, b) --.15 F .559(ut the readline redisplay algorithm assumed)-.2 F -(each character occupied ph)72 720 Q(ysical screen space and w)-.05 E -(ould wrap lines prematurely)-.1 E(.)-.65 E 0 Cg EP -%%Page: 9 9 -%%BeginPageSetup -BP -%%EndPageSetup -/F0 10/Times-Roman@0 SF(-9-)282.17 48 Q .13(Readline has a fe)97 84 R -2.63(wn)-.25 G .63 -.25(ew va)-2.63 H .13(riables, se).25 F -.15(ve)-.25 -G .13(ral ne).15 F 2.63(wb)-.25 G .13 -(indable commands, and some additional emacs mode)-2.63 F(def)72 96 Q -.918(ault k)-.1 F 1.218 -.15(ey b)-.1 H 3.418(indings. A).15 F(ne)3.418 -E 3.418(wh)-.25 G .919(istory search mode has been implemented: in this\ - mode, readline searches)-3.418 F .336(the history for lines be)72 108 R -.336(ginning with the characters between the be)-.15 F .336 -(ginning of the current line and the cursor)-.15 F(.)-.55 E .555(The e) -72 120 R .556(xisting readline incremental search commands no longer ma\ -tch identical lines more than once.)-.15 F(File-)5.556 E 1.979 -(name completion no)72 132 R 4.479(we)-.25 G 1.979(xpands v)-4.629 F -1.979(ariables in directory names.)-.25 F 1.978(The history e)6.978 F -1.978(xpansion f)-.15 F 1.978(acilities are no)-.1 F(w)-.25 E 1.449 -(nearly completely csh-compatible: missing modi\214ers ha)72 144 R 1.749 --.15(ve b)-.2 H 1.449(een added and history substitution has been).15 F --.15(ex)72 156 S(tended.).15 E(Se)97 171.6 Q -.15(ve)-.25 G .474 -(ral of the features described earlier).15 F 2.973(,s)-.4 G .473(uch as) --2.973 F/F1 10/Times-Bold@0 SF .473(set -o posix)2.973 F F0(and)2.973 E -F1($POSIX_PED)2.973 E(ANTIC)-.35 E F0 2.973(,a)C .473(re ne)-2.973 F -2.973(wi)-.25 G(n)-2.973 E -.15(ve)72 183.6 S .106(rsion 1.14.).15 F -.106(There is a ne)5.106 F 2.606(ws)-.25 G .106(hell v)-2.606 F -(ariable,)-.25 E F1(OSTYPE)2.606 E F0 2.606(,t)C 2.606(ow)-2.606 G .106 -(hich Bash assigns a v)-2.606 F .106(alue that identi\214es the v)-.25 F -(er)-.15 E(-)-.2 E 1.38(sion of)72 195.6 R/F2 9/Times-Roman@0 SF(UNIX) -3.88 E F0(it')3.88 E 3.879(sr)-.55 G 1.379(unning on \(great for puttin\ -g architecture-speci\214c binary directories into the)-3.879 F F1($P) -3.879 E -.95(AT)-.74 G(H).95 E F0(\).)A -1 -.8(Tw o)72 207.6 T -.25(va) -6.215 G 2.915(riables ha).25 F 3.215 -.15(ve b)-.2 H 2.915(een renamed:) -.15 F F1($HISTCONTR)5.416 E(OL)-.3 E F0(replaces)5.416 E F1 -($history_contr)5.416 E(ol)-.18 E F0 5.416(,a)C(nd)-5.416 E F1 -($HOSTFILE)5.416 E F0(replaces)72 219.6 Q F1 -($hostname_completion_\214le)2.521 E F0 5.021(.I)C 2.521(nb)-5.021 G -.021(oth cases, the old names are accepted for backw)-2.521 F .02 -(ards compatibil-)-.1 F(ity)72 231.6 Q 5.788(.T)-.65 G .788(he ksh) --5.788 F/F3 10/Times-Italic@0 SF(select)3.288 E F0 .788 -(construct, which allo)3.288 F .788 -(ws the generation of simple menus, has been implemented.)-.25 F(Ne) -5.788 E(w)-.25 E 1.496(capabilities ha)72 243.6 R 1.796 -.15(ve b)-.2 H -1.496(een added to e).15 F 1.495(xisting v)-.15 F(ariables:)-.25 E F1 -($auto_r)3.995 E(esume)-.18 E F0 1.495(can no)3.995 F 3.995(wt)-.25 G -(ak)-3.995 E 3.995(ev)-.1 G 1.495(alues of)-4.245 F F3 -.2(ex)3.995 G -(act).2 E F0(or)3.995 E F3(sub-)3.995 E(string)72 255.6 Q F0 4.843(,a)C -(nd)-4.843 E F1($HISTCONTR)4.843 E(OL)-.3 E F0 2.343(understands the v) -4.843 F(alue)-.25 E F3(ignor)4.844 E(eboth)-.37 E F0 4.844(,w)C 2.344 -(hich combines the tw)-4.844 F 4.844(op)-.1 G(re)-4.844 E(viously)-.25 E -1.556(acceptable v)72 267.6 R 4.056(alues. The)-.25 F F1(dirs)4.056 E F0 --.2(bu)4.056 G 1.556(iltin has acquired options to print out speci\214c\ - members of the directory).2 F 3.062(stack. The)72 279.6 R F1($nolinks) -3.062 E F0 -.25(va)3.062 G .562(riable, which forces a ph).25 F .562 -(ysical vie)-.05 F 3.062(wo)-.25 G 3.062(ft)-3.062 G .563 -(he \214le system, has been superseded by the)-3.062 F F172 291.6 -Q F0 .494(option to the)2.994 F F1(set)2.994 E F0 -.2(bu)2.994 G .494 -(iltin \(equi).2 F -.25(va)-.25 G .494(lent to).25 F F1 .494(set -o ph) -2.994 F(ysical)-.15 E F0 .493(\); the v)B .493 -(ariable is retained for backw)-.25 F .493(ards compati-)-.1 F(bility)72 -303.6 Q 5.196(.T)-.65 G .196(he v)-5.196 F .196 -(ersion string contained in)-.15 F F1($B)2.696 E(ASH_VERSION)-.3 E F0 -(no)2.696 E 2.696(wi)-.25 G .196(ncludes an indication of the patch le) --2.696 F -.15(ve)-.25 G 2.696(la).15 G(s)-2.696 E .85(well as the \231b) -72 315.6 R .85(uild v)-.2 F 3.35(ersion\232. Some)-.15 F .85 -(little-used features ha)3.35 F 1.15 -.15(ve b)-.2 H .85(een remo).15 F --.15(ve)-.15 G 3.35(d: the).15 F F1(by)3.35 E(e)-.1 E F0(synon)3.35 E -.85(ym for)-.15 F F1(exit)3.35 E F0(and)3.35 E(the)72 327.6 Q F1($NO_PR) -3.498 E(OMPT_V)-.3 E(ARS)-1.35 E F0 -.25(va)3.498 G .998 -(riable are gone.).25 F .998(There is no)5.998 F 3.498(wa)-.25 G 3.498 -(no)-3.498 G -2.19 -.18(rg a)-3.498 H .998 -(nized test suite that can be run as a).18 F(re)72 339.6 Q -(gression test when b)-.15 E(uilding a ne)-.2 E 2.5(wv)-.25 G -(ersion of Bash.)-2.65 E 1.696(The documentation has been thoroughly o) -97 355.2 R -.15(ve)-.15 G 1.696(rhauled: there is a ne).15 F 4.196(wm) --.25 G 1.695(anual page on the readline)-4.196 F .467(library and the)72 -367.2 R F3(info)2.967 E F0 .467 -(\214le has been updated to re\215ect the current v)2.967 F 2.968 -(ersion. As)-.15 F(al)2.968 E -.1(wa)-.1 G .468(ys, as man).1 F 2.968 -(yb)-.15 G .468(ugs as possi-)-3.168 F(ble ha)72 379.2 Q .3 -.15(ve b) --.2 H(een \214x).15 E(ed, although some surely remain.)-.15 E F1 2.5 -(5.2. Other)72 403.2 R -.25(Fe)2.5 G(atur).25 E(es)-.18 E F0 1.68 -(There are a fe)97 418.8 R 4.18(wf)-.25 G 1.68 -(eatures that I hope to include in later Bash releases.)-4.18 F 1.68 -(Some are based on w)6.68 F(ork)-.1 E(already done in other shells.)72 -430.8 Q .958(In addition to simple v)97 446.4 R .959(ariables, a future\ - release of Bash will include one-dimensional arrays, using)-.25 F .206 -(the ksh implementation of arrays as a model.)72 458.4 R .205 -(Additions to the ksh syntax, such as)5.205 F F3(varname)2.705 E F0 .205 -(=\( ... \) to assign)B 2.587(al)72 470.4 S .087(ist of w)-2.587 F .088 -(ords directly to an array and a mechanism to allo)-.1 F 2.588(wt)-.25 G -(he)-2.588 E F1 -.18(re)2.588 G(ad).18 E F0 -.2(bu)2.588 G .088 -(iltin to read a list of v).2 F .088(alues directly)-.25 F .092 -(into an array)72 482.4 R 2.592(,w)-.65 G .092(ould be desirable.)-2.692 -F(Gi)5.092 E -.15(ve)-.25 G 2.592(nt).15 G .092(hose e)-2.592 F .092 -(xtensions, the ksh)-.15 F F1 .092(set \255A)2.592 F F0 .091 -(syntax may not be w)2.591 F .091(orth support-)-.1 F(ing \(the)72 494.4 -Q F12.5 E F0(option assigns a list of v)2.5 E(alues to an array) --.25 E 2.5(,b)-.65 G(ut is a rather peculiar special case\).)-2.7 E .76 -(Some shells include a means of)97 510 R F3(pr)3.26 E -.1(og)-.45 G -.15 -(ra).1 G(mmable).15 E F0 -.1(wo)3.26 G .76 -(rd completion, where the user speci\214es on a per).1 F(-)-.2 E .163 -(command basis ho)72 522 R 2.663(wt)-.25 G .163(he ar)-2.663 F .163(gum\ -ents of the command are to be treated when completion is attempted: as \ -\214le-)-.18 F .194(names, hostnames, e)72 534 R -.15(xe)-.15 G .194 -(cutable \214les, and so on.).15 F .195 -(The other aspects of the current Bash implementation could)5.195 F .482 -(remain as-is; the e)72 546 R .482(xisting heuristics w)-.15 F .481 -(ould still be v)-.1 F 2.981(alid. Only)-.25 F .481 -(when completing the ar)2.981 F .481(guments to a simple)-.18 F -(command w)72 558 Q(ould the programmable completion be in ef)-.1 E -(fect.)-.25 E .479(It w)97 573.6 R .479(ould also be nice to gi)-.1 F -.779 -.15(ve t)-.25 H .479(he user \214ner).15 F .479 -(-grained control o)-.2 F -.15(ve)-.15 G 2.98(rw).15 G .48 -(hich commands are sa)-2.98 F -.15(ve)-.2 G 2.98(do).15 G .48(nto the) --2.98 F 1.786(history list.)72 585.6 R 1.786(One proposal is for a v) -6.786 F 1.786(ariable, tentati)-.25 F -.15(ve)-.25 G 1.786(ly named).15 -F F1(HISTIGNORE)4.286 E F0 4.285(,w)C 1.785(hich w)-4.285 F 1.785 -(ould contain a)-.1 F .496(colon-separated list of commands.)72 597.6 R -.496(Lines be)5.496 F .496 -(ginning with these commands, after the restrictions of)-.15 F F1($HIST) -2.997 E(-)-.92 E(CONTR)72 609.6 Q(OL)-.3 E F0(ha)2.65 E .45 -.15(ve b) --.2 H .15(een applied, w).15 F .15 -(ould not be placed onto the history list.)-.1 F .15 -(The shell pattern-matching capa-)5.15 F(bilities could also be a)72 -621.6 Q -.25(va)-.2 G(ilable when specifying the contents of).25 E F1 -($HISTIGNORE)2.5 E F0(.)A .729(One thing that ne)97 637.2 R .729 -(wer shells such as)-.25 F F1(wksh)3.229 E F0 .729(\(also kno)3.229 F -.729(wn as)-.25 F F1(dtksh)3.23 E F0 3.23(\)p)C(ro)-3.23 E .73 -(vide is a command to dynami-)-.15 F 1.189 -(cally load code implementing additional b)72 649.2 R 1.189 -(uiltin commands into a running shell.)-.2 F 1.188(This ne)6.188 F 3.688 -(wb)-.25 G 1.188(uiltin w)-3.888 F(ould)-.1 E(tak)72 661.2 Q 2.875(ea) --.1 G 2.875(no)-2.875 G .375 -(bject \214le or shared library implementing the \231body\232 of the b) --2.875 F .375(uiltin \()-.2 F F3(xxx_b)A(uiltin\(\))-.2 E F0 .375 -(for those f)2.875 F(amiliar)-.1 E .052 -(with Bash internals\) and a structure containing the name of the ne)72 -673.2 R 2.552(wc)-.25 G .051(ommand, the function to call when the) --2.552 F(ne)72 685.2 Q 3.458(wb)-.25 G .958(uiltin is in)-3.658 F -.2 -(vo)-.4 G -.1(ke).2 G 3.458(d\().1 G .959 -(presumably de\214ned in the shared object speci\214ed as an ar)-3.458 F -.959(gument\), and the docu-)-.18 F 1.352 -(mentation to be printed by the)72 697.2 R F1(help)3.851 E F0 1.351 -(command \(possibly present in the shared object as well\).)3.851 F -1.351(It w)6.351 F(ould)-.1 E(manage the details of e)72 709.2 Q -(xtending the internal table of b)-.15 E(uiltins.)-.2 E 0 Cg EP -%%Page: 10 10 -%%BeginPageSetup -BP -%%EndPageSetup -/F0 10/Times-Roman@0 SF(-10-)279.67 48 Q 3.291(Af)97 84 S 1.291 -.25 -(ew o)-3.291 H .791(ther b).25 F .791(uiltins w)-.2 F .791 -(ould also be desirable: tw)-.1 F 3.291(oa)-.1 G .791(re the POSIX.2) --3.291 F/F1 10/Times-Bold@0 SF(getconf)3.292 E F0 .792 -(command, which prints)3.292 F 1.412(the v)72 96 R 1.412 -(alues of system con\214guration v)-.25 F 1.411 -(ariables de\214ned by POSIX.2, and a)-.25 F F1(diso)3.911 E(wn)-.1 E F0 --.2(bu)3.911 G 1.411(iltin, which causes a).2 F .547 -(shell running with job control acti)72 108 R .847 -.15(ve t)-.25 H -3.047<6f99>.15 G(for)-3.047 E .547 -(get about\232 one or more background jobs in its internal jobs ta-)-.18 -F 3.866(ble. Using)72 120 R F1(getconf)3.866 E F0 3.866(,f)C 1.366(or e) --3.866 F 1.366(xample, a user could retrie)-.15 F 1.666 -.15(ve a v)-.25 -H 1.365(alue for)-.1 F F1($P)3.865 E -.95(AT)-.74 G(H).95 E F0 1.365 -(guaranteed to \214nd all of the)3.865 F .884 -(POSIX standard utilities, or \214nd out ho)72 132 R 3.385(wl)-.25 G -.885 -(ong \214lenames may be in the \214le system containing a speci\214ed) --3.385 F(directory)72 144 Q(.)-.65 E 1.521 -(There are no implementation timetables for an)97 159.6 R 4.021(yo)-.15 -G 4.021(ft)-4.021 G 1.52(hese features, nor are there concrete plans to) --4.021 F(include them.)72 171.6 Q(If an)5 E(yone has comments on these \ -proposals, feel free to send me electronic mail.)-.15 E F1 2.5 -(6. Re\215ections)72 195.6 R(and Lessons Lear)2.5 E(ned)-.15 E F0 .433 -(The lesson that has been repeated most often during Bash de)97 211.2 R --.15(ve)-.25 G .433(lopment is that there are dark corners).15 F .181 -(in the Bourne shell, and people use all of them.)72 223.2 R .18 -(In the original description of the Bourne shell, quoting and)5.181 F -.073(the shell grammar are both poorly speci\214ed and incomplete; subs\ -equent descriptions ha)72 235.2 R .373 -.15(ve n)-.2 H .073 -(ot helped much.).15 F 1.856(The grammar presented in Bourne')72 247.2 R -4.356(sp)-.55 G 1.856(aper describing the shell distrib)-4.356 F 1.855 -(uted with the Se)-.2 F -.15(ve)-.25 G 1.855(nth Edition of).15 F/F2 9 -/Times-Roman@0 SF(UNIX)72 259.2 Q F0 2.5<8769>C 2.5(ss)-2.5 G 2.5(of) --2.5 G(ar of)-2.6 E 2.5(ft)-.25 G(hat it does not allo)-2.5 E 2.5(wt) --.25 G(he command)-2.5 E/F3 10/Courier@0 SF(who|wc)2.5 E F0 5(.I)C 2.5 -(nf)-5 G(act, as T)-2.6 E(om Duf)-.8 E 2.5(fs)-.25 G(tates:)-2.5 E 1.375 -(Nobody really kno)97 274.8 R 1.375(ws what the Bourne shell')-.25 F -3.875(sg)-.55 G 1.375(rammar is.)-3.875 F(Ev)6.376 E 1.376(en e)-.15 F -1.376(xamination of the source)-.15 F(code is little help.\210)97 286.8 -Q .382(The POSIX.2 standard includes a)72 302.4 R/F4 10/Times-Italic@0 -SF(yacc)2.882 E F0 .382 -(grammar that comes close to capturing the Bourne shell')2.882 F 2.882 -(sb)-.55 G(eha)-2.882 E(vior)-.2 E(,)-.4 E -.2(bu)72 314.4 S 3.246(ti).2 -G 3.246(td)-3.246 G(isallo)-3.246 E .747(ws some constructs which sh ac\ -cepts without complaint \255 and there are scripts out there that)-.25 F -.501(use them.)72 326.4 R .501(It took a fe)5.501 F 3.001(wv)-.25 G .501 -(ersions and se)-3.151 F -.15(ve)-.25 G .501(ral b).15 F .5 -(ug reports before Bash implemented sh-compatible quoting,)-.2 F .279 -(and there are still some \231le)72 338.4 R -.05(ga)-.15 G .279 -(l\232 sh constructs which Bash \215ags as syntax errors.).05 F .28 -(Complete sh compatibility)5.28 F(is a tough nut.)72 350.4 Q 1.231 -(The shell is bigger and slo)97 366 R 1.231(wer than I w)-.25 F 1.231 -(ould lik)-.1 F 1.23(e, though the current v)-.1 F 1.23 -(ersion is substantially f)-.15 F(aster)-.1 E .086(than pre)72 378 R -(viously)-.25 E 5.086(.T)-.65 G .087 -(he readline library could stand a substantial re)-5.086 F 2.587 -(write. A)-.25 F .087(hand-written parser to replace the)2.587 F -(current)72 390 Q F4(yacc)2.978 E F0 .478(-generated one w)B .477 -(ould probably result in a speedup, and w)-.1 F .477(ould solv)-.1 F -2.977(eo)-.15 G .477(ne glaring problem:)-2.977 F(the)5.477 E .384 -(shell could parse commands in \231$\(...\)\232 constructs as the)72 402 -R 2.884(ya)-.15 G .385 -(re entered, rather than reporting errors when the)-2.884 F -(construct is e)72 414 Q(xpanded.)-.15 E 1.064(As al)97 429.6 R -.1(wa) --.1 G 1.064(ys, there is some chaf).1 F 3.564(ft)-.25 G 3.564(og)-3.564 -G 3.564(ow)-3.564 G 1.064(ith the wheat.)-3.564 F 1.063 -(Areas of duplicated functionality need to be)6.063 F .382(cleaned up.) -72 441.6 R .382(There are se)5.382 F -.15(ve)-.25 G .382 -(ral cases where Bash treats a v).15 F .382 -(ariable specially to enable functionality a)-.25 F -.25(va)-.2 G -(ilable).25 E .185(another w)72 453.6 R .185(ay \()-.1 F F1($notify)A F0 -(vs.)2.684 E F1 .184(set -o notify)5.184 F F0(and)2.684 E F1($nolinks) -2.684 E F0(vs.)2.684 E F1 .184(set -o ph)2.684 F(ysical)-.15 E F0 2.684 -(,f)C .184(or instance\); the special treatment)-2.684 F 3.421(of the v) -72 465.6 R 3.421(ariable name should probably be remo)-.25 F -.15(ve) --.15 G 5.921(d. A).15 F(fe)5.921 E 5.921(wm)-.25 G 3.422 -(ore things could stand remo)-5.921 F -.25(va)-.15 G 3.422(l; the).25 F -F1($allo)72 477.6 Q(w_null_glob_expansion)-.1 E F0(and)4.112 E F1 -($glob_dot_\214lenames)4.112 E F0 -.25(va)4.111 G 1.611 -(riables are of particularly questionable v).25 F(alue.)-.25 E(The)72 -489.6 Q F1($[...])3.977 E F0 1.477(arithmetic e)3.977 F -.25(va)-.25 G -1.478(luation syntax is redundant no).25 F 3.978(wt)-.25 G 1.478 -(hat the POSIX-mandated)-3.978 F F1($\(\(...\)\))3.978 E F0 1.478 -(construct has)3.978 F .326(been implemented, and could be deleted.)72 -501.6 R .326(It w)5.326 F .326(ould be nice if the te)-.1 F .326 -(xt output by the)-.15 F F1(help)2.825 E F0 -.2(bu)2.825 G .325 -(iltin were e).2 F(xter)-.15 E(-)-.2 E .061 -(nal to the shell rather than compiled into it.)72 513.6 R .062 -(The beha)5.062 F .062(vior enabled by)-.2 F F1 -($command_oriented_history)2.562 E F0 2.562(,w)C(hich)-2.562 E 1.125 -(causes the shell to attempt to sa)72 525.6 R 1.424 -.15(ve a)-.2 H -1.124(ll lines of a multi-line command in a single history entry).15 F -3.624(,s)-.65 G 1.124(hould be)-3.624 F(made the def)72 537.6 Q -(ault and the v)-.1 E(ariable remo)-.25 E -.15(ve)-.15 G(d.).15 E F1 2.5 -(7. A)72 561.6 R -.1(va)-1 G(ilability).1 E F0 .047 -(As with all other GNU softw)97 577.2 R .047(are, Bash is a)-.1 F -.25 -(va)-.2 G .047(ilable for anon).25 F .047(ymous FTP from)-.15 F F4(pr) -2.547 E(ep.ai.mit.edu:/pub/gnu)-.37 E F0 1.05(and from other GNU softw) -72 589.2 R 1.05(are mirror sites.)-.1 F 1.049(The current v)6.049 F -1.049(ersion is in)-.15 F F4(bash-1.14.1.tar)3.549 E(.gz)-1.11 E F0 -1.049(in that directory)3.549 F(.)-.65 E(Use)72 601.2 Q F4(ar)5.965 E --.15(ch)-.37 G(ie).15 E F0 3.465(to \214nd the nearest archi)5.965 F -3.766 -.15(ve s)-.25 H 5.966(ite. The).15 F 3.466(latest v)5.966 F 3.466 -(ersion is al)-.15 F -.1(wa)-.1 G 3.466(ys a).1 F -.25(va)-.2 G 3.466 -(ilable for FTP from).25 F F4(bash.CWR)72 613.2 Q -.25(U.)-.4 G -(Edu:/pub/dist.).25 E F0(Bash documentation is a)5 E -.25(va)-.2 G -(ilable for FTP from).25 E F4(bash.CWR)2.5 E -.25(U.)-.4 G -(Edu:/pub/bash.).25 E F0 1.169(The Free Softw)97 628.8 R 1.169(are F)-.1 -F 1.169(oundation sells tapes and CD-R)-.15 F 1.168 -(OMs containing Bash; send electronic mail to)-.4 F F3 -(gnu@prep.ai.mit.edu)72 640.8 Q F0(or call)2.5 E F3(+1-617-876-3296)2.5 -E F0(for more information.)2.5 E .694(Bash is also distrib)97 656.4 R -.694(uted with se)-.2 F -.15(ve)-.25 G .694(ral v).15 F .694(ersions of) --.15 F F2(UNIX)3.194 E F0 .694(-compatible systems.)B .695 -(It is included as /bin/sh)5.694 F .948(and /bin/bash on se)72 668.4 R --.15(ve)-.25 G .948(ral Linux distrib).15 F .948 -(utions \(more about the dif)-.2 F .948 -(ference in a moment\), and as contrib)-.25 F(uted)-.2 E .32 LW 144 -678.2 72 678.2 DL/F5 8/Times-Roman@0 SF .781 -(\207S. R. Bourne, \231UNIX T)72 688.2 R .781(ime-Sharing System:)-.28 F -.781(The UNIX Shell\232,)4.781 F/F6 8/Times-Italic@0 SF .78 -(Bell System T)2.78 F(ec)-.736 E .78(hnical J)-.12 F(ournal)-.2 E F5 -2.78(,5)C .78(7\(6\), July-)-2.78 F(August, 1978, pp. 1971-1990.)72 -698.2 Q<8854>72 710 Q .431(om Duf)-.64 F .431 -(f, \231Rc \255 A Shell for Plan 9 and)-.2 F/F7 7/Times-Roman@0 SF(UNIX) -2.432 E F5(systems\232,)2.432 E F6(Pr)2.432 E .432 -(oc. of the Summer 1990 EUUG Confer)-.36 F(ence)-.296 E F5 2.432(,L)C -(on-)-2.432 E(don, July)72 720 Q 2(,1)-.52 G(990, pp. 21-33.)-2 E 0 Cg -EP -%%Page: 11 11 -%%BeginPageSetup -BP -%%EndPageSetup -/F0 10/Times-Roman@0 SF(-11-)279.67 48 Q(softw)72 84 Q(are in BSDI')-.1 -E 2.5(sB)-.55 G(SD/386* and FreeBSD.)-2.5 E .598(The Linux distrib)97 -99.6 R .598(ution deserv)-.2 F .598(es special mention.)-.15 F .598 -(There are tw)5.598 F 3.099(oc)-.1 G .599 -(on\214gurations included in the stan-)-3.099 F .733(dard Bash distrib) -72 111.6 R .732(ution: a \231normal\232 con\214guration, in which all o\ -f the standard features are included, and a)-.2 F .519(\231minimal\232 \ -con\214guration, which omits job control, aliases, history and command \ -line editing, the directory)72 123.6 R .886(stack and)72 135.6 R/F1 10 -/Times-Bold@0 SF(pushd/popd/dirs,)3.386 E F0 .886(process substitution,\ - prompt string special character decoding, and the)3.386 F/F2 10 -/Times-Italic@0 SF(select)3.385 E F0 3.368(construct. This)72 147.6 R -.868(minimal v)3.368 F .869 -(ersion is designed to be a drop-in replacement for the traditional)-.15 -F/F3 9/Times-Roman@0 SF(UNIX)3.369 E F0(/bin/sh,)3.369 E -(and is included as the Linux /bin/sh in se)72 159.6 Q -.15(ve)-.25 G -(ral packagings.).15 E F1 2.5(8. Conclusion)72 183.6 R F0 .8 -(Bash is a w)97 199.2 R(orth)-.1 E 3.3(ys)-.05 G .8(uccessor to sh.)-3.3 -F .8(It is suf)5.8 F .8(\214ciently portable to run on nearly e)-.25 F --.15(ve)-.25 G .8(ry v).15 F .8(ersion of)-.15 F F3(UNIX)3.299 E F0 .31 -(from 4.3 BSD to SVR4.2, and se)72 211.2 R -.15(ve)-.25 G(ral).15 E F3 -(UNIX)2.81 E F0 -.1(wo)2.81 G(rkalik).1 E 2.81(es. It)-.1 F .311(is rob) -2.81 F .311(ust enough to replace sh on most of those)-.2 F 1.515 -(systems, and pro)72 223.2 R 1.515(vides more functionality)-.15 F 6.515 -(.I)-.65 G 4.015(th)-6.515 G 1.515(as se)-4.015 F -.15(ve)-.25 G 1.515 -(ral thousand re).15 F 1.515(gular users, and their feedback has)-.15 F -(helped to mak)72 235.2 Q 2.5(ei)-.1 G 2.5(ta)-2.5 G 2.5(sg)-2.5 G -(ood as it is today \255 a testament to the bene\214ts of free softw) --2.5 E(are.)-.1 E .32 LW 144 710 72 710 DL/F4 8/Times-Roman@0 SF -(*BSD/386 is a trademark of Berk)72 720 Q(ele)-.08 E 2(yS)-.12 G(oftw)-2 -E(are Design, Inc.)-.08 E 0 Cg EP -%%Trailer -end -%%EOF diff --git a/doc/bash.html b/doc/bash.html index adb9e76..50aefa8 100644 --- a/doc/bash.html +++ b/doc/bash.html @@ -14364,6 +14364,6 @@ There may be only one active coprocess at a time.
This document was created by man2html from bash.1.
-Time: 18 November 2020 15:13:09 EST +Time: 31 January 2022 01:02:50 CET diff --git a/doc/bash.info b/doc/bash.info index 2fd137a..7bb16b9 100644 --- a/doc/bash.info +++ b/doc/bash.info @@ -1,4 +1,4 @@ -This is bash.info, produced by makeinfo version 6.7 from +This is bash.info, produced by makeinfo version 6.8 from bashref.texi. This text is a brief description of the features that are present in the diff --git a/doc/bash.ps b/doc/bash.ps index bd38ef3..8070c91 100644 --- a/doc/bash.ps +++ b/doc/bash.ps @@ -1,6 +1,6 @@ %!PS-Adobe-3.0 %%Creator: groff version 1.22.4 -%%CreationDate: Wed Nov 18 15:13:06 2020 +%%CreationDate: Mon Jan 31 01:01:42 2022 %%DocumentNeededResources: font Times-Roman %%+ font Times-Bold %%+ font Times-Italic diff --git a/doc/bashbug.ps b/doc/bashbug.ps index 9c60a33..12390ff 100644 --- a/doc/bashbug.ps +++ b/doc/bashbug.ps @@ -1,6 +1,6 @@ %!PS-Adobe-3.0 %%Creator: groff version 1.22.4 -%%CreationDate: Fri Aug 7 11:58:10 2020 +%%CreationDate: Mon Jan 31 01:01:42 2022 %%DocumentNeededResources: font Times-Roman %%+ font Times-Bold %%+ font Times-Italic diff --git a/doc/bashref.aux b/doc/bashref.aux new file mode 100644 index 0000000..b67ef80 --- /dev/null +++ b/doc/bashref.aux @@ -0,0 +1,390 @@ +@xrdef{Introduction-title}{Introduction} +@xrdef{Introduction-snt}{Chapter@tie 1} +@xrdef{What is Bash?-title}{What is Bash?} +@xrdef{What is Bash?-snt}{Section@tie 1.1} +@xrdef{What is a shell?-title}{What is a shell?} +@xrdef{What is a shell?-snt}{Section@tie 1.2} +@xrdef{Introduction-pg}{1} +@xrdef{What is Bash?-pg}{1} +@xrdef{What is a shell?-pg}{1} +@xrdef{Definitions-title}{Definitions} +@xrdef{Definitions-snt}{Chapter@tie 2} +@xrdef{Definitions-pg}{3} +@xrdef{Basic Shell Features-title}{Basic Shell Features} +@xrdef{Basic Shell Features-snt}{Chapter@tie 3} +@xrdef{Shell Syntax-title}{Shell Syntax} +@xrdef{Shell Syntax-snt}{Section@tie 3.1} +@xrdef{Shell Operation-title}{Shell Operation} +@xrdef{Shell Operation-snt}{Section@tie 3.1.1} +@xrdef{Quoting-title}{Quoting} +@xrdef{Quoting-snt}{Section@tie 3.1.2} +@xrdef{Basic Shell Features-pg}{5} +@xrdef{Shell Syntax-pg}{5} +@xrdef{Shell Operation-pg}{5} +@xrdef{Escape Character-title}{Escape Character} +@xrdef{Escape Character-snt}{Section@tie 3.1.2.1} +@xrdef{Single Quotes-title}{Single Quotes} +@xrdef{Single Quotes-snt}{Section@tie 3.1.2.2} +@xrdef{Double Quotes-title}{Double Quotes} +@xrdef{Double Quotes-snt}{Section@tie 3.1.2.3} +@xrdef{ANSI-C Quoting-title}{ANSI-C Quoting} +@xrdef{ANSI-C Quoting-snt}{Section@tie 3.1.2.4} +@xrdef{Quoting-pg}{6} +@xrdef{Escape Character-pg}{6} +@xrdef{Single Quotes-pg}{6} +@xrdef{Double Quotes-pg}{6} +@xrdef{ANSI-C Quoting-pg}{6} +@xrdef{Locale Translation-title}{Locale-Specific Translation} +@xrdef{Locale Translation-snt}{Section@tie 3.1.2.5} +@xrdef{Comments-title}{Comments} +@xrdef{Comments-snt}{Section@tie 3.1.3} +@xrdef{Locale Translation-pg}{7} +@xrdef{Comments-pg}{7} +@xrdef{Shell Commands-title}{Shell Commands} +@xrdef{Shell Commands-snt}{Section@tie 3.2} +@xrdef{Reserved Words-title}{Reserved Words} +@xrdef{Reserved Words-snt}{Section@tie 3.2.1} +@xrdef{Simple Commands-title}{Simple Commands} +@xrdef{Simple Commands-snt}{Section@tie 3.2.2} +@xrdef{Pipelines-title}{Pipelines} +@xrdef{Pipelines-snt}{Section@tie 3.2.3} +@xrdef{Shell Commands-pg}{8} +@xrdef{Reserved Words-pg}{8} +@xrdef{Simple Commands-pg}{8} +@xrdef{Pipelines-pg}{8} +@xrdef{Lists-title}{Lists of Commands} +@xrdef{Lists-snt}{Section@tie 3.2.4} +@xrdef{Lists-pg}{9} +@xrdef{Compound Commands-title}{Compound Commands} +@xrdef{Compound Commands-snt}{Section@tie 3.2.5} +@xrdef{Looping Constructs-title}{Looping Constructs} +@xrdef{Looping Constructs-snt}{Section@tie 3.2.5.1} +@xrdef{Compound Commands-pg}{10} +@xrdef{Looping Constructs-pg}{10} +@xrdef{Conditional Constructs-title}{Conditional Constructs} +@xrdef{Conditional Constructs-snt}{Section@tie 3.2.5.2} +@xrdef{Conditional Constructs-pg}{11} +@xrdef{Command Grouping-title}{Grouping Commands} +@xrdef{Command Grouping-snt}{Section@tie 3.2.5.3} +@xrdef{Coprocesses-title}{Coprocesses} +@xrdef{Coprocesses-snt}{Section@tie 3.2.6} +@xrdef{Command Grouping-pg}{15} +@xrdef{Coprocesses-pg}{15} +@xrdef{GNU Parallel-title}{GNU Parallel} +@xrdef{GNU Parallel-snt}{Section@tie 3.2.7} +@xrdef{GNU Parallel-pg}{16} +@xrdef{Shell Functions-title}{Shell Functions} +@xrdef{Shell Functions-snt}{Section@tie 3.3} +@xrdef{Shell Functions-pg}{18} +@xrdef{Shell Parameters-title}{Shell Parameters} +@xrdef{Shell Parameters-snt}{Section@tie 3.4} +@xrdef{Shell Parameters-pg}{20} +@xrdef{Positional Parameters-title}{Positional Parameters} +@xrdef{Positional Parameters-snt}{Section@tie 3.4.1} +@xrdef{Special Parameters-title}{Special Parameters} +@xrdef{Special Parameters-snt}{Section@tie 3.4.2} +@xrdef{Positional Parameters-pg}{21} +@xrdef{Special Parameters-pg}{21} +@xrdef{Shell Expansions-title}{Shell Expansions} +@xrdef{Shell Expansions-snt}{Section@tie 3.5} +@xrdef{Shell Expansions-pg}{22} +@xrdef{Brace Expansion-title}{Brace Expansion} +@xrdef{Brace Expansion-snt}{Section@tie 3.5.1} +@xrdef{Brace Expansion-pg}{23} +@xrdef{Tilde Expansion-title}{Tilde Expansion} +@xrdef{Tilde Expansion-snt}{Section@tie 3.5.2} +@xrdef{Tilde Expansion-pg}{24} +@xrdef{Shell Parameter Expansion-title}{Shell Parameter Expansion} +@xrdef{Shell Parameter Expansion-snt}{Section@tie 3.5.3} +@xrdef{Shell Parameter Expansion-pg}{25} +@xrdef{Command Substitution-title}{Command Substitution} +@xrdef{Command Substitution-snt}{Section@tie 3.5.4} +@xrdef{Arithmetic Expansion-title}{Arithmetic Expansion} +@xrdef{Arithmetic Expansion-snt}{Section@tie 3.5.5} +@xrdef{Command Substitution-pg}{31} +@xrdef{Arithmetic Expansion-pg}{31} +@xrdef{Process Substitution-title}{Process Substitution} +@xrdef{Process Substitution-snt}{Section@tie 3.5.6} +@xrdef{Word Splitting-title}{Word Splitting} +@xrdef{Word Splitting-snt}{Section@tie 3.5.7} +@xrdef{Process Substitution-pg}{32} +@xrdef{Word Splitting-pg}{32} +@xrdef{Filename Expansion-title}{Filename Expansion} +@xrdef{Filename Expansion-snt}{Section@tie 3.5.8} +@xrdef{Pattern Matching-title}{Pattern Matching} +@xrdef{Pattern Matching-snt}{Section@tie 3.5.8.1} +@xrdef{Filename Expansion-pg}{33} +@xrdef{Pattern Matching-pg}{33} +@xrdef{Quote Removal-title}{Quote Removal} +@xrdef{Quote Removal-snt}{Section@tie 3.5.9} +@xrdef{Redirections-title}{Redirections} +@xrdef{Redirections-snt}{Section@tie 3.6} +@xrdef{Quote Removal-pg}{35} +@xrdef{Redirections-pg}{35} +@xrdef{Executing Commands-title}{Executing Commands} +@xrdef{Executing Commands-snt}{Section@tie 3.7} +@xrdef{Simple Command Expansion-title}{Simple Command Expansion} +@xrdef{Simple Command Expansion-snt}{Section@tie 3.7.1} +@xrdef{Command Search and Execution-title}{Command Search and Execution} +@xrdef{Command Search and Execution-snt}{Section@tie 3.7.2} +@xrdef{Executing Commands-pg}{39} +@xrdef{Simple Command Expansion-pg}{39} +@xrdef{Command Search and Execution-pg}{39} +@xrdef{Command Execution Environment-title}{Command Execution Environment} +@xrdef{Command Execution Environment-snt}{Section@tie 3.7.3} +@xrdef{Command Execution Environment-pg}{40} +@xrdef{Environment-title}{Environment} +@xrdef{Environment-snt}{Section@tie 3.7.4} +@xrdef{Exit Status-title}{Exit Status} +@xrdef{Exit Status-snt}{Section@tie 3.7.5} +@xrdef{Environment-pg}{41} +@xrdef{Exit Status-pg}{41} +@xrdef{Signals-title}{Signals} +@xrdef{Signals-snt}{Section@tie 3.7.6} +@xrdef{Shell Scripts-title}{Shell Scripts} +@xrdef{Shell Scripts-snt}{Section@tie 3.8} +@xrdef{Signals-pg}{42} +@xrdef{Shell Scripts-pg}{42} +@xrdef{Shell Builtin Commands-title}{Shell Builtin Commands} +@xrdef{Shell Builtin Commands-snt}{Chapter@tie 4} +@xrdef{Bourne Shell Builtins-title}{Bourne Shell Builtins} +@xrdef{Bourne Shell Builtins-snt}{Section@tie 4.1} +@xrdef{Shell Builtin Commands-pg}{44} +@xrdef{Bourne Shell Builtins-pg}{44} +@xrdef{Bash Builtins-title}{Bash Builtin Commands} +@xrdef{Bash Builtins-snt}{Section@tie 4.2} +@xrdef{Bash Builtins-pg}{51} +@xrdef{Modifying Shell Behavior-title}{Modifying Shell Behavior} +@xrdef{Modifying Shell Behavior-snt}{Section@tie 4.3} +@xrdef{The Set Builtin-title}{The Set Builtin} +@xrdef{The Set Builtin-snt}{Section@tie 4.3.1} +@xrdef{Modifying Shell Behavior-pg}{62} +@xrdef{The Set Builtin-pg}{62} +@xrdef{The Shopt Builtin-title}{The Shopt Builtin} +@xrdef{The Shopt Builtin-snt}{Section@tie 4.3.2} +@xrdef{The Shopt Builtin-pg}{66} +@xrdef{Special Builtins-title}{Special Builtins} +@xrdef{Special Builtins-snt}{Section@tie 4.4} +@xrdef{Special Builtins-pg}{72} +@xrdef{Shell Variables-title}{Shell Variables} +@xrdef{Shell Variables-snt}{Chapter@tie 5} +@xrdef{Bourne Shell Variables-title}{Bourne Shell Variables} +@xrdef{Bourne Shell Variables-snt}{Section@tie 5.1} +@xrdef{Bash Variables-title}{Bash Variables} +@xrdef{Bash Variables-snt}{Section@tie 5.2} +@xrdef{Shell Variables-pg}{73} +@xrdef{Bourne Shell Variables-pg}{73} +@xrdef{Bash Variables-pg}{73} +@xrdef{Bash Features-title}{Bash Features} +@xrdef{Bash Features-snt}{Chapter@tie 6} +@xrdef{Invoking Bash-title}{Invoking Bash} +@xrdef{Invoking Bash-snt}{Section@tie 6.1} +@xrdef{Bash Features-pg}{86} +@xrdef{Invoking Bash-pg}{86} +@xrdef{Bash Startup Files-title}{Bash Startup Files} +@xrdef{Bash Startup Files-snt}{Section@tie 6.2} +@xrdef{Bash Startup Files-pg}{88} +@xrdef{Interactive Shells-title}{Interactive Shells} +@xrdef{Interactive Shells-snt}{Section@tie 6.3} +@xrdef{What is an Interactive Shell?-title}{What is an Interactive Shell?} +@xrdef{What is an Interactive Shell?-snt}{Section@tie 6.3.1} +@xrdef{Interactive Shells-pg}{89} +@xrdef{Is this Shell Interactive?-title}{Is this Shell Interactive?} +@xrdef{Is this Shell Interactive?-snt}{Section@tie 6.3.2} +@xrdef{Interactive Shell Behavior-title}{Interactive Shell Behavior} +@xrdef{Interactive Shell Behavior-snt}{Section@tie 6.3.3} +@xrdef{What is an Interactive Shell?-pg}{90} +@xrdef{Is this Shell Interactive?-pg}{90} +@xrdef{Interactive Shell Behavior-pg}{90} +@xrdef{Bash Conditional Expressions-title}{Bash Conditional Expressions} +@xrdef{Bash Conditional Expressions-snt}{Section@tie 6.4} +@xrdef{Bash Conditional Expressions-pg}{91} +@xrdef{Shell Arithmetic-title}{Shell Arithmetic} +@xrdef{Shell Arithmetic-snt}{Section@tie 6.5} +@xrdef{Shell Arithmetic-pg}{93} +@xrdef{Aliases-title}{Aliases} +@xrdef{Aliases-snt}{Section@tie 6.6} +@xrdef{Aliases-pg}{94} +@xrdef{Arrays-title}{Arrays} +@xrdef{Arrays-snt}{Section@tie 6.7} +@xrdef{Arrays-pg}{95} +@xrdef{The Directory Stack-title}{The Directory Stack} +@xrdef{The Directory Stack-snt}{Section@tie 6.8} +@xrdef{Directory Stack Builtins-title}{Directory Stack Builtins} +@xrdef{Directory Stack Builtins-snt}{Section@tie 6.8.1} +@xrdef{The Directory Stack-pg}{97} +@xrdef{Directory Stack Builtins-pg}{97} +@xrdef{Controlling the Prompt-title}{Controlling the Prompt} +@xrdef{Controlling the Prompt-snt}{Section@tie 6.9} +@xrdef{Controlling the Prompt-pg}{98} +@xrdef{The Restricted Shell-title}{The Restricted Shell} +@xrdef{The Restricted Shell-snt}{Section@tie 6.10} +@xrdef{Bash POSIX Mode-title}{Bash POSIX Mode} +@xrdef{Bash POSIX Mode-snt}{Section@tie 6.11} +@xrdef{The Restricted Shell-pg}{100} +@xrdef{Bash POSIX Mode-pg}{101} +@xrdef{Shell Compatibility Mode-title}{Shell Compatibility Mode} +@xrdef{Shell Compatibility Mode-snt}{Section@tie 6.12} +@xrdef{Shell Compatibility Mode-pg}{104} +@xrdef{Job Control-title}{Job Control} +@xrdef{Job Control-snt}{Chapter@tie 7} +@xrdef{Job Control Basics-title}{Job Control Basics} +@xrdef{Job Control Basics-snt}{Section@tie 7.1} +@xrdef{Job Control-pg}{107} +@xrdef{Job Control Basics-pg}{107} +@xrdef{Job Control Builtins-title}{Job Control Builtins} +@xrdef{Job Control Builtins-snt}{Section@tie 7.2} +@xrdef{Job Control Builtins-pg}{108} +@xrdef{Job Control Variables-title}{Job Control Variables} +@xrdef{Job Control Variables-snt}{Section@tie 7.3} +@xrdef{Job Control Variables-pg}{110} +@xrdef{Command Line Editing-title}{Command Line Editing} +@xrdef{Command Line Editing-snt}{Chapter@tie 8} +@xrdef{Introduction and Notation-title}{Introduction to Line Editing} +@xrdef{Introduction and Notation-snt}{Section@tie 8.1} +@xrdef{Readline Interaction-title}{Readline Interaction} +@xrdef{Readline Interaction-snt}{Section@tie 8.2} +@xrdef{Readline Bare Essentials-title}{Readline Bare Essentials} +@xrdef{Readline Bare Essentials-snt}{Section@tie 8.2.1} +@xrdef{Command Line Editing-pg}{111} +@xrdef{Introduction and Notation-pg}{111} +@xrdef{Readline Interaction-pg}{111} +@xrdef{Readline Movement Commands-title}{Readline Movement Commands} +@xrdef{Readline Movement Commands-snt}{Section@tie 8.2.2} +@xrdef{Readline Killing Commands-title}{Readline Killing Commands} +@xrdef{Readline Killing Commands-snt}{Section@tie 8.2.3} +@xrdef{Readline Bare Essentials-pg}{112} +@xrdef{Readline Movement Commands-pg}{112} +@xrdef{Readline Arguments-title}{Readline Arguments} +@xrdef{Readline Arguments-snt}{Section@tie 8.2.4} +@xrdef{Searching-title}{Searching for Commands in the History} +@xrdef{Searching-snt}{Section@tie 8.2.5} +@xrdef{Readline Killing Commands-pg}{113} +@xrdef{Readline Arguments-pg}{113} +@xrdef{Searching-pg}{113} +@xrdef{Readline Init File-title}{Readline Init File} +@xrdef{Readline Init File-snt}{Section@tie 8.3} +@xrdef{Readline Init File Syntax-title}{Readline Init File Syntax} +@xrdef{Readline Init File Syntax-snt}{Section@tie 8.3.1} +@xrdef{Readline Init File-pg}{114} +@xrdef{Readline Init File Syntax-pg}{114} +@xrdef{Conditional Init Constructs-title}{Conditional Init Constructs} +@xrdef{Conditional Init Constructs-snt}{Section@tie 8.3.2} +@xrdef{Conditional Init Constructs-pg}{122} +@xrdef{Sample Init File-title}{Sample Init File} +@xrdef{Sample Init File-snt}{Section@tie 8.3.3} +@xrdef{Sample Init File-pg}{124} +@xrdef{Bindable Readline Commands-title}{Bindable Readline Commands} +@xrdef{Bindable Readline Commands-snt}{Section@tie 8.4} +@xrdef{Commands For Moving-title}{Commands For Moving} +@xrdef{Commands For Moving-snt}{Section@tie 8.4.1} +@xrdef{Bindable Readline Commands-pg}{127} +@xrdef{Commands For Moving-pg}{127} +@xrdef{Commands For History-title}{Commands For Manipulating The History} +@xrdef{Commands For History-snt}{Section@tie 8.4.2} +@xrdef{Commands For History-pg}{128} +@xrdef{Commands For Text-title}{Commands For Changing Text} +@xrdef{Commands For Text-snt}{Section@tie 8.4.3} +@xrdef{Commands For Text-pg}{130} +@xrdef{Commands For Killing-title}{Killing And Yanking} +@xrdef{Commands For Killing-snt}{Section@tie 8.4.4} +@xrdef{Commands For Killing-pg}{131} +@xrdef{Numeric Arguments-title}{Specifying Numeric Arguments} +@xrdef{Numeric Arguments-snt}{Section@tie 8.4.5} +@xrdef{Numeric Arguments-pg}{132} +@xrdef{Commands For Completion-title}{Letting Readline Type For You} +@xrdef{Commands For Completion-snt}{Section@tie 8.4.6} +@xrdef{Commands For Completion-pg}{133} +@xrdef{Keyboard Macros-title}{Keyboard Macros} +@xrdef{Keyboard Macros-snt}{Section@tie 8.4.7} +@xrdef{Miscellaneous Commands-title}{Some Miscellaneous Commands} +@xrdef{Miscellaneous Commands-snt}{Section@tie 8.4.8} +@xrdef{Keyboard Macros-pg}{134} +@xrdef{Miscellaneous Commands-pg}{135} +@xrdef{Readline vi Mode-title}{Readline vi Mode} +@xrdef{Readline vi Mode-snt}{Section@tie 8.5} +@xrdef{Programmable Completion-title}{Programmable Completion} +@xrdef{Programmable Completion-snt}{Section@tie 8.6} +@xrdef{Readline vi Mode-pg}{137} +@xrdef{Programmable Completion-pg}{137} +@xrdef{Programmable Completion Builtins-title}{Programmable Completion Builtins} +@xrdef{Programmable Completion Builtins-snt}{Section@tie 8.7} +@xrdef{Programmable Completion Builtins-pg}{139} +@xrdef{A Programmable Completion Example-title}{A Programmable Completion Example} +@xrdef{A Programmable Completion Example-snt}{Section@tie 8.8} +@xrdef{A Programmable Completion Example-pg}{143} +@xrdef{Using History Interactively-title}{Using History Interactively} +@xrdef{Using History Interactively-snt}{Chapter@tie 9} +@xrdef{Bash History Facilities-title}{Bash History Facilities} +@xrdef{Bash History Facilities-snt}{Section@tie 9.1} +@xrdef{Bash History Builtins-title}{Bash History Builtins} +@xrdef{Bash History Builtins-snt}{Section@tie 9.2} +@xrdef{Using History Interactively-pg}{146} +@xrdef{Bash History Facilities-pg}{146} +@xrdef{Bash History Builtins-pg}{146} +@xrdef{History Interaction-title}{History Expansion} +@xrdef{History Interaction-snt}{Section@tie 9.3} +@xrdef{History Interaction-pg}{148} +@xrdef{Event Designators-title}{Event Designators} +@xrdef{Event Designators-snt}{Section@tie 9.3.1} +@xrdef{Word Designators-title}{Word Designators} +@xrdef{Word Designators-snt}{Section@tie 9.3.2} +@xrdef{Event Designators-pg}{149} +@xrdef{Modifiers-title}{Modifiers} +@xrdef{Modifiers-snt}{Section@tie 9.3.3} +@xrdef{Word Designators-pg}{150} +@xrdef{Modifiers-pg}{150} +@xrdef{Installing Bash-title}{Installing Bash} +@xrdef{Installing Bash-snt}{Chapter@tie 10} +@xrdef{Basic Installation-title}{Basic Installation} +@xrdef{Basic Installation-snt}{Section@tie 10.1} +@xrdef{Installing Bash-pg}{152} +@xrdef{Basic Installation-pg}{152} +@xrdef{Compilers and Options-title}{Compilers and Options} +@xrdef{Compilers and Options-snt}{Section@tie 10.2} +@xrdef{Compiling For Multiple Architectures-title}{Compiling For Multiple Architectures} +@xrdef{Compiling For Multiple Architectures-snt}{Section@tie 10.3} +@xrdef{Installation Names-title}{Installation Names} +@xrdef{Installation Names-snt}{Section@tie 10.4} +@xrdef{Compilers and Options-pg}{153} +@xrdef{Compiling For Multiple Architectures-pg}{153} +@xrdef{Installation Names-pg}{153} +@xrdef{Specifying the System Type-title}{Specifying the System Type} +@xrdef{Specifying the System Type-snt}{Section@tie 10.5} +@xrdef{Sharing Defaults-title}{Sharing Defaults} +@xrdef{Sharing Defaults-snt}{Section@tie 10.6} +@xrdef{Operation Controls-title}{Operation Controls} +@xrdef{Operation Controls-snt}{Section@tie 10.7} +@xrdef{Optional Features-title}{Optional Features} +@xrdef{Optional Features-snt}{Section@tie 10.8} +@xrdef{Specifying the System Type-pg}{154} +@xrdef{Sharing Defaults-pg}{154} +@xrdef{Operation Controls-pg}{154} +@xrdef{Optional Features-pg}{155} +@xrdef{Reporting Bugs-title}{Reporting Bugs} +@xrdef{Reporting Bugs-snt}{Appendix@tie @char65{}} +@xrdef{Reporting Bugs-pg}{160} +@xrdef{Major Differences From The Bourne Shell-title}{Major Differences From The Bourne Shell} +@xrdef{Major Differences From The Bourne Shell-snt}{Appendix@tie @char66{}} +@xrdef{Major Differences From The Bourne Shell-pg}{161} +@xrdef{GNU Free Documentation License-title}{GNU Free Documentation License} +@xrdef{GNU Free Documentation License-snt}{Appendix@tie @char67{}} +@xrdef{GNU Free Documentation License-pg}{167} +@xrdef{Indexes-title}{Indexes} +@xrdef{Indexes-snt}{Appendix@tie @char68{}} +@xrdef{Builtin Index-title}{Index of Shell Builtin Commands} +@xrdef{Builtin Index-snt}{Section@tie @char68.1} +@xrdef{Indexes-pg}{175} +@xrdef{Builtin Index-pg}{175} +@xrdef{Reserved Word Index-title}{Index of Shell Reserved Words} +@xrdef{Reserved Word Index-snt}{Section@tie @char68.2} +@xrdef{Variable Index-title}{Parameter and Variable Index} +@xrdef{Variable Index-snt}{Section@tie @char68.3} +@xrdef{Reserved Word Index-pg}{176} +@xrdef{Variable Index-pg}{177} +@xrdef{Function Index-title}{Function Index} +@xrdef{Function Index-snt}{Section@tie @char68.4} +@xrdef{Function Index-pg}{179} +@xrdef{Concept Index-title}{Concept Index} +@xrdef{Concept Index-snt}{Section@tie @char68.5} +@xrdef{Concept Index-pg}{181} diff --git a/doc/bashref.bt b/doc/bashref.bt new file mode 100644 index 0000000..c474845 --- /dev/null +++ b/doc/bashref.bt @@ -0,0 +1,59 @@ +\entry{:}{44}{\code {:}} +\entry{.}{44}{\code {.}} +\entry{break}{45}{\code {break}} +\entry{cd}{45}{\code {cd}} +\entry{continue}{45}{\code {continue}} +\entry{eval}{45}{\code {eval}} +\entry{exec}{46}{\code {exec}} +\entry{exit}{46}{\code {exit}} +\entry{export}{46}{\code {export}} +\entry{getopts}{46}{\code {getopts}} +\entry{hash}{47}{\code {hash}} +\entry{pwd}{47}{\code {pwd}} +\entry{readonly}{47}{\code {readonly}} +\entry{return}{48}{\code {return}} +\entry{shift}{48}{\code {shift}} +\entry{test}{48}{\code {test}} +\entry{[}{48}{\code {[}} +\entry{times}{50}{\code {times}} +\entry{trap}{50}{\code {trap}} +\entry{umask}{51}{\code {umask}} +\entry{unset}{51}{\code {unset}} +\entry{alias}{51}{\code {alias}} +\entry{bind}{51}{\code {bind}} +\entry{builtin}{53}{\code {builtin}} +\entry{caller}{53}{\code {caller}} +\entry{command}{53}{\code {command}} +\entry{declare}{53}{\code {declare}} +\entry{echo}{55}{\code {echo}} +\entry{enable}{56}{\code {enable}} +\entry{help}{56}{\code {help}} +\entry{let}{56}{\code {let}} +\entry{local}{57}{\code {local}} +\entry{logout}{57}{\code {logout}} +\entry{mapfile}{57}{\code {mapfile}} +\entry{printf}{58}{\code {printf}} +\entry{read}{58}{\code {read}} +\entry{readarray}{60}{\code {readarray}} +\entry{source}{60}{\code {source}} +\entry{type}{60}{\code {type}} +\entry{typeset}{61}{\code {typeset}} +\entry{ulimit}{61}{\code {ulimit}} +\entry{unalias}{62}{\code {unalias}} +\entry{set}{62}{\code {set}} +\entry{shopt}{66}{\code {shopt}} +\entry{dirs}{97}{\code {dirs}} +\entry{popd}{98}{\code {popd}} +\entry{pushd}{98}{\code {pushd}} +\entry{bg}{108}{\code {bg}} +\entry{fg}{108}{\code {fg}} +\entry{jobs}{108}{\code {jobs}} +\entry{kill}{109}{\code {kill}} +\entry{wait}{109}{\code {wait}} +\entry{disown}{110}{\code {disown}} +\entry{suspend}{110}{\code {suspend}} +\entry{compgen}{139}{\code {compgen}} +\entry{complete}{140}{\code {complete}} +\entry{compopt}{143}{\code {compopt}} +\entry{fc}{147}{\code {fc}} +\entry{history}{147}{\code {history}} diff --git a/doc/bashref.bts b/doc/bashref.bts new file mode 100644 index 0000000..57416ae --- /dev/null +++ b/doc/bashref.bts @@ -0,0 +1,80 @@ +\initial {.} +\entry{\code {.}}{44} +\initial {:} +\entry{\code {:}}{44} +\initial {[} +\entry{\code {[}}{48} +\initial {A} +\entry{\code {alias}}{51} +\initial {B} +\entry{\code {bg}}{108} +\entry{\code {bind}}{51} +\entry{\code {break}}{45} +\entry{\code {builtin}}{53} +\initial {C} +\entry{\code {caller}}{53} +\entry{\code {cd}}{45} +\entry{\code {command}}{53} +\entry{\code {compgen}}{139} +\entry{\code {complete}}{140} +\entry{\code {compopt}}{143} +\entry{\code {continue}}{45} +\initial {D} +\entry{\code {declare}}{53} +\entry{\code {dirs}}{97} +\entry{\code {disown}}{110} +\initial {E} +\entry{\code {echo}}{55} +\entry{\code {enable}}{56} +\entry{\code {eval}}{45} +\entry{\code {exec}}{46} +\entry{\code {exit}}{46} +\entry{\code {export}}{46} +\initial {F} +\entry{\code {fc}}{147} +\entry{\code {fg}}{108} +\initial {G} +\entry{\code {getopts}}{46} +\initial {H} +\entry{\code {hash}}{47} +\entry{\code {help}}{56} +\entry{\code {history}}{147} +\initial {J} +\entry{\code {jobs}}{108} +\initial {K} +\entry{\code {kill}}{109} +\initial {L} +\entry{\code {let}}{56} +\entry{\code {local}}{57} +\entry{\code {logout}}{57} +\initial {M} +\entry{\code {mapfile}}{57} +\initial {P} +\entry{\code {popd}}{98} +\entry{\code {printf}}{58} +\entry{\code {pushd}}{98} +\entry{\code {pwd}}{47} +\initial {R} +\entry{\code {read}}{58} +\entry{\code {readarray}}{60} +\entry{\code {readonly}}{47} +\entry{\code {return}}{48} +\initial {S} +\entry{\code {set}}{62} +\entry{\code {shift}}{48} +\entry{\code {shopt}}{66} +\entry{\code {source}}{60} +\entry{\code {suspend}}{110} +\initial {T} +\entry{\code {test}}{48} +\entry{\code {times}}{50} +\entry{\code {trap}}{50} +\entry{\code {type}}{60} +\entry{\code {typeset}}{61} +\initial {U} +\entry{\code {ulimit}}{61} +\entry{\code {umask}}{51} +\entry{\code {unalias}}{62} +\entry{\code {unset}}{51} +\initial {W} +\entry{\code {wait}}{109} diff --git a/doc/bashref.cp b/doc/bashref.cp new file mode 100644 index 0000000..665248a --- /dev/null +++ b/doc/bashref.cp @@ -0,0 +1,121 @@ +\entry{POSIX}{3}{POSIX} +\entry{builtin}{3}{builtin} +\entry{control operator}{3}{control operator} +\entry{exit status}{3}{exit status} +\entry{field}{3}{field} +\entry{filename}{3}{filename} +\entry{job}{3}{job} +\entry{job control}{3}{job control} +\entry{metacharacter}{3}{metacharacter} +\entry{name}{3}{name} +\entry{identifier}{3}{identifier} +\entry{operator, shell}{3}{operator, shell} +\entry{process group}{3}{process group} +\entry{process group ID}{3}{process group ID} +\entry{reserved word}{3}{reserved word} +\entry{return status}{4}{return status} +\entry{signal}{4}{signal} +\entry{special builtin}{4}{special builtin} +\entry{token}{4}{token} +\entry{word}{4}{word} +\entry{Bourne shell}{5}{Bourne shell} +\entry{quoting}{6}{quoting} +\entry{quoting, ANSI}{6}{quoting, ANSI} +\entry{localization}{7}{localization} +\entry{internationalization}{7}{internationalization} +\entry{native languages}{7}{native languages} +\entry{translation, native languages}{7}{translation, native languages} +\entry{comments, shell}{7}{comments, shell} +\entry{commands, shell}{8}{commands, shell} +\entry{reserved words}{8}{reserved words} +\entry{commands, simple}{8}{commands, simple} +\entry{pipeline}{8}{pipeline} +\entry{commands, pipelines}{8}{commands, pipelines} +\entry{command timing}{8}{command timing} +\entry{commands, lists}{9}{commands, lists} +\entry{commands, compound}{10}{commands, compound} +\entry{commands, looping}{10}{commands, looping} +\entry{commands, conditional}{11}{commands, conditional} +\entry{commands, grouping}{15}{commands, grouping} +\entry{coprocess}{15}{coprocess} +\entry{shell function}{18}{shell function} +\entry{functions, shell}{18}{functions, shell} +\entry{parameters}{20}{parameters} +\entry{variable, shell}{20}{variable, shell} +\entry{shell variable}{20}{shell variable} +\entry{parameters, positional}{21}{parameters, positional} +\entry{parameters, special}{21}{parameters, special} +\entry{expansion}{22}{expansion} +\entry{brace expansion}{23}{brace expansion} +\entry{expansion, brace}{23}{expansion, brace} +\entry{tilde expansion}{24}{tilde expansion} +\entry{expansion, tilde}{24}{expansion, tilde} +\entry{parameter expansion}{25}{parameter expansion} +\entry{expansion, parameter}{25}{expansion, parameter} +\entry{command substitution}{31}{command substitution} +\entry{expansion, arithmetic}{31}{expansion, arithmetic} +\entry{arithmetic expansion}{31}{arithmetic expansion} +\entry{process substitution}{32}{process substitution} +\entry{word splitting}{32}{word splitting} +\entry{expansion, filename}{33}{expansion, filename} +\entry{expansion, pathname}{33}{expansion, pathname} +\entry{filename expansion}{33}{filename expansion} +\entry{pathname expansion}{33}{pathname expansion} +\entry{pattern matching}{33}{pattern matching} +\entry{matching, pattern}{33}{matching, pattern} +\entry{redirection}{35}{redirection} +\entry{command expansion}{39}{command expansion} +\entry{command execution}{39}{command execution} +\entry{command search}{39}{command search} +\entry{execution environment}{40}{execution environment} +\entry{environment}{41}{environment} +\entry{exit status}{41}{exit status} +\entry{signal handling}{42}{signal handling} +\entry{shell script}{42}{shell script} +\entry{special builtin}{72}{special builtin} +\entry{login shell}{88}{login shell} +\entry{interactive shell}{88}{interactive shell} +\entry{startup files}{88}{startup files} +\entry{interactive shell}{89}{interactive shell} +\entry{shell, interactive}{89}{shell, interactive} +\entry{expressions, conditional}{91}{expressions, conditional} +\entry{arithmetic, shell}{93}{arithmetic, shell} +\entry{shell arithmetic}{93}{shell arithmetic} +\entry{expressions, arithmetic}{93}{expressions, arithmetic} +\entry{evaluation, arithmetic}{93}{evaluation, arithmetic} +\entry{arithmetic evaluation}{93}{arithmetic evaluation} +\entry{alias expansion}{94}{alias expansion} +\entry{arrays}{95}{arrays} +\entry{directory stack}{97}{directory stack} +\entry{prompting}{98}{prompting} +\entry{restricted shell}{100}{restricted shell} +\entry{POSIX Mode}{101}{POSIX Mode} +\entry{Compatibility Level}{104}{Compatibility Level} +\entry{Compatibility Mode}{104}{Compatibility Mode} +\entry{job control}{107}{job control} +\entry{foreground}{107}{foreground} +\entry{background}{107}{background} +\entry{suspending jobs}{107}{suspending jobs} +\entry{Readline, how to use}{110}{Readline, how to use} +\entry{interaction, readline}{111}{interaction, readline} +\entry{notation, readline}{112}{notation, readline} +\entry{command editing}{112}{command editing} +\entry{editing command lines}{112}{editing command lines} +\entry{killing text}{113}{killing text} +\entry{yanking text}{113}{yanking text} +\entry{kill ring}{113}{kill ring} +\entry{initialization file, readline}{114}{initialization file, readline} +\entry{variables, readline}{115}{variables, readline} +\entry{programmable completion}{137}{programmable completion} +\entry{completion builtins}{139}{completion builtins} +\entry{History, how to use}{145}{History, how to use} +\entry{command history}{146}{command history} +\entry{history list}{146}{history list} +\entry{history builtins}{146}{history builtins} +\entry{history expansion}{148}{history expansion} +\entry{event designators}{149}{event designators} +\entry{history events}{149}{history events} +\entry{installation}{152}{installation} +\entry{configuration}{152}{configuration} +\entry{Bash installation}{152}{Bash installation} +\entry{Bash configuration}{152}{Bash configuration} diff --git a/doc/bashref.cps b/doc/bashref.cps new file mode 100644 index 0000000..b313917 --- /dev/null +++ b/doc/bashref.cps @@ -0,0 +1,139 @@ +\initial {A} +\entry{alias expansion}{94} +\entry{arithmetic evaluation}{93} +\entry{arithmetic expansion}{31} +\entry{arithmetic, shell}{93} +\entry{arrays}{95} +\initial {B} +\entry{background}{107} +\entry{Bash configuration}{152} +\entry{Bash installation}{152} +\entry{Bourne shell}{5} +\entry{brace expansion}{23} +\entry{builtin}{3} +\initial {C} +\entry{command editing}{112} +\entry{command execution}{39} +\entry{command expansion}{39} +\entry{command history}{146} +\entry{command search}{39} +\entry{command substitution}{31} +\entry{command timing}{8} +\entry{commands, compound}{10} +\entry{commands, conditional}{11} +\entry{commands, grouping}{15} +\entry{commands, lists}{9} +\entry{commands, looping}{10} +\entry{commands, pipelines}{8} +\entry{commands, shell}{8} +\entry{commands, simple}{8} +\entry{comments, shell}{7} +\entry{Compatibility Level}{104} +\entry{Compatibility Mode}{104} +\entry{completion builtins}{139} +\entry{configuration}{152} +\entry{control operator}{3} +\entry{coprocess}{15} +\initial {D} +\entry{directory stack}{97} +\initial {E} +\entry{editing command lines}{112} +\entry{environment}{41} +\entry{evaluation, arithmetic}{93} +\entry{event designators}{149} +\entry{execution environment}{40} +\entry{exit status}{3, 41} +\entry{expansion}{22} +\entry{expansion, arithmetic}{31} +\entry{expansion, brace}{23} +\entry{expansion, filename}{33} +\entry{expansion, parameter}{25} +\entry{expansion, pathname}{33} +\entry{expansion, tilde}{24} +\entry{expressions, arithmetic}{93} +\entry{expressions, conditional}{91} +\initial {F} +\entry{field}{3} +\entry{filename}{3} +\entry{filename expansion}{33} +\entry{foreground}{107} +\entry{functions, shell}{18} +\initial {H} +\entry{history builtins}{146} +\entry{history events}{149} +\entry{history expansion}{148} +\entry{history list}{146} +\entry{History, how to use}{145} +\initial {I} +\entry{identifier}{3} +\entry{initialization file, readline}{114} +\entry{installation}{152} +\entry{interaction, readline}{111} +\entry{interactive shell}{88, 89} +\entry{internationalization}{7} +\initial {J} +\entry{job}{3} +\entry{job control}{3, 107} +\initial {K} +\entry{kill ring}{113} +\entry{killing text}{113} +\initial {L} +\entry{localization}{7} +\entry{login shell}{88} +\initial {M} +\entry{matching, pattern}{33} +\entry{metacharacter}{3} +\initial {N} +\entry{name}{3} +\entry{native languages}{7} +\entry{notation, readline}{112} +\initial {O} +\entry{operator, shell}{3} +\initial {P} +\entry{parameter expansion}{25} +\entry{parameters}{20} +\entry{parameters, positional}{21} +\entry{parameters, special}{21} +\entry{pathname expansion}{33} +\entry{pattern matching}{33} +\entry{pipeline}{8} +\entry{POSIX}{3} +\entry{POSIX Mode}{101} +\entry{process group}{3} +\entry{process group ID}{3} +\entry{process substitution}{32} +\entry{programmable completion}{137} +\entry{prompting}{98} +\initial {Q} +\entry{quoting}{6} +\entry{quoting, ANSI}{6} +\initial {R} +\entry{Readline, how to use}{110} +\entry{redirection}{35} +\entry{reserved word}{3} +\entry{reserved words}{8} +\entry{restricted shell}{100} +\entry{return status}{4} +\initial {S} +\entry{shell arithmetic}{93} +\entry{shell function}{18} +\entry{shell script}{42} +\entry{shell variable}{20} +\entry{shell, interactive}{89} +\entry{signal}{4} +\entry{signal handling}{42} +\entry{special builtin}{4, 72} +\entry{startup files}{88} +\entry{suspending jobs}{107} +\initial {T} +\entry{tilde expansion}{24} +\entry{token}{4} +\entry{translation, native languages}{7} +\initial {V} +\entry{variable, shell}{20} +\entry{variables, readline}{115} +\initial {W} +\entry{word}{4} +\entry{word splitting}{32} +\initial {Y} +\entry{yanking text}{113} diff --git a/doc/bashref.dvi b/doc/bashref.dvi index 2b682d27696646a1393ebce7d4d6520eedfb49d7..d2afa4bc7a6f5cb6317b837e6cf4e2992d49d7bc 100644 GIT binary patch delta 71 zcmeB}Y0xp#V1k^Wk)DB}p0S~ofuVs>Hv)}{128}{\code {end-of-history (M->)}} +\entry{reverse-search-history (C-r)}{128}{\code {reverse-search-history (C-r)}} +\entry{forward-search-history (C-s)}{128}{\code {forward-search-history (C-s)}} +\entry{non-incremental-reverse-search-history (M-p)}{128}{\code {non-incremental-reverse-search-history (M-p)}} +\entry{non-incremental-forward-search-history (M-n)}{129}{\code {non-incremental-forward-search-history (M-n)}} +\entry{history-search-forward ()}{129}{\code {history-search-forward ()}} +\entry{history-search-backward ()}{129}{\code {history-search-backward ()}} +\entry{history-substring-search-forward ()}{129}{\code {history-substring-search-forward ()}} +\entry{history-substring-search-backward ()}{129}{\code {history-substring-search-backward ()}} +\entry{yank-nth-arg (M-C-y)}{129}{\code {yank-nth-arg (M-C-y)}} +\entry{yank-last-arg (M-. or M-_)}{129}{\code {yank-last-arg (M-. or M-_)}} +\entry{operate-and-get-next (C-o)}{129}{\code {operate-and-get-next (C-o)}} +\entry{end-of-file (usually C-d)}{130}{\code {\i {end-of-file} (usually C-d)}} +\entry{delete-char (C-d)}{130}{\code {delete-char (C-d)}} +\entry{backward-delete-char (Rubout)}{130}{\code {backward-delete-char (Rubout)}} +\entry{forward-backward-delete-char ()}{130}{\code {forward-backward-delete-char ()}} +\entry{quoted-insert (C-q or C-v)}{130}{\code {quoted-insert (C-q or C-v)}} +\entry{self-insert (a, b, A, 1, !, ...{})}{130}{\code {self-insert (a, b, A, 1, !, \dots {})}} +\entry{bracketed-paste-begin ()}{130}{\code {bracketed-paste-begin ()}} +\entry{transpose-chars (C-t)}{130}{\code {transpose-chars (C-t)}} +\entry{transpose-words (M-t)}{130}{\code {transpose-words (M-t)}} +\entry{upcase-word (M-u)}{131}{\code {upcase-word (M-u)}} +\entry{downcase-word (M-l)}{131}{\code {downcase-word (M-l)}} +\entry{capitalize-word (M-c)}{131}{\code {capitalize-word (M-c)}} +\entry{overwrite-mode ()}{131}{\code {overwrite-mode ()}} +\entry{kill-line (C-k)}{131}{\code {kill-line (C-k)}} +\entry{backward-kill-line (C-x Rubout)}{131}{\code {backward-kill-line (C-x Rubout)}} +\entry{unix-line-discard (C-u)}{131}{\code {unix-line-discard (C-u)}} +\entry{kill-whole-line ()}{131}{\code {kill-whole-line ()}} +\entry{kill-word (M-d)}{131}{\code {kill-word (M-d)}} +\entry{backward-kill-word (M-DEL)}{131}{\code {backward-kill-word (M-\key {DEL})}} +\entry{shell-kill-word (M-C-d)}{131}{\code {shell-kill-word (M-C-d)}} +\entry{shell-backward-kill-word ()}{131}{\code {shell-backward-kill-word ()}} +\entry{shell-transpose-words (M-C-t)}{132}{\code {shell-transpose-words (M-C-t)}} +\entry{unix-word-rubout (C-w)}{132}{\code {unix-word-rubout (C-w)}} +\entry{unix-filename-rubout ()}{132}{\code {unix-filename-rubout ()}} +\entry{delete-horizontal-space ()}{132}{\code {delete-horizontal-space ()}} +\entry{kill-region ()}{132}{\code {kill-region ()}} +\entry{copy-region-as-kill ()}{132}{\code {copy-region-as-kill ()}} +\entry{copy-backward-word ()}{132}{\code {copy-backward-word ()}} +\entry{copy-forward-word ()}{132}{\code {copy-forward-word ()}} +\entry{yank (C-y)}{132}{\code {yank (C-y)}} +\entry{yank-pop (M-y)}{132}{\code {yank-pop (M-y)}} +\entry{digit-argument (M-0, M-1, ...{} M--)}{132}{\code {digit-argument (\kbd {M-0}, \kbd {M-1}, \dots {} \kbd {M--})}} +\entry{universal-argument ()}{132}{\code {universal-argument ()}} +\entry{complete (TAB)}{133}{\code {complete (\key {TAB})}} +\entry{possible-completions (M-?)}{133}{\code {possible-completions (M-?)}} +\entry{insert-completions (M-*)}{133}{\code {insert-completions (M-*)}} +\entry{menu-complete ()}{133}{\code {menu-complete ()}} +\entry{menu-complete-backward ()}{133}{\code {menu-complete-backward ()}} +\entry{delete-char-or-list ()}{133}{\code {delete-char-or-list ()}} +\entry{complete-filename (M-/)}{133}{\code {complete-filename (M-/)}} +\entry{possible-filename-completions (C-x /)}{133}{\code {possible-filename-completions (C-x /)}} +\entry{complete-username (M-~)}{133}{\code {complete-username (M-~)}} +\entry{possible-username-completions (C-x ~)}{133}{\code {possible-username-completions (C-x ~)}} +\entry{complete-variable (M-$)}{134}{\code {complete-variable (M-$)}} +\entry{possible-variable-completions (C-x $)}{134}{\code {possible-variable-completions (C-x $)}} +\entry{complete-hostname (M-@)}{134}{\code {complete-hostname (M-@)}} +\entry{possible-hostname-completions (C-x @)}{134}{\code {possible-hostname-completions (C-x @)}} +\entry{complete-command (M-!)}{134}{\code {complete-command (M-!)}} +\entry{possible-command-completions (C-x !)}{134}{\code {possible-command-completions (C-x !)}} +\entry{dynamic-complete-history (M-TAB)}{134}{\code {dynamic-complete-history (M-\key {TAB})}} +\entry{dabbrev-expand ()}{134}{\code {dabbrev-expand ()}} +\entry{complete-into-braces (M-{\indexlbrace })}{134}{\code {complete-into-braces (M-{\tt \char 123})}} +\entry{start-kbd-macro (C-x ()}{134}{\code {start-kbd-macro (C-x ()}} +\entry{end-kbd-macro (C-x ))}{134}{\code {end-kbd-macro (C-x ))}} +\entry{call-last-kbd-macro (C-x e)}{134}{\code {call-last-kbd-macro (C-x e)}} +\entry{print-last-kbd-macro ()}{134}{\code {print-last-kbd-macro ()}} +\entry{re-read-init-file (C-x C-r)}{135}{\code {re-read-init-file (C-x C-r)}} +\entry{abort (C-g)}{135}{\code {abort (C-g)}} +\entry{do-lowercase-version (M-A, M-B, M-x, ...{})}{135}{\code {do-lowercase-version (M-A, M-B, M-\var {x}, \dots {})}} +\entry{prefix-meta (ESC)}{135}{\code {prefix-meta (\key {ESC})}} +\entry{undo (C-_ or C-x C-u)}{135}{\code {undo (C-_ or C-x C-u)}} +\entry{revert-line (M-r)}{135}{\code {revert-line (M-r)}} +\entry{tilde-expand (M-&)}{135}{\code {tilde-expand (M-&)}} +\entry{set-mark (C-@)}{135}{\code {set-mark (C-@)}} +\entry{exchange-point-and-mark (C-x C-x)}{135}{\code {exchange-point-and-mark (C-x C-x)}} +\entry{character-search (C-])}{135}{\code {character-search (C-])}} +\entry{character-search-backward (M-C-])}{135}{\code {character-search-backward (M-C-])}} +\entry{skip-csi-sequence ()}{135}{\code {skip-csi-sequence ()}} +\entry{insert-comment (M-#)}{136}{\code {insert-comment (M-#)}} +\entry{dump-functions ()}{136}{\code {dump-functions ()}} +\entry{dump-variables ()}{136}{\code {dump-variables ()}} +\entry{dump-macros ()}{136}{\code {dump-macros ()}} +\entry{glob-complete-word (M-g)}{136}{\code {glob-complete-word (M-g)}} +\entry{glob-expand-word (C-x *)}{136}{\code {glob-expand-word (C-x *)}} +\entry{glob-list-expansions (C-x g)}{136}{\code {glob-list-expansions (C-x g)}} +\entry{display-shell-version (C-x C-v)}{136}{\code {display-shell-version (C-x C-v)}} +\entry{shell-expand-line (M-C-e)}{136}{\code {shell-expand-line (M-C-e)}} +\entry{history-expand-line (M-^)}{136}{\code {history-expand-line (M-^)}} +\entry{magic-space ()}{137}{\code {magic-space ()}} +\entry{alias-expand-line ()}{137}{\code {alias-expand-line ()}} +\entry{history-and-alias-expand-line ()}{137}{\code {history-and-alias-expand-line ()}} +\entry{insert-last-argument (M-. or M-_)}{137}{\code {insert-last-argument (M-. or M-_)}} +\entry{edit-and-execute-command (C-x C-e)}{137}{\code {edit-and-execute-command (C-x C-e)}} diff --git a/doc/bashref.fns b/doc/bashref.fns new file mode 100644 index 0000000..db80cd3 --- /dev/null +++ b/doc/bashref.fns @@ -0,0 +1,132 @@ +\initial {A} +\entry{\code {abort (C-g)}}{135} +\entry{\code {accept-line (Newline or Return)}}{128} +\entry{\code {alias-expand-line ()}}{137} +\initial {B} +\entry{\code {backward-char (C-b)}}{127} +\entry{\code {backward-delete-char (Rubout)}}{130} +\entry{\code {backward-kill-line (C-x Rubout)}}{131} +\entry{\code {backward-kill-word (M-\key {DEL})}}{131} +\entry{\code {backward-word (M-b)}}{127} +\entry{\code {beginning-of-history (M-<)}}{128} +\entry{\code {beginning-of-line (C-a)}}{127} +\entry{\code {bracketed-paste-begin ()}}{130} +\initial {C} +\entry{\code {call-last-kbd-macro (C-x e)}}{134} +\entry{\code {capitalize-word (M-c)}}{131} +\entry{\code {character-search (C-])}}{135} +\entry{\code {character-search-backward (M-C-])}}{135} +\entry{\code {clear-display (M-C-l)}}{128} +\entry{\code {clear-screen (C-l)}}{128} +\entry{\code {complete (\key {TAB})}}{133} +\entry{\code {complete-command (M-!)}}{134} +\entry{\code {complete-filename (M-/)}}{133} +\entry{\code {complete-hostname (M-@)}}{134} +\entry{\code {complete-into-braces (M-{\tt \char 123})}}{134} +\entry{\code {complete-username (M-~)}}{133} +\entry{\code {complete-variable (M-$)}}{134} +\entry{\code {copy-backward-word ()}}{132} +\entry{\code {copy-forward-word ()}}{132} +\entry{\code {copy-region-as-kill ()}}{132} +\initial {D} +\entry{\code {dabbrev-expand ()}}{134} +\entry{\code {delete-char (C-d)}}{130} +\entry{\code {delete-char-or-list ()}}{133} +\entry{\code {delete-horizontal-space ()}}{132} +\entry{\code {digit-argument (\kbd {M-0}, \kbd {M-1}, \dots {} \kbd {M--})}}{132} +\entry{\code {display-shell-version (C-x C-v)}}{136} +\entry{\code {do-lowercase-version (M-A, M-B, M-\var {x}, \dots {})}}{135} +\entry{\code {downcase-word (M-l)}}{131} +\entry{\code {dump-functions ()}}{136} +\entry{\code {dump-macros ()}}{136} +\entry{\code {dump-variables ()}}{136} +\entry{\code {dynamic-complete-history (M-\key {TAB})}}{134} +\initial {E} +\entry{\code {edit-and-execute-command (C-x C-e)}}{137} +\entry{\code {end-kbd-macro (C-x ))}}{134} +\entry{\code {\i {end-of-file} (usually C-d)}}{130} +\entry{\code {end-of-history (M->)}}{128} +\entry{\code {end-of-line (C-e)}}{127} +\entry{\code {exchange-point-and-mark (C-x C-x)}}{135} +\initial {F} +\entry{\code {forward-backward-delete-char ()}}{130} +\entry{\code {forward-char (C-f)}}{127} +\entry{\code {forward-search-history (C-s)}}{128} +\entry{\code {forward-word (M-f)}}{127} +\initial {G} +\entry{\code {glob-complete-word (M-g)}}{136} +\entry{\code {glob-expand-word (C-x *)}}{136} +\entry{\code {glob-list-expansions (C-x g)}}{136} +\initial {H} +\entry{\code {history-and-alias-expand-line ()}}{137} +\entry{\code {history-expand-line (M-^)}}{136} +\entry{\code {history-search-backward ()}}{129} +\entry{\code {history-search-forward ()}}{129} +\entry{\code {history-substring-search-backward ()}}{129} +\entry{\code {history-substring-search-forward ()}}{129} +\initial {I} +\entry{\code {insert-comment (M-#)}}{136} +\entry{\code {insert-completions (M-*)}}{133} +\entry{\code {insert-last-argument (M-. or M-_)}}{137} +\initial {K} +\entry{\code {kill-line (C-k)}}{131} +\entry{\code {kill-region ()}}{132} +\entry{\code {kill-whole-line ()}}{131} +\entry{\code {kill-word (M-d)}}{131} +\initial {M} +\entry{\code {magic-space ()}}{137} +\entry{\code {menu-complete ()}}{133} +\entry{\code {menu-complete-backward ()}}{133} +\initial {N} +\entry{\code {next-history (C-n)}}{128} +\entry{\code {next-screen-line ()}}{128} +\entry{\code {non-incremental-forward-search-history (M-n)}}{129} +\entry{\code {non-incremental-reverse-search-history (M-p)}}{128} +\initial {O} +\entry{\code {operate-and-get-next (C-o)}}{129} +\entry{\code {overwrite-mode ()}}{131} +\initial {P} +\entry{\code {possible-command-completions (C-x !)}}{134} +\entry{\code {possible-completions (M-?)}}{133} +\entry{\code {possible-filename-completions (C-x /)}}{133} +\entry{\code {possible-hostname-completions (C-x @)}}{134} +\entry{\code {possible-username-completions (C-x ~)}}{133} +\entry{\code {possible-variable-completions (C-x $)}}{134} +\entry{\code {prefix-meta (\key {ESC})}}{135} +\entry{\code {previous-history (C-p)}}{128} +\entry{\code {previous-screen-line ()}}{127} +\entry{\code {print-last-kbd-macro ()}}{134} +\initial {Q} +\entry{\code {quoted-insert (C-q or C-v)}}{130} +\initial {R} +\entry{\code {re-read-init-file (C-x C-r)}}{135} +\entry{\code {redraw-current-line ()}}{128} +\entry{\code {reverse-search-history (C-r)}}{128} +\entry{\code {revert-line (M-r)}}{135} +\initial {S} +\entry{\code {self-insert (a, b, A, 1, !, \dots {})}}{130} +\entry{\code {set-mark (C-@)}}{135} +\entry{\code {shell-backward-kill-word ()}}{131} +\entry{\code {shell-backward-word (M-C-b)}}{127} +\entry{\code {shell-expand-line (M-C-e)}}{136} +\entry{\code {shell-forward-word (M-C-f)}}{127} +\entry{\code {shell-kill-word (M-C-d)}}{131} +\entry{\code {shell-transpose-words (M-C-t)}}{132} +\entry{\code {skip-csi-sequence ()}}{135} +\entry{\code {start-kbd-macro (C-x ()}}{134} +\initial {T} +\entry{\code {tilde-expand (M-&)}}{135} +\entry{\code {transpose-chars (C-t)}}{130} +\entry{\code {transpose-words (M-t)}}{130} +\initial {U} +\entry{\code {undo (C-_ or C-x C-u)}}{135} +\entry{\code {universal-argument ()}}{132} +\entry{\code {unix-filename-rubout ()}}{132} +\entry{\code {unix-line-discard (C-u)}}{131} +\entry{\code {unix-word-rubout (C-w)}}{132} +\entry{\code {upcase-word (M-u)}}{131} +\initial {Y} +\entry{\code {yank (C-y)}}{132} +\entry{\code {yank-last-arg (M-. or M-_)}}{129} +\entry{\code {yank-nth-arg (M-C-y)}}{129} +\entry{\code {yank-pop (M-y)}}{132} diff --git a/doc/bashref.html b/doc/bashref.html index 6a4c3ab..555348e 100644 --- a/doc/bashref.html +++ b/doc/bashref.html @@ -1,5 +1,8 @@ + + + - - - Bash Reference Manual @@ -25,17 +25,21 @@ A copy of the license is included in the section entitled + + + + @@ -63,7 +68,36 @@ ul.no-bullet {list-style: none} - + +
+
+

+Next: , Previous: , Up: (dir)   [Contents][Index]

+
+

Bash Features

+ +

This text is a brief description of the features that are present in +the Bash shell (version 5.1, 29 October 2020). +The Bash home page is http://www.gnu.org/software/bash/. +

+

This is Edition 5.1, last updated 29 October 2020, +of The GNU Bash Reference Manual, +for Bash, Version 5.1. +

+

Bash contains features that appear in other popular shells, and some +features that only appear in Bash. Some of the shells that Bash has +borrowed concepts from are the Bourne Shell (sh), the Korn Shell +(ksh), and the C-shell (csh and its successor, +tcsh). The following menu breaks the features up into +categories, noting which features were inspired by other shells and +which are specific to Bash. +

+

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. +

+ +

Table of Contents

@@ -266,85 +300,22 @@ ul.no-bullet {list-style: none}
- - -
-

-Next: , Previous: , Up: (dir)   [Contents][Index]

-

Bash Features

- -

This text is a brief description of the features that are present in -the Bash shell (version 5.1, 29 October 2020). -The Bash home page is http://www.gnu.org/software/bash/. -

-

This is Edition 5.1, last updated 29 October 2020, -of The GNU Bash Reference Manual, -for Bash, Version 5.1. -

-

Bash contains features that appear in other popular shells, and some -features that only appear in Bash. Some of the shells that Bash has -borrowed concepts from are the Bourne Shell (sh), the Korn Shell -(ksh), and the C-shell (csh and its successor, -tcsh). The following menu breaks the features up into -categories, noting which features were inspired by other shells and -which are specific to Bash. -

-

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. -

- - - - - - - - - - - - - - - - -
-
+
+

-Next: , Up: Top   [Contents][Index]

+Next: , Up: Bash Features   [Contents][Index]

1 Introduction

- - - - +
-
+
+ @@ -374,7 +345,9 @@ independently-supported ports exist for MS-DOS, OS/2
-
+
+
+

Previous: , Up: Introduction   [Contents][Index]

@@ -433,146 +406,132 @@ editing, command history and aliases. Each of these features is described in this manual.


-
+
+
+
+

2 Definitions

These definitions are used throughout the remainder of this manual.

-
POSIX
-
-

A family of open system standards based on Unix. Bash +

POSIX
+

A family of open system standards based on Unix. Bash is primarily concerned with the Shell and Utilities portion of the POSIX 1003.1 standard.

-
blank
+
blank

A space or tab character.

-
builtin
-
-

A command that is implemented internally by the shell itself, rather +

builtin
+

A command that is implemented internally by the shell itself, rather than by an executable program somewhere in the file system.

-
control operator
-
-

A token that performs a control function. It is a newline +

control operator
+

A token that performs a control function. It is a newline or one of the following: ‘||’, ‘&&’, ‘&’, ‘;’, ‘;;’, ‘;&’, ‘;;&’, ‘|’, ‘|&’, ‘(’, or ‘)’.

-
exit status
-
-

The value returned by a command to its caller. The value is restricted +

exit status
+

The value returned by a command to its caller. The value is restricted to eight bits, so the maximum value is 255.

-
field
-
-

A unit of text that is the result of one of the shell expansions. After +

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.

-
filename
-
-

A string of characters used to identify a file. +

filename
+

A string of characters used to identify a file.

-
job
-
-

A set of processes comprising a pipeline, and any processes descended +

job
+

A set of processes comprising a pipeline, and any processes descended from it, that are all in the same process group.

-
job control
-
-

A mechanism by which users can selectively stop (suspend) and restart +

job control
+

A mechanism by which users can selectively stop (suspend) and restart (resume) execution of processes.

-
metacharacter
-
-

A character that, when unquoted, separates words. A metacharacter is +

metacharacter
+

A character that, when unquoted, separates words. A metacharacter is a space, tab, newline, or one of the following characters: ‘|’, ‘&’, ‘;’, ‘(’, ‘)’, ‘<’, or ‘>’.

-
name
-
- +
name
+

A word consisting solely of letters, numbers, and underscores, and beginning with a letter or underscore. Names are used as shell variable and function names. Also referred to as an identifier.

-
operator
-
-

A control operator or a redirection operator. +

operator
+

A control operator or a redirection operator. See Redirections, for a list of redirection operators. Operators contain at least one unquoted metacharacter.

-
process group
-
-

A collection of related processes each having the same process +

process group
+

A collection of related processes each having the same process group ID.

-
process group ID
-
-

A unique identifier that represents a process group +

process group ID
+

A unique identifier that represents a process group during its lifetime.

-
reserved word
-
-

A word that has a special meaning to the shell. Most reserved +

reserved word
+

A word that has a special meaning to the shell. Most reserved words introduce shell flow control constructs, such as for and while.

-
return status
-
-

A synonym for exit status. +

return status
+

A synonym for exit status.

-
signal
-
-

A mechanism by which a process may be notified by the kernel +

signal
+

A mechanism by which a process may be notified by the kernel of an event occurring in the system.

-
special builtin
-
-

A shell builtin command that has been classified as special by the +

special builtin
+

A shell builtin command that has been classified as special by the POSIX standard.

-
token
-
-

A sequence of characters considered a single unit by the shell. +

token
+

A sequence of characters considered a single unit by the shell. It is either a word or an operator.

-
word
-
-

A sequence of characters treated as a unit by the shell. +

word
+

A sequence of characters treated as a unit by the shell. Words may not include unquoted metacharacters.


-
+
+
+

3 Basic Shell Features

@@ -590,40 +549,24 @@ shell expansions, redirections, which are a way to direct input and output from and to named files, and how the shell executes commands.

- - - - - - - - - - +
-
+
+

3.1 Shell Syntax

- - - - -

When the shell reads input, it proceeds through a sequence of operations. If the input indicates the beginning of a @@ -640,8 +583,14 @@ 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.

+
-
+
+

Next: , Up: Shell Syntax   [Contents][Index]

@@ -679,27 +628,14 @@ status (see Exit Status).
-
+
+
+

Next: , Previous: , Up: Shell Syntax   [Contents][Index]

3.1.2 Quoting

- - - - - - -

Quoting is used to remove the special meaning of certain characters or words to the shell. Quoting can be used to @@ -711,7 +647,7 @@ parameter expansion. 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 -(see History Interaction), the +(see History Expansion), the history expansion character, usually ‘!’, must be quoted to prevent history expansion. See Bash History Facilities, for more details concerning history expansion. @@ -719,8 +655,16 @@ more details concerning history expansion.

There are three quoting mechanisms: the escape character, single quotes, and double quotes.

+
-
+
+

Next: , Up: Quoting   [Contents][Index]

@@ -733,7 +677,9 @@ is treated as a line continuation (that is, it is removed from the input stream and effectively ignored).


-
+
+
+

Next: , Previous: , Up: Quoting   [Contents][Index]

@@ -744,7 +690,9 @@ of each character within the quotes. A single quote may not occur between single quotes, even when preceded by a backslash.


-
+
+
+

Next: , Previous: , Up: Quoting   [Contents][Index]

@@ -776,9 +724,11 @@ The backslash preceding the ‘!’ is not removed. when in double quotes (see Shell Parameter Expansion).


-
+
+
+

3.1.2.4 ANSI-C Quoting

@@ -789,60 +739,60 @@ as specified by the ANSI C standard. Backslash escape sequences, if present, are decoded as follows:

-
\a
+
\a

alert (bell)

-
\b
+
\b

backspace

-
\e
-
\E
+
\e
+
\E

an escape character (not ANSI C)

-
\f
+
\f

form feed

-
\n
+
\n

newline

-
\r
+
\r

carriage return

-
\t
+
\t

horizontal tab

-
\v
+
\v

vertical tab

-
\\
+
\\

backslash

-
\'
+
\'

single quote

-
\"
+
\"

double quote

-
\?
+
\?

question mark

-
\nnn
+
\nnn

the eight-bit character whose value is the octal value nnn (one to three octal digits)

-
\xHH
+
\xHH

the eight-bit character whose value is the hexadecimal value HH (one or two hex digits)

-
\uHHHH
+
\uHHHH

the Unicode (ISO/IEC 10646) character whose value is the hexadecimal value HHHH (one to four hex digits)

-
\UHHHHHHHH
+
\UHHHHHHHH

the Unicode (ISO/IEC 10646) character whose value is the hexadecimal value HHHHHHHH (one to eight hex digits)

-
\cx
+
\cx

a control-x character

@@ -851,7 +801,9 @@ present, are decoded as follows: been present.


-
+
+
+

Previous: , Up: Quoting   [Contents][Index]

@@ -886,7 +838,10 @@ fashion: TEXTDOMAINDIR/LC_MESSAGES/LC_MESSAGES/TEXTDOMAIN.mo.


-
+
+
+
+

Previous: , Up: Shell Syntax   [Contents][Index]

@@ -905,7 +860,10 @@ See Interactive Shells, for a description of w a shell interactive.


-
+
+
+
+ @@ -920,26 +878,19 @@ 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.

- - - - - - - - - +
-
+
+ @@ -965,7 +916,9 @@ the first word of a command (see below for exceptions): words if they are the third word in a for command.


-
+
+
+

Next: , Previous: , Up: Shell Commands   [Contents][Index]

@@ -984,9 +937,11 @@ by the POSIX 1003.1 waitpid function, or 128+n< the command was terminated by signal n.


-
+
+
+

3.2.3 Pipelines

@@ -1038,7 +993,7 @@ total user and system time consumed by the shell and its children. The TIMEFORMAT variable may be used to specify the format of the time information.

-

If the pipeline is not executed asynchronously (see Lists), the +

If the pipeline is not executed asynchronously (see Lists of Commands), the shell waits for all commands in the pipeline to complete.

Each command in a pipeline is executed in its own subshell, which is a @@ -1061,7 +1016,9 @@ The shell waits for all commands in the pipeline to terminate before returning a value.


-
+
+
+ @@ -1120,21 +1077,15 @@ returns a non-zero exit status. executed in the list.


-
+
+
+

-Next: , Previous: , Up: Shell Commands   [Contents][Index]

+Next: , Previous: , Up: Shell Commands   [Contents][Index]

3.2.5 Compound Commands

- - - - -

Compound commands are the shell programming language constructs. Each construct begins with a reserved word or control operator and is @@ -1149,8 +1100,14 @@ followed by a newline in place of a semicolon.

Bash provides looping constructs, conditional commands, and mechanisms to group commands and execute them as a unit.

+
-
+
+ @@ -1163,9 +1120,8 @@ Next:
+

The syntax of the until command is:

@@ -1179,9 +1135,8 @@ The return status is the exit status of the last command executed in consequent-commands, or zero if none was executed.

-
while
-
-

The syntax of the while command is: +

while
+

The syntax of the while command is:

while test-commands; do consequent-commands; done
@@ -1193,9 +1148,8 @@ The return status is the exit status of the last command executed
 in consequent-commands, or zero if none was executed.
 

-
for
-
-

The syntax of the for command is: +

for
+

The syntax of the for command is:

for name [ [in [words …] ] ; ] do commands; done
@@ -1235,17 +1189,18 @@ that is executed, or false if any of the expressions is invalid.
 may be used to control loop execution.
 


-
+
+
+

3.2.5.2 Conditional Constructs

-
if
-
- +
if
+
@@ -1273,9 +1228,8 @@ The return status is the exit status of the last command executed, or zero if no condition tested true.

-
case
-
- +
case
+

The syntax of the case command is:

@@ -1342,9 +1296,8 @@ continuing the case statement execution as if the pattern list had not matched. return status is the exit status of the command-list executed.

-
select
-
- +
select
+

The select construct allows the easy generation of menus. It has almost the same syntax as the for command:

@@ -1383,7 +1336,7 @@ done
-
((…))
+
((…))
(( expression ))
 
@@ -1395,12 +1348,11 @@ otherwise the return status is 1. This is exactly equivalent to

let "expression"
 
-

See Bash Builtins, for a full description of the let builtin. +

See Bash Builtin Commands, for a full description of the let builtin.

-
[[…]]
-
- +
[[…]]
+
[[ expression ]]
 
@@ -1523,20 +1475,20 @@ pattern loses its special meaning of matching any single character. in decreasing order of precedence:

-
( expression )
+
( expression )

Returns the value of expression. This may be used to override the normal precedence of operators.

-
! expression
+
! expression

True if expression is false.

-
expression1 && expression2
+
expression1 && expression2

True if both expression1 and expression2 are true.

-
expression1 || expression2
+
expression1 || expression2

True if either expression1 or expression2 is true.

@@ -1548,7 +1500,9 @@ value of the entire conditional expression.

-
+
+
+ @@ -1561,7 +1515,7 @@ to the entire command list. For example, the output of all the commands in the list may be redirected to a single stream.

-
()
+
()
( list )
 
@@ -1573,9 +1527,8 @@ of the commands in list to be executed in that subshell. Since the effect after the subshell completes.

-
{}
-
- +
{}
+
{ list; }
 
@@ -1598,7 +1551,10 @@ from the list by whitespace. list.


-
+
+
+
+ @@ -1648,7 +1604,9 @@ the coproc command always returns success. The return status of a coprocess is the exit status of command.


-
+
+
+

Previous: , Up: Shell Commands   [Contents][Index]

@@ -1771,7 +1729,10 @@ shell commands, one per line, supplied as an argument), in blocks of ten shell jobs at a time.


-
+
+
+
+ @@ -1943,7 +1904,7 @@ variable with that name that had been shadowed will become visible.

Function names and definitions may be listed with the -f option to the declare (typeset) -builtin command (see Bash Builtins). +builtin command (see Bash Builtin Commands). The -F option to declare or typeset will list the function names only (and optionally the source file and line number, if the extdebug @@ -1959,7 +1920,9 @@ function call stack and restrict the number of function invocations. By default, no limit is placed on the number of recursive calls.


-
+
+
+ @@ -1968,12 +1931,6 @@ Next: , - - - -

A parameter is an entity that stores values. It can be a name, a number, or one of the special characters @@ -1981,7 +1938,7 @@ listed below. A variable is a parameter denoted by a name. A variable has a value and zero or more attributes. Attributes are assigned using the declare builtin command -(see the description of the declare builtin in Bash Builtins). +(see the description of the declare builtin in Bash Builtin Commands).

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 @@ -2030,7 +1987,7 @@ appended to the variable’s value.

A variable can be assigned the nameref attribute using the -n option to the declare or local builtin commands -(see Bash Builtins) +(see Bash Builtin Commands) to create a nameref, or a reference to another variable. This allows variables to be manipulated indirectly. Whenever the nameref variable is referenced, assigned to, unset, or has @@ -2063,8 +2020,13 @@ Namerefs can be unset using the -n option to the unset Otherwise, if unset is executed with the name of a nameref variable as an argument, the variable referenced by the nameref variable will be unset.

+
-
+
+ @@ -2088,7 +2050,9 @@ temporarily replaced when a shell function is executed digit is expanded, it must be enclosed in braces.


-
+
+
+ @@ -2099,9 +2063,7 @@ Previous:

($*) Expands to the positional parameters, starting from one. When the expansion is not within double quotes, each positional parameter @@ -2119,9 +2081,7 @@ If IFS is null, the parameters are joined without intervening separators.

-
@ - -
+
@

($@) Expands to the positional parameters, starting from one. In contexts where word splitting is performed, this expands each @@ -2144,24 +2104,18 @@ When there are no positional parameters, "$@" and expand to nothing (i.e., they are removed).

-
# - -
+
#

($#) Expands to the number of positional parameters in decimal.

-
? - -
+
?

($?) Expands to the exit status of the most recently executed foreground pipeline.

-
- - -
+
-

($-, a hyphen.) Expands to the current option flags as specified upon invocation, by the set @@ -2169,26 +2123,20 @@ builtin command, or those set by the shell itself (such as the -i option).

-
$ - -
+
$

($$) Expands to the process ID of the shell. In a () subshell, it expands to the process ID of the invoking shell, not the subshell.

-
! - -
+
!

($!) Expands to the process ID of the job most recently placed into the background, whether executed as an asynchronous command or using the bg builtin (see Job Control Builtins).

-
0 - -
+
0

($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 @@ -2201,7 +2149,10 @@ to the filename used to invoke Bash, as given by argument zero.


-
+
+
+
+ @@ -2221,29 +2172,6 @@ Next: , Previou
  • filename expansion
  • - - - - - - - - - - -

    The order of expansions is: brace expansion; @@ -2273,8 +2201,20 @@ The only exceptions to this are the expansions of

    After all expansions, quote removal (see Quote Removal) is performed.

    +
    -
    +
    + @@ -2349,7 +2289,9 @@ above example:

    -
    +
    +
    + @@ -2397,35 +2339,35 @@ and the shell assigns the expanded value.

    The following table shows how Bash treats unquoted tilde-prefixes:

    -
    ~
    +
    ~

    The value of $HOME

    -
    ~/foo
    +
    ~/foo

    $HOME/foo

    -
    ~fred/foo
    +
    ~fred/foo

    The subdirectory foo of the home directory of the user fred

    -
    ~+/foo
    +
    ~+/foo

    $PWD/foo

    -
    ~-/foo
    +
    ~-/foo

    ${OLDPWD-'~-'}/foo

    -
    ~N
    +
    ~N

    The string that would be displayed by ‘dirs +N

    -
    ~+N
    +
    ~+N

    The string that would be displayed by ‘dirs +N

    -
    ~-N
    +
    ~-N

    The string that would be displayed by ‘dirs -N

    @@ -2437,7 +2379,9 @@ Bash does not do this, except for the declaration commands listed above, when in POSIX mode.


    -
    +
    +
    + @@ -2496,13 +2440,13 @@ the operator tests for both parameter’s existence and that its is not null; if the colon is omitted, the operator tests only for existence.

    -
    ${parameter:-word}
    +
    ${parameter:-word}

    If parameter is unset or null, the expansion of word is substituted. Otherwise, the value of parameter is substituted.

    -
    ${parameter:=word}
    +
    ${parameter:=word}

    If parameter is unset or null, the expansion of word is assigned to parameter. @@ -2511,7 +2455,7 @@ Positional parameters and special parameters may not be assigned to in this way.

    -
    ${parameter:?word}
    +
    ${parameter:?word}

    If parameter is null or unset, the expansion of word (or a message to that effect if word @@ -2520,14 +2464,14 @@ is not interactive, exits. Otherwise, the value of parameter is substituted.

    -
    ${parameter:+word}
    +
    ${parameter:+word}

    If parameter is null or unset, nothing is substituted, otherwise the expansion of word is substituted.

    -
    ${parameter:offset}
    -
    ${parameter:offset:length}
    +
    ${parameter:offset}
    +
    ${parameter:offset:length}

    This is referred to as Substring Expansion. It expands to up to length characters of the value of parameter starting at the character specified by offset. @@ -2669,16 +2613,16 @@ If offset is 0, and the positional parameters are used, $0

    -
    ${!prefix*}
    -
    ${!prefix@}
    +
    ${!prefix*}
    +
    ${!prefix@}

    Expands to the names of variables whose names begin with prefix, separated by the first character of the IFS special variable. When ‘@’ is used and the expansion appears within double quotes, each variable name expands to a separate word.

    -
    ${!name[@]}
    -
    ${!name[*]}
    +
    ${!name[@]}
    +
    ${!name[*]}

    If name is an array variable, expands to the list of array indices (keys) assigned in name. If name is not an array, expands to 0 if name is set and null @@ -2687,7 +2631,7 @@ When ‘@’ is used and the expansion appears within doubl key expands to a separate word.

    -
    ${#parameter}
    +
    ${#parameter}

    The length in characters of the expanded value of parameter is substituted. If parameter is ‘*’ or ‘@’, the value substituted @@ -2701,8 +2645,8 @@ interpreted as relative to one greater than the maximum index of array, and an index of -1 references the last element.

    -
    ${parameter#word}
    -
    ${parameter##word}
    +
    ${parameter#word}
    +
    ${parameter##word}

    The word is expanded to produce a pattern and matched according to the rules described below (see Pattern Matching). If the pattern matches @@ -2719,8 +2663,8 @@ the pattern removal operation is applied to each member of the array in turn, and the expansion is the resultant list.

    -
    ${parameter%word}
    -
    ${parameter%%word}
    +
    ${parameter%word}
    +
    ${parameter%%word}

    The word is expanded to produce a pattern and matched according to the rules described below (see Pattern Matching). @@ -2737,7 +2681,7 @@ the pattern removal operation is applied to each member of the array in turn, and the expansion is the resultant list.

    -
    ${parameter/pattern/string}
    +
    ${parameter/pattern/string}

    The pattern is expanded to produce a pattern just as in filename expansion. @@ -2766,10 +2710,10 @@ the substitution operation is applied to each member of the array in turn, and the expansion is the resultant list.

    -
    ${parameter^pattern}
    -
    ${parameter^^pattern}
    -
    ${parameter,pattern}
    -
    ${parameter,,pattern}
    +
    ${parameter^pattern}
    +
    ${parameter^^pattern}
    +
    ${parameter,pattern}
    +
    ${parameter,,pattern}

    This expansion modifies the case of alphabetic characters in parameter. The pattern is expanded to produce a pattern just as in filename expansion. @@ -2793,48 +2737,48 @@ the case modification operation is applied to each member of the array in turn, and the expansion is the resultant list.

    -
    ${parameter@operator}
    +
    ${parameter@operator}

    The expansion is either a transformation of the value of parameter or information about parameter itself, depending on the value of operator. Each operator is a single letter:

    -
    U
    +
    U

    The expansion is a string that is the value of parameter with lowercase alphabetic characters converted to uppercase.

    -
    u
    +
    u

    The expansion is a string that is the value of parameter with the first character converted to uppercase, if it is alphabetic.

    -
    L
    +
    L

    The expansion is a string that is the value of parameter with uppercase alphabetic characters converted to lowercase.

    -
    Q
    +
    Q

    The expansion is a string that is the value of parameter quoted in a format that can be reused as input.

    -
    E
    +
    E

    The expansion is a string that is the value of parameter with backslash escape sequences expanded as with the $'…' quoting mechanism.

    -
    P
    +
    P

    The expansion is a string that is the result of expanding the value of parameter as if it were a prompt string (see Controlling the Prompt).

    -
    A
    +
    A

    The expansion is a string in the form of an assignment statement or declare command that, if evaluated, will recreate parameter with its attributes and value.

    -
    K
    +
    K

    Produces a possibly-quoted version of the value of parameter, except that it prints the values of indexed and associative arrays as a sequence of quoted key-value pairs (see Arrays).

    -
    a
    +
    a

    The expansion is a string consisting of flag values representing parameter’s attributes.

    @@ -2854,7 +2798,9 @@ expansion as described below.

    -
    +
    +
    + @@ -2895,7 +2841,9 @@ form, escape the inner backquotes with backslashes. filename expansion are not performed on the results.


    -
    +
    +
    + @@ -2923,7 +2871,9 @@ If the expression is invalid, Bash prints a message indicating failure to the standard error and no substitution occurs.


    -
    +
    +
    + @@ -2960,7 +2910,9 @@ parameter and variable expansion, command substitution, and arithmetic expansion.


    -
    +
    +
    + @@ -3008,15 +2960,13 @@ null argument removal. is performed.


    -
    +
    +
    +

    3.5.8 Filename Expansion

    - - - @@ -3075,8 +3025,12 @@ To get the old behavior of ignoring filenames beginning with a The dotglob option is disabled when GLOBIGNORE is unset.

    +
    -
    +
    + @@ -3094,7 +3048,7 @@ literally.

    The special pattern characters have the following meanings:

    -
    *
    +
    *

    Matches any string, including the null string. When the globstar shell option is enabled, and ‘*’ is used in a filename expansion context, two adjacent ‘*’s used as a single @@ -3103,10 +3057,10 @@ subdirectories. If followed by a ‘/’, two adjacent ‘*’s will match only directories and subdirectories.

    -
    ?
    +
    ?

    Matches any single character.

    -
    […]
    +
    […]

    Matches any one of the enclosed characters. A pair of characters separated by a hyphen denotes a range expression; any character that falls between those two characters, inclusive, @@ -3160,23 +3114,23 @@ Composite patterns may be formed using one or more of the following sub-patterns:

    -
    ?(pattern-list)
    +
    ?(pattern-list)

    Matches zero or one occurrence of the given patterns.

    -
    *(pattern-list)
    +
    *(pattern-list)

    Matches zero or more occurrences of the given patterns.

    -
    +(pattern-list)
    +
    +(pattern-list)

    Matches one or more occurrences of the given patterns.

    -
    @(pattern-list)
    +
    @(pattern-list)

    Matches one of the given patterns.

    -
    !(pattern-list)
    +
    !(pattern-list)

    Matches anything except one of the given patterns.

    @@ -3188,7 +3142,10 @@ Using separate matches against shorter strings, or using arrays of strings instead of a single long string, may be faster.


    -
    +
    +
    +
    + @@ -3199,7 +3156,10 @@ characters ‘\’, ‘'’, and &lsqu result from one of the above expansions are removed.


    -
    +
    +
    +
    + @@ -3265,29 +3225,29 @@ special files, bash will use them; otherwise it will emulate them internally with the behavior described below.

    -
    /dev/fd/fd
    +
    /dev/fd/fd

    If fd is a valid integer, file descriptor fd is duplicated.

    -
    /dev/stdin
    +
    /dev/stdin

    File descriptor 0 is duplicated.

    -
    /dev/stdout
    +
    /dev/stdout

    File descriptor 1 is duplicated.

    -
    /dev/stderr
    +
    /dev/stderr

    File descriptor 2 is duplicated.

    -
    /dev/tcp/host/port
    +
    /dev/tcp/host/port

    If host is a valid hostname or Internet address, and port is an integer port number or service name, Bash attempts to open the corresponding TCP socket.

    -
    /dev/udp/host/port
    +
    /dev/udp/host/port

    If host is a valid hostname or Internet address, and port is an integer port number or service name, Bash attempts to open the corresponding UDP socket. @@ -3300,7 +3260,20 @@ the corresponding UDP socket. care, as they may conflict with file descriptors the shell uses internally.

    -

    3.6.1 Redirecting Input

    + +
    +

    3.6.1 Redirecting Input

    Redirection of input causes the file whose name results from the expansion of word to be opened for reading on file descriptor n, @@ -3312,7 +3285,9 @@ is not specified.

    [n]<word
     
    -

    3.6.2 Redirecting Output

    +
    +
    +

    3.6.2 Redirecting Output

    Redirection of output causes the file whose name results from the expansion of word to be opened for writing on file descriptor n, @@ -3333,7 +3308,9 @@ If the redirection operator is ‘>|’, or the redirect ‘>’ and the noclobber option is not enabled, the redirection is attempted even if the file named by word exists.

    -

    3.6.3 Appending Redirected Output

    +
    +
    +

    3.6.3 Appending Redirected Output

    Redirection of output in this fashion causes the file whose name results from the expansion of word @@ -3346,7 +3323,9 @@ is not specified. If the file does not exist it is created.

    [n]>>word
     
    -

    3.6.4 Redirecting Standard Output and Standard Error

    +
    +
    +

    3.6.4 Redirecting Standard Output and Standard Error

    This construct allows both the standard output (file descriptor 1) and the standard error output (file descriptor 2) @@ -3371,7 +3350,9 @@ This is semantically equivalent to ‘-’. If it does, other redirection operators apply (see Duplicating File Descriptors below) for compatibility reasons.

    -

    3.6.5 Appending Standard Output and Standard Error

    +
    +
    +

    3.6.5 Appending Standard Output and Standard Error

    This construct allows both the standard output (file descriptor 1) and the standard error output (file descriptor 2) @@ -3388,7 +3369,9 @@ expansion of word.

    (see Duplicating File Descriptors below).

    -

    3.6.6 Here Documents

    +
    +
    +

    3.6.6 Here Documents

    This type of redirection instructs the shell to read input from the current source until a line containing only word (with no trailing blanks) is seen. All of @@ -3420,7 +3403,9 @@ line containing delimiter. This allows here-documents within shell scripts to be indented in a natural fashion.

    -

    3.6.7 Here Strings

    +
    +
    +

    3.6.7 Here Strings

    A variant of here documents, the format is:

    [n]<<< word
    @@ -3435,7 +3420,9 @@ with a newline appended,
     to the command on its
     standard input (or file descriptor n if n is specified).
     

    -

    3.6.8 Duplicating File Descriptors

    +
    +
    +

    3.6.8 Duplicating File Descriptors

    The redirection operator

    [n]<&word
    @@ -3464,7 +3451,9 @@ As a special case, if n is omitted, and word does not
     expand to one or more digits or ‘-’, the standard output and standard
     error are redirected as described previously.
     

    -

    3.6.9 Moving File Descriptors

    +
    +
    +

    3.6.9 Moving File Descriptors

    The redirection operator

    [n]<&digit-
    @@ -3480,7 +3469,9 @@ or the standard input (file descriptor 0) if n is not specified.
     

    moves the file descriptor digit to file descriptor n, or the standard output (file descriptor 1) if n is not specified.

    -

    3.6.10 Opening File Descriptors for Reading and Writing

    +
    +
    +

    3.6.10 Opening File Descriptors for Reading and Writing

    The redirection operator

    [n]<>word
    @@ -3491,34 +3482,27 @@ to be opened for both reading and writing on file descriptor
     is not specified.  If the file does not exist, it is created.
     


    -
    +
    +
    +
    +

    3.7 Executing Commands

    - - - - - - - - +
    -
    +
    + @@ -3564,7 +3548,9 @@ the exit status of the last command substitution performed. If there were no command substitutions, the command exits with a status of zero.


    -
    +
    +
    + @@ -3619,7 +3605,9 @@ the command to complete and collects its exit status.
    -
    +
    +
    + @@ -3655,7 +3643,7 @@ arguments) or by set
  • shell aliases defined with alias (see Aliases)
  • various process IDs, including those of background jobs -(see Lists), the value of $$, and the value of +(see Lists of Commands), the value of $$, and the value of $PPID
  • @@ -3704,7 +3692,9 @@ Otherwise, the invoked command inherits the file descriptors of the calling shell as modified by redirections.


    -
    +
    +
    + @@ -3746,7 +3736,9 @@ is set to the full pathname of the command and passed to that command in its environment.


    -
    +
    +
    +

    Next: , Previous: , Up: Executing Commands   [Contents][Index]

    @@ -3779,7 +3771,7 @@ the exit status is greater than zero.

    The exit status is used by the Bash conditional commands (see Conditional Constructs) and some of the list -constructs (see Lists). +constructs (see Lists of Commands).

    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 @@ -3788,7 +3780,9 @@ All builtins return an exit status of 2 to indicate incorrect usage, generally invalid options or missing arguments.


    -
    +
    +
    + @@ -3838,7 +3832,10 @@ immediately with an exit status greater than 128, immediately after which the trap is executed.


    -
    +
    +
    +
    + @@ -3910,25 +3907,15 @@ under another shell. It’s a common idiom to use env to find in $PATH.


    -
    +
    +
    +
    +

    4 Shell Builtin Commands

    - - - - - -

    Builtin commands are contained within the shell itself. When the name of a builtin command is used as the first word of @@ -3963,10 +3950,17 @@ Other builtins that accept arguments but are not specified as accepting options interpret arguments beginning with ‘-’ as invalid options and require ‘--’ to prevent this interpretation.

    +
    -
    +
    +

    4.1 Bourne Shell Builtins

    @@ -3974,9 +3968,8 @@ Next: , Up: < These commands are implemented as specified by the POSIX standard.

    -
    : (a colon)
    -
    -
    +
    : (a colon)
    +
    : [arguments]
     
    @@ -3984,9 +3977,8 @@ These commands are implemented as specified by the POSIX standard The return status is zero.

    -
    . (a period)
    -
    -
    +
    . (a period)
    +
    . filename [arguments]
     
    @@ -4010,9 +4002,8 @@ cannot be read, the return status is non-zero. This builtin is equivalent to source.

    -
    break
    -
    -
    +
    break
    +
    break [n]
     
    @@ -4022,9 +4013,8 @@ If n is supplied, the nth enclosing loop is exited. The return status is zero unless n is not greater than or equal to 1.

    -
    cd
    -
    -
    +
    cd
    +
    cd [-L|[-P [-e]] [-@] [directory]
     
    @@ -4071,9 +4061,8 @@ written to the standard output. non-zero otherwise.

    -
    continue
    -
    -
    +
    continue
    +
    continue [n]
     
    @@ -4085,9 +4074,8 @@ is resumed. The return status is zero unless n is not greater than or equal to 1.

    -
    eval
    -
    -
    +
    eval
    +
    eval [arguments]
     
    @@ -4098,9 +4086,8 @@ If there are no arguments or only empty arguments, the return status is zero.

    -
    exec
    -
    -
    +
    exec
    +
    exec [-cl] [-a name] [command [arguments]]
     
    @@ -4124,9 +4111,8 @@ the current shell environment. If there are no redirection errors, the return status is zero; otherwise the return status is non-zero.

    -
    exit
    -
    -
    +
    exit
    +
    exit [n]
     
    @@ -4135,9 +4121,8 @@ If n is omitted, the exit status is that of the last command executed Any trap on EXIT is executed before the shell terminates.

    -
    export
    -
    -
    +
    export
    +
    export [-fn] [-p] [name[=value]]
     
    @@ -4156,9 +4141,8 @@ the names is not a valid shell variable name, or -f is supplied with a name that is not a shell function.

    -
    getopts
    -
    -
    +
    getopts
    +
    getopts optstring name [arg …]
     
    @@ -4212,9 +4196,8 @@ If getopts is silent, then a colon (‘:’) i name and OPTARG is set to the option character found.

    -
    hash
    -
    -
    +
    hash
    +
    hash [-r] [-p filename] [-dt] [name]
     
    @@ -4241,9 +4224,8 @@ The return status is zero unless a name is not found or an invalid option is supplied.

    -
    pwd
    -
    -
    +
    pwd
    +
    pwd [-LP]
     
    @@ -4257,9 +4239,8 @@ determining the name of the current directory or an invalid option is supplied.

    -
    readonly
    -
    -
    +
    readonly
    +
    readonly [-aAf] [-p] [name[=value]] …
     
    @@ -4284,9 +4265,8 @@ the name arguments is not a valid shell variable or function name, or the -f option is supplied with a name that is not a shell function.

    -
    return
    -
    -
    +
    return
    +
    return [n]
     
    @@ -4313,9 +4293,8 @@ argument or is used outside a function and not during the execution of a script by . or source.

    -
    shift
    -
    -
    +
    shift
    +
    shift [n]
     
    @@ -4332,10 +4311,9 @@ The return status is zero unless n is greater than $# or less than zero, non-zero otherwise.

    -
    test
    -
    [
    -
    - +
    test
    +
    [
    +
    test expr
     
    @@ -4357,20 +4335,20 @@ The evaluation depends on the number of arguments; see below. Operator precedence is used when there are five or more arguments.

    -
    ! expr
    +
    ! expr

    True if expr is false.

    -
    ( expr )
    +
    ( expr )

    Returns the value of expr. This may be used to override the normal precedence of operators.

    -
    expr1 -a expr2
    +
    expr1 -a expr2

    True if both expr1 and expr2 are true.

    -
    expr1 -o expr2
    +
    expr1 -o expr2

    True if either expr1 or expr2 is true.

    @@ -4379,15 +4357,15 @@ This may be used to override the normal precedence of operators. expressions using a set of rules based on the number of arguments.

    -
    0 arguments
    +
    0 arguments

    The expression is false.

    -
    1 argument
    +
    1 argument

    The expression is true if, and only if, the argument is not null.

    -
    2 arguments
    +
    2 arguments

    If the first argument is ‘!’, the expression is true if and only if the second argument is null. If the first argument is one of the unary conditional operators @@ -4397,7 +4375,7 @@ If the first argument is not a valid unary operator, the expression is false.

    -
    3 arguments
    +
    3 arguments

    The following conditions are applied in the order listed.

      @@ -4416,14 +4394,14 @@ argument.
    -
    4 arguments
    +
    4 arguments

    If the first argument is ‘!’, 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.

    -
    5 or more arguments
    +
    5 or more arguments

    The expression is parsed and evaluated according to precedence using the rules listed above.

    @@ -4433,9 +4411,8 @@ using the rules listed above. operators sort lexicographically using ASCII ordering.

    -
    times
    -
    -
    +
    times
    +
    times
     
    @@ -4443,9 +4420,8 @@ operators sort lexicographically using ASCII ordering. The return status is zero.

    -
    trap
    -
    -
    +
    trap
    +
    trap [-lp] [arg] [sigspec …]
     
    @@ -4505,9 +4481,8 @@ values in a subshell or subshell environment when one is created. valid signal.

    -
    umask
    -
    -
    +
    umask
    +
    umask [-p] [-S] [mode]
     
    @@ -4528,9 +4503,8 @@ of the umask is subtracted from 7. Thus, a umask of 022755.

    -
    unset
    -
    -
    +
    unset
    +
    unset [-fnv] [name]
     
    @@ -4554,7 +4528,9 @@ The return status is zero unless a name is readonly.

    -
    +
    +
    + @@ -4565,9 +4541,8 @@ or have been extended in Bash. Some of these commands are specified in the POSIX standard.

    -
    alias
    -
    -
    +
    alias
    +
    alias [-p] [name[=value] …]
     
    @@ -4580,9 +4555,8 @@ and value of the alias is printed. Aliases are described in Aliases.

    -
    bind
    -
    -
    +
    bind
    +
    bind [-m keymap] [-lpsvPSVX]
     bind [-m keymap] [-q function] [-u function] [-r keyseq]
     bind [-m keymap] -f filename
    @@ -4603,7 +4577,7 @@ but each binding or command must be passed as a separate argument;  e.g.,
     

    Options, if supplied, have the following meanings:

    -
    -m keymap
    +
    -m keymap

    Use keymap as the keymap to be affected by the subsequent bindings. Acceptable keymap names are @@ -4619,55 +4593,55 @@ names are synonym); emacs is equivalent to emacs-standard.

    -
    -l
    +
    -l

    List the names of all Readline functions.

    -
    -p
    +
    -p

    Display Readline function names and bindings in such a way that they can be used as input or in a Readline initialization file.

    -
    -P
    +
    -P

    List current Readline function names and bindings.

    -
    -v
    +
    -v

    Display Readline variable names and values in such a way that they can be used as input or in a Readline initialization file.

    -
    -V
    +
    -V

    List current Readline variable names and values.

    -
    -s
    +
    -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.

    -
    -S
    +
    -S

    Display Readline key sequences bound to macros and the strings they output.

    -
    -f filename
    +
    -f filename

    Read key bindings from filename.

    -
    -q function
    +
    -q function

    Query about which keys invoke the named function.

    -
    -u function
    +
    -u function

    Unbind all keys bound to the named function.

    -
    -r keyseq
    +
    -r keyseq

    Remove any current binding for keyseq.

    -
    -x keyseq:shell-command
    +
    -x keyseq:shell-command

    Cause shell-command to be executed whenever keyseq is entered. When shell-command is executed, the shell sets the @@ -4680,7 +4654,7 @@ If the executed command changes the value of any of READLINE_LINE, reflected in the editing state.

    -
    -X
    +
    -X

    List all key sequences bound to shell commands and the associated commands in a format that can be reused as input.

    @@ -4690,9 +4664,8 @@ in a format that can be reused as input. error occurs.

    -
    builtin
    -
    -
    +
    builtin
    +
    builtin [shell-builtin [args]]
     
    @@ -4704,9 +4677,8 @@ The return status is non-zero if shell-builtin is not a shell builtin command.

    -
    caller
    -
    -
    +
    caller
    +
    caller [expr]
     
    @@ -4726,9 +4698,8 @@ call or expr does not correspond to a valid position in the call stack.

    -
    command
    -
    -
    +
    command
    +
    command [-pVv] command [arguments …]
     
    @@ -4753,9 +4724,8 @@ a more verbose description. In this case, the return status is zero if command is found, and non-zero if not.

    -
    declare
    -
    -
    +
    declare
    +
    declare [-aAfFgiIlnrtux] [-p] [name[=value] …]
     
    @@ -4795,31 +4765,31 @@ If there is no existing variable, the local variable is initially unset. the specified attributes or to give variables attributes:

    -
    -a
    +
    -a

    Each name is an indexed array variable (see Arrays).

    -
    -A
    +
    -A

    Each name is an associative array variable (see Arrays).

    -
    -f
    +
    -f

    Use function names only.

    -
    -i
    +
    -i

    The variable is to be treated as an integer; arithmetic evaluation (see Shell Arithmetic) is performed when the variable is assigned a value.

    -
    -l
    +
    -l

    When the variable is assigned a value, all upper-case characters are converted to lower-case. The upper-case attribute is disabled.

    -
    -n
    +
    -n

    Give each name the nameref attribute, making it a name reference to another variable. That other variable is defined by the value of name. @@ -4830,25 +4800,25 @@ to name, except for those using or changing the The nameref attribute cannot be applied to array variables.

    -
    -r
    +
    -r

    Make names readonly. These names cannot then be assigned values by subsequent assignment statements or unset.

    -
    -t
    +
    -t

    Give each name the trace attribute. Traced functions inherit the DEBUG and RETURN traps from the calling shell. The trace attribute has no special meaning for variables.

    -
    -u
    +
    -u

    When the variable is assigned a value, all lower-case characters are converted to upper-case. The lower-case attribute is disabled.

    -
    -x
    +
    -x

    Mark each name for export to subsequent commands via the environment.

    @@ -4878,9 +4848,8 @@ 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 -f.

    -
    echo
    -
    -
    +
    echo
    +
    echo [-neE] [arg …]
     
    @@ -4899,59 +4868,58 @@ escape characters by default.

    echo interprets the following escape sequences:

    -
    \a
    +
    \a

    alert (bell)

    -
    \b
    +
    \b

    backspace

    -
    \c
    +
    \c

    suppress further output

    -
    \e
    -
    \E
    +
    \e
    +
    \E

    escape

    -
    \f
    +
    \f

    form feed

    -
    \n
    +
    \n

    new line

    -
    \r
    +
    \r

    carriage return

    -
    \t
    +
    \t

    horizontal tab

    -
    \v
    +
    \v

    vertical tab

    -
    \\
    +
    \\

    backslash

    -
    \0nnn
    +
    \0nnn

    the eight-bit character whose value is the octal value nnn (zero to three octal digits)

    -
    \xHH
    +
    \xHH

    the eight-bit character whose value is the hexadecimal value HH (one or two hex digits)

    -
    \uHHHH
    +
    \uHHHH

    the Unicode (ISO/IEC 10646) character whose value is the hexadecimal value HHHH (one to four hex digits)

    -
    \UHHHHHHHH
    +
    \UHHHHHHHH

    the Unicode (ISO/IEC 10646) character whose value is the hexadecimal value HHHHHHHH (one to eight hex digits)

    -
    enable
    -
    -
    +
    enable
    +
    enable [-a] [-dnps] [-f filename] [name …]
     
    @@ -4983,9 +4951,8 @@ a special builtin (see Special Builtins). or there is an error loading a new builtin from a shared object.

    -
    help
    -
    -
    +
    help
    +
    help [-dms] [pattern]
     
    @@ -4997,13 +4964,13 @@ the builtins is printed.

    Options, if supplied, have the following meanings:

    -
    -d
    +
    -d

    Display a short description of each pattern

    -
    -m
    +
    -m

    Display the description of each pattern in a manpage-like format

    -
    -s
    +
    -s

    Display only a short usage synopsis for each pattern

    @@ -5011,9 +4978,8 @@ the builtins is printed.

    The return status is zero unless no command matches pattern.

    -
    let
    -
    -
    +
    let
    +
    let expression [expression …]
     
    @@ -5024,9 +4990,8 @@ last expression evaluates to 0, let returns 1; otherwise 0 is returned.

    -
    local
    -
    -
    +
    local
    +
    local [option] name[=value] …
     
    @@ -5047,9 +5012,8 @@ a function, an invalid name is supplied, or name is a readonly variable.

    -
    logout
    -
    -
    +
    logout
    +
    logout [n]
     
    @@ -5057,9 +5021,8 @@ readonly variable. parent.

    -
    mapfile
    -
    -
    +
    mapfile
    +
    mapfile [-d delim] [-n count] [-O origin] [-s count]
         [-t] [-u fd] [-C callback] [-c quantum] [array]
     
    @@ -5071,33 +5034,33 @@ The variable MAPFILE is the default array. Options, if supplied, have the following meanings:

    -
    -d
    +
    -d

    The first character of delim is used to terminate each input line, rather than newline. If delim is the empty string, mapfile will terminate a line when it reads a NUL character.

    -
    -n
    +
    -n

    Copy at most count lines. If count is 0, all lines are copied.

    -
    -O
    +
    -O

    Begin assigning to array at index origin. The default index is 0.

    -
    -s
    +
    -s

    Discard the first count lines read.

    -
    -t
    +
    -t

    Remove a trailing delim (default newline) from each line read.

    -
    -u
    +
    -u

    Read lines from file descriptor fd instead of the standard input.

    -
    -C
    +
    -C

    Evaluate callback each time quantum lines are read. The -c option specifies quantum.

    -
    -c
    +
    -c

    Specify the number of lines read between each call to callback.

    @@ -5118,9 +5081,8 @@ argument is supplied, array is invalid or unassignable, or array is not an indexed array.

    -
    printf
    -
    -
    +
    printf
    +
    printf [-v var] format [arguments]
     
    @@ -5138,16 +5100,16 @@ In addition to the standard printf(1) formats, printf interprets the following extensions:

    -
    %b
    +
    %b

    Causes printf to expand backslash escape sequences in the corresponding argument in the same way as echo -e -(see Bash Builtins). +(see Bash Builtin Commands).

    -
    %q
    +
    %q

    Causes printf to output the corresponding argument in a format that can be reused as shell input.

    -
    %(datefmt)T
    +
    %(datefmt)T

    Causes printf to output the date-time string resulting from using datefmt as a format string for strftime(3). The corresponding argument is an integer representing the number of @@ -5176,9 +5138,8 @@ appropriate, had been supplied. The return value is zero on success, non-zero on failure.

    -
    read
    -
    -
    +
    read
    +
    read [-ers] [-a aname] [-d delim] [-i text] [-n nchars]
         [-N nchars] [-p prompt] [-t timeout] [-u fd] [name …]
     
    @@ -5203,38 +5164,38 @@ meaning for the next character read and for line continuation.

    Options, if supplied, have the following meanings:

    -
    -a aname
    +
    -a aname

    The words are assigned to sequential indices of the array variable aname, starting at 0. All elements are removed from aname before the assignment. Other name arguments are ignored.

    -
    -d delim
    +
    -d delim

    The first character of delim is used to terminate the input line, rather than newline. If delim is the empty string, read will terminate a line when it reads a NUL character.

    -
    -e
    +
    -e

    Readline (see Command Line Editing) is used to obtain the line. Readline uses the current (or default, if line editing was not previously active) editing settings, but uses Readline’s default filename completion.

    -
    -i text
    +
    -i text

    If Readline is being used to read the line, text is placed into the editing buffer before editing begins.

    -
    -n nchars
    +
    -n nchars

    read returns after reading nchars characters rather than waiting for a complete line of input, but honors a delimiter if fewer than nchars characters are read before the delimiter.

    -
    -N nchars
    +
    -N nchars

    read returns after reading exactly nchars characters rather than waiting for a complete line of input, unless EOF is encountered or read times out. @@ -5246,25 +5207,25 @@ that the variable is assigned exactly the characters read (with the exception of backslash; see the -r option below).

    -
    -p prompt
    +
    -p prompt

    Display prompt, without a trailing newline, before attempting to read any input. The prompt is displayed only if input is coming from a terminal.

    -
    -r
    +
    -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 then be used as a line continuation.

    -
    -s
    +
    -s

    Silent mode. If input is coming from a terminal, characters are not echoed.

    -
    -t timeout
    +
    -t timeout

    Cause read to time out and return failure if a complete line of input (or a specified number of characters) is not read within timeout seconds. @@ -5281,7 +5242,7 @@ the specified file descriptor, non-zero otherwise. The exit status is greater than 128 if the timeout is exceeded.

    -
    -u fd
    +
    -u fd

    Read input from file descriptor fd.

    @@ -5296,9 +5257,8 @@ a variable assignment error (such as assigning to a readonly variable) occurs, or an invalid file descriptor is supplied as the argument to -u.

    -
    readarray
    -
    -
    +
    readarray
    +
    readarray [-d delim] [-n count] [-O origin] [-s count]
         [-t] [-u fd] [-C callback] [-c quantum] [array]
     
    @@ -5310,18 +5270,16 @@ if the -u option is supplied.

    A synonym for mapfile.

    -
    source
    -
    -
    +
    source
    +
    source filename
     

    A synonym for . (see Bourne Shell Builtins).

    -
    type
    -
    -
    +
    type
    +
    type [-afptP] [name …]
     
    @@ -5358,9 +5316,8 @@ shell functions, as with the command builtin. if any are not found.

    -
    typeset
    -
    -
    +
    typeset
    +
    typeset [-afFgrxilnrtux] [-p] [name[=value] …]
     
    @@ -5369,9 +5326,8 @@ shell. It is a synonym for the declare builtin command.

    -
    ulimit
    -
    -
    +
    ulimit
    +
    ulimit [-HS] -a
     ulimit [-HS] [-bcdefiklmnpqrstuvxPRT] [limit]
     
    @@ -5381,101 +5337,101 @@ started by the shell, on systems that allow such control. If an option is given, it is interpreted as follows:

    -
    -S
    +
    -S

    Change and report the soft limit associated with a resource.

    -
    -H
    +
    -H

    Change and report the hard limit associated with a resource.

    -
    -a
    +
    -a

    All current limits are reported; no limits are set.

    -
    -b
    +
    -b

    The maximum socket buffer size.

    -
    -c
    +
    -c

    The maximum size of core files created.

    -
    -d
    +
    -d

    The maximum size of a process’s data segment.

    -
    -e
    +
    -e

    The maximum scheduling priority ("nice").

    -
    -f
    +
    -f

    The maximum size of files written by the shell and its children.

    -
    -i
    +
    -i

    The maximum number of pending signals.

    -
    -k
    +
    -k

    The maximum number of kqueues that may be allocated.

    -
    -l
    +
    -l

    The maximum size that may be locked into memory.

    -
    -m
    +
    -m

    The maximum resident set size (many systems do not honor this limit).

    -
    -n
    +
    -n

    The maximum number of open file descriptors (most systems do not allow this value to be set).

    -
    -p
    +
    -p

    The pipe buffer size.

    -
    -q
    +
    -q

    The maximum number of bytes in POSIX message queues.

    -
    -r
    +
    -r

    The maximum real-time scheduling priority.

    -
    -s
    +
    -s

    The maximum stack size.

    -
    -t
    +
    -t

    The maximum amount of cpu time in seconds.

    -
    -u
    +
    -u

    The maximum number of processes available to a single user.

    -
    -v
    +
    -v

    The maximum amount of virtual memory available to the shell, and, on some systems, to its children.

    -
    -x
    +
    -x

    The maximum number of file locks.

    -
    -P
    +
    -P

    The maximum number of pseudoterminals.

    -
    -R
    +
    -R

    The maximum time a real-time process can run before blocking, in microseconds.

    -
    -T
    +
    -T

    The maximum number of threads.

    @@ -5511,9 +5467,8 @@ and, when in POSIX Mode (see Bash POSI or an error occurs while setting a new limit.

    -
    unalias
    -
    -
    +
    unalias
    +
    unalias [-a] [name … ]
     
    @@ -5524,22 +5479,22 @@ Aliases are described in Aliases.

    -
    +
    +
    +

    4.3 Modifying Shell Behavior

    - - - - +
    -
    +
    + @@ -5550,9 +5505,8 @@ allows you to change the values of shell options and set the positional parameters, or to display the names and values of shell variables.

    -
    set
    -
    -
    +
    set
    +
    set [--abefhkmnptuvxBCEHPT] [-o option-name] [argument …]
     set [+abefhkmnptuvxBCEHPT] [+o option-name] [argument …]
     
    @@ -5568,22 +5522,22 @@ In POSIX mode, only shell variables are listed. Options, if specified, have the following meanings:

    -
    -a
    +
    -a

    Each variable or function that is created or modified is given the export attribute and marked for export to the environment of subsequent commands.

    -
    -b
    +
    -b

    Cause the status of terminated background jobs to be reported immediately, rather than before printing the next primary prompt.

    -
    -e
    +
    -e

    Exit immediately if a pipeline (see Pipelines), which may consist of a single simple command (see Simple Commands), -a list (see Lists), +a list (see Lists of Commands), or a compound command (see Compound Commands) returns a non-zero status. The shell does not exit if the command that fails is part of the @@ -5613,129 +5567,129 @@ effect until the compound command or the command containing the function call completes.

    -
    -f
    +
    -f

    Disable filename expansion (globbing).

    -
    -h
    +
    -h

    Locate and remember (hash) commands as they are looked up for execution. This option is enabled by default.

    -
    -k
    +
    -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.

    -
    -m
    +
    -m

    Job control is enabled (see Job Control). All processes run in a separate process group. When a background job completes, the shell prints a line containing its exit status.

    -
    -n
    +
    -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.

    -
    -o option-name
    +
    -o option-name

    Set the option corresponding to option-name:

    -
    allexport
    +
    allexport

    Same as -a.

    -
    braceexpand
    +
    braceexpand

    Same as -B.

    -
    emacs
    +
    emacs

    Use an emacs-style line editing interface (see Command Line Editing). This also affects the editing interface used for read -e.

    -
    errexit
    +
    errexit

    Same as -e.

    -
    errtrace
    +
    errtrace

    Same as -E.

    -
    functrace
    +
    functrace

    Same as -T.

    -
    hashall
    +
    hashall

    Same as -h.

    -
    histexpand
    +
    histexpand

    Same as -H.

    -
    history
    +
    history

    Enable command history, as described in Bash History Facilities. This option is on by default in interactive shells.

    -
    ignoreeof
    +
    ignoreeof

    An interactive shell will not exit upon reading EOF.

    -
    keyword
    +
    keyword

    Same as -k.

    -
    monitor
    +
    monitor

    Same as -m.

    -
    noclobber
    +
    noclobber

    Same as -C.

    -
    noexec
    +
    noexec

    Same as -n.

    -
    noglob
    +
    noglob

    Same as -f.

    -
    nolog
    +
    nolog

    Currently ignored.

    -
    notify
    +
    notify

    Same as -b.

    -
    nounset
    +
    nounset

    Same as -u.

    -
    onecmd
    +
    onecmd

    Same as -t.

    -
    physical
    +
    physical

    Same as -P.

    -
    pipefail
    +
    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.

    -
    posix
    +
    posix

    Change the behavior of Bash where the default operation differs from the POSIX standard to match the standard (see Bash POSIX Mode). @@ -5743,26 +5697,26 @@ This is intended to make Bash behave as a strict superset of that standard.

    -
    privileged
    +
    privileged

    Same as -p.

    -
    verbose
    +
    verbose

    Same as -v.

    -
    vi
    +
    vi

    Use a vi-style line editing interface. This also affects the editing interface used for read -e.

    -
    xtrace
    +
    xtrace

    Same as -x.

    -
    -p
    +
    -p

    Turn on privileged mode. In this mode, the $BASH_ENV and $ENV files are not processed, shell functions are not inherited from the environment, @@ -5777,22 +5731,22 @@ Turning this option off causes the effective user and group ids to be set to the real user and group ids.

    -
    -t
    +
    -t

    Exit after reading and executing one command.

    -
    -u
    +
    -u

    Treat unset variables and parameters other than the special parameters ‘@’ or ‘*’ as an error when performing parameter expansion. An error message will be written to the standard error, and a non-interactive shell will exit.

    -
    -v
    +
    -v

    Print shell input lines as they are read.

    -
    -x
    +
    -x

    Print a trace of simple commands, for commands, case commands, select commands, and arithmetic for commands and their arguments or associated word lists after they are @@ -5801,28 +5755,28 @@ variable is expanded and the resultant value is printed before the command and its expanded arguments.

    -
    -B
    +
    -B

    The shell will perform brace expansion (see Brace Expansion). This option is on by default.

    -
    -C
    +
    -C

    Prevent output redirection using ‘>’, ‘>&’, and ‘<>’ from overwriting existing files.

    -
    -E
    +
    -E

    If set, any trap on ERR is inherited by shell functions, command substitutions, and commands executed in a subshell environment. The ERR trap is normally not inherited in such cases.

    -
    -H
    -

    Enable ‘!’ style history substitution (see History Interaction). +

    -H
    +

    Enable ‘!’ style history substitution (see History Expansion). This option is on by default for interactive shells.

    -
    -P
    +
    -P

    If set, do not resolve symbolic links when performing commands such as cd which change the current directory. The physical directory is used instead. By default, Bash follows @@ -5847,7 +5801,7 @@ $ cd ..; pwd

    -
    -T
    +
    -T

    If set, any trap on DEBUG and RETURN are inherited by shell functions, command substitutions, and commands executed in a subshell environment. @@ -5855,13 +5809,13 @@ The DEBUG and RETURN traps are normally not inherited in such cases.

    -
    --
    +
    --

    If no arguments follow this option, then the positional parameters are unset. Otherwise, the positional parameters are set to the arguments, even if some of them begin with a ‘-’.

    -
    -
    +
    -

    Signal the end of options, cause all remaining arguments to be assigned to the positional parameters. The -x and -v options are turned off. @@ -5882,7 +5836,9 @@ The special parameter # is set to N.


    -
    +
    +
    + @@ -5891,9 +5847,8 @@ Previous: This builtin allows you to change additional shell optional behavior.

    -
    shopt
    -
    -
    +
    shopt
    +
    shopt [-pqsu] [-o] [optname …]
     
    @@ -5909,15 +5864,15 @@ may be reused as input. Other options have the following meanings:

    -
    -s
    +
    -s

    Enable (set) each optname.

    -
    -u
    +
    -u

    Disable (unset) each optname.

    -
    -q
    +
    -q

    Suppresses normal output; the return status indicates whether the optname is set or unset. If multiple optname arguments are given with -q, @@ -5925,7 +5880,7 @@ the return status is zero if all optnames are enabled; non-zero otherwise.

    -
    -o
    +
    -o

    Restricts the values of optname to be those defined for the -o option to the set builtin (see The Set Builtin). @@ -5946,26 +5901,26 @@ option.

    The list of shopt options is:

    -
    assoc_expand_once
    +
    assoc_expand_once

    If set, the shell suppresses multiple evaluation of associative array subscripts during arithmetic expression evaluation, while executing builtins that can perform variable assignments, and while executing builtins that perform array dereferencing.

    -
    autocd
    +
    autocd

    If set, a command name that is the name of a directory is executed as if it were the argument to the cd command. This option is only used by interactive shells.

    -
    cdable_vars
    +
    cdable_vars

    If this is set, an argument to the 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.

    -
    cdspell
    +
    cdspell

    If set, minor errors in the spelling of a directory component in a cd command will be corrected. The errors checked for are transposed characters, @@ -5975,13 +5930,13 @@ and the command proceeds. This option is only used by interactive shells.

    -
    checkhash
    +
    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.

    -
    checkjobs
    +
    checkjobs

    If set, Bash lists the status of any stopped and running jobs before exiting an interactive shell. If any jobs are running, this causes the exit to be deferred until a second exit is attempted without an @@ -5989,14 +5944,14 @@ intervening command (see Job Control). The shell always postpones exiting if any jobs are stopped.

    -
    checkwinsize
    +
    checkwinsize

    If set, Bash checks the window size after each external (non-builtin) command and, if necessary, updates the values of LINES and COLUMNS. This option is enabled by default.

    -
    cmdhist
    +
    cmdhist

    If set, Bash attempts to save all lines of a multiple-line command in the same history entry. This allows @@ -6005,18 +5960,18 @@ This option is enabled by default, but only has an effect if command history is enabled (see Bash History Facilities).

    -
    compat31
    -
    compat32
    -
    compat40
    -
    compat41
    -
    compat42
    -
    compat43
    -
    compat44
    +
    compat31
    +
    compat32
    +
    compat40
    +
    compat41
    +
    compat42
    +
    compat43
    +
    compat44

    These control aspects of the shell’s compatibility mode (see Shell Compatibility Mode).

    -
    complete_fullquote
    +
    complete_fullquote

    If set, Bash quotes all shell metacharacters in filenames and directory names when performing completion. @@ -6034,7 +5989,7 @@ This variable is set by default, which is the default Bash behavior in versions through 4.2.

    -
    direxpand
    +
    direxpand

    If set, Bash replaces directory names with the results of word expansion when performing filename completion. This changes the contents of the readline editing @@ -6042,33 +5997,33 @@ buffer. If not set, Bash attempts to preserve what the user typed.

    -
    dirspell
    +
    dirspell

    If set, Bash attempts spelling correction on directory names during word completion if the directory name initially supplied does not exist.

    -
    dotglob
    +
    dotglob

    If set, Bash includes filenames beginning with a ‘.’ in the results of filename expansion. The filenames ‘.’ and ‘..’ must always be matched explicitly, even if dotglob is set.

    -
    execfail
    +
    execfail

    If this is set, a non-interactive shell will not exit if it cannot execute the file specified as an argument to the exec builtin command. An interactive shell does not exit if exec fails.

    -
    expand_aliases
    +
    expand_aliases

    If set, aliases are expanded as described below under Aliases, Aliases. This option is enabled by default for interactive shells.

    -
    extdebug
    +
    extdebug

    If set at shell invocation, or in a shell startup file, arrange to execute the debugger profile @@ -6076,7 +6031,7 @@ before the shell starts, identical to the --debugger option. If set after invocation, behavior intended for use by debuggers is enabled:

      -
    1. The -F option to the declare builtin (see Bash Builtins) +
    2. The -F option to the declare builtin (see Bash Builtin Commands) displays the source file name and line number corresponding to each function name supplied as an argument. @@ -6101,23 +6056,23 @@ subshells invoked with ( command ) inherit the
    -
    extglob
    +
    extglob

    If set, the extended pattern matching features described above (see Pattern Matching) are enabled.

    -
    extquote
    +
    extquote

    If set, $'string' and $"string" quoting is performed within ${parameter} expansions enclosed in double quotes. This option is enabled by default.

    -
    failglob
    +
    failglob

    If set, patterns which fail to match filenames during filename expansion result in an expansion error.

    -
    force_fignore
    +
    force_fignore

    If set, the suffixes specified by the FIGNORE shell variable cause words to be ignored when performing word completion even if the ignored words are the only possible completions. @@ -6125,7 +6080,7 @@ See Bash Variables, for a description of FIG This option is enabled by default.

    -
    globasciiranges
    +
    globasciiranges

    If set, range expressions used in pattern matching bracket expressions (see Pattern Matching) behave as if in the traditional C locale when performing @@ -6135,110 +6090,110 @@ is not taken into account, so and upper-case and lower-case ASCII characters will collate together.

    -
    globstar
    +
    globstar

    If set, the pattern ‘**’ used in a filename expansion context will match all files and zero or more directories and subdirectories. If the pattern is followed by a ‘/’, only directories and subdirectories match.

    -
    gnu_errfmt
    +
    gnu_errfmt

    If set, shell error messages are written in the standard GNU error message format.

    -
    histappend
    +
    histappend

    If set, the history list is appended to the file named by the value of the HISTFILE variable when the shell exits, rather than overwriting the file.

    -
    histreedit
    +
    histreedit

    If set, and Readline is being used, a user is given the opportunity to re-edit a failed history substitution.

    -
    histverify
    +
    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.

    -
    hostcomplete
    +
    hostcomplete

    If set, and Readline is being used, Bash will attempt to perform hostname completion when a word containing a ‘@’ is being -completed (see Commands For Completion). This option is enabled +completed (see Letting Readline Type For You). This option is enabled by default.

    -
    huponexit
    +
    huponexit

    If set, Bash will send SIGHUP to all jobs when an interactive login shell exits (see Signals).

    -
    inherit_errexit
    +
    inherit_errexit

    If set, command substitution inherits the value of the errexit option, instead of unsetting it in the subshell environment. This option is enabled when POSIX mode is enabled.

    -
    interactive_comments
    +
    interactive_comments

    Allow a word beginning with ‘#’ to cause that word and all remaining characters on that line to be ignored in an interactive shell. This option is enabled by default.

    -
    lastpipe
    +
    lastpipe

    If set, and job control is not active, the shell runs the last command of a pipeline not executed in the background in the current shell environment.

    -
    lithist
    +
    lithist

    If enabled, and the cmdhist option is enabled, multi-line commands are saved to the history with embedded newlines rather than using semicolon separators where possible.

    -
    localvar_inherit
    +
    localvar_inherit

    If set, local variables inherit the value and attributes of a variable of the same name that exists at a previous scope before any new value is assigned. The nameref attribute is not inherited.

    -
    localvar_unset
    +
    localvar_unset

    If set, calling unset on local variables in previous function scopes marks them so subsequent lookups find them unset until that function returns. This is identical to the behavior of unsetting local variables at the current function scope.

    -
    login_shell
    +
    login_shell

    The shell sets this option if it is started as a login shell (see Invoking Bash). The value may not be changed.

    -
    mailwarn
    +
    mailwarn

    If set, and a file that Bash is checking for mail has been accessed since the last time it was checked, the message "The mail in mailfile has been read" is displayed.

    -
    no_empty_cmd_completion
    +
    no_empty_cmd_completion

    If set, and Readline is being used, Bash will not attempt to search the PATH for possible completions when completion is attempted on an empty line.

    -
    nocaseglob
    +
    nocaseglob

    If set, Bash matches filenames in a case-insensitive fashion when performing filename expansion.

    -
    nocasematch
    +
    nocasematch

    If set, Bash matches patterns in a case-insensitive fashion when performing matching while executing case or [[ conditional commands, @@ -6246,25 +6201,25 @@ when performing pattern substitution word expansions, or when filtering possible completions as part of programmable completion.

    -
    nullglob
    +
    nullglob

    If set, Bash allows filename patterns which match no files to expand to a null string, rather than themselves.

    -
    progcomp
    +
    progcomp

    If set, the programmable completion facilities (see Programmable Completion) are enabled. This option is enabled by default.

    -
    progcomp_alias
    +
    progcomp_alias

    If set, and programmable completion is enabled, Bash treats a command name that doesn’t have any completions as a possible alias and attempts alias expansion. If it has an alias, Bash attempts programmable completion using the command word resulting from the expanded alias.

    -
    promptvars
    +
    promptvars

    If set, prompt strings undergo parameter expansion, command substitution, arithmetic expansion, and quote removal after being expanded @@ -6272,7 +6227,7 @@ as described below (see Controlling the Prompt This option is enabled by default.

    -
    restricted_shell
    +
    restricted_shell

    The shell sets this option if it is started in restricted mode (see The Restricted Shell). The value may not be changed. @@ -6280,19 +6235,19 @@ This is not reset when the startup files are executed, allowing the startup files to discover whether or not a shell is restricted.

    -
    shift_verbose
    +
    shift_verbose

    If this is set, the shift builtin prints an error message when the shift count exceeds the number of positional parameters.

    -
    sourcepath
    +
    sourcepath

    If set, the source builtin uses the value of PATH to find the directory containing the file supplied as an argument. This option is enabled by default.

    -
    xpg_echo
    +
    xpg_echo

    If set, the echo builtin expands backslash-escape sequences by default.

    @@ -6302,7 +6257,10 @@ by default.

    -
    +
    +
    +
    + @@ -6334,25 +6292,26 @@ shift trap unset

    -
    +
    +
    +
    +

    5 Shell Variables

    - - - -

    This chapter describes the shell variables that Bash uses. Bash automatically assigns default values to a number of variables.

    +
    -
    +
    + @@ -6362,41 +6321,31 @@ Next: , Up: In some cases, Bash assigns a default value to the variable.

    -
    CDPATH - -
    +
    CDPATH

    A colon-separated list of directories used as a search path for the cd builtin command.

    -
    HOME - -
    +
    HOME

    The current user’s home directory; the default for the cd builtin command. The value of this variable is also used by tilde expansion (see Tilde Expansion).

    -
    IFS - -
    +
    IFS

    A list of characters that separate fields; used when the shell splits words as part of expansion.

    -
    MAIL - -
    +
    MAIL

    If this parameter is set to a filename or directory name and the MAILPATH variable is not set, Bash informs the user of the arrival of mail in the specified file or Maildir-format directory.

    -
    MAILPATH - -
    +
    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 @@ -6406,21 +6355,15 @@ When used in the text of the message, $_ expands to the name of the current mail file.

    -
    OPTARG - -
    +
    OPTARG

    The value of the last option argument processed by the getopts builtin.

    -
    OPTIND - -
    +
    OPTIND

    The index of the last option argument processed by the getopts builtin.

    -
    PATH - -
    +
    PATH

    A colon-separated list of directories in which the shell looks for commands. A zero-length (null) directory name in the value of PATH indicates the @@ -6429,17 +6372,13 @@ A null directory name may appear as two adjacent colons, or as an initial or trailing colon.

    -
    PS1 - -
    +
    PS1

    The primary prompt string. The default value is ‘\s-\v\$ ’. See Controlling the Prompt, for the complete list of escape sequences that are expanded before PS1 is displayed.

    -
    PS2 - -
    +
    PS2

    The secondary prompt string. The default value is ‘> ’. PS2 is expanded in the same way as PS1 before being displayed. @@ -6448,7 +6387,9 @@ displayed.


    -
    +
    +
    + @@ -6462,9 +6403,7 @@ variables for controlling the job control facilities (see Job Control Variables).

    -
    _ - -
    +
    _

    ($_, an underscore.) At shell startup, set to the pathname used to invoke the @@ -6477,15 +6416,11 @@ and placed in the environment exported to that command. When checking mail, this parameter holds the name of the mail file.

    -
    BASH - -
    +
    BASH

    The full pathname used to execute the current instance of Bash.

    -
    BASHOPTS - -
    +
    BASHOPTS

    A colon-separated list of enabled shell options. Each word in the list is a valid argument for the -s option to the shopt builtin command (see The Shopt Builtin). @@ -6496,9 +6431,7 @@ starts up, each shell option in the list will be enabled before reading any startup files. This variable is readonly.

    -
    BASHPID - -
    +
    BASHPID

    Expands to the process ID of the current Bash process. This differs from $$ under certain circumstances, such as subshells that do not require Bash to be re-initialized. @@ -6508,9 +6441,7 @@ is unset, it loses its special properties, even if it is subsequently reset.

    -
    BASH_ALIASES - -
    +
    BASH_ALIASES

    An associative array variable whose members correspond to the internal list of aliases as maintained by the alias builtin. (see Bourne Shell Builtins). @@ -6522,9 +6453,7 @@ is unset, it loses its special properties, even if it is subsequently reset.

    -
    BASH_ARGC - -
    +
    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 @@ -6540,9 +6469,7 @@ or referencing this variable when extdebug is not set, may result in inconsistent values.

    -
    BASH_ARGV - -
    +
    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 @@ -6557,9 +6484,7 @@ or referencing this variable when extdebug is not set, may result in inconsistent values.

    -
    BASH_ARGV0 - -
    +
    BASH_ARGV0

    When referenced, this variable expands to the name of the shell or shell script (identical to $0; See Special Parameters, for the description of special parameter 0). @@ -6570,9 +6495,7 @@ is unset, it loses its special properties, even if it is subsequently reset.

    -
    BASH_CMDS - -
    +
    BASH_CMDS

    An associative array variable whose members correspond to the internal hash table of commands as maintained by the hash builtin (see Bourne Shell Builtins). @@ -6584,9 +6507,7 @@ is unset, it loses its special properties, even if it is subsequently reset.

    -
    BASH_COMMAND - -
    +
    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. @@ -6595,9 +6516,7 @@ is unset, it loses its special properties, even if it is subsequently reset.

    -
    BASH_COMPAT - -
    +
    BASH_COMPAT

    The value is used to set the shell’s compatibility level. See Shell Compatibility Mode, for a description of the various compatibility levels and their effects. @@ -6616,23 +6535,17 @@ and set the compatibility level to 42. The current version is also a valid value.

    -
    BASH_ENV - -
    +
    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. See Bash Startup Files.

    -
    BASH_EXECUTION_STRING - -
    +
    BASH_EXECUTION_STRING

    The command argument to the -c invocation option.

    -
    BASH_LINENO - -
    +
    BASH_LINENO

    An array variable whose members are the line numbers in source files where each corresponding member of FUNCNAME was invoked. ${BASH_LINENO[$i]} is the line number in the source file @@ -6642,17 +6555,13 @@ referenced within another shell function). Use LINENO to obtain the current line number.

    -
    BASH_LOADABLES_PATH - -
    +
    BASH_LOADABLES_PATH

    A colon-separated list of directories in which the shell looks for dynamically loadable builtins specified by the enable command.

    -
    BASH_REMATCH - -
    +
    BASH_REMATCH

    An array variable whose members are assigned by the ‘=~’ binary operator to the [[ conditional command (see Conditional Constructs). @@ -6662,9 +6571,7 @@ The element with index n is the portion of the string matching the nth parenthesized subexpression.

    -
    BASH_SOURCE - -
    +
    BASH_SOURCE

    An array variable whose members are the source filenames where the corresponding shell function names in the FUNCNAME array variable are defined. @@ -6672,9 +6579,7 @@ The shell function ${FUNCNAME[$i]} is defined in the file ${BASH_SOURCE[$i]} and called from ${BASH_SOURCE[$i+1]}

    -
    BASH_SUBSHELL - -
    +
    BASH_SUBSHELL

    Incremented by one within each subshell or subshell environment when the shell begins executing in that environment. The initial value is 0. @@ -6683,49 +6588,43 @@ is unset, it loses its special properties, even if it is subsequently reset.

    -
    BASH_VERSINFO - -
    +
    BASH_VERSINFO

    A readonly array variable (see Arrays) whose members hold version information for this instance of Bash. The values assigned to the array members are as follows:

    -
    BASH_VERSINFO[0]
    +
    BASH_VERSINFO[0]

    The major version number (the release).

    -
    BASH_VERSINFO[1]
    +
    BASH_VERSINFO[1]

    The minor version number (the version).

    -
    BASH_VERSINFO[2]
    +
    BASH_VERSINFO[2]

    The patch level.

    -
    BASH_VERSINFO[3]
    +
    BASH_VERSINFO[3]

    The build version.

    -
    BASH_VERSINFO[4]
    +
    BASH_VERSINFO[4]

    The release status (e.g., beta1).

    -
    BASH_VERSINFO[5]
    +
    BASH_VERSINFO[5]

    The value of MACHTYPE.

    -
    BASH_VERSION - -
    +
    BASH_VERSION

    The version number of the current instance of Bash.

    -
    BASH_XTRACEFD - -
    +
    BASH_XTRACEFD

    If set to an integer corresponding to a valid file descriptor, Bash will write the trace output generated when ‘set -x’ is enabled to that file descriptor. @@ -6740,9 +6639,7 @@ descriptor) and then unsetting it will result in the standard error being closed.

    -
    CHILD_MAX - -
    +
    CHILD_MAX

    Set the number of exited child status values for the shell to remember. Bash will not allow this value to be decreased below a POSIX-mandated minimum, and there is a maximum value (currently 8192) that this may @@ -6750,9 +6647,7 @@ not exceed. The minimum value is system-dependent.

    -
    COLUMNS - -
    +
    COLUMNS

    Used by the select command to determine the terminal width when printing selection lists. Automatically set if the checkwinsize option is enabled @@ -6760,27 +6655,21 @@ Automatically set if the checkwinsize option is enabled SIGWINCH.

    -
    COMP_CWORD - -
    +
    COMP_CWORD

    An index into ${COMP_WORDS} of the word containing the current cursor position. This variable is available only in shell functions invoked by the programmable completion facilities (see Programmable Completion).

    -
    COMP_LINE - -
    +
    COMP_LINE

    The current command line. This variable is available only in shell functions and external commands invoked by the programmable completion facilities (see Programmable Completion).

    -
    COMP_POINT - -
    +
    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, @@ -6790,9 +6679,7 @@ commands invoked by the programmable completion facilities (see Programmable Completion).

    -
    COMP_TYPE - -
    +
    COMP_TYPE

    Set to an integer value corresponding to the type of completion attempted that caused a completion function to be called: TAB, for normal completion, @@ -6806,16 +6693,12 @@ commands invoked by the programmable completion facilities (see Programmable Completion).

    -
    COMP_KEY - -
    +
    COMP_KEY

    The key (or final key of a key sequence) used to invoke the current completion function.

    -
    COMP_WORDBREAKS - -
    +
    COMP_WORDBREAKS

    The set of characters that the Readline library treats as word separators when performing word completion. If COMP_WORDBREAKS @@ -6823,9 +6706,7 @@ is unset, it loses its special properties, even if it is subsequently reset.

    -
    COMP_WORDS - -
    +
    COMP_WORDS

    An array variable consisting of the individual words in the current command line. The line is split into words as Readline would split it, using @@ -6834,25 +6715,19 @@ This variable is available only in shell functions invoked by the programmable completion facilities (see Programmable Completion).

    -
    COMPREPLY - -
    +
    COMPREPLY

    An array variable from which Bash reads the possible completions generated by a shell function invoked by the programmable completion facility (see Programmable Completion). Each array element contains one possible completion.

    -
    COPROC - -
    +
    COPROC

    An array variable created to hold the file descriptors for output from and input to an unnamed coprocess (see Coprocesses).

    -
    DIRSTACK - -
    +
    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 dirs builtin. @@ -6865,26 +6740,20 @@ is unset, it loses its special properties, even if it is subsequently reset.

    -
    EMACS - -
    +
    EMACS

    If Bash finds this variable in the environment when the shell starts with value ‘t’, it assumes that the shell is running in an Emacs shell buffer and disables line editing.

    -
    ENV - -
    +
    ENV

    Expanded and executed similarlty to BASH_ENV (see Bash Startup Files) when an interactive shell is invoked in POSIX Mode (see Bash POSIX Mode).

    -
    EPOCHREALTIME - -
    +
    EPOCHREALTIME

    Each time this parameter is referenced, it expands to the number of seconds since the Unix Epoch as a floating point value with micro-second granularity (see the documentation for the C library function time for the @@ -6895,9 +6764,7 @@ is unset, it loses its special properties, even if it is subsequently reset.

    -
    EPOCHSECONDS - -
    +
    EPOCHSECONDS

    Each time this parameter is referenced, it expands to the number of seconds since the Unix Epoch (see the documentation for the C library function time for the definition of Epoch). @@ -6907,16 +6774,12 @@ is unset, it loses its special properties, even if it is subsequently reset.

    -
    EUID - -
    +
    EUID

    The numeric effective user id of the current user. This variable is readonly.

    -
    EXECIGNORE - -
    +
    EXECIGNORE

    A colon-separated list of shell patterns (see Pattern Matching) defining the list of filenames to be ignored by command search using PATH. @@ -6932,16 +6795,12 @@ The pattern matching honors the setting of the extglob shell option.

    -
    FCEDIT - -
    +
    FCEDIT

    The editor used as a default by the -e option to the fc builtin command.

    -
    FIGNORE - -
    +
    FIGNORE

    A colon-separated list of suffixes to ignore when performing filename completion. A filename whose suffix matches one of the entries in @@ -6950,9 +6809,7 @@ is excluded from the list of matched filenames. A sample value is ‘.o:~

    -
    FUNCNAME - -
    +
    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 @@ -6974,17 +6831,13 @@ The caller builtin displays the current call stack using this information.

    -
    FUNCNEST - -
    +
    FUNCNEST

    If set to a numeric value greater than 0, defines a maximum function nesting level. Function invocations that exceed this nesting level will cause the current command to abort.

    -
    GLOBIGNORE - -
    +
    GLOBIGNORE

    A colon-separated list of patterns defining the set of file names to be ignored by filename expansion. If a file name matched by a filename expansion pattern also matches one @@ -6994,9 +6847,7 @@ The pattern matching honors the setting of the extglob shell option.

    -
    GROUPS - -
    +
    GROUPS

    An array variable containing the list of groups of which the current user is a member. Assignments to GROUPS have no effect. @@ -7005,11 +6856,9 @@ is unset, it loses its special properties, even if it is subsequently reset.

    -
    histchars - -
    +
    histchars

    Up to three characters which control history expansion, quick -substitution, and tokenization (see History Interaction). +substitution, and tokenization (see History Expansion). The first character is the history expansion character, that is, the character which signifies the start of a history expansion, normally ‘!’. The second character is the @@ -7022,9 +6871,7 @@ remaining words on the line. It does not necessarily cause the shell parser to treat the rest of the line as a comment.

    -
    HISTCMD - -
    +
    HISTCMD

    The history number, or index in the history list, of the current command. Assignments to HISTCMD are ignored. @@ -7033,9 +6880,7 @@ is unset, it loses its special properties, even if it is subsequently reset.

    -
    HISTCONTROL - -
    +
    HISTCONTROL

    A colon-separated list of values controlling how commands are saved on the history list. If the list of values includes ‘ignorespace’, lines which begin @@ -7056,16 +6901,12 @@ not tested, and are added to the history regardless of the value of HISTCONTROL.

    -
    HISTFILE - -
    +
    HISTFILE

    The name of the file to which the command history is saved. The default value is ~/.bash_history.

    -
    HISTFILESIZE - -
    +
    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 @@ -7078,9 +6919,7 @@ The shell sets the default value to the value of HISTSIZE after reading any startup files.

    -
    HISTIGNORE - -
    +
    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 @@ -7103,9 +6942,7 @@ Combining these two patterns, separating them with a colon, provides the functionality of ignoreboth.

    -
    HISTSIZE - -
    +
    HISTSIZE

    The maximum number of commands to remember on the history list. If the value is 0, commands are not saved in the history list. Numeric values less than zero result in every command being saved @@ -7113,9 +6950,7 @@ on the history list (there is no limit). The shell sets the default value to 500 after reading any startup files.

    -
    HISTTIMEFORMAT - -
    +
    HISTTIMEFORMAT

    If this variable is set and not null, its value is used as a format string for strftime to print the time stamp associated with each history entry displayed by the history builtin. @@ -7125,9 +6960,7 @@ This uses the history comment character to distinguish timestamps from other history lines.

    -
    HOSTFILE - -
    +
    HOSTFILE

    Contains the name of a file in the same format as /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 @@ -7141,21 +6974,15 @@ Bash attempts to read When HOSTFILE is unset, the hostname list is cleared.

    -
    HOSTNAME - -
    +
    HOSTNAME

    The name of the current host.

    -
    HOSTTYPE - -
    +
    HOSTTYPE

    A string describing the machine Bash is running on.

    -
    IGNOREEOF - -
    +
    IGNOREEOF

    Controls the action of the shell on receipt of an EOF character as the sole input. If set, the value denotes the number of consecutive EOF characters that can be read as the @@ -7166,38 +6993,28 @@ If the variable does not exist, then EOF signifies the end of input to the shell. This is only in effect for interactive shells.

    -
    INPUTRC - -
    +
    INPUTRC

    The name of the Readline initialization file, overriding the default of ~/.inputrc.

    -
    INSIDE_EMACS - -
    +
    INSIDE_EMACS

    If Bash finds this variable in the environment when the shell starts, it assumes that the shell is running in an Emacs shell buffer and may disable line editing depending on the value of TERM.

    -
    LANG - -
    +
    LANG

    Used to determine the locale category for any category not specifically selected with a variable starting with LC_.

    -
    LC_ALL - -
    +
    LC_ALL

    This variable overrides the value of LANG and any other LC_ variable specifying a locale category.

    -
    LC_COLLATE - -
    +
    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, @@ -7205,46 +7022,34 @@ and collating sequences within filename expansion and pattern matching (see Filename Expansion).

    -
    LC_CTYPE - -
    +
    LC_CTYPE

    This variable determines the interpretation of characters and the behavior of character classes within filename expansion and pattern matching (see Filename Expansion).

    -
    LC_MESSAGES - -
    +
    LC_MESSAGES

    This variable determines the locale used to translate double-quoted -strings preceded by a ‘$’ (see Locale Translation). +strings preceded by a ‘$’ (see Locale-Specific Translation).

    -
    LC_NUMERIC - -
    +
    LC_NUMERIC

    This variable determines the locale category used for number formatting.

    -
    LC_TIME - -
    +
    LC_TIME

    This variable determines the locale category used for data and time formatting.

    -
    LINENO - -
    +
    LINENO

    The line number in the script or shell function currently executing. If LINENO is unset, it loses its special properties, even if it is subsequently reset.

    -
    LINES - -
    +
    LINES

    Used by the select command to determine the column length for printing selection lists. Automatically set if the checkwinsize option is enabled @@ -7252,16 +7057,12 @@ Automatically set if the checkwinsize option is enabled SIGWINCH.

    -
    MACHTYPE - -
    +
    MACHTYPE

    A string that fully describes the system type on which Bash is executing, in the standard GNU cpu-company-system format.

    -
    MAILCHECK - -
    +
    MAILCHECK

    How often (in seconds) that the shell should check for mail in the files specified in the MAILPATH or MAIL variables. The default is 60 seconds. When it is time to check @@ -7270,44 +7071,32 @@ 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.

    -
    MAPFILE - -
    +
    MAPFILE

    An array variable created to hold the text read by the mapfile builtin when no variable name is supplied.

    -
    OLDPWD - -
    +
    OLDPWD

    The previous working directory as set by the cd builtin.

    -
    OPTERR - -
    +
    OPTERR

    If set to the value 1, Bash displays error messages generated by the getopts builtin command.

    -
    OSTYPE - -
    +
    OSTYPE

    A string describing the operating system Bash is running on.

    -
    PIPESTATUS - -
    +
    PIPESTATUS

    An array variable (see 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).

    -
    POSIXLY_CORRECT - -
    +
    POSIXLY_CORRECT

    If this variable is in the environment when Bash starts, the shell enters POSIX mode (see Bash POSIX Mode) before reading the startup files, as if the --posix invocation option had been supplied. @@ -7321,16 +7110,12 @@ When the shell enters POSIX mode, it sets this variable if it was not already set.

    -
    PPID - -
    +
    PPID

    The process ID of the shell’s parent process. This variable is readonly.

    -
    PROMPT_COMMAND - -
    +
    PROMPT_COMMAND

    If this variable is set, and is an array, the value of each set element is interpreted as a command to execute before printing the primary prompt ($PS1). @@ -7338,34 +7123,26 @@ If this is set but not an array variable, its value is used as a command to execute instead.

    -
    PROMPT_DIRTRIM - -
    +
    PROMPT_DIRTRIM

    If set to a number greater than zero, the value is used as the number of trailing directory components to retain when expanding the \w and \W prompt string escapes (see Controlling the Prompt). Characters removed are replaced with an ellipsis.

    -
    PS0 - -
    +
    PS0

    The value of this parameter is expanded like PS1 and displayed by interactive shells after reading a command and before the command is executed.

    -
    PS3 - -
    +
    PS3

    The value of this variable is used as the prompt for the select command. If this variable is not set, the select command prompts with ‘#?

    -
    PS4 - -
    +
    PS4

    The value of this parameter is expanded like PS1 and the expanded value is the prompt printed before the command line is echoed when the -x option is set (see The Set Builtin). @@ -7374,15 +7151,11 @@ as necessary, to indicate multiple levels of indirection. The default is ‘+ ’.

    -
    PWD - -
    +
    PWD

    The current working directory as set by the cd builtin.

    -
    RANDOM - -
    +
    RANDOM

    Each time this parameter is referenced, it expands to a random integer between 0 and 32767. Assigning a value to this variable seeds the random number generator. @@ -7391,39 +7164,29 @@ is unset, it loses its special properties, even if it is subsequently reset.

    -
    READLINE_LINE - -
    +
    READLINE_LINE

    The contents of the Readline line buffer, for use -with ‘bind -x’ (see Bash Builtins). +with ‘bind -x’ (see Bash Builtin Commands).

    -
    READLINE_MARK - -
    +
    READLINE_MARK

    The position of the mark (saved insertion point) in the Readline line buffer, for use -with ‘bind -x’ (see Bash Builtins). +with ‘bind -x’ (see Bash Builtin Commands). The characters between the insertion point and the mark are often called the region.

    -
    READLINE_POINT - -
    +
    READLINE_POINT

    The position of the insertion point in the Readline line buffer, for use -with ‘bind -x’ (see Bash Builtins). +with ‘bind -x’ (see Bash Builtin Commands).

    -
    REPLY - -
    +
    REPLY

    The default variable for the read builtin.

    -
    SECONDS - -
    +
    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 @@ -7436,17 +7199,13 @@ is unset, it loses its special properties, even if it is subsequently reset.

    -
    SHELL - -
    +
    SHELL

    This environment variable expands to the full pathname to the shell. If it is not set when the shell starts, Bash assigns to it the full pathname of the current user’s login shell.

    -
    SHELLOPTS - -
    +
    SHELLOPTS

    A colon-separated list of enabled shell options. Each word in the list is a valid argument for the -o option to the set builtin command (see The Set Builtin). @@ -7457,16 +7216,12 @@ starts up, each shell option in the list will be enabled before reading any startup files. This variable is readonly.

    -
    SHLVL - -
    +
    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.

    -
    SRANDOM - -
    +
    SRANDOM

    This variable expands to a 32-bit pseudo-random number each time it is referenced. The random number generator is not linear on systems that support /dev/urandom or arc4random, so each returned number @@ -7478,9 +7233,7 @@ is unset, it loses its special properties, even if it is subsequently reset.

    -
    TIMEFORMAT - -
    +
    TIMEFORMAT

    The value of this parameter is used as a format string specifying how the timing information for pipelines prefixed with the time reserved word should be displayed. @@ -7491,23 +7244,23 @@ The escape sequences and their meanings are as follows; the braces denote optional portions.

    -
    %%
    +
    %%

    A literal ‘%’.

    -
    %[p][l]R
    +
    %[p][l]R

    The elapsed time in seconds.

    -
    %[p][l]U
    +
    %[p][l]U

    The number of CPU seconds spent in user mode.

    -
    %[p][l]S
    +
    %[p][l]S

    The number of CPU seconds spent in system mode.

    -
    %P
    +
    %P

    The CPU percentage, computed as (%U + %S) / %R.

    @@ -7531,11 +7284,9 @@ The value of p determines whether or not the fraction is included. A trailing newline is added when the format string is displayed.

    -
    TMOUT - -
    +
    TMOUT

    If set to a value greater than zero, TMOUT is treated as the -default timeout for the read builtin (see Bash Builtins). +default timeout for the read builtin (see Bash Builtin Commands). The select command (see Conditional Constructs) terminates if input does not arrive after TMOUT seconds when input is coming from a terminal. @@ -7548,63 +7299,47 @@ terminates after waiting for that number of seconds if a complete line of input does not arrive.

    -
    TMPDIR - -
    +
    TMPDIR

    If set, Bash uses its value as the name of a directory in which Bash creates temporary files for the shell’s use.

    -
    UID - -
    +
    UID

    The numeric real user id of the current user. This variable is readonly.


    -
    +
    +
    +
    +

    -Next: , Previous: , Up: Top   [Contents][Index]

    +Next: , Previous: , Up: Bash Features   [Contents][Index]

    6 Bash Features

    This chapter describes features unique to Bash.

    - - - - - - - - - - - - - - +
    -
    +
    + @@ -7626,57 +7361,57 @@ options that you can use. These options must appear on the command line before the single-character options to be recognized.

    -
    --debugger
    +
    --debugger

    Arrange for the debugger profile to be executed before the shell starts. Turns on extended debugging mode (see The Shopt Builtin for a description of the extdebug option to the shopt builtin).

    -
    --dump-po-strings
    +
    --dump-po-strings

    A list of all double-quoted strings preceded by ‘$’ is printed on the standard output in the GNU gettext PO (portable object) file format. Equivalent to -D except for the output format.

    -
    --dump-strings
    +
    --dump-strings

    Equivalent to -D.

    -
    --help
    +
    --help

    Display a usage message on standard output and exit successfully.

    -
    --init-file filename
    -
    --rcfile filename
    +
    --init-file filename
    +
    --rcfile filename

    Execute commands from filename (instead of ~/.bashrc) in an interactive shell.

    -
    --login
    +
    --login

    Equivalent to -l.

    -
    --noediting
    +
    --noediting

    Do not use the GNU Readline library (see Command Line Editing) to read command lines when the shell is interactive.

    -
    --noprofile
    +
    --noprofile

    Don’t load the system-wide startup file /etc/profile or any of the personal initialization files ~/.bash_profile, ~/.bash_login, or ~/.profile when Bash is invoked as a login shell.

    -
    --norc
    +
    --norc

    Don’t read the ~/.bashrc initialization file in an interactive shell. This is on by default if the shell is invoked as sh.

    -
    --posix
    +
    --posix

    Change the behavior of Bash where the default operation differs from the POSIX standard to match the standard. This is intended to make Bash behave as a strict superset of that @@ -7684,15 +7419,15 @@ standard. See Bash POSIX Mode, for a description POSIX mode.

    -
    --restricted
    +
    --restricted

    Make the shell a restricted shell (see The Restricted Shell).

    -
    --verbose
    +
    --verbose

    Equivalent to -v. Print shell input lines as they’re read.

    -
    --version
    +
    --version

    Show version information for this instance of Bash on the standard output and exit successfully.

    @@ -7702,7 +7437,7 @@ Bash on the standard output and exit successfully. invocation which are not available with the set builtin.

    -
    -c
    +
    -c

    Read and execute commands from the first non-option argument command_string, then exit. If there are arguments after the command_string, @@ -7712,12 +7447,12 @@ The assignment to $0 sets the name of the shell, which is used in warning and error messages.

    -
    -i
    +
    -i

    Force the shell to run interactively. Interactive shells are described in Interactive Shells.

    -
    -l
    +
    -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 ‘exec -l bash’. @@ -7729,11 +7464,11 @@ See Bash Startup Files, for a description of t of a login shell.

    -
    -r
    +
    -r

    Make the shell a restricted shell (see The Restricted Shell).

    -
    -s
    +
    -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 @@ -7741,16 +7476,16 @@ when invoking an interactive shell or when reading input through a pipe.

    -
    -D
    +
    -D

    A list of all double-quoted strings preceded by ‘$’ is printed on the standard output. These are the strings that are subject to language translation when the current locale -is not C or POSIX (see Locale Translation). +is not C or POSIX (see Locale-Specific Translation). This implies the -n option; no commands will be executed.

    -
    [-+]O [shopt_option]
    +
    [-+]O [shopt_option]

    shopt_option is one of the shell options accepted by the shopt builtin (see The Shopt Builtin). If shopt_option is present, -O sets the value of that option; @@ -7761,7 +7496,7 @@ If the invocation option is +O, the output is displayed in a format that may be reused as input.

    -
    --
    +
    --

    A -- signals the end of options and disables further option processing. Any arguments after the -- are treated as filenames and arguments. @@ -7792,7 +7527,9 @@ 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.


    -
    +
    +
    + @@ -7912,7 +7649,9 @@ If the -p option is supplied at invocation, the startup behavior is the same, but the effective user id is not reset.


    -
    +
    +
    + @@ -7920,17 +7659,15 @@ Next:
    -
    +
    + @@ -7950,7 +7687,9 @@ terminal. when an interactive shell is started.


    -
    +
    +
    + @@ -7981,7 +7720,9 @@ fi

    -
    +
    +
    + @@ -8017,7 +7758,7 @@ instead of exiting immediately when it receives an EOF on its standard input when reading a command (see The Set Builtin).
  • Command history (see Bash History Facilities) -and history expansion (see History Interaction) +and history expansion (see History Expansion) are enabled by default. Bash will save the command history to the file named by $HISTFILE when a shell with history enabled exits. @@ -8071,7 +7812,10 @@ printing $PS1 (see Bash Variables).

  • -
    +
    +
    +
    + @@ -8107,130 +7851,130 @@ The test command uses ASCII ordering. links and operate on the target of the link, rather than the link itself.

    -
    -a file
    +
    -a file

    True if file exists.

    -
    -b file
    +
    -b file

    True if file exists and is a block special file.

    -
    -c file
    +
    -c file

    True if file exists and is a character special file.

    -
    -d file
    +
    -d file

    True if file exists and is a directory.

    -
    -e file
    +
    -e file

    True if file exists.

    -
    -f file
    +
    -f file

    True if file exists and is a regular file.

    -
    -g file
    +
    -g file

    True if file exists and its set-group-id bit is set.

    -
    -h file
    +
    -h file

    True if file exists and is a symbolic link.

    -
    -k file
    +
    -k file

    True if file exists and its "sticky" bit is set.

    -
    -p file
    +
    -p file

    True if file exists and is a named pipe (FIFO).

    -
    -r file
    +
    -r file

    True if file exists and is readable.

    -
    -s file
    +
    -s file

    True if file exists and has a size greater than zero.

    -
    -t fd
    +
    -t fd

    True if file descriptor fd is open and refers to a terminal.

    -
    -u file
    +
    -u file

    True if file exists and its set-user-id bit is set.

    -
    -w file
    +
    -w file

    True if file exists and is writable.

    -
    -x file
    +
    -x file

    True if file exists and is executable.

    -
    -G file
    +
    -G file

    True if file exists and is owned by the effective group id.

    -
    -L file
    +
    -L file

    True if file exists and is a symbolic link.

    -
    -N file
    +
    -N file

    True if file exists and has been modified since it was last read.

    -
    -O file
    +
    -O file

    True if file exists and is owned by the effective user id.

    -
    -S file
    +
    -S file

    True if file exists and is a socket.

    -
    file1 -ef file2
    +
    file1 -ef file2

    True if file1 and file2 refer to the same device and inode numbers.

    -
    file1 -nt file2
    +
    file1 -nt file2

    True if file1 is newer (according to modification date) than file2, or if file1 exists and file2 does not.

    -
    file1 -ot file2
    +
    file1 -ot file2

    True if file1 is older than file2, or if file2 exists and file1 does not.

    -
    -o optname
    +
    -o optname

    True if the shell option optname is enabled. The list of options appears in the description of the -o option to the set builtin (see The Set Builtin).

    -
    -v varname
    +
    -v varname

    True if the shell variable varname is set (has been assigned a value).

    -
    -R varname
    +
    -R varname

    True if the shell variable varname is set and is a name reference.

    -
    -z string
    +
    -z string

    True if the length of string is zero.

    -
    -n string
    -
    string
    +
    -n string
    +
    string

    True if the length of string is non-zero.

    -
    string1 == string2
    -
    string1 = string2
    +
    string1 == string2
    +
    string1 = string2

    True if the strings are equal. When used with the [[ command, this performs pattern matching as described above (see Conditional Constructs). @@ -8238,19 +7982,19 @@ described above (see Conditional Constructs=’ should be used with the test command for POSIX conformance.

    -
    string1 != string2
    +
    string1 != string2

    True if the strings are not equal.

    -
    string1 < string2
    +
    string1 < string2

    True if string1 sorts before string2 lexicographically.

    -
    string1 > string2
    +
    string1 > string2

    True if string1 sorts after string2 lexicographically.

    -
    arg1 OP arg2
    +
    arg1 OP arg2

    OP is one of ‘-eq’, ‘-ne’, ‘-lt’, ‘-le’, ‘-gt’, or ‘-ge’. These arithmetic binary operators return true if arg1 @@ -8264,7 +8008,9 @@ are evaluated as arithmetic expressions (see Shell A


    -
    +
    +
    + @@ -8288,75 +8034,75 @@ equal-precedence operators. The levels are listed in order of decreasing precedence.

    -
    id++ id--
    +
    id++ id--

    variable post-increment and post-decrement

    -
    ++id --id
    +
    ++id --id

    variable pre-increment and pre-decrement

    -
    - +
    +
    - +

    unary minus and plus

    -
    ! ~
    +
    ! ~

    logical and bitwise negation

    -
    **
    +
    **

    exponentiation

    -
    * / %
    +
    * / %

    multiplication, division, remainder

    -
    + -
    +
    + -

    addition, subtraction

    -
    << >>
    +
    << >>

    left and right bitwise shifts

    -
    <= >= < >
    +
    <= >= < >

    comparison

    -
    == !=
    +
    == !=

    equality and inequality

    -
    &
    +
    &

    bitwise AND

    -
    ^
    +
    ^

    bitwise exclusive OR

    -
    |
    +
    |

    bitwise OR

    -
    &&
    +
    &&

    logical AND

    -
    ||
    +
    ||

    logical OR

    -
    expr ? expr : expr
    +
    expr ? expr : expr

    conditional operator

    -
    = *= /= %= += -= <<= >>= &= ^= |=
    +
    = *= /= %= += -= <<= >>= &= ^= |=

    assignment

    -
    expr1 , expr2
    +
    expr1 , expr2

    comma

    @@ -8395,7 +8141,9 @@ parentheses are evaluated first and may override the precedence rules above.


    -
    +
    +
    +

    Next: , Previous: , Up: Bash Features   [Contents][Index]

    @@ -8460,7 +8208,9 @@ in compound commands.

    For almost every purpose, shell functions are preferred over aliases.


    -
    +
    +
    + @@ -8613,18 +8363,15 @@ builtins display array values in a way that allows them to be reused as input.


    -
    +
    +
    +

    6.8 The Directory Stack

    - - -

    The directory stack is a list of recently-visited directories. The pushd builtin adds directories to the stack as it changes @@ -8637,17 +8384,20 @@ of the directory stack.

    The contents of the directory stack are also visible as the value of the DIRSTACK shell variable.

    +
    -
    +
    +

    6.8.1 Directory Stack Builtins

    -
    dirs
    -
    -
    +
    dirs
    +
    dirs [-clpv] [+N | -N]
     
    @@ -8657,27 +8407,27 @@ are added to the list with the pushd command; the The current directory is always the first directory in the stack.

    -
    -c
    +
    -c

    Clears the directory stack by deleting all of the elements.

    -
    -l
    +
    -l

    Produces a listing using full pathnames; the default listing format uses a tilde to denote the home directory.

    -
    -p
    +
    -p

    Causes dirs to print the directory stack with one entry per line.

    -
    -v
    +
    -v

    Causes dirs to print the directory stack with one entry per line, prefixing each entry with its index in the stack.

    -
    +N
    +
    +N

    Displays the Nth directory (counting from the left of the list printed by dirs when invoked without options), starting with zero.

    -
    -N
    +
    -N

    Displays the Nth directory (counting from the right of the list printed by dirs when invoked without options), starting with zero. @@ -8685,9 +8435,8 @@ with zero.

    -
    popd
    -
    -
    +
    popd
    +
    popd [-n] [+N | -N]
     
    @@ -8698,15 +8447,15 @@ The elements are numbered from 0 starting at the first directory listed with dirs; that is, popd is equivalent to popd +0.

    -
    -n
    +
    -n

    Suppresses the normal change of directory when removing directories from the stack, so that only the stack is manipulated.

    -
    +N
    +
    +N

    Removes the Nth directory (counting from the left of the list printed by dirs), starting with zero.

    -
    -N
    +
    -N

    Removes the Nth directory (counting from the right of the list printed by dirs), starting with zero.

    @@ -8714,7 +8463,7 @@ list printed by dirs), starting with zero.
    -
    pushd
    +
    pushd
    pushd [-n] [+N | -N | dir]
     
    @@ -8725,21 +8474,21 @@ With no arguments, pushd exchanges the top two directories and makes the new top the current directory.

    -
    -n
    +
    -n

    Suppresses the normal change of directory when rotating or adding directories to the stack, so that only the stack is manipulated.

    -
    +N
    +
    +N

    Brings the Nth directory (counting from the left of the list printed by dirs, starting with zero) to the top of the list by rotating the stack.

    -
    -N
    +
    -N

    Brings the Nth directory (counting from the right of the list printed by dirs, starting with zero) to the top of the list by rotating the stack.

    -
    dir
    +
    dir

    Makes dir be the top of the stack, making it the new current directory as if it had been supplied as an argument to the cd builtin. @@ -8749,7 +8498,10 @@ to the cd builtin.


    -
    +
    +
    +
    + @@ -8767,90 +8519,90 @@ can appear in the prompt variables PS0, PS1, PS2 PS4:

    -
    \a
    +
    \a

    A bell character.

    -
    \d
    +
    \d

    The date, in "Weekday Month Date" format (e.g., "Tue May 26").

    -
    \D{format}
    +
    \D{format}

    The format is passed to strftime(3) and the result is inserted into the prompt string; an empty format results in a locale-specific time representation. The braces are required.

    -
    \e
    +
    \e

    An escape character.

    -
    \h
    +
    \h

    The hostname, up to the first ‘.’.

    -
    \H
    +
    \H

    The hostname.

    -
    \j
    +
    \j

    The number of jobs currently managed by the shell.

    -
    \l
    +
    \l

    The basename of the shell’s terminal device name.

    -
    \n
    +
    \n

    A newline.

    -
    \r
    +
    \r

    A carriage return.

    -
    \s
    +
    \s

    The name of the shell, the basename of $0 (the portion following the final slash).

    -
    \t
    +
    \t

    The time, in 24-hour HH:MM:SS format.

    -
    \T
    +
    \T

    The time, in 12-hour HH:MM:SS format.

    -
    \@
    +
    \@

    The time, in 12-hour am/pm format.

    -
    \A
    +
    \A

    The time, in 24-hour HH:MM format.

    -
    \u
    +
    \u

    The username of the current user.

    -
    \v
    +
    \v

    The version of Bash (e.g., 2.00)

    -
    \V
    +
    \V

    The release of Bash, version + patchlevel (e.g., 2.00.0)

    -
    \w
    +
    \w

    The current working directory, with $HOME abbreviated with a tilde (uses the $PROMPT_DIRTRIM variable).

    -
    \W
    +
    \W

    The basename of $PWD, with $HOME abbreviated with a tilde.

    -
    \!
    +
    \!

    The history number of this command.

    -
    \#
    +
    \#

    The command number of this command.

    -
    \$
    +
    \$

    If the effective uid is 0, #, otherwise $.

    -
    \nnn
    +
    \nnn

    The character whose ASCII code is the octal value nnn.

    -
    \\
    +
    \\

    A backslash.

    -
    \[
    +
    \[

    Begin a sequence of non-printing characters. This could be used to embed a terminal control sequence into the prompt.

    -
    \]
    +
    \]

    End a sequence of non-printing characters.

    @@ -8871,7 +8623,9 @@ appear within command substitution or contain characters special to word expansion.


    -
    +
    +
    + @@ -8932,7 +8686,9 @@ such as jails, zones, or containers.


    -
    +
    +
    + @@ -9195,7 +8951,9 @@ the --enable-strict-posix-default to configure when bu (see Optional Features).


    -
    +
    +
    + @@ -9260,14 +9018,14 @@ For bash-4.3 and later versions, the BASH_COMPAT variable is prefer and it is required for bash-5.1 and later versions.

    -
    compat31
    +
    compat31
    • quoting the rhs of the [[ command’s regexp matching operator (=~) has no special effect
    -
    compat32
    +
    compat32
    • interrupting a command list such as "a ; b ; c" causes the execution of the next command in the list (in bash-4.0 and later versions, @@ -9277,7 +9035,7 @@ entire list)
    -
    compat40
    +
    compat40
    • the ‘<’ and ‘>’ operators to the [[ command do not consider the current locale when comparing strings; they use ASCII @@ -9288,7 +9046,7 @@ strcoll(3).
    -
    compat41
    +
    compat41
    • in posix mode, time may be followed by options and still be recognized as a reserved word (this is POSIX interpretation 267) @@ -9300,7 +9058,7 @@ the single quotes are considered quoted
    -
    compat42
    +
    compat42
    • the replacement string in double-quoted pattern substitution does not undergo quote removal, as it does in versions after bash-4.2 @@ -9313,7 +9071,7 @@ are not special within double-quoted word expansions
    -
    compat43
    +
    compat43
    • the shell does not print a warning message if an attempt is made to use a quoted compound assignment as an argument to declare @@ -9330,7 +9088,7 @@ the loop state to prevent this
    -
    compat44
    +
    compat44
    • the shell sets up the values used by BASH_ARGV and BASH_ARGC so they can expand to the shell’s positional parameters even if extended @@ -9345,7 +9103,7 @@ mode
    -
    compat50 (set using BASH_COMPAT)
    +
    compat50 (set using BASH_COMPAT)
    • Bash-5.1 changed the way $RANDOM is generated to introduce slightly more randomness. If the shell compatibility level is set to 50 or @@ -9361,28 +9119,27 @@ when the -l option is supplied.

    -
    +
    +
    +
    +

    7 Job Control

    This chapter discusses what job control is, how it works, and how Bash allows you to access its facilities.

    - - - - - +
    -
    +
    + @@ -9496,16 +9253,17 @@ job changes state. The -f option causes wait to wait until the job or process terminates before returning.


    -
    +
    +
    +

    7.2 Job Control Builtins

    -
    bg
    -
    -
    +
    bg
    +
    bg [jobspec …]
     
    @@ -9518,9 +9276,8 @@ enabled, or, when run with job control enabled, any that was started without job control.

    -
    fg
    -
    -
    +
    fg
    +
    fg [jobspec]
     
    @@ -9532,9 +9289,8 @@ job control enabled, jobspec does not specify a valid job or jobspec specifies a job that was started without job control.

    -
    jobs
    -
    -
    +
    jobs
    +
    jobs [-lnprs] [jobspec]
     jobs -x command [arguments]
     
    @@ -9543,24 +9299,24 @@ jobs -x command [arguments] following meanings:

    -
    -l
    +
    -l

    List process IDs in addition to the normal information.

    -
    -n
    +
    -n

    Display information only about jobs that have changed status since the user was last notified of their status.

    -
    -p
    +
    -p

    List only the process ID of the job’s process group leader.

    -
    -r
    +
    -r

    Display only running jobs.

    -
    -s
    +
    -s

    Display only stopped jobs.

    @@ -9576,9 +9332,8 @@ corresponding process group ID, and executes command, passing it arguments, returning its exit status.

    -
    kill
    -
    -
    +
    kill
    +
    kill [-s sigspec] [-n signum] [-sigspec] jobspec or pid
     kill -l|-L [exit_status]
     
    @@ -9600,9 +9355,8 @@ 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.

    -
    wait
    -
    -
    +
    wait
    +
    wait [-fn] [-p varname] [jobspec or pid …]
     
    @@ -9635,9 +9389,8 @@ If neither jobspec nor pid specifies an active child proce of the shell, the return status is 127.

    -
    disown
    -
    -
    +
    disown
    +
    disown [-ar] [-h] [jobspec … | pid … ]
     
    @@ -9653,9 +9406,8 @@ mark all jobs; the -r option without a jobspec argument restricts operation to running jobs.

    -
    suspend
    -
    -
    +
    suspend
    +
    suspend [-f]
     
    @@ -9671,16 +9423,16 @@ builtins do not accept jobspec arguments. They must be supplied process IDs.


    -
    +
    +
    +

    7.3 Job Control Variables

    -
    auto_resume - -
    +
    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 @@ -9707,9 +9459,12 @@ analogous to the ‘%’ job ID.


    -
    +
    +
    +
    +

    8 Command Line Editing

    @@ -9720,7 +9475,7 @@ used by several different programs, including Bash. Command line editing is enabled by default when using an interactive shell, unless the --noediting option is supplied at shell invocation. Line editing is also used when using the -e option to the -read builtin command (see Bash Builtins). +read builtin command (see Bash Builtin Commands). By default, the line editing commands are similar to those of Emacs. A vi-style line editing interface is also available. Line editing can be enabled at any time using the -o emacs or @@ -9728,32 +9483,20 @@ Line editing can be enabled at any time using the -o emacs or (see The Set Builtin), or disabled using the +o emacs or +o vi options to set.

    - - - - - - - - - - +
    -
    +
    + @@ -9795,9 +9538,11 @@ The RET key may be labeled Return or < some keyboards.


    -
    +
    +
    +

    8.2 Readline Interaction

    @@ -9813,21 +9558,17 @@ the line, you simply press RET. You do not have to be at t end of the line to press RET; the entire line is accepted regardless of the location of the cursor within the line.

    - - - - - - - +
    -
    +
    + @@ -9855,22 +9596,22 @@ blank space created by the removal of the text. A list of the bare essentials for editing the text of an input line follows.

    -
    C-b
    +
    C-b

    Move back one character.

    -
    C-f
    +
    C-f

    Move forward one character.

    -
    DEL or Backspace
    +
    DEL or Backspace

    Delete the character to the left of the cursor.

    -
    C-d
    +
    C-d

    Delete the character underneath the cursor.

    -
    Printing characters
    +
    Printing characters

    Insert the character into the line at the cursor.

    -
    C-_ or C-x C-u
    +
    C-_ or C-x C-u

    Undo the last editing command. You can undo all the way back to an empty line.

    @@ -9882,7 +9623,9 @@ to delete the character underneath the cursor, like C-d, rather than the character to the left of the cursor.)


    -
    +
    +
    + @@ -9896,19 +9639,19 @@ other commands have been added in addition to C-b, C-f, about the line.

    -
    C-a
    +
    C-a

    Move to the start of the line.

    -
    C-e
    +
    C-e

    Move to the end of the line.

    -
    M-f
    +
    M-f

    Move forward a word, where a word is composed of letters and digits.

    -
    M-b
    +
    M-b

    Move backward a word.

    -
    C-l
    +
    C-l

    Clear the screen, reprinting the current line at the top.

    @@ -9918,7 +9661,9 @@ forward a word. It is a loose convention that control keystrokes operate on characters while meta keystrokes operate on words.


    -
    +
    +
    + @@ -9947,23 +9692,23 @@ another line.

    Here is the list of commands for killing text.

    -
    C-k
    +
    C-k

    Kill the text from the current cursor position to the end of the line.

    -
    M-d
    +
    M-d

    Kill from the cursor 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 M-f.

    -
    M-DEL
    +
    M-DEL

    Kill from the cursor the start of the current word, or, if between words, to the start of the previous word. Word boundaries are the same as those used by M-b.

    -
    C-w
    +
    C-w

    Kill from the cursor to the previous whitespace. This is different than M-DEL because the word boundaries differ.

    @@ -9974,20 +9719,22 @@ Word boundaries are the same as those used by M-b. means to copy the most-recently-killed text from the kill buffer.

    -
    C-y
    +
    C-y

    Yank the most recently killed text back into the buffer at the cursor.

    -
    M-y
    +
    M-y

    Rotate the kill-ring, and yank the new top. You can only do this if the prior command is C-y or M-y.


    -
    +
    +
    +

    8.2.4 Readline Arguments

    @@ -10007,7 +9754,9 @@ the C-d command an argument of 10, you could type ‘M-1 0 which will delete the next ten characters on the input line.


    -
    +
    +
    + @@ -10054,7 +9803,10 @@ 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.


    -
    +
    +
    +
    + @@ -10073,7 +9825,7 @@ file does not exist or cannot be read, the ultimate default is /etc/inputrc. The bind builtin command can also be used to set Readline keybindings and variables. -See Bash Builtins. +See Bash Builtin Commands.

    When a program which uses the Readline library starts up, the init file is read, and the key bindings are set. @@ -10081,21 +9833,15 @@ init file is read, and the key bindings are set.

    In addition, the C-x C-r command re-reads this init file, thus incorporating any changes that you might have made to it.

    - - - - - +
    -
    +
    + @@ -10109,7 +9855,7 @@ constructs (see Conditional Init Construc denote variable settings and key bindings.

    -
    Variable Settings
    +
    Variable Settings

    You can modify the run-time behavior of Readline by altering the values of variables in Readline using the set command within the init file. @@ -10135,64 +9881,57 @@ the value is null or empty, on (case-insensitive), or 1. Any other value results in the variable being set to off.

    The bind -V command lists the current Readline variable names -and values. See Bash Builtins. +and values. See Bash Builtin Commands.

    A great deal of run-time behavior is changeable with the following variables.

    -
    bell-style
    -
    -

    Controls what happens when Readline wants to ring the terminal bell. +

    bell-style
    +

    Controls what happens when Readline wants to ring the terminal bell. If set to ‘none’, Readline never rings the bell. If set to ‘visible’, Readline uses a visible bell if one is available. If set to ‘audible’ (the default), Readline attempts to ring the terminal’s bell.

    -
    bind-tty-special-chars
    -
    -

    If set to ‘on’ (the default), Readline attempts to bind the control +

    bind-tty-special-chars
    +

    If set to ‘on’ (the default), Readline attempts to bind the control characters treated specially by the kernel’s terminal driver to their Readline equivalents.

    -
    blink-matching-paren
    -
    -

    If set to ‘on’, Readline attempts to briefly move the cursor to an +

    +

    If set to ‘on’, Readline attempts to briefly move the cursor to an opening parenthesis when a closing parenthesis is inserted. The default is ‘off’.

    -
    colored-completion-prefix
    -
    -

    If set to ‘on’, when listing completions, Readline displays the +

    colored-completion-prefix
    +

    If set to ‘on’, when listing completions, Readline displays the common prefix of the set of possible completions using a different color. The color definitions are taken from the value of the LS_COLORS environment variable. The default is ‘off’.

    -
    colored-stats
    -
    -

    If set to ‘on’, Readline displays possible completions using different +

    colored-stats
    +

    If set to ‘on’, Readline displays possible completions using different colors to indicate their file type. The color definitions are taken from the value of the LS_COLORS environment variable. The default is ‘off’.

    -
    comment-begin
    -
    -

    The string to insert at the beginning of the line when the +

    comment-begin
    +

    The string to insert at the beginning of the line when the insert-comment command is executed. The default value is "#".

    -
    completion-display-width
    -
    -

    The number of screen columns used to display possible matches +

    completion-display-width
    +

    The number of screen columns used to display possible matches when performing completion. The value is ignored if it is less than 0 or greater than the terminal screen width. @@ -10200,32 +9939,28 @@ A value of 0 will cause matches to be displayed one per line. The default value is -1.

    -
    completion-ignore-case
    -
    -

    If set to ‘on’, Readline performs filename matching and completion +

    completion-ignore-case
    +

    If set to ‘on’, Readline performs filename matching and completion in a case-insensitive fashion. The default value is ‘off’.

    -
    completion-map-case
    -
    -

    If set to ‘on’, and completion-ignore-case is enabled, Readline +

    completion-map-case
    +

    If set to ‘on’, and completion-ignore-case is enabled, Readline treats hyphens (‘-’) and underscores (‘_’) as equivalent when performing case-insensitive filename matching and completion. The default value is ‘off’.

    -
    completion-prefix-display-length
    -
    -

    The length in characters of the common prefix of a list of possible +

    completion-prefix-display-length
    +

    The length in characters of the common prefix of a list of possible completions that is displayed without modification. When set to a value greater than zero, common prefixes longer than this value are replaced with an ellipsis when displaying possible completions.

    -
    completion-query-items
    -
    -

    The number of possible completions that determines when the user is +

    completion-query-items
    +

    The number of possible completions that determines when the user is asked whether the list of possibilities should be displayed. If the number of possible completions is greater than or equal to this value, Readline will ask whether or not the user wishes to view them; @@ -10235,9 +9970,8 @@ A negative value means Readline should never ask. The default limit is 100.

    -
    convert-meta
    -
    -

    If set to ‘on’, Readline will convert characters with the +

    convert-meta
    +

    If set to ‘on’, Readline will convert characters with the eighth bit set to an ASCII key sequence by stripping the eighth bit and prefixing an ESC character, converting them to a meta-prefixed key sequence. The default value is ‘on’, but @@ -10245,31 +9979,27 @@ will be set to ‘off’ if the locale is one that contains eight-bit characters.

    -
    disable-completion
    -
    -

    If set to ‘On’, Readline will inhibit word completion. +

    disable-completion
    +

    If set to ‘On’, Readline will inhibit word completion. Completion characters will be inserted into the line as if they had been mapped to self-insert. The default is ‘off’.

    -
    echo-control-characters
    -
    -

    When set to ‘on’, on operating systems that indicate they support it, +

    echo-control-characters
    +

    When set to ‘on’, on operating systems that indicate they support it, readline echoes a character corresponding to a signal generated from the keyboard. The default is ‘on’.

    -
    editing-mode
    -
    -

    The editing-mode variable controls which default set of +

    editing-mode
    +

    The editing-mode variable controls which default set of key bindings is used. By default, Readline starts up in Emacs editing mode, where the keystrokes are most similar to Emacs. This variable can be set to either ‘emacs’ or ‘vi’.

    -
    emacs-mode-string
    -
    -

    If the show-mode-in-prompt variable is enabled, +

    emacs-mode-string
    +

    If the show-mode-in-prompt variable is enabled, this string is displayed immediately before the last line of the primary prompt when emacs editing mode is active. The value is expanded like a key binding, so the standard set of meta- and control prefixes and @@ -10280,46 +10010,41 @@ sequence into the mode string. The default is ‘@’.

    -
    enable-bracketed-paste
    -
    -

    When set to ‘On’, Readline will configure the terminal in a way +

    enable-bracketed-paste
    +

    When set to ‘On’, Readline will configure the terminal in a way that will enable it to insert each paste into the editing buffer as a single string of characters, instead of treating each character as if it had been read from the keyboard. This can prevent pasted characters from being interpreted as editing commands. The default is ‘On’.

    -
    enable-keypad
    -
    -

    When set to ‘on’, Readline will try to enable the application +

    enable-keypad
    +

    When set to ‘on’, Readline will try to enable the application keypad when it is called. Some systems need this to enable the arrow keys. The default is ‘off’.

    -
    enable-meta-key
    +
    enable-meta-key

    When set to ‘on’, Readline will try to enable any meta modifier key the terminal claims to support when it is called. On many terminals, the meta key is used to send eight-bit characters. The default is ‘on’.

    -
    expand-tilde
    -
    -

    If set to ‘on’, tilde expansion is performed when Readline +

    expand-tilde
    +

    If set to ‘on’, tilde expansion is performed when Readline attempts word completion. The default is ‘off’.

    -
    history-preserve-point
    -
    -

    If set to ‘on’, the history code attempts to place the point (the +

    history-preserve-point
    +

    If set to ‘on’, the history code attempts to place the point (the current cursor position) at the same location on each history line retrieved with previous-history or next-history. The default is ‘off’.

    -
    history-size
    -
    -

    Set the maximum number of history entries saved in the history list. +

    history-size
    +

    Set the maximum number of history entries saved in the history list. If set to zero, any existing history entries are deleted and no new entries are saved. If set to a value less than zero, the number of history entries is not @@ -10329,9 +10054,8 @@ If an attempt is made to set history-size to a non-numeric value, the maximum number of history entries will be set to 500.

    -
    horizontal-scroll-mode
    -
    -

    This variable can be set to either ‘on’ or ‘off’. Setting it +

    horizontal-scroll-mode
    +

    This variable can be set to either ‘on’ or ‘off’. Setting it to ‘on’ means that the text of the lines being edited will scroll horizontally on a single screen line when they are longer than the width of the screen, instead of wrapping onto a new screen line. @@ -10339,9 +10063,8 @@ This variable is automatically set to ‘on’ for terminal By default, this variable is set to ‘off’.

    -
    input-meta
    -
    - +
    input-meta
    +

    If set to ‘on’, Readline will enable eight-bit input (it will not clear the eighth bit in the characters it reads), regardless of what the terminal claims it can support. The @@ -10350,17 +10073,15 @@ locale contains eight-bit characters. The name meta-flag is a synonym for this variable.

    -
    isearch-terminators
    -
    -

    The string of characters that should terminate an incremental search without -subsequently executing the character as a command (see Searching). +

    isearch-terminators
    +

    The string of characters that should terminate an incremental search without +subsequently executing the character as a command (see Searching for Commands in the History). If this variable has not been given a value, the characters ESC and C-J will terminate an incremental search.

    -
    keymap
    -
    -

    Sets Readline’s idea of the current keymap for key binding commands. +

    keymap
    +

    Sets Readline’s idea of the current keymap for key binding commands. Built-in keymap names are emacs, emacs-standard, @@ -10378,7 +10099,7 @@ The value of the editing-mode variable also affects the default keymap.

    -
    keyseq-timeout
    +
    keyseq-timeout

    Specifies the duration Readline will wait for a character when reading an ambiguous key sequence (one that can form a complete key sequence using the input read so far, or can take additional input to complete a longer @@ -10395,29 +10116,26 @@ decide which key sequence to complete. The default value is 500.

    -
    mark-directories
    +
    mark-directories

    If set to ‘on’, completed directory names have a slash appended. The default is ‘on’.

    -
    mark-modified-lines
    -
    -

    This variable, when set to ‘on’, causes Readline to display an +

    mark-modified-lines
    +

    This variable, when set to ‘on’, causes Readline to display an asterisk (‘*’) at the start of history lines which have been modified. This variable is ‘off’ by default.

    -
    mark-symlinked-directories
    -
    -

    If set to ‘on’, completed names which are symbolic links +

    mark-symlinked-directories
    +

    If set to ‘on’, completed names which are symbolic links to directories have a slash appended (subject to the value of mark-directories). The default is ‘off’.

    -
    match-hidden-files
    -
    -

    This variable, when set to ‘on’, causes Readline to match files whose +

    match-hidden-files
    +

    This variable, when set to ‘on’, causes Readline to match files whose names begin with a ‘.’ (hidden files) when performing filename completion. If set to ‘off’, the leading ‘.’ must be @@ -10425,55 +10143,49 @@ supplied by the user in the filename to be completed. This variable is ‘on’ by default.

    -
    menu-complete-display-prefix
    -
    -

    If set to ‘on’, menu completion displays the common prefix of the +

    menu-complete-display-prefix
    +

    If set to ‘on’, menu completion displays the common prefix of the list of possible completions (which may be empty) before cycling through the list. The default is ‘off’.

    -
    output-meta
    -
    -

    If set to ‘on’, Readline will display characters with the +

    output-meta
    +

    If set to ‘on’, Readline will display characters with the eighth bit set directly rather than as a meta-prefixed escape sequence. The default is ‘off’, but Readline will set it to ‘on’ if the locale contains eight-bit characters.

    -
    page-completions
    -
    -

    If set to ‘on’, Readline uses an internal more-like pager +

    page-completions
    +

    If set to ‘on’, Readline uses an internal more-like pager to display a screenful of possible completions at a time. This variable is ‘on’ by default.

    -
    print-completions-horizontally
    +
    print-completions-horizontally

    If set to ‘on’, Readline will display completions with matches sorted horizontally in alphabetical order, rather than down the screen. The default is ‘off’.

    -
    revert-all-at-newline
    -
    -

    If set to ‘on’, Readline will undo all changes to history lines +

    revert-all-at-newline
    +

    If set to ‘on’, Readline will undo all changes to history lines before returning when accept-line is executed. By default, history lines may be modified and retain individual undo lists across calls to readline. The default is ‘off’.

    -
    show-all-if-ambiguous
    -
    -

    This alters the default behavior of the completion functions. If +

    show-all-if-ambiguous
    +

    This alters the default behavior of the completion functions. If set to ‘on’, words which have more than one possible completion cause the matches to be listed immediately instead of ringing the bell. The default value is ‘off’.

    -
    show-all-if-unmodified
    -
    -

    This alters the default behavior of the completion functions in +

    show-all-if-unmodified
    +

    This alters the default behavior of the completion functions in a fashion similar to show-all-if-ambiguous. If set to ‘on’, words which have more than one possible completion without any @@ -10483,17 +10195,15 @@ of ringing the bell. The default value is ‘off’.

    -
    show-mode-in-prompt
    -
    -

    If set to ‘on’, add a string to the beginning of the prompt +

    show-mode-in-prompt
    +

    If set to ‘on’, add a string to the beginning of the prompt indicating the editing mode: emacs, vi command, or vi insertion. The mode strings are user-settable (e.g., emacs-mode-string). The default value is ‘off’.

    -
    skip-completed-text
    -
    -

    If set to ‘on’, this alters the default completion behavior when +

    skip-completed-text
    +

    If set to ‘on’, this alters the default completion behavior when inserting a single match into the line. It’s only active when performing completion in the middle of a word. If enabled, readline does not insert characters from the completion that match characters @@ -10506,9 +10216,8 @@ completion. The default value is ‘off’.

    -
    vi-cmd-mode-string
    -
    -

    If the show-mode-in-prompt variable is enabled, +

    vi-cmd-mode-string
    +

    If the show-mode-in-prompt variable is enabled, this string is displayed immediately before the last line of the primary prompt when vi editing mode is active and in command mode. The value is expanded like a @@ -10520,9 +10229,8 @@ sequence into the mode string. The default is ‘(cmd)’.

    -
    vi-ins-mode-string
    -
    -

    If the show-mode-in-prompt variable is enabled, +

    vi-ins-mode-string
    +

    If the show-mode-in-prompt variable is enabled, this string is displayed immediately before the last line of the primary prompt when vi editing mode is active and in insertion mode. The value is expanded like a @@ -10534,9 +10242,8 @@ sequence into the mode string. The default is ‘(ins)’.

    -
    visible-stats
    -
    -

    If set to ‘on’, a character denoting a file’s type +

    visible-stats
    +

    If set to ‘on’, a character denoting a file’s type is appended to the filename when listing possible completions. The default is ‘off’.

    @@ -10544,7 +10251,7 @@ completions. The default is ‘off’.
    -
    Key Bindings
    +
    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 want to change. The following sections contain tables of the command @@ -10565,10 +10272,10 @@ to a string that is inserted when the key is pressed (a macro).

    The bind -p command displays Readline function names and bindings in a format that can put directly into an initialization file. -See Bash Builtins. +See Bash Builtin Commands.

    -
    keynamefunction-name or macro
    +
    keynamefunction-name or macro

    keyname is the name of a key spelled out in English. For example:

    Control-u: universal-argument
    @@ -10599,7 +10306,7 @@ and
     TAB.
     

    -
    "keyseq": function-name or macro
    +
    "keyseq": function-name or macro

    keyseq differs from keyname above in that strings denoting an entire key sequence can be specified, by placing the key sequence in double quotes. Some GNU Emacs style key @@ -10625,22 +10332,22 @@ the text ‘Function Key 1’. specifying key sequences:

    -
    \C-
    +
    \C-

    control prefix

    -
    \M-
    +
    \M-

    meta prefix

    -
    \e
    +
    \e

    an escape character

    -
    \\
    +
    \\

    backslash

    -
    \"
    +
    \"

    ", a double quotation mark

    -
    \'
    +
    \'

    ', a single quote or apostrophe

    @@ -10649,35 +10356,35 @@ specifying key sequences: set of backslash escapes is available:

    -
    \a
    +
    \a

    alert (bell)

    -
    \b
    +
    \b

    backspace

    -
    \d
    +
    \d

    delete

    -
    \f
    +
    \f

    form feed

    -
    \n
    +
    \n

    newline

    -
    \r
    +
    \r

    carriage return

    -
    \t
    +
    \t

    horizontal tab

    -
    \v
    +
    \v

    vertical tab

    -
    \nnn
    +
    \nnn

    the eight-bit character whose value is the octal value nnn (one to three digits)

    -
    \xHH
    +
    \xHH

    the eight-bit character whose value is the hexadecimal value HH (one or two hex digits)

    @@ -10699,7 +10406,9 @@ insert a single ‘\’ into the line:

    -
    +
    +
    + @@ -10711,7 +10420,7 @@ bindings and variable settings to be performed as the result of tests. There are four parser directives used.

    -
    $if
    +
    $if

    The $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, after any comparison operator, @@ -10719,7 +10428,7 @@ extends to the end of the line; unless otherwise noted, no characters are required to isolate it.

    -
    mode
    +
    mode

    The mode= form of the $if directive is used to test whether Readline is in emacs or vi mode. This may be used in conjunction @@ -10728,7 +10437,7 @@ the emacs-standard and emacs-ctlx keymaps only if Readline is starting out in emacs mode.

    -
    term
    +
    term

    The term= 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 @@ -10738,7 +10447,7 @@ allows sun to match both sun and sun-cmd, for instance.

    -
    version
    +
    version

    The version test may be used to perform comparisons against specific Readline versions. The version expands to the current Readline version. @@ -10760,7 +10469,7 @@ $endif

    -
    application
    +
    application

    The application construct is used to include application-specific settings. Each program using the Readline library sets the application name, and you can test for @@ -10776,7 +10485,7 @@ $endif

    -
    variable
    +
    variable

    The variable construct provides simple equality tests for Readline variables and values. The permitted comparison operators are ‘=’, ‘==’, and ‘!=’. @@ -10796,17 +10505,17 @@ $endif

    -
    $endif
    +
    $endif

    This command, as seen in the previous example, terminates an $if command.

    -
    $else
    +
    $else

    Commands in this branch of the $if directive are executed if the test fails.

    -
    $include
    +
    $include

    This directive takes a single filename as an argument and reads commands and bindings from that file. For example, the following directive reads from /etc/inputrc: @@ -10817,7 +10526,9 @@ For example, the following directive reads from /etc/inputrc:


    -
    +
    +
    + @@ -10929,36 +10640,21 @@ $endif

    -
    +
    +
    +
    +

    8.4 Bindable Readline Commands

    - - - - - - - - - -

    This section describes Readline commands that may be bound to key sequences. You can list your key bindings by executing bind -P or, for a more terse format, suitable for an -inputrc file, bind -p. (See Bash Builtins.) +inputrc file, bind -p. (See Bash Builtin Commands.) Command names without an accompanying key sequence are unbound by default.

    In the following descriptions, point refers to the current cursor @@ -10966,77 +10662,68 @@ position, and mark refers to a cursor position saved by the set-mark command. The text between the point and mark is referred to as the region.

    +
    -
    +
    +

    8.4.1 Commands For Moving

    -
    beginning-of-line (C-a) - -
    +
    beginning-of-line (C-a)

    Move to the start of the current line.

    -
    end-of-line (C-e) - -
    +
    end-of-line (C-e)

    Move to the end of the line.

    -
    forward-char (C-f) - -
    +
    forward-char (C-f)

    Move forward a character.

    -
    backward-char (C-b) - -
    +
    backward-char (C-b)

    Move back a character.

    -
    forward-word (M-f) - -
    +
    forward-word (M-f)

    Move forward to the end of the next word. Words are composed of letters and digits.

    -
    backward-word (M-b) - -
    +
    backward-word (M-b)

    Move back to the start of the current or previous word. Words are composed of letters and digits.

    -
    shell-forward-word (M-C-f) - -
    +
    shell-forward-word (M-C-f)

    Move forward to the end of the next word. Words are delimited by non-quoted shell metacharacters.

    -
    shell-backward-word (M-C-b) - -
    +
    shell-backward-word (M-C-b)

    Move back to the start of the current or previous word. Words are delimited by non-quoted shell metacharacters.

    -
    previous-screen-line () - -
    +
    previous-screen-line ()

    Attempt to move point to the same physical screen column on the previous physical screen line. This will not have the desired effect if the current Readline line does not take up more than one physical line or if point is not greater than the length of the prompt plus the screen width.

    -
    next-screen-line () - -
    +
    next-screen-line ()

    Attempt to move point to the same physical screen column on the next physical screen line. This will not have the desired effect if the current Readline line does not take up more than one physical line or if the length @@ -11044,41 +10731,35 @@ of the current Readline line is not greater than the length of the prompt plus the screen width.

    -
    clear-display (M-C-l) - -
    +
    clear-display (M-C-l)

    Clear the screen and, if possible, the terminal’s scrollback buffer, then redraw the current line, leaving the current line at the top of the screen.

    -
    clear-screen (C-l) - -
    +
    clear-screen (C-l)

    Clear the screen, then redraw the current line, leaving the current line at the top of the screen.

    -
    redraw-current-line () - -
    +
    redraw-current-line ()

    Refresh the current line. By default, this is unbound.


    -
    +
    +
    +

    8.4.2 Commands For Manipulating The History

    -
    accept-line (Newline or Return) - -
    +
    accept-line (Newline or 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 setting of @@ -11087,68 +10768,50 @@ If this line is a modified history line, then restore the history line to its original state.

    -
    previous-history (C-p) - -
    +
    previous-history (C-p)

    Move ‘back’ through the history list, fetching the previous command.

    -
    next-history (C-n) - -
    +
    next-history (C-n)

    Move ‘forward’ through the history list, fetching the next command.

    -
    beginning-of-history (M-<) - -
    +
    beginning-of-history (M-<)

    Move to the first line in the history.

    -
    end-of-history (M->) - -
    +
    end-of-history (M->)

    Move to the end of the input history, i.e., the line currently being entered.

    -
    reverse-search-history (C-r) - -
    +
    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. This command sets the region to the matched text and activates the mark.

    -
    forward-search-history (C-s) - -
    +
    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. This command sets the region to the matched text and activates the mark.

    -
    non-incremental-reverse-search-history (M-p) - -
    +
    non-incremental-reverse-search-history (M-p)

    Search backward starting at the current line and moving ‘up’ through the history as necessary using a non-incremental search for a string supplied by the user. The search string may match anywhere in a history line.

    -
    non-incremental-forward-search-history (M-n) - -
    +
    non-incremental-forward-search-history (M-n)

    Search forward starting at the current line and moving ‘down’ through the history as necessary using a non-incremental search for a string supplied by the user. The search string may match anywhere in a history line.

    -
    history-search-forward () - -
    +
    history-search-forward ()

    Search forward through the history for the string of characters between the start of the current line and the point. The search string must match at the beginning of a history line. @@ -11156,9 +10819,7 @@ This is a non-incremental search. By default, this command is unbound.

    -
    history-search-backward () - -
    +
    history-search-backward ()

    Search backward through the history for the string of characters between the start of the current line and the point. The search string must match at the beginning of a history line. @@ -11166,9 +10827,7 @@ This is a non-incremental search. By default, this command is unbound.

    -
    history-substring-search-forward () - -
    +
    history-substring-search-forward ()

    Search forward through the history for the string of characters between the start of the current line and the point. The search string may match anywhere in a history line. @@ -11176,9 +10835,7 @@ This is a non-incremental search. By default, this command is unbound.

    -
    history-substring-search-backward () - -
    +
    history-substring-search-backward ()

    Search backward through the history for the string of characters between the start of the current line and the point. The search string may match anywhere in a history line. @@ -11186,9 +10843,7 @@ This is a non-incremental search. By default, this command is unbound.

    -
    yank-nth-arg (M-C-y) - -
    +
    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 n, @@ -11199,9 +10854,7 @@ Once the argument n is computed, the argument is extracted as if the ‘!n’ history expansion had been specified.

    -
    yank-last-arg (M-. or M-_) - -
    +
    yank-last-arg (M-. or M-_)

    Insert last argument to the previous command (the last word of the previous history entry). With a numeric argument, behave exactly like yank-nth-arg. @@ -11215,9 +10868,7 @@ The history expansion facilities are used to extract the last argument, as if the ‘!$’ history expansion had been specified.

    -
    operate-and-get-next (C-o) - -
    +
    operate-and-get-next (C-o)

    Accept the current line for return to the calling application as if a newline had been entered, and fetch the next line relative to the current line from the history @@ -11229,62 +10880,50 @@ of the current line.


    -
    +
    +
    +

    8.4.3 Commands For Changing Text

    -
    end-of-file (usually C-d) - -
    +
    end-of-file (usually C-d)

    The character indicating end-of-file as set, for example, by stty. If this character is read when there are no characters on the line, and point is at the beginning of the line, Readline interprets it as the end of input and returns EOF.

    -
    delete-char (C-d) - -
    +
    delete-char (C-d)

    Delete the character at point. If this function is bound to the same character as the tty EOF character, as C-d commonly is, see above for the effects.

    -
    backward-delete-char (Rubout) - -
    +
    backward-delete-char (Rubout)

    Delete the character behind the cursor. A numeric argument means to kill the characters instead of deleting them.

    -
    forward-backward-delete-char () - -
    +
    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. By default, this is not bound to a key.

    -
    quoted-insert (C-q or C-v) - -
    +
    quoted-insert (C-q or C-v)

    Add the next character typed to the line verbatim. This is how to insert key sequences like C-q, for example.

    -
    self-insert (a, b, A, 1, !, …) - -
    +
    self-insert (a, b, A, 1, !, …)

    Insert yourself.

    -
    bracketed-paste-begin () - -
    +
    bracketed-paste-begin ()

    This function is intended to be bound to the "bracketed paste" escape sequence sent by some terminals, and such a binding is assigned by default. It allows Readline to insert the pasted text as a single unit without treating @@ -11298,9 +10937,7 @@ mark is active, Readline redisplay uses the terminal’s standout mode to denote the region.

    -
    transpose-chars (C-t) - -
    +
    transpose-chars (C-t)

    Drag the character before the cursor forward over the character at the cursor, moving the cursor forward as well. If the insertion point @@ -11309,39 +10946,29 @@ transposes the last two characters of the line. Negative arguments have no effect.

    -
    transpose-words (M-t) - -
    +
    transpose-words (M-t)

    Drag the word before point past the word after point, moving point past that word as well. If the insertion point is at the end of the line, this transposes the last two words on the line.

    -
    upcase-word (M-u) - -
    +
    upcase-word (M-u)

    Uppercase the current (or following) word. With a negative argument, uppercase the previous word, but do not move the cursor.

    -
    downcase-word (M-l) - -
    +
    downcase-word (M-l)

    Lowercase the current (or following) word. With a negative argument, lowercase the previous word, but do not move the cursor.

    -
    capitalize-word (M-c) - -
    +
    capitalize-word (M-c)

    Capitalize the current (or following) word. With a negative argument, capitalize the previous word, but do not move the cursor.

    -
    overwrite-mode () - -
    +
    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 @@ -11359,75 +10986,59 @@ before point with a space.


    -
    +
    +
    +

    8.4.4 Killing And Yanking

    -
    kill-line (C-k) - -
    +
    kill-line (C-k)

    Kill the text from point to the end of the line. With a negative numeric argument, kill backward from the cursor to the beginning of the current line.

    -
    backward-kill-line (C-x Rubout) - -
    +
    backward-kill-line (C-x Rubout)

    Kill backward from the cursor to the beginning of the current line. With a negative numeric argument, kill forward from the cursor to the end of the current line.

    -
    unix-line-discard (C-u) - -
    +
    unix-line-discard (C-u)

    Kill backward from the cursor to the beginning of the current line.

    -
    kill-whole-line () - -
    +
    kill-whole-line ()

    Kill all characters on the current line, no matter where point is. By default, this is unbound.

    -
    kill-word (M-d) - -
    +
    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 forward-word.

    -
    backward-kill-word (M-DEL) - -
    +
    backward-kill-word (M-DEL)

    Kill the word behind point. Word boundaries are the same as backward-word.

    -
    shell-kill-word (M-C-d) - -
    +
    shell-kill-word (M-C-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 shell-forward-word.

    -
    shell-backward-kill-word () - -
    +
    shell-backward-kill-word ()

    Kill the word behind point. Word boundaries are the same as shell-backward-word.

    -
    shell-transpose-words (M-C-t) - -
    +
    shell-transpose-words (M-C-t)

    Drag the word before point past the word after point, moving point past that word as well. If the insertion point is at the end of the line, this transposes @@ -11436,88 +11047,68 @@ Word boundaries are the same as shell-forward-word and shell-backward-word.

    -
    unix-word-rubout (C-w) - -
    +
    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.

    -
    unix-filename-rubout () - -
    +
    unix-filename-rubout ()

    Kill the word behind point, using white space and the slash character as the word boundaries. The killed text is saved on the kill-ring.

    -
    delete-horizontal-space () - -
    +
    delete-horizontal-space ()

    Delete all spaces and tabs around point. By default, this is unbound.

    -
    kill-region () - -
    +
    kill-region ()

    Kill the text in the current region. By default, this command is unbound.

    -
    copy-region-as-kill () - -
    +
    copy-region-as-kill ()

    Copy the text in the region to the kill buffer, so it can be yanked right away. By default, this command is unbound.

    -
    copy-backward-word () - -
    +
    copy-backward-word ()

    Copy the word before point to the kill buffer. The word boundaries are the same as backward-word. By default, this command is unbound.

    -
    copy-forward-word () - -
    +
    copy-forward-word ()

    Copy the word following point to the kill buffer. The word boundaries are the same as forward-word. By default, this command is unbound.

    -
    yank (C-y) - -
    +
    yank (C-y)

    Yank the top of the kill ring into the buffer at point.

    -
    yank-pop (M-y) - -
    +
    yank-pop (M-y)

    Rotate the kill-ring, and yank the new top. You can only do this if the prior command is yank or yank-pop.


    -
    +
    +
    +

    8.4.5 Specifying Numeric Arguments

    -
    digit-argument (M-0, M-1, … M--) - -
    +
    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.

    -
    universal-argument () - -
    +
    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. @@ -11534,16 +11125,16 @@ By default, this is not bound to a key.


    -
    +
    +
    +

    8.4.6 Letting Readline Type For You

    -
    complete (TAB) - -
    +
    complete (TAB)

    Attempt to perform completion on the text before point. The actual completion performed is application-specific. Bash attempts completion treating the text as a variable (if the @@ -11553,25 +11144,19 @@ command (including aliases and functions) in turn. If none of these produces a match, filename completion is attempted.

    -
    possible-completions (M-?) - -
    +
    possible-completions (M-?)

    List the possible completions of the text before point. When displaying completions, Readline sets the number of columns used for display to the value of completion-display-width, the value of the environment variable COLUMNS, or the screen width, in that order.

    -
    insert-completions (M-*) - -
    +
    insert-completions (M-*)

    Insert all completions of the text before point that would have been generated by possible-completions.

    -
    menu-complete () - -
    +
    menu-complete ()

    Similar to complete, but replaces the word to be completed with a single match from the list of possible completions. Repeated execution of menu-complete steps through the list @@ -11586,17 +11171,13 @@ This command is intended to be bound to TAB, but is unbound by default.

    -
    menu-complete-backward () - -
    +
    menu-complete-backward ()

    Identical to menu-complete, but moves backward through the list of possible completions, as if menu-complete had been given a negative argument.

    -
    delete-char-or-list () - -
    +
    delete-char-or-list ()

    Deletes the character under the cursor if not at the beginning or end of the line (like delete-char). If at the end of the line, behaves identically to @@ -11604,64 +11185,46 @@ If at the end of the line, behaves identically to This command is unbound by default.

    -
    complete-filename (M-/) - -
    +
    complete-filename (M-/)

    Attempt filename completion on the text before point.

    -
    possible-filename-completions (C-x /) - -
    +
    possible-filename-completions (C-x /)

    List the possible completions of the text before point, treating it as a filename.

    -
    complete-username (M-~) - -
    +
    complete-username (M-~)

    Attempt completion on the text before point, treating it as a username.

    -
    possible-username-completions (C-x ~) - -
    +
    possible-username-completions (C-x ~)

    List the possible completions of the text before point, treating it as a username.

    -
    complete-variable (M-$) - -
    +
    complete-variable (M-$)

    Attempt completion on the text before point, treating it as a shell variable.

    -
    possible-variable-completions (C-x $) - -
    +
    possible-variable-completions (C-x $)

    List the possible completions of the text before point, treating it as a shell variable.

    -
    complete-hostname (M-@) - -
    +
    complete-hostname (M-@)

    Attempt completion on the text before point, treating it as a hostname.

    -
    possible-hostname-completions (C-x @) - -
    +
    possible-hostname-completions (C-x @)

    List the possible completions of the text before point, treating it as a hostname.

    -
    complete-command (M-!) - -
    +
    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 @@ -11669,32 +11232,24 @@ functions, shell builtins, and finally executable filenames, in that order.

    -
    possible-command-completions (C-x !) - -
    +
    possible-command-completions (C-x !)

    List the possible completions of the text before point, treating it as a command name.

    -
    dynamic-complete-history (M-TAB) - -
    +
    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.

    -
    dabbrev-expand () - -
    +
    dabbrev-expand ()

    Attempt menu completion on the text before point, comparing the text against lines from the history list for possible completion matches.

    -
    complete-into-braces (M-{) - -
    +
    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 Brace Expansion). @@ -11703,35 +11258,29 @@ enclosed within braces so the list is available to the shell


    -
    +
    +
    +

    8.4.7 Keyboard Macros

    -
    start-kbd-macro (C-x () - -
    +
    start-kbd-macro (C-x ()

    Begin saving the characters typed into the current keyboard macro.

    -
    end-kbd-macro (C-x )) - -
    +
    end-kbd-macro (C-x ))

    Stop saving the characters typed into the current keyboard macro and save the definition.

    -
    call-last-kbd-macro (C-x e) - -
    +
    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.

    -
    print-last-kbd-macro () - -
    +
    print-last-kbd-macro ()

    Print the last keboard macro defined in a format suitable for the inputrc file.

    @@ -11739,94 +11288,72 @@ in the macro appear as if typed at the keyboard.

    -
    +
    +
    +

    8.4.8 Some Miscellaneous Commands

    -
    re-read-init-file (C-x C-r) - -
    +
    re-read-init-file (C-x C-r)

    Read in the contents of the inputrc file, and incorporate any bindings or variable assignments found there.

    -
    abort (C-g) - -
    +
    abort (C-g)

    Abort the current editing command and ring the terminal’s bell (subject to the setting of bell-style).

    -
    do-lowercase-version (M-A, M-B, M-x, …) - -
    +
    do-lowercase-version (M-A, M-B, M-x, …)

    If the metafied character x is upper case, run the command that is bound to the corresponding metafied lower case character. The behavior is undefined if x is already lower case.

    -
    prefix-meta (ESC) - -
    +
    prefix-meta (ESC)

    Metafy the next character typed. This is for keyboards without a meta key. Typing ‘ESC f’ is equivalent to typing M-f.

    -
    undo (C-_ or C-x C-u) - -
    +
    undo (C-_ or C-x C-u)

    Incremental undo, separately remembered for each line.

    -
    revert-line (M-r) - -
    +
    revert-line (M-r)

    Undo all changes made to this line. This is like executing the undo command enough times to get back to the beginning.

    -
    tilde-expand (M-&) - -
    +
    tilde-expand (M-&)

    Perform tilde expansion on the current word.

    -
    set-mark (C-@) - -
    +
    set-mark (C-@)

    Set the mark to the point. If a numeric argument is supplied, the mark is set to that position.

    -
    exchange-point-and-mark (C-x C-x) - -
    +
    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.

    -
    character-search (C-]) - -
    +
    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.

    -
    character-search-backward (M-C-]) - -
    +
    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.

    -
    skip-csi-sequence () - -
    +
    skip-csi-sequence ()

    Read enough characters to consume a multi-key sequence such as those defined for keys like Home and End. Such sequences begin with a Control Sequence Indicator (CSI), usually ESC-[. If this sequence is @@ -11836,9 +11363,7 @@ stray characters into the editing buffer. This is unbound by default, but usually bound to ESC-[.

    -
    insert-comment (M-#) - -
    +
    insert-comment (M-#)

    Without a numeric argument, the value of the 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 @@ -11853,107 +11378,79 @@ If a numeric argument causes the comment character to be removed, the line will be executed by the shell.

    -
    dump-functions () - -
    +
    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 inputrc file. This command is unbound by default.

    -
    dump-variables () - -
    +
    dump-variables ()

    Print all of the settable 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 inputrc file. This command is unbound by default.

    -
    dump-macros () - -
    +
    dump-macros ()

    Print all of the Readline key sequences bound to macros and the strings they output. If a numeric argument is supplied, the output is formatted in such a way that it can be made part of an inputrc file. This command is unbound by default.

    -
    glob-complete-word (M-g) - -
    +
    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.

    -
    glob-expand-word (C-x *) - -
    +
    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, a ‘*’ is appended before pathname expansion.

    -
    glob-list-expansions (C-x g) - -
    +
    glob-list-expansions (C-x g)

    The list of expansions that would have been generated by glob-expand-word is displayed, and the line is redrawn. If a numeric argument is supplied, a ‘*’ is appended before pathname expansion.

    -
    display-shell-version (C-x C-v) - -
    +
    display-shell-version (C-x C-v)

    Display version information about the current instance of Bash.

    -
    shell-expand-line (M-C-e) - -
    +
    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 Shell Expansions).

    -
    history-expand-line (M-^) - -
    +
    history-expand-line (M-^)

    Perform history expansion on the current line.

    -
    magic-space () - -
    +
    magic-space ()

    Perform history expansion on the current line and insert a space -(see History Interaction). +(see History Expansion).

    -
    alias-expand-line () - -
    +
    alias-expand-line ()

    Perform alias expansion on the current line (see Aliases).

    -
    history-and-alias-expand-line () - -
    +
    history-and-alias-expand-line ()

    Perform history and alias expansion on the current line.

    -
    insert-last-argument (M-. or M-_) - -
    +
    insert-last-argument (M-. or M-_)

    A synonym for yank-last-arg.

    -
    edit-and-execute-command (C-x C-e) - -
    +
    edit-and-execute-command (C-x C-e)

    Invoke an editor on the current command line, and execute the result as shell commands. Bash attempts to invoke @@ -11966,7 +11463,10 @@ as the editor, in that order.


    -
    +
    +
    +
    + @@ -11990,7 +11490,9 @@ history lines with ‘k’ and subsequent lines with &lsquo so forth.


    -
    +
    +
    + @@ -12021,7 +11523,7 @@ for the command word from any successful expansion

    Once a compspec has been found, it is used to generate the list of matching words. If a compspec is not found, the default Bash completion -described above (see Commands For Completion) is performed. +described above (see Letting Readline Type For You) is performed.

    First, the actions specified by the compspec are used. Only matches which are prefixed by the word being completed are @@ -12152,7 +11654,9 @@ complete -D -F _completion_loader -o bashdefault -o default


    -
    +
    +
    + @@ -12164,9 +11668,8 @@ facilities: one to specify how the arguments to a particular command are to be completed, and two to modify the completion as it is happening.

    -
    compgen
    -
    -
    +
    compgen
    +
    compgen [option] [word]
     
    @@ -12189,9 +11692,8 @@ will be displayed. matches were generated.

    -
    complete
    -
    -
    +
    complete
    +
    complete [-abcdefgjksuv] [-o comp-option] [-DEI] [-A action] [-G globpat]
     [-W wordlist] [-F function] [-C command] [-X filterpat]
     [-P prefix] [-S suffix] name [name …]
    @@ -12232,27 +11734,27 @@ should be quoted to protect them from expansion before the
     

    -
    -o comp-option
    +
    -o comp-option

    The comp-option controls several aspects of the compspec’s behavior beyond the simple generation of completions. comp-option may be one of:

    -
    bashdefault
    +
    bashdefault

    Perform the rest of the default Bash completions if the compspec generates no matches.

    -
    default
    +
    default

    Use Readline’s default filename completion if the compspec generates no matches.

    -
    dirnames
    +
    dirnames

    Perform directory name completion if the compspec generates no matches.

    -
    filenames
    +
    filenames

    Tell Readline that the compspec generates filenames, so it can perform any filename-specific processing (like adding a slash to directory names, quoting special characters, or suppressing trailing spaces). @@ -12260,21 +11762,21 @@ This option is intended to be used with shell functions specified with -F.

    -
    noquote
    +
    noquote

    Tell Readline not to quote the completed words if they are filenames (quoting filenames is the default).

    -
    nosort
    +
    nosort

    Tell Readline not to sort the list of possible completions alphabetically.

    -
    nospace
    +
    nospace

    Tell Readline not to append a space (the default) to words completed at the end of the line.

    -
    plusdirs
    +
    plusdirs

    After any matches defined by the compspec are generated, directory name completion is attempted and any matches are added to the results of the other actions. @@ -12283,118 +11785,118 @@ matches are added to the results of the other actions.

    -
    -A action
    +
    -A action

    The action may be one of the following to generate a list of possible completions:

    -
    alias
    +
    alias

    Alias names. May also be specified as -a.

    -
    arrayvar
    +
    arrayvar

    Array variable names.

    -
    binding
    +
    binding

    Readline key binding names (see Bindable Readline Commands).

    -
    builtin
    +
    builtin

    Names of shell builtin commands. May also be specified as -b.

    -
    command
    +
    command

    Command names. May also be specified as -c.

    -
    directory
    +
    directory

    Directory names. May also be specified as -d.

    -
    disabled
    +
    disabled

    Names of disabled shell builtins.

    -
    enabled
    +
    enabled

    Names of enabled shell builtins.

    -
    export
    +
    export

    Names of exported shell variables. May also be specified as -e.

    -
    file
    +
    file

    File names. May also be specified as -f.

    -
    function
    +
    function

    Names of shell functions.

    -
    group
    +
    group

    Group names. May also be specified as -g.

    -
    helptopic
    -

    Help topics as accepted by the help builtin (see Bash Builtins). +

    helptopic
    +

    Help topics as accepted by the help builtin (see Bash Builtin Commands).

    -
    hostname
    +
    hostname

    Hostnames, as taken from the file specified by the HOSTFILE shell variable (see Bash Variables).

    -
    job
    +
    job

    Job names, if job control is active. May also be specified as -j.

    -
    keyword
    +
    keyword

    Shell reserved words. May also be specified as -k.

    -
    running
    +
    running

    Names of running jobs, if job control is active.

    -
    service
    +
    service

    Service names. May also be specified as -s.

    -
    setopt
    +
    setopt

    Valid arguments for the -o option to the set builtin (see The Set Builtin).

    -
    shopt
    +
    shopt

    Shell option names as accepted by the shopt builtin -(see Bash Builtins). +(see Bash Builtin Commands).

    -
    signal
    +
    signal

    Signal names.

    -
    stopped
    +
    stopped

    Names of stopped jobs, if job control is active.

    -
    user
    +
    user

    User names. May also be specified as -u.

    -
    variable
    +
    variable

    Names of all shell variables. May also be specified as -v.

    -
    -C command
    +
    -C command

    command is executed in a subshell environment, and its output is used as the possible completions.

    -
    -F function
    +
    -F function

    The shell function function is executed in the current shell environment. When it is executed, $1 is the name of the command whose arguments are @@ -12405,22 +11907,22 @@ When it finishes, the possible completions are retrieved from the value of the COMPREPLY array variable.

    -
    -G globpat
    +
    -G globpat

    The filename expansion pattern globpat is expanded to generate the possible completions.

    -
    -P prefix
    +
    -P prefix

    prefix is added at the beginning of each possible completion after all other options have been applied.

    -
    -S suffix
    +
    -S suffix

    suffix is appended to each possible completion after all other options have been applied.

    -
    -W wordlist
    +
    -W wordlist

    The wordlist is split using the characters in the IFS special variable as delimiters, and each resultant word is expanded. @@ -12428,7 +11930,7 @@ The possible completions are the members of the resultant list which match the word being completed.

    -
    -X filterpat
    +
    -X filterpat

    filterpat 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 @@ -12445,9 +11947,8 @@ a name for which no specification exists, or an error occurs adding a completion specification.

    -
    compopt
    -
    -
    +
    compopt
    +
    compopt [-o option] [-DEI] [+o option] [name]
     

    Modify completion options for each name according to the @@ -12479,7 +11980,9 @@ specification exists, or an output error occurs.


    -
    +
    +
    + @@ -12602,9 +12105,12 @@ in the examples/complete subdirectory.
    -
    +
    +
    +
    +

    9 Using History Interactively

    @@ -12615,19 +12121,15 @@ It should be considered a user’s guide. For information on using the GNU History Library in other programs, see the GNU Readline Library Manual.

    - - - - - +
    -
    +
    + @@ -12657,7 +12159,7 @@ the value of the HISTFILESIZE variable. When a shell with history enabled exits, the last $HISTSIZE lines are copied from the history list to the file named by $HISTFILE. -If the histappend shell option is set (see Bash Builtins), +If the histappend shell option is set (see Bash Builtin Commands), the lines are appended to the history file, otherwise the history file is overwritten. If HISTFILE @@ -12680,7 +12182,7 @@ The 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 (see Commands For History). +history list (see Commands For Manipulating The History).

    The shell allows control over which commands are saved on the history list. The HISTCONTROL and HISTIGNORE @@ -12697,9 +12199,11 @@ The shopt builtin is used to set these options. See The Shopt Builtin, for a description of shopt.


    -
    +
    +
    +

    9.2 Bash History Builtins

    @@ -12708,9 +12212,8 @@ Next:
    +
    fc [-e ename] [-lnr] [first] [last]
     fc -s [pat=rep] [command]
     
    @@ -12751,9 +12254,8 @@ that typing ‘r cc’ runs the last command beginning with and typing ‘r’ re-executes the last command (see Aliases).

    -
    history
    -
    -
    +
    history
    +
    history [n]
     history -c
     history -d offset
    @@ -12774,12 +12276,12 @@ and the history line.
     

    Options, if supplied, have the following meanings:

    -
    -c
    +
    -c

    Clear the history list. This may be combined with the other options to replace the history list completely.

    -
    -d offset
    +
    -d offset

    Delete the history entry at position offset. If offset is positive, it should be specified as it appears when the history is displayed. @@ -12789,39 +12291,39 @@ end of the history, and an index of ‘-1’ refers to the history -d command.

    -
    -d start-end
    +
    -d start-end

    Delete the history entries between positions start and end, inclusive. Positive and negative values for start and end are interpreted as described above.

    -
    -a
    +
    -a

    Append the new history lines to the history file. These are history lines entered since the beginning of the current Bash session, but not already appended to the history file.

    -
    -n
    +
    -n

    Append the history lines not already read from the history file to the current history list. These are lines appended to the history file since the beginning of the current Bash session.

    -
    -r
    +
    -r

    Read the history file and append its contents to the history list.

    -
    -w
    +
    -w

    Write out the current history list to the history file.

    -
    -p
    +
    -p

    Perform history substitution on the args and display the result on the standard output, without storing the results in the history list.

    -
    -s
    +
    -s

    The args are added to the end of the history list as a single entry.

    @@ -12837,7 +12339,9 @@ the value of the HISTFILE variable is used.

    -
    +
    +
    + @@ -12908,19 +12412,17 @@ as explained above (see Bash Variables). The shel the history comment character to mark history timestamps when writing the history file.

    - - - - - +
    -
    +
    +

    9.3.1 Event Designators

    @@ -12932,31 +12434,31 @@ position in the history list.

    -
    !
    +
    !

    Start a history substitution, except when followed by a space, tab, the end of the line, ‘=’ or ‘(’ (when the extglob shell option is enabled using the shopt builtin).

    -
    !n
    +
    !n

    Refer to command line n.

    -
    !-n
    +
    !-n

    Refer to the command n lines back.

    -
    !!
    +
    !!

    Refer to the previous command. This is a synonym for ‘!-1’.

    -
    !string
    +
    !string

    Refer to the most recent command preceding the current position in the history list starting with string.

    -
    !?string[?]
    +
    !?string[?]

    Refer to the most recent command preceding the current position in the history list containing string. @@ -12967,22 +12469,24 @@ If string is missing, the string from the most recent search is used; it is an error if there is no previous search string.

    -
    ^string1^string2^
    +
    ^string1^string2^

    Quick Substitution. Repeat the last command, replacing string1 with string2. Equivalent to !!:s^string1^string2^.

    -
    !#
    +
    !#

    The entire command line typed so far.


    -
    +
    +
    +

    9.3.2 Word Designators

    @@ -12996,17 +12500,17 @@ inserted into the current line separated by single spaces.

    For example,

    -
    !!
    +
    !!

    designates the preceding command. When you type this, the preceding command is repeated in toto.

    -
    !!:$
    +
    !!:$

    designates the last argument of the preceding command. This may be shortened to !$.

    -
    !fi:2
    +
    !fi:2

    designates the second argument of the most recent command starting with the letters fi.

    @@ -13015,42 +12519,42 @@ the letters fi.

    Here are the word designators:

    -
    0 (zero)
    +
    0 (zero)

    The 0th word. For many applications, this is the command word.

    -
    n
    +
    n

    The nth word.

    -
    ^
    +
    ^

    The first argument; that is, word 1.

    -
    $
    +
    $

    The last argument.

    -
    %
    +
    %

    The first word matched by the most recent ‘?string?’ search, if the search string begins with a character that is part of a word.

    -
    x-y
    +
    x-y

    A range of words; ‘-y’ abbreviates ‘0-y’.

    -
    *
    +
    *

    All of the words, except the 0th. This is a synonym for ‘1-$’. It is not an error to use ‘*’ if there is just one word in the event; the empty string is returned in that case.

    -
    x*
    +
    x*

    Abbreviates ‘x-$

    -
    x-
    +
    x-

    Abbreviates ‘x-$’ like ‘x*’, but omits the last word. If ‘x’ is missing, it defaults to 0.

    @@ -13061,9 +12565,11 @@ If ‘x’ is missing, it defaults to 0. previous command is used as the event.


    -
    +
    +
    +

    9.3.3 Modifiers

    @@ -13072,39 +12578,39 @@ of the following modifiers, each preceded by a ‘:’. These modify, or edit, the word or words selected from the history event.

    -
    h
    +
    h

    Remove a trailing pathname component, leaving only the head.

    -
    t
    +
    t

    Remove all leading pathname components, leaving the tail.

    -
    r
    +
    r

    Remove a trailing suffix of the form ‘.suffix’, leaving the basename.

    -
    e
    +
    e

    Remove all but the trailing suffix.

    -
    p
    +
    p

    Print the new command but do not execute it.

    -
    q
    +
    q

    Quote the substituted words, escaping further substitutions.

    -
    x
    +
    x

    Quote the substituted words as with ‘q’, but break into words at spaces, tabs, and newlines. The ‘q’ and ‘x’ modifiers are mutually exclusive; the last one supplied is used.

    -
    s/old/new/
    +
    s/old/new/

    Substitute new for the first occurrence of old in the event line. Any character may be used as the delimiter in place of ‘/’. @@ -13122,18 +12628,18 @@ The final delimiter is optional if it is the last character on the input line.

    -
    &
    +
    &

    Repeat the previous substitution.

    -
    g
    -
    a
    +
    g
    +
    a

    Cause changes to be applied over the entire event line. Used in conjunction with ‘s’, as in gs/old/new/, or with ‘&’.

    -
    G
    +
    G

    Apply the following ‘s’ or ‘&’ modifier once to each word in the event.

    @@ -13141,9 +12647,13 @@ in the event.

    -
    +
    +
    +
    +
    +

    10 Installing Bash

    @@ -13154,32 +12664,20 @@ non-Unix systems such as BeOS and Interix. Other independent ports exist for MS-DOS, OS/2, and Windows platforms.

    - - - - - - - - - - +
    -
    +
    + @@ -13274,7 +12772,9 @@ files that configure created (so you can compile Bash for a different kind of computer), type ‘make distclean’.


    -
    +
    +
    + @@ -13300,7 +12800,9 @@ can do that on the command line like this: is available.


    -
    +
    +
    + @@ -13340,7 +12842,9 @@ Bash for at least one architecture before you can create build directories for other architectures.


    -
    +
    +
    + @@ -13361,7 +12865,9 @@ If you give configure the option Documentation and other data files will still use the regular prefix.


    -
    +
    +
    + @@ -13380,7 +12886,9 @@ or a canonical name with three fields: ‘CPU-COMPANY-SYSTEM&rs values of each field.


    -
    +
    +
    + @@ -13397,7 +12905,9 @@ script. A warning: the Bash configure looks for a site script, but not all configure scripts do.


    -
    +
    +
    + @@ -13407,29 +12917,29 @@ Next:
    -
    --cache-file=file
    +
    --cache-file=file

    Use and save the results of the tests in file instead of ./config.cache. Set file to /dev/null to disable caching, for debugging configure.

    -
    --help
    +
    --help

    Print a summary of the options to configure, and exit.

    -
    --quiet
    -
    --silent
    -
    -q
    +
    --quiet
    +
    --silent
    +
    -q

    Do not print messages saying which checks are being made.

    -
    --srcdir=dir
    +
    --srcdir=dir

    Look for the Bash source code in directory dir. Usually configure can determine that directory automatically.

    -
    --version
    +
    --version

    Print the version of Autoconf used to generate the configure script, and exit.

    @@ -13439,7 +12949,9 @@ script, and exit. options. ‘configure --help’ prints the complete list.


    -
    +
    +
    + @@ -13457,11 +12969,11 @@ that is enabled by default, use --disable-feature. --with- options that the Bash configure recognizes.

    -
    --with-afs
    +
    --with-afs

    Define if you are using the Andrew File System from Transarc.

    -
    --with-bash-malloc
    +
    --with-bash-malloc

    Use the Bash version of malloc in the directory lib/malloc. This is not the same malloc that appears in GNU libc, but an older version @@ -13473,17 +12985,17 @@ which this should be turned off, and configure disables this option automatically for a number of systems.

    -
    --with-curses
    +
    --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.

    -
    --with-gnu-malloc
    +
    --with-gnu-malloc

    A synonym for --with-bash-malloc.

    -
    --with-installed-readline[=PREFIX]
    +
    --with-installed-readline[=PREFIX]

    Define this to make Bash link with a locally-installed version of Readline rather than the version in lib/readline. This works only with Readline 5.0 and later versions. If PREFIX is yes or not @@ -13500,12 +13012,12 @@ the installed version of Readline in subdirectories of that directory PREFIX/lib).

    -
    --with-purify
    +
    --with-purify

    Define this to use the Purify memory allocation checker from Rational Software.

    -
    --enable-minimal-config
    +
    --enable-minimal-config

    This produces a shell with minimal features, close to the historical Bourne shell.

    @@ -13515,18 +13027,18 @@ Bourne shell. compiled and linked, rather than changing run-time features.

    -
    --enable-largefile
    +
    --enable-largefile

    Enable support for 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.

    -
    --enable-profiling
    +
    --enable-profiling

    This builds a Bash binary that produces profiling information to be processed by gprof each time it is executed.

    -
    --enable-static-link
    +
    --enable-static-link

    This causes Bash to be linked statically, if gcc is being used. This could be used to build a version to use as root’s shell.

    @@ -13543,212 +13055,212 @@ enabled by default, unless the operating system does not provide the necessary support.

    -
    --enable-alias
    +
    --enable-alias

    Allow alias expansion and include the alias and unalias builtins (see Aliases).

    -
    --enable-arith-for-command
    +
    --enable-arith-for-command

    Include support for the alternate form of the for command that behaves like the C language for statement (see Looping Constructs).

    -
    --enable-array-variables
    +
    --enable-array-variables

    Include support for one-dimensional array shell variables (see Arrays).

    -
    --enable-bang-history
    +
    --enable-bang-history

    Include support for csh-like history substitution -(see History Interaction). +(see History Expansion).

    -
    --enable-brace-expansion
    +
    --enable-brace-expansion

    Include csh-like brace expansion ( b{a,b}cbac bbc ). See Brace Expansion, for a complete description.

    -
    --enable-casemod-attributes
    +
    --enable-casemod-attributes

    Include support for case-modifying attributes in the declare builtin and assignment statements. Variables with the uppercase attribute, for example, will have their values converted to uppercase upon assignment.

    -
    --enable-casemod-expansion
    +
    --enable-casemod-expansion

    Include support for case-modifying word expansions.

    -
    --enable-command-timing
    +
    --enable-command-timing

    Include support for recognizing time as a reserved word and for displaying timing statistics for the pipeline following time (see Pipelines). This allows pipelines as well as shell builtins and functions to be timed.

    -
    --enable-cond-command
    +
    --enable-cond-command

    Include support for the [[ conditional command. (see Conditional Constructs).

    -
    --enable-cond-regexp
    +
    --enable-cond-regexp

    Include support for matching POSIX regular expressions using the ‘=~’ binary operator in the [[ conditional command. (see Conditional Constructs).

    -
    --enable-coprocesses
    +
    --enable-coprocesses

    Include support for coprocesses and the coproc reserved word (see Pipelines).

    -
    --enable-debugger
    +
    --enable-debugger

    Include support for the bash debugger (distributed separately).

    -
    --enable-dev-fd-stat-broken
    +
    --enable-dev-fd-stat-broken

    If calling stat on /dev/fd/N returns different results than calling fstat on file descriptor N, supply this option to enable a workaround. This has implications for conditional commands that test file attributes.

    -
    --enable-direxpand-default
    +
    --enable-direxpand-default

    Cause the direxpand shell option (see The Shopt Builtin) to be enabled by default when the shell starts. It is normally disabled by default.

    -
    --enable-directory-stack
    +
    --enable-directory-stack

    Include support for a csh-like directory stack and the pushd, popd, and dirs builtins (see The Directory Stack).

    -
    --enable-disabled-builtins
    +
    --enable-disabled-builtins

    Allow builtin commands to be invoked via ‘builtin xxx’ even after xxx has been disabled using ‘enable -n xxx’. -See Bash Builtins, for details of the builtin and +See Bash Builtin Commands, for details of the builtin and enable builtin commands.

    -
    --enable-dparen-arithmetic
    +
    --enable-dparen-arithmetic

    Include support for the ((…)) command (see Conditional Constructs).

    -
    --enable-extended-glob
    +
    --enable-extended-glob

    Include support for the extended pattern matching features described above under Pattern Matching.

    -
    --enable-extended-glob-default
    +
    --enable-extended-glob-default

    Set the default value of the extglob shell option described above under The Shopt Builtin to be enabled.

    -
    --enable-function-import
    +
    --enable-function-import

    Include support for importing function definitions exported by another instance of the shell from the environment. This option is enabled by default.

    -
    --enable-glob-asciirange-default
    +
    --enable-glob-asciirange-default

    Set the default value of the globasciiranges shell option described above under The Shopt Builtin to be enabled. This controls the behavior of character ranges when used in pattern matching bracket expressions.

    -
    --enable-help-builtin
    +
    --enable-help-builtin

    Include the help builtin, which displays help on shell builtins and -variables (see Bash Builtins). +variables (see Bash Builtin Commands).

    -
    --enable-history
    +
    --enable-history

    Include command history and the fc and history builtin commands (see Bash History Facilities).

    -
    --enable-job-control
    +
    --enable-job-control

    This enables the job control features (see Job Control), if the operating system supports them.

    -
    --enable-multibyte
    +
    --enable-multibyte

    This enables support for multibyte characters if the operating system provides the necessary support.

    -
    --enable-net-redirections
    +
    --enable-net-redirections

    This enables the special handling of filenames of the form /dev/tcp/host/port and /dev/udp/host/port when used in redirections (see Redirections).

    -
    --enable-process-substitution
    +
    --enable-process-substitution

    This enables process substitution (see Process Substitution) if the operating system provides the necessary support.

    -
    --enable-progcomp
    +
    --enable-progcomp

    Enable the programmable completion facilities (see Programmable Completion). If Readline is not enabled, this option has no effect.

    -
    --enable-prompt-string-decoding
    +
    --enable-prompt-string-decoding

    Turn on the interpretation of a number of backslash-escaped characters in the $PS0, $PS1, $PS2, and $PS4 prompt strings. See Controlling the Prompt, for a complete list of prompt string escape sequences.

    -
    --enable-readline
    +
    --enable-readline

    Include support for command-line editing and history with the Bash version of the Readline library (see Command Line Editing).

    -
    --enable-restricted
    +
    --enable-restricted

    Include support for a restricted shell. If this is enabled, Bash, when called as rbash, enters a restricted mode. See The Restricted Shell, for a description of restricted mode.

    -
    --enable-select
    +
    --enable-select

    Include the select compound command, which allows the generation of simple menus (see Conditional Constructs).

    -
    --enable-separate-helpfiles
    +
    --enable-separate-helpfiles

    Use external files for the documentation displayed by the help builtin instead of storing the text internally.

    -
    --enable-single-help-strings
    +
    --enable-single-help-strings

    Store the text displayed by the help builtin as a single string for each help topic. This aids in translating the text to different languages. You may need to disable this if your compiler cannot handle very long string literals.

    -
    --enable-strict-posix-default
    +
    --enable-strict-posix-default

    Make Bash POSIX-conformant by default (see Bash POSIX Mode).

    -
    --enable-usg-echo-default
    +
    --enable-usg-echo-default

    A synonym for --enable-xpg-echo-default.

    -
    --enable-xpg-echo-default
    +
    --enable-xpg-echo-default

    Make the echo builtin expand backslash-escaped characters by default, without requiring the -e option. This sets the default value of the xpg_echo shell option to on, which makes the Bash echo behave more like the version specified in the Single Unix Specification, version 3. -See Bash Builtins, for a description of the escape sequences that +See Bash Builtin Commands, for a description of the escape sequences that echo recognizes.

    @@ -13762,9 +13274,12 @@ Read the comments associated with each definition for more information about its effect.


    -
    +
    +
    +
    +

    Appendix A Reporting Bugs

    @@ -13799,9 +13314,11 @@ the template it provides for filing a bug report. bug-bash@gnu.org.


    -
    +
    +
    +

    Appendix B Major Differences From The Bourne Shell

    @@ -13836,7 +13353,7 @@ The Bash history list maintains timestamp information and uses the value of the HISTTIMEFORMAT variable to display it.
  • Bash implements csh-like history expansion -(see History Interaction). +(see History Expansion).
  • Bash has one-dimensional array variables (see Arrays), and the appropriate variable expansions and assignment syntax to use them. @@ -13851,7 +13368,7 @@ is supported (see ANSI-C Quoting). locale-specific translation of the characters between the double quotes. The -D, --dump-strings, and --dump-po-strings invocation options list the translatable strings found in a script -(see Locale Translation). +(see Locale-Specific Translation).
  • Bash implements the ! keyword to negate the return value of a pipeline (see Pipelines). @@ -13955,7 +13472,7 @@ shell option is enabled (see Pattern Matching).
  • Bash functions are permitted to have local variables using the local builtin, and thus useful recursive functions may be written -(see Bash Builtins). +(see Bash Builtin Commands).
  • Variable assignments preceding commands affect only that command, even builtins and functions (see Environment). @@ -13993,13 +13510,13 @@ physical modes.
  • 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 -builtin and command builtins (see Bash Builtins). +builtin and command builtins (see Bash Builtin Commands).
  • The command builtin allows selective disabling of functions -when command lookup is performed (see Bash Builtins). +when command lookup is performed (see Bash Builtin Commands).
  • Individual builtins may be enabled or disabled using the enable -builtin (see Bash Builtins). +builtin (see Bash Builtin Commands).
  • The Bash exec builtin takes additional options that allow users to control the contents of the environment passed to the executed @@ -14022,12 +13539,12 @@ searching the $PATH, using ‘hash -p’ (see Bourne Shell Builtins).
  • Bash includes a help builtin for quick reference to shell -facilities (see Bash Builtins). +facilities (see Bash Builtin Commands).
  • The printf builtin is available to display formatted output -(see Bash Builtins). +(see Bash Builtin Commands). -
  • The Bash read builtin (see Bash Builtins) +
  • The Bash read builtin (see Bash Builtin Commands) will read a line ending in ‘\’ with the -r option, and will use the REPLY variable as a default if no non-option arguments are supplied. @@ -14096,7 +13613,7 @@ function has been given the trace attribute or the functrace option has been enabled using the shopt builtin.

  • The Bash type builtin is more extensive and gives more information -about the names it finds (see Bash Builtins). +about the names it finds (see Bash Builtin Commands).
  • The Bash umask builtin permits a -p option to cause the output to be displayed in the form of a umask command @@ -14137,7 +13654,11 @@ shell scripts.

    More features unique to Bash may be found in Bash Features.

    -

    B.1 Implementation Differences From The SVR4.2 Shell

    + +
    +

    B.1 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: @@ -14185,9 +13706,12 @@ only for certain failures, as enumerated in the POSIX standard.


  • -
    +
    +
    +
    +

    Appendix C GNU Free Documentation License

    @@ -14661,31 +14185,27 @@ to permit their use in free software.
    -
    +
    +
    +

    Appendix D Indexes

    - - - - - - - +
    -
    +
    +

    D.1 Index of Shell Builtin Commands

    Jump to:   . @@ -14883,9 +14403,11 @@ Next:

    -
    +
    +
    +

    D.2 Index of Shell Reserved Words

    Jump to:   ! @@ -15003,9 +14525,11 @@ Next: , Pre

    -
    +
    +
    +

    D.3 Parameter and Variable Index

    Jump to:   ! @@ -15354,9 +14878,11 @@ Next: , Pre

    -
    +
    +
    +

    D.4 Function Index

    Jump to:   A @@ -15599,7 +15125,9 @@ Next: , Previ

    -
    +
    +
    +

    Previous: , Up: Indexes   [Contents][Index]

    @@ -15864,7 +15392,9 @@ Previous: ,   -
    +
    +
    +
    diff --git a/doc/bashref.info b/doc/bashref.info index 20ebf24..00749d9 100644 --- a/doc/bashref.info +++ b/doc/bashref.info @@ -1,4 +1,4 @@ -This is bashref.info, produced by makeinfo version 6.7 from +This is bashref.info, produced by makeinfo version 6.8 from bashref.texi. This text is a brief description of the features that are present in the diff --git a/doc/bashref.log b/doc/bashref.log new file mode 100644 index 0000000..cf171d8 --- /dev/null +++ b/doc/bashref.log @@ -0,0 +1,315 @@ +This is pdfTeX, Version 3.141592653-2.6-1.40.22 (TeX Live 2021) (preloaded format=etex 2022.1.31) 31 JAN 2022 01:02 +entering extended mode + restricted \write18 enabled. + file:line:error style messages enabled. + %&-line parsing enabled. +**\nonstopmode \input ././bashref.texi \input ././bashref.texi \input ././bashr +ef.texi +(././bashref.texi (/home/luk/lineage-19.0/external/bash/doc/texinfo.tex +Loading texinfo [version 2015-11-22.14]: +\outerhsize=\dimen16 +\outervsize=\dimen17 +\cornerlong=\dimen18 +\cornerthick=\dimen19 +\topandbottommargin=\dimen20 +\bindingoffset=\dimen21 +\normaloffset=\dimen22 +\pagewidth=\dimen23 +\pageheight=\dimen24 +\headlinebox=\box16 +\footlinebox=\box17 +\margin=\insert252 +\EMsimple=\toks13 +\groupbox=\box18 +\groupinvalidhelp=\toks14 +\mil=\dimen25 +\exdentamount=\skip18 +\inmarginspacing=\skip19 +\centerpenalty=\count27 + pdf, +\tempnum=\count28 +\lnkcount=\count29 +\filename=\toks15 +\filenamelength=\count30 +\pgn=\count31 +\toksA=\toks16 +\toksB=\toks17 +\toksC=\toks18 +\toksD=\toks19 +\boxA=\box19 +\boxB=\box20 +\countA=\count32 +\nopdfimagehelp=\toks20 + fonts, +\sffam=\fam8 +\textleading=\dimen26 + markup, +\fontdepth=\count33 + glyphs, +\errorbox=\box21 + +page headings, +\titlepagetopglue=\skip20 +\titlepagebottomglue=\skip21 +\evenheadline=\toks21 +\oddheadline=\toks22 +\evenfootline=\toks23 +\oddfootline=\toks24 + tables, +\tableindent=\dimen27 +\itemindent=\dimen28 +\itemmargin=\dimen29 +\itemmax=\dimen30 +\itemno=\count34 +\multitableparskip=\skip22 +\multitableparindent=\skip23 +\multitablecolspace=\dimen31 +\multitablelinespace=\skip24 +\colcount=\count35 +\everytab=\toks25 + conditionals, +\doignorecount=\count36 + indexing, +\dummybox=\box22 +\whatsitskip=\skip25 +\whatsitpenalty=\count37 +\entryrightmargin=\dimen32 +\thinshrinkable=\skip26 +\entryindexbox=\box23 +\secondaryindent=\skip27 +\partialpage=\box24 +\doublecolumnhsize=\dimen33 +\doublecolumntopgap=\dimen34 +\savedtopmark=\toks26 +\savedfirstmark=\toks27 + sectioning, +\unnumberedno=\count38 +\chapno=\count39 +\secno=\count40 +\subsecno=\count41 +\subsubsecno=\count42 +\appendixno=\count43 +\absseclevel=\count44 +\secbase=\count45 +\chapheadingskip=\skip28 +\secheadingskip=\skip29 +\subsecheadingskip=\skip30 + toc, +\tocfile=\write0 +\contentsrightmargin=\skip31 +\savepageno=\count46 +\lastnegativepageno=\count47 +\tocindent=\dimen35 + environments, +\lispnarrowing=\skip32 +\envskipamount=\skip33 +\circthick=\dimen36 +\cartouter=\dimen37 +\cartinner=\dimen38 +\normbskip=\skip34 +\normpskip=\skip35 +\normlskip=\skip36 +\lskip=\skip37 +\rskip=\skip38 +\nonfillparindent=\dimen39 +\tabw=\dimen40 +\verbbox=\box25 + +defuns, +\defbodyindent=\skip39 +\defargsindent=\skip40 +\deflastargmargin=\skip41 +\defunpenalty=\count48 +\parencount=\count49 +\brackcount=\count50 + macros, +\paramno=\count51 +\macname=\toks28 + cross references, +\auxfile=\write1 +\savesfregister=\count52 +\toprefbox=\box26 +\printedrefnamebox=\box27 +\infofilenamebox=\box28 +\printedmanualbox=\box29 + insertions, +\footnoteno=\count53 +\SAVEfootins=\box30 +\SAVEmargin=\box31 + +(/usr/share/texlive/texmf-dist/tex/generic/epsf/epsf.tex +This is `epsf.tex' v2.7.4 <14 February 2011> +\epsffilein=\read1 +\epsfframemargin=\dimen41 +\epsfframethickness=\dimen42 +\epsfrsize=\dimen43 +\epsftmp=\dimen44 +\epsftsize=\dimen45 +\epsfxsize=\dimen46 +\epsfysize=\dimen47 +\pspoints=\dimen48 +) +\noepsfhelp=\toks29 + localization, +\nolanghelp=\toks30 +\countUTFx=\count54 +\countUTFy=\count55 +\countUTFz=\count56 + formatting, +\defaultparindent=\dimen49 + and turning on texinfo input format.) +texinfo.tex: doing @include of version.texi + + +(/home/luk/lineage-19.0/external/bash/doc/version.texi) [1] [2] +(/home/luk/lineage-19.0/external/bash/doc/bashref.toc [-1] [-2] [-3]) [-4] +Chapter 1 +\openout0 = `bashref.toc'. + + (/home/luk/lineage-19.0/external/bash/doc/bashref.aux) +\openout1 = `bashref.aux'. + + Chapter 2 +[1] [2] +@cpindfile=@write2 +\openout2 = `bashref.cp'. + + [3] Chapter 3 [4] [5] [6] +@vrindfile=@write3 +\openout3 = `bashref.vr'. + + [7] +Overfull \hbox (3.12749pt too wide) in paragraph at lines 613--614 + @texttt coproc[]| + +@hbox(9.34993+3.85005)x43.36464 +.@glue(@leftskip) 12.0 +.@texttt c +.@texttt o +.@texttt p +.@texttt r +.etc. + + +Overfull \hbox (3.12749pt too wide) in paragraph at lines 614--614 + @texttt select[]| + +@hbox(9.34993+3.85005)x43.36464 +.@glue(@leftskip) 12.0 +.@texttt s +.@texttt e +.@texttt l +.@texttt e +.etc. + + +Overfull \hbox (5.95723pt too wide) in paragraph at lines 614--615 + @texttt function[]| + +@hbox(9.34993+3.85005)x52.03227 +.@glue(@leftskip) 12.0 +.@texttt f +.@texttt u +.@texttt n +.@texttt c +.etc. + +@rwindfile=@write4 +\openout4 = `bashref.rw'. + +[8] [9] [10] [11] [12] [13] [14] [15] [16] [17] [18] [19] [20] [21] [22] +[23] [24] [25] [26] [27] [28] [29] [30] [31] [32] [33] [34] [35] [36] [37] +[38] [39] [40] [41] [42] Chapter 4 [43] +@btindfile=@write5 +\openout5 = `bashref.bt'. + + [44] [45] [46] [47] [48] [49] [50] +[51] [52] [53] [54] [55] [56] [57] [58] [59] [60] [61] [62] [63] [64] [65] +[66] [67] [68] [69] [70] [71] Chapter 5 [72] [73] [74] [75] [76] [77] [78] +[79] [80] [81] [82] [83] [84] Chapter 6 [85] [86] [87] [88] [89] [90] [91] +[92] [93] [94] [95] [96] [97] [98] [99] [100] [101] [102] [103] [104] [105] +Chapter 7 [106] [107] [108] [109] +texinfo.tex: doing @include of rluser.texi + + +(/home/luk/lineage-19.0/external/bash/lib/readline/doc/rluser.texi Chapter 8 +[110] [111] [112] [113] [114] [115] [116] [117] [118] [119] [120] +Underfull \hbox (badness 7540) in paragraph at lines 813--819 + []@textrm In the ex-am-ple above, @textttsl C-u[] @textrm is bound to the func +-tion + +@hbox(7.60416+2.12917)x433.62, glue set 4.22592 +.@glue(@leftskip) 115.63242 +.@hbox(0.0+0.0)x0.0 +.@textrm I +.@textrm n +.@glue 3.65 plus 1.825 minus 1.21666 +.etc. + + +Underfull \hbox (badness 10000) in paragraph at lines 813--819 + @texttt universal-argument[]@textrm , @textttsl M-DEL[] @textrm is bound to th +e func-tion + +@hbox(7.60416+2.43333)x433.62, glue set 5.18782 +.@glue(@leftskip) 115.63242 +.@texttt u +.@texttt n +.@texttt i +.@texttt v +.etc. + +[121] [122] [123] [124] +Overfull \hbox (26.43913pt too wide) in paragraph at lines 1047--1047 + []@texttt Meta-Control-h: backward-kill-word Text after the function name is i +gnored[] + +@hbox(6.69167+2.43333)x433.62 +.@glue(@leftskip) 28.90755 +.@hbox(0.0+0.0)x0.0 +.@texttt M +.@texttt e +.@texttt t +.etc. + +[125] [126] +@fnindfile=@write6 +\openout6 = `bashref.fn'. + + [127] [128] [129] [130] [131] [132] [133] [134] [135] [136] +[137] [138] [139] +Overfull \hbox (15.27109pt too wide) in paragraph at lines 2062--2062 + []@texttt complete [-abcdefgjksuv] [-o @textttsl comp-option@texttt ] [-DEI] [ +-A @textttsl ac-tion@texttt ] [- + +@hbox(7.60416+2.43333)x433.62 +.@glue(@leftskip) 86.72375 +.@hbox(0.0+0.0)x0.0 +.@texttt c +.@texttt o +.@texttt m +.etc. + +[140] [141] [142] [143] [144]) +texinfo.tex: doing @include of hsuser.texi + + +(/home/luk/lineage-19.0/external/bash/lib/readline/doc/hsuser.texi Chapter 9 +[145] [146] [147] [148] [149] [150]) Chapter 10 [151] [152] [153] [154] +[155] [156] [157] [158] Appendix A [159] Appendix B [160] [161] [162] [163] +[164] [165] Appendix C [166] +texinfo.tex: doing @include of fdl.texi + + (/home/luk/lineage-19.0/external/bash/doc/fdl.texi [167] [168] [169] [170] [17 +1] [172] [173]) Appendix D [174] [175] [176] +[177] [178] [179] [180] [181] [182] [183] ) +Here is how much of TeX's memory you used: + 3531 strings out of 497094 + 40208 string characters out of 6206931 + 87692 words of memory out of 6000000 + 4702 multiletter control sequences out of 15000+600000 + 34315 words of font info for 116 fonts, out of 8000000 for 9000 + 51 hyphenation exceptions out of 8191 + 16i,6n,16p,358b,942s stack positions out of 5000i,500n,10000p,200000b,80000s + +Output written on bashref.dvi (189 pages, 789640 bytes). diff --git a/doc/bashref.ps b/doc/bashref.ps index 0ef38c1..c808b2c 100644 --- a/doc/bashref.ps +++ b/doc/bashref.ps @@ -1,7 +1,7 @@ %!PS-Adobe-2.0 -%%Creator: dvips(k) 2020.1 Copyright 2020 Radical Eye Software +%%Creator: dvips(k) 2021.1 Copyright 2021 Radical Eye Software %%Title: bashref.dvi -%%CreationDate: Wed Nov 18 20:13:07 2020 +%%CreationDate: Mon Jan 31 00:02:48 2022 %%Pages: 189 %%PageOrder: Ascend %%BoundingBox: 0 0 612 792 @@ -12,7 +12,7 @@ %DVIPSWebPage: (www.radicaleye.com) %DVIPSCommandLine: dvips -D 600 -t letter -o bashref.ps bashref.dvi %DVIPSParameters: dpi=600 -%DVIPSSource: TeX output 2020.11.18:1513 +%DVIPSSource: TeX output 2022.01.31:0102 %%BeginProcSet: tex.pro 0 0 %! /TeXDict 300 dict def TeXDict begin/N{def}def/B{bind def}N/S{exch}N/X{S diff --git a/doc/bashref.rw b/doc/bashref.rw new file mode 100644 index 0000000..0daacf2 --- /dev/null +++ b/doc/bashref.rw @@ -0,0 +1,21 @@ +\entry{time}{8}{\code {time}} +\entry{!}{8}{\code {!}} +\entry{until}{10}{\code {until}} +\entry{do}{10}{\code {do}} +\entry{done}{10}{\code {done}} +\entry{while}{10}{\code {while}} +\entry{for}{10}{\code {for}} +\entry{if}{11}{\code {if}} +\entry{then}{11}{\code {then}} +\entry{else}{11}{\code {else}} +\entry{elif}{11}{\code {elif}} +\entry{fi}{11}{\code {fi}} +\entry{case}{11}{\code {case}} +\entry{in}{11}{\code {in}} +\entry{esac}{11}{\code {esac}} +\entry{select}{12}{\code {select}} +\entry{[[}{13}{\code {[[}} +\entry{]]}{13}{\code {]]}} +\entry{{\indexlbrace }}{15}{\code {{\tt \char 123}}} +\entry{{\indexrbrace }}{15}{\code {{\tt \char 125}}} +\entry{function}{18}{\code {function}} diff --git a/doc/bashref.rws b/doc/bashref.rws new file mode 100644 index 0000000..4fcd137 --- /dev/null +++ b/doc/bashref.rws @@ -0,0 +1,35 @@ +\initial {!} +\entry{\code {!}}{8} +\initial {[} +\entry{\code {[[}}{13} +\initial {]} +\entry{\code {]]}}{13} +\initial {{\indexlbrace }} +\entry{\code {{\tt \char 123}}}{15} +\initial {{\indexrbrace }} +\entry{\code {{\tt \char 125}}}{15} +\initial {C} +\entry{\code {case}}{11} +\initial {D} +\entry{\code {do}}{10} +\entry{\code {done}}{10} +\initial {E} +\entry{\code {elif}}{11} +\entry{\code {else}}{11} +\entry{\code {esac}}{11} +\initial {F} +\entry{\code {fi}}{11} +\entry{\code {for}}{10} +\entry{\code {function}}{18} +\initial {I} +\entry{\code {if}}{11} +\entry{\code {in}}{11} +\initial {S} +\entry{\code {select}}{12} +\initial {T} +\entry{\code {then}}{11} +\entry{\code {time}}{8} +\initial {U} +\entry{\code {until}}{10} +\initial {W} +\entry{\code {while}}{10} diff --git a/doc/bashref.toc b/doc/bashref.toc new file mode 100644 index 0000000..5fb001c --- /dev/null +++ b/doc/bashref.toc @@ -0,0 +1,141 @@ +@numchapentry{Introduction}{1}{Introduction}{1} +@numsecentry{What is Bash?}{1.1}{What is Bash?}{1} +@numsecentry{What is a shell?}{1.2}{What is a shell?}{1} +@numchapentry{Definitions}{2}{Definitions}{3} +@numchapentry{Basic Shell Features}{3}{Basic Shell Features}{5} +@numsecentry{Shell Syntax}{3.1}{Shell Syntax}{5} +@numsubsecentry{Shell Operation}{3.1.1}{Shell Operation}{5} +@numsubsecentry{Quoting}{3.1.2}{Quoting}{6} +@numsubsubsecentry{Escape Character}{3.1.2.1}{Escape Character}{6} +@numsubsubsecentry{Single Quotes}{3.1.2.2}{Single Quotes}{6} +@numsubsubsecentry{Double Quotes}{3.1.2.3}{Double Quotes}{6} +@numsubsubsecentry{ANSI-C Quoting}{3.1.2.4}{ANSI-C Quoting}{6} +@numsubsubsecentry{Locale-Specific Translation}{3.1.2.5}{Locale Translation}{7} +@numsubsecentry{Comments}{3.1.3}{Comments}{7} +@numsecentry{Shell Commands}{3.2}{Shell Commands}{8} +@numsubsecentry{Reserved Words}{3.2.1}{Reserved Words}{8} +@numsubsecentry{Simple Commands}{3.2.2}{Simple Commands}{8} +@numsubsecentry{Pipelines}{3.2.3}{Pipelines}{8} +@numsubsecentry{Lists of Commands}{3.2.4}{Lists}{9} +@numsubsecentry{Compound Commands}{3.2.5}{Compound Commands}{10} +@numsubsubsecentry{Looping Constructs}{3.2.5.1}{Looping Constructs}{10} +@numsubsubsecentry{Conditional Constructs}{3.2.5.2}{Conditional Constructs}{11} +@numsubsubsecentry{Grouping Commands}{3.2.5.3}{Command Grouping}{15} +@numsubsecentry{Coprocesses}{3.2.6}{Coprocesses}{15} +@numsubsecentry{GNU Parallel}{3.2.7}{GNU Parallel}{16} +@numsecentry{Shell Functions}{3.3}{Shell Functions}{18} +@numsecentry{Shell Parameters}{3.4}{Shell Parameters}{20} +@numsubsecentry{Positional Parameters}{3.4.1}{Positional Parameters}{21} +@numsubsecentry{Special Parameters}{3.4.2}{Special Parameters}{21} +@numsecentry{Shell Expansions}{3.5}{Shell Expansions}{22} +@numsubsecentry{Brace Expansion}{3.5.1}{Brace Expansion}{23} +@numsubsecentry{Tilde Expansion}{3.5.2}{Tilde Expansion}{24} +@numsubsecentry{Shell Parameter Expansion}{3.5.3}{Shell Parameter Expansion}{25} +@numsubsecentry{Command Substitution}{3.5.4}{Command Substitution}{31} +@numsubsecentry{Arithmetic Expansion}{3.5.5}{Arithmetic Expansion}{31} +@numsubsecentry{Process Substitution}{3.5.6}{Process Substitution}{32} +@numsubsecentry{Word Splitting}{3.5.7}{Word Splitting}{32} +@numsubsecentry{Filename Expansion}{3.5.8}{Filename Expansion}{33} +@numsubsubsecentry{Pattern Matching}{3.5.8.1}{Pattern Matching}{33} +@numsubsecentry{Quote Removal}{3.5.9}{Quote Removal}{35} +@numsecentry{Redirections}{3.6}{Redirections}{35} +@numsubsecentry{Redirecting Input}{3.6.1}{}{36} +@numsubsecentry{Redirecting Output}{3.6.2}{}{36} +@numsubsecentry{Appending Redirected Output}{3.6.3}{}{36} +@numsubsecentry{Redirecting Standard Output and Standard Error}{3.6.4}{}{37} +@numsubsecentry{Appending Standard Output and Standard Error}{3.6.5}{}{37} +@numsubsecentry{Here Documents}{3.6.6}{}{37} +@numsubsecentry{Here Strings}{3.6.7}{}{38} +@numsubsecentry{Duplicating File Descriptors}{3.6.8}{}{38} +@numsubsecentry{Moving File Descriptors}{3.6.9}{}{38} +@numsubsecentry{Opening File Descriptors for Reading and Writing}{3.6.10}{}{38} +@numsecentry{Executing Commands}{3.7}{Executing Commands}{39} +@numsubsecentry{Simple Command Expansion}{3.7.1}{Simple Command Expansion}{39} +@numsubsecentry{Command Search and Execution}{3.7.2}{Command Search and Execution}{39} +@numsubsecentry{Command Execution Environment}{3.7.3}{Command Execution Environment}{40} +@numsubsecentry{Environment}{3.7.4}{Environment}{41} +@numsubsecentry{Exit Status}{3.7.5}{Exit Status}{41} +@numsubsecentry{Signals}{3.7.6}{Signals}{42} +@numsecentry{Shell Scripts}{3.8}{Shell Scripts}{42} +@numchapentry{Shell Builtin Commands}{4}{Shell Builtin Commands}{44} +@numsecentry{Bourne Shell Builtins}{4.1}{Bourne Shell Builtins}{44} +@numsecentry{Bash Builtin Commands}{4.2}{Bash Builtins}{51} +@numsecentry{Modifying Shell Behavior}{4.3}{Modifying Shell Behavior}{62} +@numsubsecentry{The Set Builtin}{4.3.1}{The Set Builtin}{62} +@numsubsecentry{The Shopt Builtin}{4.3.2}{The Shopt Builtin}{66} +@numsecentry{Special Builtins}{4.4}{Special Builtins}{72} +@numchapentry{Shell Variables}{5}{Shell Variables}{73} +@numsecentry{Bourne Shell Variables}{5.1}{Bourne Shell Variables}{73} +@numsecentry{Bash Variables}{5.2}{Bash Variables}{73} +@numchapentry{Bash Features}{6}{Bash Features}{86} +@numsecentry{Invoking Bash}{6.1}{Invoking Bash}{86} +@numsecentry{Bash Startup Files}{6.2}{Bash Startup Files}{88} +@numsecentry{Interactive Shells}{6.3}{Interactive Shells}{89} +@numsubsecentry{What is an Interactive Shell?}{6.3.1}{What is an Interactive Shell?}{90} +@numsubsecentry{Is this Shell Interactive?}{6.3.2}{Is this Shell Interactive?}{90} +@numsubsecentry{Interactive Shell Behavior}{6.3.3}{Interactive Shell Behavior}{90} +@numsecentry{Bash Conditional Expressions}{6.4}{Bash Conditional Expressions}{91} +@numsecentry{Shell Arithmetic}{6.5}{Shell Arithmetic}{93} +@numsecentry{Aliases}{6.6}{Aliases}{94} +@numsecentry{Arrays}{6.7}{Arrays}{95} +@numsecentry{The Directory Stack}{6.8}{The Directory Stack}{97} +@numsubsecentry{Directory Stack Builtins}{6.8.1}{Directory Stack Builtins}{97} +@numsecentry{Controlling the Prompt}{6.9}{Controlling the Prompt}{98} +@numsecentry{The Restricted Shell}{6.10}{The Restricted Shell}{100} +@numsecentry{Bash POSIX Mode}{6.11}{Bash POSIX Mode}{101} +@numsecentry{Shell Compatibility Mode}{6.12}{Shell Compatibility Mode}{104} +@numchapentry{Job Control}{7}{Job Control}{107} +@numsecentry{Job Control Basics}{7.1}{Job Control Basics}{107} +@numsecentry{Job Control Builtins}{7.2}{Job Control Builtins}{108} +@numsecentry{Job Control Variables}{7.3}{Job Control Variables}{110} +@numchapentry{Command Line Editing}{8}{Command Line Editing}{111} +@numsecentry{Introduction to Line Editing}{8.1}{Introduction and Notation}{111} +@numsecentry{Readline Interaction}{8.2}{Readline Interaction}{111} +@numsubsecentry{Readline Bare Essentials}{8.2.1}{Readline Bare Essentials}{112} +@numsubsecentry{Readline Movement Commands}{8.2.2}{Readline Movement Commands}{112} +@numsubsecentry{Readline Killing Commands}{8.2.3}{Readline Killing Commands}{113} +@numsubsecentry{Readline Arguments}{8.2.4}{Readline Arguments}{113} +@numsubsecentry{Searching for Commands in the History}{8.2.5}{Searching}{113} +@numsecentry{Readline Init File}{8.3}{Readline Init File}{114} +@numsubsecentry{Readline Init File Syntax}{8.3.1}{Readline Init File Syntax}{114} +@numsubsecentry{Conditional Init Constructs}{8.3.2}{Conditional Init Constructs}{122} +@numsubsecentry{Sample Init File}{8.3.3}{Sample Init File}{124} +@numsecentry{Bindable Readline Commands}{8.4}{Bindable Readline Commands}{127} +@numsubsecentry{Commands For Moving}{8.4.1}{Commands For Moving}{127} +@numsubsecentry{Commands For Manipulating The History}{8.4.2}{Commands For History}{128} +@numsubsecentry{Commands For Changing Text}{8.4.3}{Commands For Text}{130} +@numsubsecentry{Killing And Yanking}{8.4.4}{Commands For Killing}{131} +@numsubsecentry{Specifying Numeric Arguments}{8.4.5}{Numeric Arguments}{132} +@numsubsecentry{Letting Readline Type For You}{8.4.6}{Commands For Completion}{133} +@numsubsecentry{Keyboard Macros}{8.4.7}{Keyboard Macros}{134} +@numsubsecentry{Some Miscellaneous Commands}{8.4.8}{Miscellaneous Commands}{135} +@numsecentry{Readline vi Mode}{8.5}{Readline vi Mode}{137} +@numsecentry{Programmable Completion}{8.6}{Programmable Completion}{137} +@numsecentry{Programmable Completion Builtins}{8.7}{Programmable Completion Builtins}{139} +@numsecentry{A Programmable Completion Example}{8.8}{A Programmable Completion Example}{143} +@numchapentry{Using History Interactively}{9}{Using History Interactively}{146} +@numsecentry{Bash History Facilities}{9.1}{Bash History Facilities}{146} +@numsecentry{Bash History Builtins}{9.2}{Bash History Builtins}{146} +@numsecentry{History Expansion}{9.3}{History Interaction}{148} +@numsubsecentry{Event Designators}{9.3.1}{Event Designators}{149} +@numsubsecentry{Word Designators}{9.3.2}{Word Designators}{150} +@numsubsecentry{Modifiers}{9.3.3}{Modifiers}{150} +@numchapentry{Installing Bash}{10}{Installing Bash}{152} +@numsecentry{Basic Installation}{10.1}{Basic Installation}{152} +@numsecentry{Compilers and Options}{10.2}{Compilers and Options}{153} +@numsecentry{Compiling For Multiple Architectures}{10.3}{Compiling For Multiple Architectures}{153} +@numsecentry{Installation Names}{10.4}{Installation Names}{153} +@numsecentry{Specifying the System Type}{10.5}{Specifying the System Type}{154} +@numsecentry{Sharing Defaults}{10.6}{Sharing Defaults}{154} +@numsecentry{Operation Controls}{10.7}{Operation Controls}{154} +@numsecentry{Optional Features}{10.8}{Optional Features}{155} +@appentry{Reporting Bugs}{A}{Reporting Bugs}{160} +@appentry{Major Differences From The Bourne Shell}{B}{Major Differences From The Bourne Shell}{161} +@appsecentry{Implementation Differences From The SVR4.2 Shell}{B.1}{}{165} +@appentry{GNU Free Documentation License}{C}{GNU Free Documentation License}{167} +@appentry{Indexes}{D}{Indexes}{175} +@appsecentry{Index of Shell Builtin Commands}{D.1}{Builtin Index}{175} +@appsecentry{Index of Shell Reserved Words}{D.2}{Reserved Word Index}{176} +@appsecentry{Parameter and Variable Index}{D.3}{Variable Index}{177} +@appsecentry{Function Index}{D.4}{Function Index}{179} +@appsecentry{Concept Index}{D.5}{Concept Index}{181} diff --git a/doc/bashref.vr b/doc/bashref.vr new file mode 100644 index 0000000..4a9d7d7 --- /dev/null +++ b/doc/bashref.vr @@ -0,0 +1,168 @@ +\entry{LC_MESSAGES}{7}{\code {LC_MESSAGES}} +\entry{TEXTDOMAIN}{7}{\code {TEXTDOMAIN}} +\entry{TEXTDOMAINDIR}{7}{\code {TEXTDOMAINDIR}} +\entry{*}{22}{\code {*}} +\entry{$*}{22}{\code {$*}} +\entry{@}{22}{\code {@}} +\entry{$@}{22}{\code {$@}} +\entry{#}{22}{\code {#}} +\entry{$#}{22}{\code {$#}} +\entry{?}{22}{\code {?}} +\entry{$?}{22}{\code {$?}} +\entry{-}{22}{\code {-}} +\entry{$-}{22}{\code {$-}} +\entry{$}{22}{\code {$}} +\entry{$$}{22}{\code {$$}} +\entry{!}{22}{\code {!}} +\entry{$!}{22}{\code {$!}} +\entry{0}{22}{\code {0}} +\entry{$0}{22}{\code {$0}} +\entry{CDPATH}{73}{\code {CDPATH}} +\entry{HOME}{73}{\code {HOME}} +\entry{IFS}{73}{\code {IFS}} +\entry{MAIL}{73}{\code {MAIL}} +\entry{MAILPATH}{73}{\code {MAILPATH}} +\entry{OPTARG}{73}{\code {OPTARG}} +\entry{OPTIND}{73}{\code {OPTIND}} +\entry{PATH}{73}{\code {PATH}} +\entry{PS1}{73}{\code {PS1}} +\entry{PS2}{73}{\code {PS2}} +\entry{_}{73}{\code {_}} +\entry{$_}{73}{\code {$_}} +\entry{BASH}{74}{\code {BASH}} +\entry{BASHOPTS}{74}{\code {BASHOPTS}} +\entry{BASHPID}{74}{\code {BASHPID}} +\entry{BASH_ALIASES}{74}{\code {BASH_ALIASES}} +\entry{BASH_ARGC}{74}{\code {BASH_ARGC}} +\entry{BASH_ARGV}{74}{\code {BASH_ARGV}} +\entry{BASH_ARGV0}{75}{\code {BASH_ARGV0}} +\entry{BASH_CMDS}{75}{\code {BASH_CMDS}} +\entry{BASH_COMMAND}{75}{\code {BASH_COMMAND}} +\entry{BASH_COMPAT}{75}{\code {BASH_COMPAT}} +\entry{BASH_ENV}{75}{\code {BASH_ENV}} +\entry{BASH_EXECUTION_STRING}{75}{\code {BASH_EXECUTION_STRING}} +\entry{BASH_LINENO}{75}{\code {BASH_LINENO}} +\entry{BASH_LOADABLES_PATH}{76}{\code {BASH_LOADABLES_PATH}} +\entry{BASH_REMATCH}{76}{\code {BASH_REMATCH}} +\entry{BASH_SOURCE}{76}{\code {BASH_SOURCE}} +\entry{BASH_SUBSHELL}{76}{\code {BASH_SUBSHELL}} +\entry{BASH_VERSINFO}{76}{\code {BASH_VERSINFO}} +\entry{BASH_VERSION}{76}{\code {BASH_VERSION}} +\entry{BASH_XTRACEFD}{76}{\code {BASH_XTRACEFD}} +\entry{CHILD_MAX}{77}{\code {CHILD_MAX}} +\entry{COLUMNS}{77}{\code {COLUMNS}} +\entry{COMP_CWORD}{77}{\code {COMP_CWORD}} +\entry{COMP_LINE}{77}{\code {COMP_LINE}} +\entry{COMP_POINT}{77}{\code {COMP_POINT}} +\entry{COMP_TYPE}{77}{\code {COMP_TYPE}} +\entry{COMP_KEY}{77}{\code {COMP_KEY}} +\entry{COMP_WORDBREAKS}{77}{\code {COMP_WORDBREAKS}} +\entry{COMP_WORDS}{77}{\code {COMP_WORDS}} +\entry{COMPREPLY}{78}{\code {COMPREPLY}} +\entry{COPROC}{78}{\code {COPROC}} +\entry{DIRSTACK}{78}{\code {DIRSTACK}} +\entry{EMACS}{78}{\code {EMACS}} +\entry{ENV}{78}{\code {ENV}} +\entry{EPOCHREALTIME}{78}{\code {EPOCHREALTIME}} +\entry{EPOCHSECONDS}{78}{\code {EPOCHSECONDS}} +\entry{EUID}{78}{\code {EUID}} +\entry{EXECIGNORE}{78}{\code {EXECIGNORE}} +\entry{FCEDIT}{79}{\code {FCEDIT}} +\entry{FIGNORE}{79}{\code {FIGNORE}} +\entry{FUNCNAME}{79}{\code {FUNCNAME}} +\entry{FUNCNEST}{79}{\code {FUNCNEST}} +\entry{GLOBIGNORE}{79}{\code {GLOBIGNORE}} +\entry{GROUPS}{79}{\code {GROUPS}} +\entry{histchars}{79}{\code {histchars}} +\entry{HISTCMD}{79}{\code {HISTCMD}} +\entry{HISTCONTROL}{80}{\code {HISTCONTROL}} +\entry{HISTFILE}{80}{\code {HISTFILE}} +\entry{HISTFILESIZE}{80}{\code {HISTFILESIZE}} +\entry{HISTIGNORE}{80}{\code {HISTIGNORE}} +\entry{HISTSIZE}{80}{\code {HISTSIZE}} +\entry{HISTTIMEFORMAT}{80}{\code {HISTTIMEFORMAT}} +\entry{HOSTFILE}{81}{\code {HOSTFILE}} +\entry{HOSTNAME}{81}{\code {HOSTNAME}} +\entry{HOSTTYPE}{81}{\code {HOSTTYPE}} +\entry{IGNOREEOF}{81}{\code {IGNOREEOF}} +\entry{INPUTRC}{81}{\code {INPUTRC}} +\entry{INSIDE_EMACS}{81}{\code {INSIDE_EMACS}} +\entry{LANG}{81}{\code {LANG}} +\entry{LC_ALL}{81}{\code {LC_ALL}} +\entry{LC_COLLATE}{81}{\code {LC_COLLATE}} +\entry{LC_CTYPE}{81}{\code {LC_CTYPE}} +\entry{LC_MESSAGES}{81}{\code {LC_MESSAGES}} +\entry{LC_NUMERIC}{82}{\code {LC_NUMERIC}} +\entry{LC_TIME}{82}{\code {LC_TIME}} +\entry{LINENO}{82}{\code {LINENO}} +\entry{LINES}{82}{\code {LINES}} +\entry{MACHTYPE}{82}{\code {MACHTYPE}} +\entry{MAILCHECK}{82}{\code {MAILCHECK}} +\entry{MAPFILE}{82}{\code {MAPFILE}} +\entry{OLDPWD}{82}{\code {OLDPWD}} +\entry{OPTERR}{82}{\code {OPTERR}} +\entry{OSTYPE}{82}{\code {OSTYPE}} +\entry{PIPESTATUS}{82}{\code {PIPESTATUS}} +\entry{POSIXLY_CORRECT}{82}{\code {POSIXLY_CORRECT}} +\entry{PPID}{82}{\code {PPID}} +\entry{PROMPT_COMMAND}{82}{\code {PROMPT_COMMAND}} +\entry{PROMPT_DIRTRIM}{83}{\code {PROMPT_DIRTRIM}} +\entry{PS0}{83}{\code {PS0}} +\entry{PS3}{83}{\code {PS3}} +\entry{PS4}{83}{\code {PS4}} +\entry{PWD}{83}{\code {PWD}} +\entry{RANDOM}{83}{\code {RANDOM}} +\entry{READLINE_LINE}{83}{\code {READLINE_LINE}} +\entry{READLINE_MARK}{83}{\code {READLINE_MARK}} +\entry{READLINE_POINT}{83}{\code {READLINE_POINT}} +\entry{REPLY}{83}{\code {REPLY}} +\entry{SECONDS}{83}{\code {SECONDS}} +\entry{SHELL}{83}{\code {SHELL}} +\entry{SHELLOPTS}{83}{\code {SHELLOPTS}} +\entry{SHLVL}{84}{\code {SHLVL}} +\entry{SRANDOM}{84}{\code {SRANDOM}} +\entry{TIMEFORMAT}{84}{\code {TIMEFORMAT}} +\entry{TMOUT}{84}{\code {TMOUT}} +\entry{TMPDIR}{85}{\code {TMPDIR}} +\entry{UID}{85}{\code {UID}} +\entry{auto_resume}{110}{\code {auto_resume}} +\entry{bell-style}{115}{\code {bell-style}} +\entry{bind-tty-special-chars}{115}{\code {bind-tty-special-chars}} +\entry{blink-matching-paren}{115}{\code {blink-matching-paren}} +\entry{colored-completion-prefix}{115}{\code {colored-completion-prefix}} +\entry{colored-stats}{115}{\code {colored-stats}} +\entry{comment-begin}{115}{\code {comment-begin}} +\entry{completion-display-width}{115}{\code {completion-display-width}} +\entry{completion-ignore-case}{116}{\code {completion-ignore-case}} +\entry{completion-map-case}{116}{\code {completion-map-case}} +\entry{completion-prefix-display-length}{116}{\code {completion-prefix-display-length}} +\entry{completion-query-items}{116}{\code {completion-query-items}} +\entry{convert-meta}{116}{\code {convert-meta}} +\entry{disable-completion}{116}{\code {disable-completion}} +\entry{echo-control-characters}{116}{\code {echo-control-characters}} +\entry{editing-mode}{116}{\code {editing-mode}} +\entry{emacs-mode-string}{117}{\code {emacs-mode-string}} +\entry{enable-bracketed-paste}{117}{\code {enable-bracketed-paste}} +\entry{enable-keypad}{117}{\code {enable-keypad}} +\entry{expand-tilde}{117}{\code {expand-tilde}} +\entry{history-preserve-point}{117}{\code {history-preserve-point}} +\entry{history-size}{117}{\code {history-size}} +\entry{horizontal-scroll-mode}{117}{\code {horizontal-scroll-mode}} +\entry{input-meta}{118}{\code {input-meta}} +\entry{meta-flag}{118}{\code {meta-flag}} +\entry{isearch-terminators}{118}{\code {isearch-terminators}} +\entry{keymap}{118}{\code {keymap}} +\entry{mark-modified-lines}{118}{\code {mark-modified-lines}} +\entry{mark-symlinked-directories}{119}{\code {mark-symlinked-directories}} +\entry{match-hidden-files}{119}{\code {match-hidden-files}} +\entry{menu-complete-display-prefix}{119}{\code {menu-complete-display-prefix}} +\entry{output-meta}{119}{\code {output-meta}} +\entry{page-completions}{119}{\code {page-completions}} +\entry{revert-all-at-newline}{119}{\code {revert-all-at-newline}} +\entry{show-all-if-ambiguous}{119}{\code {show-all-if-ambiguous}} +\entry{show-all-if-unmodified}{119}{\code {show-all-if-unmodified}} +\entry{show-mode-in-prompt}{120}{\code {show-mode-in-prompt}} +\entry{skip-completed-text}{120}{\code {skip-completed-text}} +\entry{vi-cmd-mode-string}{120}{\code {vi-cmd-mode-string}} +\entry{vi-ins-mode-string}{120}{\code {vi-ins-mode-string}} +\entry{visible-stats}{120}{\code {visible-stats}} diff --git a/doc/bashref.vrs b/doc/bashref.vrs new file mode 100644 index 0000000..e5e8a75 --- /dev/null +++ b/doc/bashref.vrs @@ -0,0 +1,195 @@ +\initial {!} +\entry{\code {!}}{22} +\initial {#} +\entry{\code {#}}{22} +\initial {$} +\entry{\code {$}}{22} +\entry{\code {$!}}{22} +\entry{\code {$#}}{22} +\entry{\code {$$}}{22} +\entry{\code {$*}}{22} +\entry{\code {$-}}{22} +\entry{\code {$?}}{22} +\entry{\code {$@}}{22} +\entry{\code {$_}}{73} +\entry{\code {$0}}{22} +\initial {*} +\entry{\code {*}}{22} +\initial {-} +\entry{\code {-}}{22} +\initial {?} +\entry{\code {?}}{22} +\initial {@} +\entry{\code {@}}{22} +\initial {_} +\entry{\code {_}}{73} +\initial {0} +\entry{\code {0}}{22} +\initial {A} +\entry{\code {auto_resume}}{110} +\initial {B} +\entry{\code {BASH}}{74} +\entry{\code {BASH_ALIASES}}{74} +\entry{\code {BASH_ARGC}}{74} +\entry{\code {BASH_ARGV}}{74} +\entry{\code {BASH_ARGV0}}{75} +\entry{\code {BASH_CMDS}}{75} +\entry{\code {BASH_COMMAND}}{75} +\entry{\code {BASH_COMPAT}}{75} +\entry{\code {BASH_ENV}}{75} +\entry{\code {BASH_EXECUTION_STRING}}{75} +\entry{\code {BASH_LINENO}}{75} +\entry{\code {BASH_LOADABLES_PATH}}{76} +\entry{\code {BASH_REMATCH}}{76} +\entry{\code {BASH_SOURCE}}{76} +\entry{\code {BASH_SUBSHELL}}{76} +\entry{\code {BASH_VERSINFO}}{76} +\entry{\code {BASH_VERSION}}{76} +\entry{\code {BASH_XTRACEFD}}{76} +\entry{\code {BASHOPTS}}{74} +\entry{\code {BASHPID}}{74} +\entry{\code {bell-style}}{115} +\entry{\code {bind-tty-special-chars}}{115} +\entry{\code {blink-matching-paren}}{115} +\initial {C} +\entry{\code {CDPATH}}{73} +\entry{\code {CHILD_MAX}}{77} +\entry{\code {colored-completion-prefix}}{115} +\entry{\code {colored-stats}}{115} +\entry{\code {COLUMNS}}{77} +\entry{\code {comment-begin}}{115} +\entry{\code {COMP_CWORD}}{77} +\entry{\code {COMP_KEY}}{77} +\entry{\code {COMP_LINE}}{77} +\entry{\code {COMP_POINT}}{77} +\entry{\code {COMP_TYPE}}{77} +\entry{\code {COMP_WORDBREAKS}}{77} +\entry{\code {COMP_WORDS}}{77} +\entry{\code {completion-display-width}}{115} +\entry{\code {completion-ignore-case}}{116} +\entry{\code {completion-map-case}}{116} +\entry{\code {completion-prefix-display-length}}{116} +\entry{\code {completion-query-items}}{116} +\entry{\code {COMPREPLY}}{78} +\entry{\code {convert-meta}}{116} +\entry{\code {COPROC}}{78} +\initial {D} +\entry{\code {DIRSTACK}}{78} +\entry{\code {disable-completion}}{116} +\initial {E} +\entry{\code {echo-control-characters}}{116} +\entry{\code {editing-mode}}{116} +\entry{\code {emacs-mode-string}}{117} +\entry{\code {EMACS}}{78} +\entry{\code {enable-bracketed-paste}}{117} +\entry{\code {enable-keypad}}{117} +\entry{\code {ENV}}{78} +\entry{\code {EPOCHREALTIME}}{78} +\entry{\code {EPOCHSECONDS}}{78} +\entry{\code {EUID}}{78} +\entry{\code {EXECIGNORE}}{78} +\entry{\code {expand-tilde}}{117} +\initial {F} +\entry{\code {FCEDIT}}{79} +\entry{\code {FIGNORE}}{79} +\entry{\code {FUNCNAME}}{79} +\entry{\code {FUNCNEST}}{79} +\initial {G} +\entry{\code {GLOBIGNORE}}{79} +\entry{\code {GROUPS}}{79} +\initial {H} +\entry{\code {histchars}}{79} +\entry{\code {HISTCMD}}{79} +\entry{\code {HISTCONTROL}}{80} +\entry{\code {HISTFILE}}{80} +\entry{\code {HISTFILESIZE}}{80} +\entry{\code {HISTIGNORE}}{80} +\entry{\code {history-preserve-point}}{117} +\entry{\code {history-size}}{117} +\entry{\code {HISTSIZE}}{80} +\entry{\code {HISTTIMEFORMAT}}{80} +\entry{\code {HOME}}{73} +\entry{\code {horizontal-scroll-mode}}{117} +\entry{\code {HOSTFILE}}{81} +\entry{\code {HOSTNAME}}{81} +\entry{\code {HOSTTYPE}}{81} +\initial {I} +\entry{\code {IFS}}{73} +\entry{\code {IGNOREEOF}}{81} +\entry{\code {input-meta}}{118} +\entry{\code {INPUTRC}}{81} +\entry{\code {INSIDE_EMACS}}{81} +\entry{\code {isearch-terminators}}{118} +\initial {K} +\entry{\code {keymap}}{118} +\initial {L} +\entry{\code {LANG}}{81} +\entry{\code {LC_ALL}}{81} +\entry{\code {LC_COLLATE}}{81} +\entry{\code {LC_CTYPE}}{81} +\entry{\code {LC_MESSAGES}}{7, 81} +\entry{\code {LC_NUMERIC}}{82} +\entry{\code {LC_TIME}}{82} +\entry{\code {LINENO}}{82} +\entry{\code {LINES}}{82} +\initial {M} +\entry{\code {MACHTYPE}}{82} +\entry{\code {MAIL}}{73} +\entry{\code {MAILCHECK}}{82} +\entry{\code {MAILPATH}}{73} +\entry{\code {MAPFILE}}{82} +\entry{\code {mark-modified-lines}}{118} +\entry{\code {mark-symlinked-directories}}{119} +\entry{\code {match-hidden-files}}{119} +\entry{\code {menu-complete-display-prefix}}{119} +\entry{\code {meta-flag}}{118} +\initial {O} +\entry{\code {OLDPWD}}{82} +\entry{\code {OPTARG}}{73} +\entry{\code {OPTERR}}{82} +\entry{\code {OPTIND}}{73} +\entry{\code {OSTYPE}}{82} +\entry{\code {output-meta}}{119} +\initial {P} +\entry{\code {page-completions}}{119} +\entry{\code {PATH}}{73} +\entry{\code {PIPESTATUS}}{82} +\entry{\code {POSIXLY_CORRECT}}{82} +\entry{\code {PPID}}{82} +\entry{\code {PROMPT_COMMAND}}{82} +\entry{\code {PROMPT_DIRTRIM}}{83} +\entry{\code {PS0}}{83} +\entry{\code {PS1}}{73} +\entry{\code {PS2}}{73} +\entry{\code {PS3}}{83} +\entry{\code {PS4}}{83} +\entry{\code {PWD}}{83} +\initial {R} +\entry{\code {RANDOM}}{83} +\entry{\code {READLINE_LINE}}{83} +\entry{\code {READLINE_MARK}}{83} +\entry{\code {READLINE_POINT}}{83} +\entry{\code {REPLY}}{83} +\entry{\code {revert-all-at-newline}}{119} +\initial {S} +\entry{\code {SECONDS}}{83} +\entry{\code {SHELL}}{83} +\entry{\code {SHELLOPTS}}{83} +\entry{\code {SHLVL}}{84} +\entry{\code {show-all-if-ambiguous}}{119} +\entry{\code {show-all-if-unmodified}}{119} +\entry{\code {show-mode-in-prompt}}{120} +\entry{\code {skip-completed-text}}{120} +\entry{\code {SRANDOM}}{84} +\initial {T} +\entry{\code {TEXTDOMAIN}}{7} +\entry{\code {TEXTDOMAINDIR}}{7} +\entry{\code {TIMEFORMAT}}{84} +\entry{\code {TMOUT}}{84} +\entry{\code {TMPDIR}}{85} +\initial {U} +\entry{\code {UID}}{85} +\initial {V} +\entry{\code {vi-cmd-mode-string}}{120} +\entry{\code {vi-ins-mode-string}}{120} +\entry{\code {visible-stats}}{120} diff --git a/doc/builtins.ps b/doc/builtins.ps index ae11c54..5627eab 100644 --- a/doc/builtins.ps +++ b/doc/builtins.ps @@ -1,6 +1,6 @@ %!PS-Adobe-3.0 %%Creator: groff version 1.22.4 -%%CreationDate: Wed Nov 18 15:13:06 2020 +%%CreationDate: Mon Jan 31 01:01:42 2022 %%DocumentNeededResources: font Times-Roman %%+ font Times-Bold %%+ font Times-Italic diff --git a/doc/rbash.ps b/doc/rbash.ps index 45c9f66..5fb9d6e 100644 --- a/doc/rbash.ps +++ b/doc/rbash.ps @@ -1,6 +1,6 @@ %!PS-Adobe-3.0 %%Creator: groff version 1.22.4 -%%CreationDate: Wed Nov 18 15:13:06 2020 +%%CreationDate: Mon Jan 31 01:01:42 2022 %%DocumentNeededResources: font Times-Roman %%+ font Times-Bold %%DocumentSuppliedResources: procset grops 1.22 4 diff --git a/general.c b/general.c index 50d5216..7ebc3fa 100644 --- a/general.c +++ b/general.c @@ -89,12 +89,12 @@ static struct { int *posix_mode_var; } posix_vars[] = { - &interactive_comments, - &source_uses_path, - &expand_aliases, - &inherit_errexit, - &print_shift_error, - 0 + {&interactive_comments}, + {&source_uses_path}, + {&expand_aliases}, + {&inherit_errexit}, + {&print_shift_error}, + {0} }; static char *saved_posix_vars = 0; diff --git a/lib/Android.mk b/lib/Android.mk new file mode 100644 index 0000000..6361f9b --- /dev/null +++ b/lib/Android.mk @@ -0,0 +1,2 @@ +LOCAL_PATH := $(call my-dir) +include $(call all-makefiles-under,$(LOCAL_PATH)) diff --git a/lib/glob/Android.mk b/lib/glob/Android.mk new file mode 100644 index 0000000..02dabe8 --- /dev/null +++ b/lib/glob/Android.mk @@ -0,0 +1,37 @@ +LOCAL_PATH := $(call my-dir) + +# ======================================================== +# libglob.a +# ======================================================== +include $(CLEAR_VARS) + +LOCAL_SRC_FILES:= \ + glob.c \ + smatch.c \ + strmatch.c \ + xmbsrtowcs.c \ + gmisc.c + +LOCAL_C_INCLUDES += \ + $(LOCAL_PATH)/../.. \ + $(LOCAL_PATH)/../../include \ + $(LOCAL_PATH)/../../lib + +LOCAL_CFLAGS += \ + -DHAVE_CONFIG_H + +LOCAL_CFLAGS += \ + -Wno-parentheses \ + -Wno-sign-compare \ + -Wno-unused-label \ + -Wno-unused-parameter \ + -Wno-unused-variable + +LOCAL_MODULE_TAGS := optional + +LOCAL_MODULE := libglob + +include $(BUILD_STATIC_LIBRARY) + +# ======================================================== +include $(call all-makefiles-under,$(LOCAL_PATH)) diff --git a/lib/readline/Android.mk b/lib/readline/Android.mk new file mode 100644 index 0000000..28882ac --- /dev/null +++ b/lib/readline/Android.mk @@ -0,0 +1,112 @@ +LOCAL_PATH := $(call my-dir) + +# ======================================================== +# libhistory.a +# ======================================================== +include $(CLEAR_VARS) + +LOCAL_SRC_FILES:= \ + history.c \ + histexpand.c \ + histfile.c \ + histsearch.c \ + shell.c \ + savestring.c \ + mbutil.c \ + xmalloc.c + +LOCAL_C_INCLUDES += \ + $(LOCAL_PATH)/../.. \ + $(LOCAL_PATH)/../../include \ + $(LOCAL_PATH)/../../lib + +LOCAL_CFLAGS += \ + -DHAVE_CONFIG_H + +LOCAL_CFLAGS += \ + -Wno-incompatible-pointer-types-discards-qualifiers \ + -Wno-missing-braces \ + -Wno-parentheses \ + -Wno-sometimes-uninitialized \ + -Wno-sign-compare \ + -Wno-unused-function \ + -Wno-unused-parameter \ + -Wno-unused-variable \ + -Wno-user-defined-warnings + +LOCAL_MODULE := libhistory + +LOCAL_MODULE_TAGS := optional + +include $(BUILD_STATIC_LIBRARY) + +# ======================================================== +# libreadline.a +# ======================================================== +include $(CLEAR_VARS) + +LOCAL_SRC_FILES:= \ + readline.c \ + vi_mode.c \ + funmap.c \ + keymaps.c \ + parens.c \ + search.c \ + rltty.c \ + colors.c \ + parse-colors.c \ + complete.c \ + bind.c \ + isearch.c \ + display.c \ + signals.c \ + util.c \ + kill.c \ + undo.c \ + macro.c \ + input.c \ + callback.c \ + terminal.c \ + text.c \ + nls.c \ + misc.c \ + history.c \ + histexpand.c \ + histfile.c \ + histsearch.c \ + shell.c \ + savestring.c \ + mbutil.c \ + tilde.c \ + xmalloc.c \ + compat.c + +LOCAL_C_INCLUDES += \ + $(LOCAL_PATH)/../.. \ + $(LOCAL_PATH)/../../include \ + $(LOCAL_PATH)/../../lib + +LOCAL_CFLAGS += \ + -DHAVE_CONFIG_H + +LOCAL_CFLAGS += \ + -Wno-incompatible-pointer-types-discards-qualifiers \ + -Wno-missing-braces \ + -Wno-parentheses \ + -Wno-sometimes-uninitialized \ + -Wno-sign-compare \ + -Wno-uninitialized \ + -Wno-unused-function \ + -Wno-unused-label \ + -Wno-unused-parameter \ + -Wno-unused-variable \ + -Wno-user-defined-warnings + +LOCAL_MODULE := libreadline + +LOCAL_MODULE_TAGS := optional + +include $(BUILD_STATIC_LIBRARY) + +# ======================================================== +include $(call all-makefiles-under,$(LOCAL_PATH)) diff --git a/lib/readline/doc/Makefile b/lib/readline/doc/Makefile deleted file mode 100644 index af5ee3e..0000000 --- a/lib/readline/doc/Makefile +++ /dev/null @@ -1,145 +0,0 @@ -# Derived by hand from the generated readline-src/doc/Makefile -# This makefile for Readline library documentation is in -*- text -*- mode. -# Emacs likes it that way. - -# 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 3 of the License, 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, see . -# - - -topdir = . -srcdir = . -VPATH = . - -prefix = /usr/local -infodir = ${prefix}/info - -mandir = ${prefix}/man -manpfx = man - -man1ext = 1 -man1dir = $(mandir)/$(manpfx)$(man1ext) -man3ext = 3 -man3dir = $(mandir)/$(manpfx)$(man3ext) - -SHELL = /bin/sh -RM = rm -f - -INSTALL = /usr/bin/install -c -INSTALL_DATA = ${INSTALL} -m 644 - -BUILD_DIR = . -TEXINPUTDIR = $(srcdir) - -MAKEINFO = LANGUAGE= makeinfo -TEXI2DVI = $(srcdir)/texi2dvi -TEXI2HTML = $(srcdir)/texi2html -QUIETPS = #set this to -q to shut up dvips -PSDPI = 300 # I don't have any 600-dpi printers -DVIPS = dvips -D ${PSDPI} $(QUIETPS) -o $@ # tricky - -RLSRC = $(srcdir)/rlman.texi $(srcdir)/rluser.texi \ - $(srcdir)/rltech.texi $(srcdir)/version.texi \ - $(srcdir)/rluserman.texi -HISTSRC = $(srcdir)/history.texi $(srcdir)/hsuser.texi \ - $(srcdir)/hstech.texi $(srcdir)/version.texi - -# This should be a program that converts troff to an ascii-readable format -NROFF = groff -Tascii - -# This should be a program that converts troff to postscript -GROFF = groff - -DVIOBJ = readline.dvi history.dvi rluserman.dvi -INFOOBJ = readline.info history.info rluserman.info -PSOBJ = readline.ps history.ps rluserman.ps -HTMLOBJ = readline.html history.html rluserman.html - -INTERMEDIATE_OBJ = rlman.dvi - -CREATED_DOCS = $(DVIOBJ) $(INFOOBJ) $(PSOBJ) $(HTMLOBJ) - -.SUFFIXES: .ps .txt .dvi - -all: info dvi html ps -nodvi: info html - -readline.dvi: $(RLSRC) - TEXINPUTS=.:$(TEXINPUTDIR):$$TEXINPUTS $(TEXI2DVI) $(srcdir)/rlman.texi - mv rlman.dvi readline.dvi - -readline.info: $(RLSRC) - $(MAKEINFO) --no-split -I $(TEXINPUTDIR) -o $@ $(srcdir)/rlman.texi - -rluserman.dvi: $(RLSRC) - TEXINPUTS=.:$(TEXINPUTDIR):$$TEXINPUTS $(TEXI2DVI) $(srcdir)/rluserman.texi - -rluserman.info: $(RLSRC) - $(MAKEINFO) --no-split -I $(TEXINPUTDIR) -o $@ $(srcdir)/rluserman.texi - -history.dvi: ${HISTSRC} - TEXINPUTS=.:$(TEXINPUTDIR):$$TEXINPUTS $(TEXI2DVI) $(srcdir)/history.texi - -history.info: ${HISTSRC} - $(MAKEINFO) --no-split -I $(TEXINPUTDIR) -o $@ $(srcdir)/history.texi - -readline.ps: readline.dvi - $(RM) $@ - $(DVIPS) readline.dvi - -rluserman.ps: rluserman.dvi - $(RM) $@ - $(DVIPS) rluserman.dvi - -history.ps: history.dvi - $(RM) $@ - $(DVIPS) history.dvi - -readline.html: ${RLSRC} - $(TEXI2HTML) -menu -monolithic -I $(TEXINPUTDIR) $(srcdir)/rlman.texi - sed -e 's:rlman.html:readline.html:' rlman.html > readline.html - $(RM) rlman.html - -rluserman.html: ${RLSRC} - $(TEXI2HTML) -menu -monolithic -I $(TEXINPUTDIR) $(srcdir)/rluserman.texi - -history.html: ${HISTSRC} - $(TEXI2HTML) -menu -monolithic -I $(TEXINPUTDIR) $(srcdir)/history.texi - -info: $(INFOOBJ) -dvi: $(DVIOBJ) -ps: $(PSOBJ) -html: $(HTMLOBJ) - -clean: - $(RM) *.aux *.cp *.fn *.ky *.log *.pg *.toc *.tp *.vr *.cps *.pgs \ - *.fns *.kys *.tps *.vrs *.o core - -distclean: clean - $(RM) $(CREATED_DOCS) - $(RM) $(INTERMEDIATE_OBJ) - $(RM) Makefile - -mostlyclean: clean - -maintainer-clean: clean - $(RM) $(CREATED_DOCS) - $(RM) $(INTERMEDIATE_OBJ) - $(RM) Makefile - -install: - @echo "This documentation should not be installed." - -uninstall: diff --git a/lib/sh/Android.mk b/lib/sh/Android.mk new file mode 100644 index 0000000..63887b6 --- /dev/null +++ b/lib/sh/Android.mk @@ -0,0 +1,107 @@ +LOCAL_PATH := $(call my-dir) + +# ======================================================== +# libsh.a +# ======================================================== +include $(CLEAR_VARS) + +LOCAL_SRC_FILES:= \ + casemod.c \ + clktck.c \ + clock.c \ + dprintf.c \ + eaccess.c \ + fmtullong.c \ + fmtulong.c \ + fmtumax.c \ + fnxform.c \ + fpurge.c \ + getcwd.c \ + getenv.c \ + gettimeofday.c \ + inet_aton.c \ + input_avail.c \ + itos.c \ + mailstat.c \ + makepath.c \ + mbscasecmp.c \ + mbschr.c \ + mbscmp.c \ + mktime.c \ + netconn.c \ + netopen.c \ + oslib.c \ + pathcanon.c \ + pathphys.c \ + random.c \ + rename.c \ + setlinebuf.c \ + shmatch.c \ + shmbchar.c \ + shquote.c \ + shtty.c \ + snprintf.c \ + spell.c \ + strcasecmp.c \ + strcasestr.c \ + strchrnul.c \ + strdup.c \ + strerror.c \ + strftime.c \ + stringlist.c \ + stringvec.c \ + strnlen.c \ + strpbrk.c \ + strstr.c \ + strtod.c \ + strtoimax.c \ + strtol.c \ + strtoll.c \ + strtoul.c \ + strtoull.c \ + strtoumax.c \ + strtrans.c \ + times.c \ + timeval.c \ + tmpfile.c \ + uconvert.c \ + ufuncs.c \ + unicode.c \ + utf8.c \ + vprint.c \ + wcsdup.c \ + wcsnwidth.c \ + wcswidth.c \ + winsize.c \ + zcatfd.c \ + zgetline.c \ + zmapfd.c \ + zread.c \ + zwrite.c + +LOCAL_C_INCLUDES += \ + $(LOCAL_PATH)/../.. \ + $(LOCAL_PATH)/../../include \ + $(LOCAL_PATH)/../../lib \ + external/clearsilver \ + external/clearsilver/util/regex + +LOCAL_CFLAGS += \ + -DHAVE_CONFIG_H + +LOCAL_CFLAGS += \ + -Wno-missing-braces \ + -Wno-parentheses \ + -Wno-sign-compare \ + -Wno-unused-function \ + -Wno-unused-parameter \ + -Wno-unused-variable + +LOCAL_MODULE := libsh + +LOCAL_MODULE_TAGS := optional + +include $(BUILD_STATIC_LIBRARY) + +# ======================================================== +include $(call all-makefiles-under,$(LOCAL_PATH)) diff --git a/lib/tilde/Android.mk b/lib/tilde/Android.mk new file mode 100644 index 0000000..c322aba --- /dev/null +++ b/lib/tilde/Android.mk @@ -0,0 +1,29 @@ +LOCAL_PATH:= $(call my-dir) + +# ======================================================== +# libtilde.a +# ======================================================== +include $(CLEAR_VARS) + +LOCAL_SRC_FILES:= \ + tilde.c + +LOCAL_C_INCLUDES += \ + $(LOCAL_PATH)/../.. \ + $(LOCAL_PATH)/../../include \ + $(LOCAL_PATH)/../../lib + +LOCAL_CFLAGS += \ + -DHAVE_CONFIG_H + +LOCAL_CFLAGS += \ + -Wno-parentheses + +LOCAL_MODULE := libtilde + +LOCAL_MODULE_TAGS := optional + +include $(BUILD_STATIC_LIBRARY) + +# ======================================================== +include $(call all-makefiles-under,$(LOCAL_PATH)) diff --git a/pathnames.h b/pathnames.h new file mode 100644 index 0000000..99a540a --- /dev/null +++ b/pathnames.h @@ -0,0 +1,33 @@ +/* pathnames.h -- absolute filenames that bash wants for various defaults. */ + +/* Copyright (C) 1987-2009 Free Software Foundation, Inc. + + This file is part of GNU Bash, the Bourne Again SHell. + + Bash is free software: you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation, either version 3 of the License, or + (at your option) any later version. + + Bash is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with Bash. If not, see . +*/ + +#if !defined (_PATHNAMES_H_) +#define _PATHNAMES_H_ + +/* The default file for hostname completion. */ +#define DEFAULT_HOSTS_FILE "/etc/hosts" + +/* The default login shell startup file. */ +#define SYS_PROFILE "/etc/profile" + +/* The default location of the bash debugger initialization/startup file. */ +#define DEBUGGER_START_FILE "/usr/local/share/bashdb/bashdb-main.inc" + +#endif /* _PATHNAMES_H */ diff --git a/signames.h b/signames.h new file mode 100644 index 0000000..9f9eb21 --- /dev/null +++ b/signames.h @@ -0,0 +1,78 @@ +/* This file was automatically created by ./mksignames. + Do not edit. Edit support/mksignames.c instead. */ + +/* A translation list so we can be polite to our users. */ +char *signal_names[NSIG + 4] = { + "EXIT", + "SIGHUP", + "SIGINT", + "SIGQUIT", + "SIGILL", + "SIGTRAP", + "SIGABRT", + "SIGBUS", + "SIGFPE", + "SIGKILL", + "SIGUSR1", + "SIGSEGV", + "SIGUSR2", + "SIGPIPE", + "SIGALRM", + "SIGTERM", + "SIGSTKFLT", + "SIGCHLD", + "SIGCONT", + "SIGSTOP", + "SIGTSTP", + "SIGTTIN", + "SIGTTOU", + "SIGURG", + "SIGXCPU", + "SIGXFSZ", + "SIGVTALRM", + "SIGPROF", + "SIGWINCH", + "SIGIO", + "SIGPWR", + "SIGSYS", + "SIGJUNK(32)", + "SIGJUNK(33)", + "SIGRTMIN", + "SIGRTMIN+1", + "SIGRTMIN+2", + "SIGRTMIN+3", + "SIGRTMIN+4", + "SIGRTMIN+5", + "SIGRTMIN+6", + "SIGRTMIN+7", + "SIGRTMIN+8", + "SIGRTMIN+9", + "SIGRTMIN+10", + "SIGRTMIN+11", + "SIGRTMIN+12", + "SIGRTMIN+13", + "SIGRTMIN+14", + "SIGRTMIN+15", + "SIGRTMAX-14", + "SIGRTMAX-13", + "SIGRTMAX-12", + "SIGRTMAX-11", + "SIGRTMAX-10", + "SIGRTMAX-9", + "SIGRTMAX-8", + "SIGRTMAX-7", + "SIGRTMAX-6", + "SIGRTMAX-5", + "SIGRTMAX-4", + "SIGRTMAX-3", + "SIGRTMAX-2", + "SIGRTMAX-1", + "SIGRTMAX", + "DEBUG", + "ERR", + "RETURN", + (char *)0x0 +}; + +#define initialize_signames() + diff --git a/syntax.c b/syntax.c new file mode 100644 index 0000000..c14e068 --- /dev/null +++ b/syntax.c @@ -0,0 +1,269 @@ +/* + * This file was generated by mksyntax. DO NOT EDIT. + */ + + +#include "config.h" +#include "stdc.h" +#include "syntax.h" + + +int sh_syntabsiz = 256; +int sh_syntaxtab[256] = { + CWORD, /* 0 */ + CSPECL, /* CTLESC */ + CWORD, /* 2 */ + CWORD, /* 3 */ + CWORD, /* 4 */ + CWORD, /* 5 */ + CWORD, /* 6 */ + CWORD, /* \a */ + CWORD, /* \b */ + CSHBRK|CBLANK, /* \t */ + CSHBRK|CBSDQUOTE, /* \n */ + CWORD, /* \v */ + CWORD, /* \f */ + CWORD, /* \r */ + CWORD, /* 14 */ + CWORD, /* 15 */ + CWORD, /* 16 */ + CWORD, /* 17 */ + CWORD, /* 18 */ + CWORD, /* 19 */ + CWORD, /* 20 */ + CWORD, /* 21 */ + CWORD, /* 22 */ + CWORD, /* 23 */ + CWORD, /* 24 */ + CWORD, /* 25 */ + CWORD, /* 26 */ + CWORD, /* ESC */ + CWORD, /* 28 */ + CWORD, /* 29 */ + CWORD, /* 30 */ + CWORD, /* 31 */ + CSHBRK|CBLANK, /* SPC */ + CXGLOB|CSPECVAR, /* ! */ + CQUOTE|CBSDQUOTE|CXQUOTE, /* " */ + CSPECVAR, /* # */ + CEXP|CBSDQUOTE|CBSHDOC|CSPECVAR, /* $ */ + CWORD, /* % */ + CSHMETA|CSHBRK, /* & */ + CQUOTE|CXQUOTE, /* ' */ + CSHMETA|CSHBRK, /* ( */ + CSHMETA|CSHBRK, /* ) */ + CGLOB|CXGLOB|CSPECVAR, /* * */ + CXGLOB|CSUBSTOP, /* + */ + CWORD, /* , */ + CSPECVAR|CSUBSTOP, /* - */ + CWORD, /* . */ + CWORD, /* / */ + CWORD, /* 0 */ + CWORD, /* 1 */ + CWORD, /* 2 */ + CWORD, /* 3 */ + CWORD, /* 4 */ + CWORD, /* 5 */ + CWORD, /* 6 */ + CWORD, /* 7 */ + CWORD, /* 8 */ + CWORD, /* 9 */ + CWORD, /* : */ + CSHMETA|CSHBRK, /* ; */ + CSHMETA|CSHBRK|CEXP, /* < */ + CSUBSTOP, /* = */ + CSHMETA|CSHBRK|CEXP, /* > */ + CGLOB|CXGLOB|CSPECVAR|CSUBSTOP, /* ? */ + CXGLOB|CSPECVAR, /* @ */ + CWORD, /* A */ + CWORD, /* B */ + CWORD, /* C */ + CWORD, /* D */ + CWORD, /* E */ + CWORD, /* F */ + CWORD, /* G */ + CWORD, /* H */ + CWORD, /* I */ + CWORD, /* J */ + CWORD, /* K */ + CWORD, /* L */ + CWORD, /* M */ + CWORD, /* N */ + CWORD, /* O */ + CWORD, /* P */ + CWORD, /* Q */ + CWORD, /* R */ + CWORD, /* S */ + CWORD, /* T */ + CWORD, /* U */ + CWORD, /* V */ + CWORD, /* W */ + CWORD, /* X */ + CWORD, /* Y */ + CWORD, /* Z */ + CGLOB, /* [ */ + CBSDQUOTE|CBSHDOC|CXQUOTE, /* \ */ + CGLOB, /* ] */ + CGLOB, /* ^ */ + CWORD, /* _ */ + CBACKQ|CQUOTE|CBSDQUOTE|CBSHDOC|CXQUOTE, /* ` */ + CWORD, /* a */ + CWORD, /* b */ + CWORD, /* c */ + CWORD, /* d */ + CWORD, /* e */ + CWORD, /* f */ + CWORD, /* g */ + CWORD, /* h */ + CWORD, /* i */ + CWORD, /* j */ + CWORD, /* k */ + CWORD, /* l */ + CWORD, /* m */ + CWORD, /* n */ + CWORD, /* o */ + CWORD, /* p */ + CWORD, /* q */ + CWORD, /* r */ + CWORD, /* s */ + CWORD, /* t */ + CWORD, /* u */ + CWORD, /* v */ + CWORD, /* w */ + CWORD, /* x */ + CWORD, /* y */ + CWORD, /* z */ + CWORD, /* { */ + CSHMETA|CSHBRK, /* | */ + CWORD, /* } */ + CWORD, /* ~ */ + CSPECL, /* CTLNUL */ + CWORD, /* 128 */ + CWORD, /* 129 */ + CWORD, /* 130 */ + CWORD, /* 131 */ + CWORD, /* 132 */ + CWORD, /* 133 */ + CWORD, /* 134 */ + CWORD, /* 135 */ + CWORD, /* 136 */ + CWORD, /* 137 */ + CWORD, /* 138 */ + CWORD, /* 139 */ + CWORD, /* 140 */ + CWORD, /* 141 */ + CWORD, /* 142 */ + CWORD, /* 143 */ + CWORD, /* 144 */ + CWORD, /* 145 */ + CWORD, /* 146 */ + CWORD, /* 147 */ + CWORD, /* 148 */ + CWORD, /* 149 */ + CWORD, /* 150 */ + CWORD, /* 151 */ + CWORD, /* 152 */ + CWORD, /* 153 */ + CWORD, /* 154 */ + CWORD, /* 155 */ + CWORD, /* 156 */ + CWORD, /* 157 */ + CWORD, /* 158 */ + CWORD, /* 159 */ + CWORD, /* 160 */ + CWORD, /* 161 */ + CWORD, /* 162 */ + CWORD, /* 163 */ + CWORD, /* 164 */ + CWORD, /* 165 */ + CWORD, /* 166 */ + CWORD, /* 167 */ + CWORD, /* 168 */ + CWORD, /* 169 */ + CWORD, /* 170 */ + CWORD, /* 171 */ + CWORD, /* 172 */ + CWORD, /* 173 */ + CWORD, /* 174 */ + CWORD, /* 175 */ + CWORD, /* 176 */ + CWORD, /* 177 */ + CWORD, /* 178 */ + CWORD, /* 179 */ + CWORD, /* 180 */ + CWORD, /* 181 */ + CWORD, /* 182 */ + CWORD, /* 183 */ + CWORD, /* 184 */ + CWORD, /* 185 */ + CWORD, /* 186 */ + CWORD, /* 187 */ + CWORD, /* 188 */ + CWORD, /* 189 */ + CWORD, /* 190 */ + CWORD, /* 191 */ + CWORD, /* 192 */ + CWORD, /* 193 */ + CWORD, /* 194 */ + CWORD, /* 195 */ + CWORD, /* 196 */ + CWORD, /* 197 */ + CWORD, /* 198 */ + CWORD, /* 199 */ + CWORD, /* 200 */ + CWORD, /* 201 */ + CWORD, /* 202 */ + CWORD, /* 203 */ + CWORD, /* 204 */ + CWORD, /* 205 */ + CWORD, /* 206 */ + CWORD, /* 207 */ + CWORD, /* 208 */ + CWORD, /* 209 */ + CWORD, /* 210 */ + CWORD, /* 211 */ + CWORD, /* 212 */ + CWORD, /* 213 */ + CWORD, /* 214 */ + CWORD, /* 215 */ + CWORD, /* 216 */ + CWORD, /* 217 */ + CWORD, /* 218 */ + CWORD, /* 219 */ + CWORD, /* 220 */ + CWORD, /* 221 */ + CWORD, /* 222 */ + CWORD, /* 223 */ + CWORD, /* 224 */ + CWORD, /* 225 */ + CWORD, /* 226 */ + CWORD, /* 227 */ + CWORD, /* 228 */ + CWORD, /* 229 */ + CWORD, /* 230 */ + CWORD, /* 231 */ + CWORD, /* 232 */ + CWORD, /* 233 */ + CWORD, /* 234 */ + CWORD, /* 235 */ + CWORD, /* 236 */ + CWORD, /* 237 */ + CWORD, /* 238 */ + CWORD, /* 239 */ + CWORD, /* 240 */ + CWORD, /* 241 */ + CWORD, /* 242 */ + CWORD, /* 243 */ + CWORD, /* 244 */ + CWORD, /* 245 */ + CWORD, /* 246 */ + CWORD, /* 247 */ + CWORD, /* 248 */ + CWORD, /* 249 */ + CWORD, /* 250 */ + CWORD, /* 251 */ + CWORD, /* 252 */ + CWORD, /* 253 */ + CWORD, /* 254 */ + CWORD, /* 255 */ +}; diff --git a/version.h b/version.h new file mode 100644 index 0000000..b312bfa --- /dev/null +++ b/version.h @@ -0,0 +1,17 @@ +/* Version control for the shell. This file gets changed when you say + `make version.h' to the Makefile. It is created by mkversion. */ + +/* The distribution version number of this shell. */ +#define DISTVERSION "5.1" + +/* The last built version of this shell. */ +#define BUILDVERSION 1 + +/* The release status of this shell. */ +#define RELSTATUS "release" + +/* The default shell compatibility-level (the current version) */ +#define DEFAULT_COMPAT_LEVEL 51 + +/* A version string for use by sccs and the what command. */ +#define SCCSVERSION "@(#)Bash version 5.1.0(1) release GNU"