bash-2.05a/ 40775 436 0 0 7373776007 10660 5ustar chetwheelbash-2.05a/CWRU/ 40775 436 0 0 7373775243 11441 5ustar chetwheelbash-2.05a/CWRU/misc/ 40775 436 0 0 7373775243 12374 5ustar chetwheelbash-2.05a/CWRU/misc/open-files.c100644 436 0 362 4716100162 14631 0ustar chetwheel#include #include #include #include main() { register int i; for (i = 0; i < getdtablesize(); i++) { if (fcntl(i, F_GETFD, 0) != -1) fprintf(stderr, "fd %d: open\n", i); } exit(0); } bash-2.05a/CWRU/misc/sigs.c100644 436 0 652 5015341474 13545 0ustar chetwheel#include #include extern char *sys_siglist[]; typedef void sighandler(); main(argc, argv) int argc; char **argv; { register int i; sighandler *h; for (i = 1; i < NSIG; i++) { h = signal(i, SIG_DFL); if (h != SIG_DFL) { if (h == SIG_IGN) fprintf(stderr, "%d: ignored (%s)\n", i, sys_siglist[i]); else fprintf(stderr, "%d: caught (%s)\n", i, sys_siglist[i]); } } exit(0); } bash-2.05a/CWRU/misc/pid.c100664 436 0 115 5222352344 13346 0ustar chetwheel#include main() { fprintf(stderr, "%d\n", getpid()); exit(0); } bash-2.05a/CWRU/misc/sigstat.c100664 436 0 12567 5152517150 14326 0ustar chetwheel/* * sigstat - print out useful information about signal arguments * */ #include #include #include extern char *strrchr(); static char *signames[NSIG]; char *progname; void sigstat(); main(argc, argv) int argc; char **argv; { register int i; char *t; if (t = strrchr(argv[0], '/')) progname = ++t; else progname = argv[0]; init_signames(); if (argc == 1) { for (i = 1; i < NSIG; i++) sigstat(i); exit(0); } for (i = 1; i < argc; i++) sigstat(atoi(argv[i])); exit(0); } void sigstat(sig) int sig; { struct sigaction oact; char *signame; sigset_t set, oset; int blocked; if (sig < 0 || sig >= NSIG) { fprintf(stderr, "%s: %d: signal out of range\n", progname, sig); return; } signame = signames[sig]; sigemptyset(&oset); sigprocmask(SIG_BLOCK, (sigset_t *)NULL, &oset); if (sigismember(&oset, sig)) printf("%s: signal is blocked\n", signame); sigaction(sig, (struct sigaction *)NULL, &oact); if (oact.sa_handler == SIG_IGN) printf("%s: signal is ignored\n", signame); else if (oact.sa_handler == SIG_DFL) printf("%s: signal is defaulted\n", signame); else printf("%s: signal is trapped (?)\n", signame); } init_signames() { register int i; bzero(signames, sizeof(signames)); #if defined (SIGHUP) /* hangup */ signames[SIGHUP] = "SIGHUP"; #endif #if defined (SIGINT) /* interrupt */ signames[SIGINT] = "SIGINT"; #endif #if defined (SIGQUIT) /* quit */ signames[SIGQUIT] = "SIGQUIT"; #endif #if defined (SIGILL) /* illegal instruction (not reset when caught) */ signames[SIGILL] = "SIGILL"; #endif #if defined (SIGTRAP) /* trace trap (not reset when caught) */ signames[SIGTRAP] = "SIGTRAP"; #endif #if defined (SIGABRT) /* */ signames[SIGABRT] = "SIGABRT"; #endif #if defined (SIGIOT) /* IOT instruction */ signames[SIGIOT] = "SIGIOT"; #endif #if defined (SIGEMT) /* EMT instruction */ signames[SIGEMT] = "SIGEMT"; #endif #if defined (SIGFPE) /* floating point exception */ signames[SIGFPE] = "SIGFPE"; #endif #if defined (SIGKILL) /* kill (cannot be caught or ignored) */ signames[SIGKILL] = "SIGKILL"; #endif #if defined (SIGBUS) /* bus error */ signames[SIGBUS] = "SIGBUS"; #endif #if defined (SIGSEGV) /* segmentation violation */ signames[SIGSEGV] = "SIGSEGV"; #endif #if defined (SIGSYS) /* bad argument to system call */ signames[SIGSYS] = "SIGSYS"; #endif #if defined (SIGPIPE) /* write on a pipe with no one to read it */ signames[SIGPIPE] = "SIGPIPE"; #endif #if defined (SIGALRM) /* alarm clock */ signames[SIGALRM] = "SIGALRM"; #endif #if defined (SIGTERM) /* software termination signal from kill */ signames[SIGTERM] = "SIGTERM"; #endif #if defined (SIGCLD) /* Like SIGCHLD. */ signames[SIGCLD] = "SIGCLD"; #endif #if defined (SIGPWR) /* Magic thing for some machines. */ signames[SIGPWR] = "SIGPWR"; #endif #if defined (SIGPOLL) /* For keyboard input? */ signames[SIGPOLL] = "SIGPOLL"; #endif #if defined (SIGURG) /* urgent condition on IO channel */ signames[SIGURG] = "SIGURG"; #endif #if defined (SIGSTOP) /* sendable stop signal not from tty */ signames[SIGSTOP] = "SIGSTOP"; #endif #if defined (SIGTSTP) /* stop signal from tty */ signames[SIGTSTP] = "SIGTSTP"; #endif #if defined (SIGCONT) /* continue a stopped process */ signames[SIGCONT] = "SIGCONT"; #endif #if defined (SIGCHLD) /* to parent on child stop or exit */ signames[SIGCHLD] = "SIGCHLD"; #endif #if defined (SIGTTIN) /* to readers pgrp upon background tty read */ signames[SIGTTIN] = "SIGTTIN"; #endif #if defined (SIGTTOU) /* like TTIN for output if (tp->t_local<OSTOP) */ signames[SIGTTOU] = "SIGTTOU"; #endif #if defined (SIGIO) /* input/output possible signal */ signames[SIGIO] = "SIGIO"; #endif #if defined (SIGXCPU) /* exceeded CPU time limit */ signames[SIGXCPU] = "SIGXCPU"; #endif #if defined (SIGXFSZ) /* exceeded file size limit */ signames[SIGXFSZ] = "SIGXFSZ"; #endif #if defined (SIGVTALRM) /* virtual time alarm */ signames[SIGVTALRM] = "SIGVTALRM"; #endif #if defined (SIGPROF) /* profiling time alarm */ signames[SIGPROF] = "SIGPROF"; #endif #if defined (SIGWINCH) /* window changed */ signames[SIGWINCH] = "SIGWINCH"; #endif #if defined (SIGLOST) /* resource lost (eg, record-lock lost) */ signames[SIGLOST] = "SIGLOST"; #endif #if defined (SIGUSR1) /* user defined signal 1 */ signames[SIGUSR1] = "SIGUSR1"; #endif #if defined (SIGUSR2) /* user defined signal 2 */ signames[SIGUSR2] = "SIGUSR2"; #endif #if defined (SIGMSG) /* HFT input data pending */ signames[SIGMSG] = "SIGMSG"; #endif #if defined (SIGPWR) /* power failure imminent (save your data) */ signames[SIGPWR] = "SIGPWR"; #endif #if defined (SIGDANGER) /* system crash imminent */ signames[SIGDANGER] = "SIGDANGER"; #endif #if defined (SIGMIGRATE) /* migrate process to another CPU */ signames[SIGMIGRATE] = "SIGMIGRATE"; #endif #if defined (SIGPRE) /* programming error */ signames[SIGPRE] = "SIGPRE"; #endif #if defined (SIGGRANT) /* HFT monitor mode granted */ signames[SIGGRANT] = "SIGGRANT"; #endif #if defined (SIGRETRACT) /* HFT monitor mode retracted */ signames[SIGRETRACT] = "SIGRETRACT"; #endif #if defined (SIGSOUND) /* HFT sound sequence has completed */ signames[SIGSOUND] = "SIGSOUND"; #endif for (i = 0; i < NSIG; i++) if (signames[i] == (char *)NULL) { signames[i] = (char *)malloc (16);; sprintf (signames[i], "signal %d", i); } } bash-2.05a/CWRU/misc/bison100755 436 0 115 5352472051 13466 0ustar chetwheel#! /bin/sh if [ "$1" = '-y' ]; then shift fi exec /usr/bin/yacc ${1+"$@"} bash-2.05a/CWRU/misc/errlist.c100664 436 0 710 6570312660 14263 0ustar chetwheel/* * If necessary, link with lib/sh/libsh.a */ #include #include extern char *strerror(); extern int sys_nerr; int main(c, v) int c; char **v; { int i, n; if (c == 1) { for (i = 1; i < sys_nerr; i++) printf("%d --> %s\n", i, strerror(i)); } else { for (i = 1; i < c; i++) { n = atoi(v[i]); printf("%d --> %s\n", n, strerror(n)); } } exit (0); } programming_error(a, b) char *a; int b; { } fatal_error() { } bash-2.05a/CWRU/misc/hpux10-dlfcn.h100664 436 0 2253 6644460410 15040 0ustar chetwheel/* * HPUX 10.x stubs to implement dl* in terms of shl* * * Not needed for later versions; HPUX 11.x has dlopen() and friends. * * configure also needs to be faked out. You can create a dummy libdl.a * with stub entries for dlopen, dlclose, dlsym, and dlerror: * * int dlopen() { return(0);} * int dlclose() { return(0);} * int dlsym() { return(0);} * int dlerror() { return(0);} * * This has not been tested; I just read the manual page and coded this up. * * According to the ld manual page, you need to link bash with -dld and add * the -E flag to LOCAL_LDFLAGS. */ #if !defined (__HPUX10_DLFCN_H__) #define __HPUX10_DLFCN_H__ #include #include #ifndef errno extern int errno; #endif #define RTLD_LAZY BIND_DEFERRED #define RTLD_NOW BIND_IMMEDIATE #define RTLD_GLOBAL DYNAMIC_PATH char *bash_global_sym_addr; #define dlopen(file,mode) (void *)shl_load((file), (mode), 0L) #define dlclose(handle) shl_unload((shl_t)(handle)) #define dlsym(handle,name) (bash_global_sym_addr=0,shl_findsym((shl_t *)&(handle),name,TYPE_UNDEFINED,&bash_global_sym_addr), (void *)bash_global_sym_addr) #define dlerror() strerror(errno) #endif /* __HPUX10_DLFCN_H__ */ bash-2.05a/CWRU/PLATFORMS100664 436 0 706 6345301642 12775 0ustar chetwheelThe version of bash in this directory has been compiled on the following systems: By chet: SunOS 4.1.4 SunOS 5.5 BSDI BSD/OS 2.1 FreeBSD 2.2 NetBSD 1.2 AIX 4.2 AIX 4.1.4 HP/UX 9.05, 10.01, 10.10, 10.20 Linux 2.0.29 (libc 5.3.12) Linux 2.0.4 (libc 5.3.12) By other testers: SCO ODT 2.0 SCO 3.2v5.0, 3.2v4.2 SunOS 5.3 SunOS 5.5 BSD/OS 2.1 FreeBSD 2.2 SunOS 4.1.3 Irix 5.3 Irix 6.2 Linux 2.0 (unknown distribution) Digital OSF/1 3.2 GNU Hurd 0.1 SVR4.2 bash-2.05a/CWRU/README100664 436 0 1046 6555410000 12371 0ustar chetwheelContents of this directory: changelog - my change log since the last release POSIX.NOTES - list of what changes for `posix mode' README - this file misc - directory with some useful tools The following are distributed `as-is'. They will not apply without some modification. sh-redir-hack - diff to parse.y to get redirections before compound commands empty-for-wordlist - diff to parse.y to allow an empty wordlist after the `in' keyword in a `for' statement mh-folder-comp - diffs that reportedly add MH folder completion bash-2.05a/CWRU/POSIX.NOTES100664 436 0 12624 7260442772 13270 0ustar chetwheelBash POSIX Mode =============== Starting Bash with the `--posix' command-line option or executing `set -o posix' while Bash is running will cause Bash to conform more closely to the POSIX 1003.2 standard by changing the behavior to match that specified by POSIX in areas where the Bash default differs. The following list is what's changed when `POSIX mode' is in effect: 1. When a command in the hash table no longer exists, Bash will re-search `$PATH' to find the new location. This is also available with `shopt -s checkhash'. 2. The message printed by the job control code and builtins when a job exits with a non-zero status is `Done(status)'. 3. The message printed by the job control code and builtins when a job is stopped is `Stopped(SIGNAME)', where SIGNAME is, for example, `SIGTSTP'. 4. Reserved words may not be aliased. 5. The POSIX 1003.2 `PS1' and `PS2' expansions of `!' to the history number and `!!' to `!' are enabled, and parameter expansion is performed on the values of `PS1' and `PS2' regardless of the setting of the `promptvars' option. 6. Interactive comments are enabled by default. (Bash has them on by default anyway.) 7. The POSIX 1003.2 startup files are executed (`$ENV') rather than the normal Bash files. 8. Tilde expansion is only performed on assignments preceding a command name, rather than on all assignment statements on the line. 9. The default history file is `~/.sh_history' (this is the default value of `$HISTFILE'). 10. The output of `kill -l' prints all the signal names on a single line, separated by spaces. 11. Non-interactive shells exit if FILENAME in `.' FILENAME is not found. 12. Non-interactive shells exit if a syntax error in an arithmetic expansion results in an invalid expression. 13. Redirection operators do not perform filename expansion on the word in the redirection unless the shell is interactive. 14. Redirection operators do not perform word splitting on the word in the redirection. 15. Function names must be valid shell `name's. That is, they may not contain characters other than letters, digits, and underscores, and may not start with a digit. Declaring a function with an invalid name causes a fatal syntax error in non-interactive shells. 16. POSIX 1003.2 `special' builtins are found before shell functions during command lookup. 17. If a POSIX 1003.2 special builtin returns an error status, a non-interactive shell exits. The fatal errors are those listed in the POSIX.2 standard, and include things like passing incorrect options, redirection errors, variable assignment errors for assignments preceding the command name, and so on. 18. If the `cd' builtin finds a directory to change to using `$CDPATH', the value it assigns to the `PWD' variable does not contain any symbolic links, as if `cd -P' had been executed. 19. If `CDPATH' is set, the `cd' builtin will not implicitly append the current directory to it. This means that `cd' will fail if no valid directory name can be constructed from any of the entries in `$CDPATH', even if the a directory with the same name as the name given as an argument to `cd' exists in the current directory. 20. A non-interactive shell exits with an error status if a variable assignment error occurs when no command name follows the assignment statements. A variable assignment error occurs, for example, when trying to assign a value to a readonly variable. 21. A non-interactive shell exits with an error status if the iteration variable in a `for' statement or the selection variable in a `select' statement is a readonly variable. 22. Process substitution is not available. 23. Assignment statements preceding POSIX 1003.2 special builtins persist in the shell environment after the builtin completes. 24. Assignment statements preceding shell function calls persist in the shell environment after the function returns, as if a POSIX special builtin command had been executed. 25. The `export' and `readonly' builtin commands display their output in the format required by POSIX 1003.2. 26. The `trap' builtin displays signal names without the leading `SIG'. 27. The `.' and `source' builtins do not search the current directory for the filename argument if it is not found by searching `PATH'. 28. Subshells spawned to execute command substitutions inherit the value of the `-e' option from the parent shell. When not in POSIX mode, Bash clears the `-e' option in such subshells. 29. Alias expansion is always enabled, even in non-interactive shells. 30. When the `set' builtin is invoked without options, it does not display shell function names and definitions. There is other POSIX 1003.2 behavior that Bash does not implement. Specifically: 1. Assignment statements affect the execution environment of all builtins, not just special ones. 2. When a subshell is created to execute a shell script with execute permission, but without a leading `#!', Bash sets `$0' to the full pathname of the script as found by searching `$PATH', rather than the command as typed by the user. 3. When using `.' to source a shell script found in `$PATH', bash checks execute permission bits rather than read permission bits, just as if it were searching for a command. bash-2.05a/CWRU/changelog100664 436 0 272344 7372503001 13440 0ustar chetwheel 4/9/2001 -------- [bash-2.05 released] 4/10 ---- redir.c - check return value of fclose() in write_here_document() for error returns; don't just rely on fwrite() failing support/bashbug.sh - set TMPDIR to /tmp if it's null or unset - use $TMPDIR in the TEMP tempfile name template - fixed the call to `mktemp', if it exists, to make it more portable jobs.c - if WCONTINUED is not defined, define it to 0 and add a define for WIFCONTINUED(wstatus) which expands to 0 - add WCONTINUED to the flags passed to waitpid(2) in waitchld() - don't increment children_exited if waitpid's status is WIFCONTINUED, since we don't want to call a SIGCHLD trap handler in this case - in waitchld(), we set child->running to 1 if WIFCONTINUED(status) is non-zero - make sure pretty_print_job doesn't check for the core dump bit if the process has been continued; it's only valid if the job is dead - in set_job_status_and_cleanup, set the job to JRUNNING if job_state is non-zero and the job was previously marked as JSTOPPED configure.in - add -DBROKEN_DIRENT_D_INO to interix LOCAL_CFLAGS lib/glob/glob.c - if BROKEN_DIRENT_D_INO is defined, define REAL_DIR_ENTRY to 1 jobs.c - in kill_pid, we only need to block and unblock SIGCHLD if the `group' argument is non-zero, since otherwise we just call `kill' on the pid argument version.c - update copyright date to 2001 bashline.c - prog_complete_return needs to take a `const char *' as its first argument - history_completion_generator needs to take a `const char *' as its first argument, and `text' needs to be a `const char *' 4/11 ---- redir.c - fixed a weird typo in redir_special_open, case RF_DEVFD, added call to all_digits before call to legal_number - fixed do_redirection_internal to call legal_number instead of atol(3) when translating r_duplicating_{in,out}put_word, so it handles overflow better - produce an error message in redirection_error for out-of-range file descriptors - change allocation strategy in redirection_error so we don't have to malloc scratch memory if redirection_expand() fails jobs.h - added defines for `running' member of a struct process general.c - fix legal_number to return 0 when strtol(3) reports overflow or underflow parse.y - changed read_token_word to call legal_number instead of atoi(3) input.c - return -1/EBADF from close_buffered_fd if fd is < 0 command.h - fixed bogus comment about IS_DESCRIPTOR in description of the REDIRECTEE struct print_cmd.c - change cprintf's 'd' modifier code to display negative numbers as an out-of-range value. We can do this only because the only use of %d is to output file descriptor numbers in redirections support/mksignames.c - need to include config.h to get a possible value for UNUSABLE_RT_SIGNALS 4/16 ---- lib/readline/doc/rluser.texinfo - corrected a small error in one description of M-DEL 4/17 ---- stringlib.c - need to initialize `ind' before calls to RESIZE_MALLOCED_BUFFER in strcreplace() support/bashversion.c - new file, prints bash version information Makefile.in - rules for building bashversion and linking it to version.o 4/24 ---- conftypes.h - new file with HOSTTYPE, OSTYPE, MACHTYPE, etc. defines from variables.h variables.h, version.c - include conftypes.h patchlevel.h - new file, contains define for PATCHLEVEL. Doing away with the old scheme of having the information in configure.in version.c - include patchlevel.h Makefile.in - run bashversion -p to find patch level rather than have configure substitute in a value - pass -S ${top_srcdir} to support/mkversion.sh support/mkversion.sh - don't put PATCHLEVEL define into version.h, but accept and ignore a -p option - take a new -S srcdir option - find the patch level by parsing it out of patchlevel.h configure.in - hard-code BASHVERS assignment instead of reading it from a file - remove BASHPATCH; don't substitute it _distribution,_patchlevel - removed 4/26 ---- shell.c - call init_noninteractive() in open_shell_script if forced_interactive is non-zero (the shell was started with -i) and fd_is_tty is 0 (the script file is a real file, not something like /dev/stdin), since it wasn't done earlier builtins/printf.def - change for POSIX.2 compliance when conversion errors are encountered when processing %d, %u, and floating point conversion operators (print a warning message, return the value accumulated at the time of the error -- which is always 0 -- and exit with a non-zero status) command.h - added CMD_COMMAND_BUILTIN for use by the `command' builtin and the code in execute_cmd.c builtins/command.def - add CMD_COMMAND_BUILTIN to the created command's flags 5/1 --- configure.in - add call to AC_C_CONST to test `const' compiler behavior - add call to AC_C_INLINE to test `inline' compiler behavior - add call to AC_C_STRINGIZE to test cpp #x stringizing operator config.h.in - add `#undef const' for configure to substitute - add `#undef inline' for configure to substitute - add `#undef HAVE_STRINGIZE' for configure to substitute include/stdc.h - remove code that defines or undefines `const' and `inline' - change the __STRING macro to be defined depending on the value of HAVE_STRINGIZE lib/malloc/malloc.c - change the __STRING macro to be defined depending on the value of HAVE_STRINGIZE lib/readline/{readline,rlprivate}.h - moved rl_get_termcap to readline.h, making it a public function lib/readline/readline.h - new #define, RL_READLINE_VERSION, hex-encoded library version number, currently set to 0x0402 - new public int variable, rl_readline_version lib/readline/readline.c - #define RL_READLINE_VERSION if it is not already defined (which it should be in readline.h) - initialize rl_readline_version to RL_READLINE_VERSION lib/readline/doc/rltech.texinfo - documented rl_get_termcap - documented rl_readline_version jobs.c - job_exit_status should return an int, not a WAIT (undetected before because on most POSIX-like systems a WAIT is really an int) builtins/evalfile.c - added FEVAL_REGFILE (file must be a regular file) to accepted _evalfile flags - fc_execute_file() adds FEVAL_REGFILE to _evalfile flags. This means that startup files and files read with `.' no longer need to be regular files 5/2 --- lib/termcap/Makefile.in - fix target for installed termcap library (normally unused) lib/tilde/Makefile.in - fix install target to install in $(libdir) (normally unused) Makefile.in - don't make $(man3dir) since there's nothing installed there Makefile.in,doc/Makefile.in - change `man1ext' to `.1', `man3ext' to `.3' - change appropriate install targets to use new values of man[13]ext - use `test ...' instead of `[...]' - add support for DESTDIR root installation prefix, for package building (installdirs, install, install-strip, uninstall targets) builtins/common.c - new function int get_exitstat(WORD_LIST *list) returns an eight-bit exit status value for use in return, exit, logout builtins builtins/common.h - extern declaration for get_exitstat() builtins/{exit,return}.def - call get_exitstat where appropriate builtins/printf.def - add support for "'" flag character as posix 1003.2-200x d6 says - fix core dump when user-supplied field width or precision is 0 - fix to printstr() to handle zero-length precision with `%b' format specifier (printf '%.0b-%.0s\n' foo bar) - fix to printstr() to treat a negative field width as a positive field width with left-justification - fix to mklong to avoid static buffers, which can always be overrun by someone sufficiently motivated bashline.c - change var in add_host_name to type `size_t' for passing to xrealloc 5/3 --- execute_cmd.c - change restore_signal_mask to accept a sigset_t *, since a sigset_t may not fit into a pointer, change call unwind_prot.c - use a union UWP in restore_variable when restoring a variable whose size is the same as sizeof(int), the reverse of the method used to store it in unwind_protect_int builtins/printf.def - use a #define LENMODS containing the length modifiers instead of testing against each possible modifier character, save any mod character found - add support for ISO C99 length specifiers `j', `t', and `z' - if `L' modifier is supplied with a floating point conversion char, pass a `long double' to printf if HAVE_LONG_DOUBLE is defined configure.in,config.h.in - call AC_C_LONG_DOUBLE to check for `long double'; define HAVE_LONG_DOUBLE if supported bashline.c - fix an inadvertantly-unclosed comment in attempt_shell_completion - make set_saved_history return a value - make dynamic_complete_history return a useful value {make_cmd,execute_cmd,shell,subst,trap,variables,input,unwind_prot,test, pcomplete}.c - removed some declared-but-unused variables builtins/{cd,enable,fc,set,setattr,type,umask,printf,complete}.def - removed some declared-but-unused variables lib/sh/{zread,netopen}.c - removed some declared-but-unused variables execute_cmd.c - in execute_arith_command, use a long variable to hold the result of evalexp(), since that's what it returns builtins/evalstring.c - make cat_file return -1 on a read or write error lib/sh/stringlib.c - make merge_stringlists() return the right value 5/7 --- pcomplete.c - remove typo that caused empty declaration (;;) parse.y - fix yyerror() to accept a single string argument; fix callers trap.c - cast pointer to long instead of int when printing message with internal_warning() in run_pending_traps() subst.c - fix process_substitute to handle stdin being closed test.c - change `while' to `if' in and() and or(), since the loop isn't actually performed -- there's an unconditional `return' in the loop body - check for integer overflow of arguments to `-t' lib/sh/netopen.c - change _getserv() to reject negative port/service numbers expr.c - fix strlong() to not convert the base specification from long to int before checking for overflow, since truncation on machines where sizeof(int) != sizeof(long) may mask errors builtins/{jobs,kill,wait}.def - use legal_number instead of atoi when converting strings to pid_t; check for numeric overflow input.c - fix for cygwin in b_fill_buffer -- off-by-one error when checking buffer for \r\n termination general.h - new #define INT_STRLEN_BOUND(t), computes max length of string representing integer value of type T, possibly including a sign character - include if it's present {execute_cmd,findcmd,test}.c - don't include , since general.h does it now {execute_cmd,lib/sh/itos,pcomplete,print_cmd,subst,variables}.c - use INT_STRLEN_BOUND instead of static array sizes when converting various strings to integer values shell.h - struct fd_bitmap now uses an `int' size, since it's bounded by the number of file descriptors, which must fit into an `int' execute_cmd.c - FD_BITMAP_DEFAULT_SIZE is now 32, not 32L - new_fd_bitmap takes an `int' size parameter, not a `long' execute_cmd.h - change prototype for new_fd_bitmap() test.c - fix test_stat to check for overflow when parsing the integer file descriptor number; return ENOENT instead of EBADF for files that are not open hashlib.c - don't discard the upper 32 bits of the random value, if present lib/readline/shell.c - use the same INT_STRLEN_BOUND mechanism to decide how much space to allocated in sh_set_lines_and_columns 5/8 --- aclocal.m4 - add check for libtinfo (termcap-specific portion of ncurses-5.2) to BASH_CHECK_LIB_TERMCAP - new macro, RL_LIB_READLINE_VERSION, checks version of installed readline library and (optionally) writes version #defines to config.h. Bash doesn't use the version defines configure.in - call RL_LIB_READLINE_VERSION instead of support/rlvers.sh execute_cmd.c - fix execute_shell_script and the WHITECHAR and STRINGCHAR macros to check array bounds before indexing into the sample string unwind_prot.[ch] - import new versions submitted by Paul Eggert with a couple of changes for backwards compatibility, so the rest of the source doesn't need to be changed yet jobs.c - use unwind_protect_var on last_made_pid in run_sigchld_trap builtins/bind.def - use unwind_protect_var on rl_outstream general.c - rework print_rlimtype to use INT_STRLEN_BOUND and handle the most negative number correctly expr.c - `tokval' should have been a `long', since all arithmetic is done as longs builtins/history.def - consolidate tests for valid history position in one block to avoid duplicate code and strings builtins/ulimit.def - fix check for overflow when setting limit to work when int is 32 bits and RLIMTYPE is 64 lib/sh/tmpfile.c - don't truncate the result of time(3) to int; just use time_t, since it's being assigned to an `unsigned long' mailcheck.c - use legal_number instead of atoi in time_to_check_mail() to catch more numeric errors; consolidate error checking in one block - last_time_mail_checked should be a time_t 5/9 --- builtins/set.def - recognize `set [-+]o nolog' if HISTORY is defined bashline.c - new variable `dont_save_function_defs', set by `set -o nolog'; currently ignored command.h - the `dest' member of a REDIRECTEE is now an `int' parse.y,redir.c - changed uses of `redir.test' (where redir is a REDIRECTEE) since it's now an int lib/readline/rlstdc.h - don't mess around with `const', rely on configure to supply a proper definition if the compiler doesn't support it lib/tilde/tilde.h - include if HAVE_CONFIG_H is defined - don't mess around with `const', rely on configure builtins/shopt.def - new read-only `shopt' option, login_shell, non-zero if shell is a login shell (as decided by shell.c) - new function set_login_shell(), sets shopt private value of login_shell builtins/common.h - new extern declaration for set_login_shell shell.c - call set_login_shell after setting value of login_shell (in main() and set_shell_name()) parse.y - added new `\A' prompt string escape sequence: time in 24-hour HH:MM format configure.in, config.h.in - check for , define HAVE_GRP_H if found builtins/complete.def - add new `-A group/-g' option to complete group names pcomplete.h - new define for CA_GROUP, used with group name completion pcomplete.c - add code to support CA_GROUP group name completion bashline.c - new function, bash_groupname_completion_function(), supports programmable completion of group names bashline.h - extern declaration for bash_groupname_completion_function lib/readline/bind.c - new inputrc variable, `match-hidden-files', controls completion matching files beginning with a `.' (on Unix) lib/readline/complete.c - new variable, _rl_match_hidden_files, mirrors `match-hidden-files' inputrc variable lib/readline/rlprivate.h - extern declaration for _rl_match_hidden_files builtins/hash.def - new `-t' option to list hash values for each filename argument builtins/read.def - alarm(3) takes an `unsigned int' argument, not int - check for arithmetic overflow with -t and -n options input.c - check for read error before doing \r\n translation on cygnus in b_fill_buffer - reset bp->b_used to 0 instead of leaving it at -1 on read error in b_fill_buffer builtins/shopt.def - new functions, shopt_setopt(name, mode) and shopt_listopt(name, mode) to give the rest of the shell an easy interface builtins/common.h - extern declarations for shopt_setopt and shopt_listopt shell.c - new invocation options -O and +O, to list or set/unset shopt options like +o/-o sets and unsets `set -o' options doc/{bash.1,bashref.texi} - document `set -o nolog' - document `login_shell' shopt option - document new `\A' prompt string escape sequence - document new `-t' option to `hash' - document new `[+-]O' invocation option doc/bashref.texi - add text to `Invoking Bash' section defining a login shell; text taken from man page doc/bash.1, lib/readline/doc/rluser.texinfo - documented new complete/compgen `-A group/-g' option lib/readline/doc/{rluser.texinfo,readline.3}, doc/bash.1 - documented new `match-hidden-files' inputrc variable 5/10 ---- configure.in - fix AC_CHECK_PROG(ar, ...) - add AC_CHECK_TYPE for ssize_t config.h.in - new #undef for ssize_t lib/sh/zread.c - int -> ssize_t fixes to mirror modern declarations of read and write - the `off' variable in zsyncfd should be an off_t since it computes a file offset - the local buffer `lbuf' is now char, since it's not nice to pass unsigned char * to read(2), and the values from it are assigned to a char anyway - lind and lused are now size_t, since they index into a buffer - set lused to 0 on read error lib/sh/zwrite.c - change second argument to type `char *', since ISO C says you have to pass a `char *' to `write' externs.h - fix extern declarations of zread, zread1, zreadc, and zwrite - prototype extern declaration of qsort_string_compare - add extern declaration for history_delimiting_chars() from parse.y input.h - b_used and b_inputp members ofr struct BSTREAM are now size_t builtins/evalstring.c - the number of chars read with zread in cat_file should be assigned to a variable of type ssize_t input.c - the number of chars read with zread in b_fill_buffer should be assigned to a variable of type ssize_t - `localbuf' is now type char[], since POSIX says you shouldn't pass unsigned char * to read(2) - in getc_with_restart(), use a variable of type unsigned char to get a value from the local buffer and return it - in ungetc_with_restart, explicitly return the character arg passed to avoid relying on localbuf being unsigned char subst.c - the number of chars read with zread in read_comsub should be assigned to a variable of type ssize_t mksyntax.c - instead of casting to unsigned char * in addcstr, use a variable of type unsigned char and let the compiler do the work parse.y - instead of casting to unsigned char * in yy_readline_get, use a variable of type unsigned char and let the compiler do the work - ditto for yy_string_get and shell_getc (cast to unsigned char) subst.c - instead of casting to unsigned char when assigning to ifscmap in expand_word_internal, use a variable of type unsigned char and let the compiler do the work lib/sh/strtrans.c - instead of casting to unsigned char in ansic_quote, use a variable of type unsigned char and let the compiler do the work builtins/evalstring.c - remove extern declarations for zwrite and run_trap_cleanup; they're in externs.h - prototype cat_file forward declaration Makefile.in - remove -I$(includedir) from INCLUDES and SUBDIR_INCLUDES aclocal.m4 - change RL_LIB_READLINE_VERSION to set RL_PREFIX, RL_LIBDIR, and RL_INCLUDEDIR to what it used to test the installed readline library version for use by the caller - change RL_LIB_READLINE_VERSION to not compute ac_cv_rl_prefix if the caller has already assigned it a value - rename _rl_prefix -> ac_cv_rl_prefix, _rl_libdir -> ac_cv_rl_libdir, _rl_includedir -> ac_cv_rl_includedir configure.in - change testing of whether to use the value of $opt_with_installed_readline to be != no, to allow the user to specify a prefix where the installed readline library may be found - if --with-installed-readline=PREFIX is supplied, set ac_cv_rl_prefix to PREFIX before calling RL_LIB_READLINE_VERSION - if --with-installed-readline[=PREFIX] is supplied, don't set RL_LIBDIR and RL_INCLUDEDIR; let RL_LIB_READLINE_VERSION take care of it, set RL_INCLUDE=-I${RL_INCLUDEDIR} - if --with-installed-readline[=PREFIX] is supplied, and we're linking with the history library, assign $RL_LIBDIR to HIST_LIBDIR so we use the same version of the installed readline and history libraries Makefile.in, builtins/Makefile.in - have configure substitute RL_INCLUDEDIR, set RL_INCLUDEDIR variable doc/bashref.texi - updated description of --with-installed-readline configure option general.c - moved QSFUNC typedef here from builtins/common.c {alias,bashline,variables,lib/sh/stringvec}.c - cast fourth argument to qsort to (QSFUNC *) alias.c - prototype forward declaration of qsort_alias_compare bashhist.c - include for extern declaration of glob_pattern_p - remove extern declaration of history_delimiting_chars; it's now in externs.h - prototype forward declarations of histignore_item_func, maybe_add_history, and bash_add_history bracecomp.c - remove extern declaration for sh_backslash_quote; it's in externs.h braces.c - remove extern declaration for extract_command_subst; it's in subst.h - prototype forward declarations for expand_amble, array_concat, and brace_gobbler error.c - prototype extern declaration of give_terminal_to, fix bad call {execute_cmd,expr,findcmd,jobs,mailcheck,nojobs,pcomplete,print_cmd,redir, shell}.c - prototype all static forward function declarations pcomplete.c - changed some function parameters to `const char *' to avoid discarding const qualifier make_cmd.c - make_bare_word, make_word_flags, and make_word now take a `const char *' string argument make_cmd.h - changed extern declarations for make_bare_word and make_word print_cmd.c - cprintf now takes a `const char *' as its first argument, like xprintf and printf - the conditional define for xprintf should have been HAVE_VPRINTF, not HAVE_VFPRINTF shell.c - in isnetconn(), the return value of sizeof() is size_t aclocal.m4 - add inclusion of stddef.h if STDC_HEADERS is defined to 1 in BASH_CHECK_TYPE configure.in - add a call to BASH_CHECK_TYPE for socklen_t (type of third argument to getpeername(2)) 5/11 ---- lib/readline/bind.c - make `useq' a char array to pass to rl_macro_bind in rl_parse_and_bind lib/readline/{{bind,isearch}.c,rlprivate.h} - _rl_isearch_terminators is now a char *, not unsigned char * {subst,variables,lib/sh/tmpfile}.c - dollar_dollar_pid is now a `pid_t' instead of `int' variables.c - sbrand() now takes an `unsigned long' to set the seed value - changed last_random_value to type int, since it's always between 0 and 32767 - use strtoul to convert the value in assign_random instead of atoi - take out casts in any arguments to sbrand() - take out cast to int in call to inttostr in set_ppid() subst.c - don't cast last_asynchronous_pid when passing to itos() {sig,subst}.c - prototype all static forward function declarations 5/14 ---- {test,trap,variables}.c - prototype all static forward function declarations variables.c - free_variable_hash_data() now takes a PTR_T, a `generic pointer' builtins/{alias,bind,break,cd,complete,declare,enable,exit,fc,fg_bg,help, history,jobs,pushd,read,set,trap,umask, - prototype all static forward function declarations builtins/read.def - reset_eol_delim now takes a `char *' arg, since that's what the unwind_protect functions pass it, and it ignores its arguments anyway lib/readline/{histsearch,input,kill,rltty,search,vi_mode}.c - prototype all static forward function declarations lib/tilde/tilde.c - prototype all static forward function declarations - tilde_find_prefix, tilde_find_suffix, isolate_tilde_prefix, and glue_prefix_and_suffix now take `const char *' arguments where appropriate configure.in,config.h.in - check for vsnprintf, define HAVE_VSNPRINTF if found lib/readline/display.c - use vsnprintf() in rl_message if it's available; if we don't, at least set the last character in msg_buf to 0 to avoid overrun -- we really can't do anything about overflow at this point. if it's available, this fixes buffer overflow problems in rl_message 5/15 ---- lib/readline/histexpand.c - in get_history_word_specifier, allow any character to terminate a `:first-' modifier, not just `:' and null. This is what csh appears to do. This allows things like `!:0- xyzzy' to replace the last argument with xyzzy 5/18 ---- configure.in, config.h.in - check for , define HAVE_STDINT_H if found - check for intmax_t in , define intmax_t as long if not found 5/21 ---- builtins/kill.def - change to use strerror() for error message when kill(2) fails aclocal.m4 - new macro, BASH_C_LONG_LONG, check for `long long' configure.in, config.h.in - call BASH_C_LONG_LONG, define HAVE_LONG_LONG if found lib/sh/snprintf.c - new file, with implementations of snprintf, vsnprintf, asprintf, and vasprintf, derived from inetutils version Makefile.in, lib/sh/Makefile.in - add snprintf.c/snprintf.o configure.in, config.h.in - add checks for snprintf, asprintf, vasprintf, with appropriate cpp defines lib/readline/{rldefs,xmalloc}.h, lib/readline/xmalloc.c - xmalloc and xrealloc now take `size_t' arguments, like their bash counterparts externs.h,lib/sh/itos.c - inttostr and itos now take `long' arguments - inttostr takes a `size_t' argument for the buffer size {expr,lib/malloc/malloc,variables,general}.c - fixed calls to itos() by removing casts, etc. subst.[ch] - get_dollar_var_value now takes a long, not an int - sub_append_number now takes a long, not an int subst.c - in parameter_brace_expand_word, use a long and legal_number to translate ${N}, to avoid overflow - in parameter_brace_expand_length, use a long and legal_number to translate ${#N}, to avoid overflow - in do_array_element_assignment, array_expand_index, array_value_internal, use arrayind_t instead of int - let verify_substring_values take long * arguments for the return value of evalexp() - pass long * arguments to verify_substring_values in parameter_brace_substring - parameter_brace_expand_length now returns `long' - parameter_brace_expand now uses a long variable for the return value of parameter_brace_expand_length - param_expand now uses a long variable for the return value from evalexp - array_length reference now returns an `arrayind_t', since it can return the num_elements member of an array, which is of type arrayind_t subst.h - array_expand_index now returns an `arrayind_t' array.[ch] - array_subrange now takes arrayind_t arguments, not `int' - dup_array_subrange now uses arrayind_t local variable to do array indexing - use long to print array indices in print_element variables.c - null_array_assign, assign_dirstack, bind_array_variable now take arrayind_t arguments as array indices - assign_array_var_from_word_list, assign_array_var_from_string, unbind_array_element now use arrayind_t local variables for array indexing variables.h - change extern declaration of bind_array_variable builtins/common.[ch] - get_numeric_arg now returns a `long', since it usually returns the value of legal_number() builtins/{shift,break}.def - use long variables for the return value of get_numeric_arg builtins/history.def - convert string argument to int only if it's in range builtins/pushd.def - set_dirstack_element and get_dirstack_element now take `long' index arguments - get_dirstack_index now takes a `long' index argument, since it's passed the converted value from legal_number lib/sh/timeval.c - in print_timeval, don't assume that the number of minutes fits into an int, since it's just seconds/60. lib/sh/clock.c - ditto for print_clock_t 5/22 ---- shell.c - since the -O option settings may possibly be overridden by the normal shell initialization or posix initialization, save the invocation options on an alist (with add_shopt_to_alist) and process them after basic initialization (with run_shopt_alist) 5/23 ---- trap.h - new define, BASH_NSIG, all system signals plus special bash traps trap.c, builtins/trap.def - use BASH_NSIG for array bounds and loops where appropriate trap.c - change decode_signal to disallow numeric signal numbers above NSIG -- this means you can only reference special traps like DEBUG by name - new SPECIAL_TRAP(s) macro to test whether s is one of the special bash traps (currently DEBUG and EXIT) - change reset_or_restore_signal_handlers so command substitution doesn't inherit the debug trap (like ksh93), and child processes don't have to rely on initialize_traps being run to get rid of any debug trap support/mksignames.c - add extra "ERR" signal name, value NSIG+1, allocate space for it and write it out in signal_names[] trap.h - new define: ERROR_TRAP == NSIG+1, change BASH_NSIG to NSIG+2 - extern declarations for set_error_trap, run_error_trap - new define: TRAP_STRING(s), expands to trap_list[s] if signal S is trapped and not ignored, NULL otherwise trap.c - add ERROR_TRAP to SPECIAL_TRAPS define - initialize ERROR_TRAP stuff in initialize_traps - new function: set_error_trap(command), sets the ERR trap string - new function: run_error_trap(command), runs the ERR trap string - set trap string for ERROR_TRAP to NULL in free_trap_strings - change reset_or_restore_signal_handlers so child processes don't inherit the ERR trap - add case to call run_error_trap in maybe_call_trap_handler execute_cmd.c - in execute_command_internal, keep track of ERR trap and call it if necessary - use TRAP_STRING to get the value of debug and error traps - in execute_function, arrange things so the ERR trap is not inherited by shell functions, and is saved and restored like the DEBUG trap doc/{bash.1,bashref.texi} - documented new ERR trap tests/{trap.{tests,right},trap2.sub,trap2a.sub} - added ERR trap tests subst.c - on machines without /dev/fd, change the named pipe fifo list to a list of structs containing pathname and proc information - change unlink_fifo_list to kill the proc in the fifo list with signal 0 and not remove the fifo if the proc is still alive. This should fix the problem on those backward systems without /dev/fd where fifos were removed when a job using process substitution was suspended 5/24 ---- examples/loadables/getconf.h - new file, with basic defines needed to make getconf work minimally on POSIX systems without the necessary definitions examples/loadables/getconf.c - replacement functions for confstr, sysconf, pathconf for systems that lack them, providing a minimal posix interface - heavily augmented getconf, now supports all POSIX.1-200x, POSIX.2-200x, Solaris 7, AIX 4.2 getconf variables 5/29 ---- builtins/setattr.def - make `readonly', `export', and `declare' print `invisible' variables as just a command and variable name, without a value, when listing all variables (as POSIX.2-200x d6 requires) 5/30 ---- configure.in - upgraded to autoconf-2.50 on main development machine, so require autoconf-2.50 in preparation for using some if its new features - call AC_C_PROTOTYPES - remove call to AC_EXEEXT, which now does the wrong thing - changed AC_INIT to new flavor - added call to AC_CONFIG_SRCDIR - AC_CONFIG_HEADER -> AC_CONFIG_HEADERS - AC_RETSIGTYPE -> AC_TYPE_SIGNAL configure.in, aclocal.m4, config.h.in - removed call to BASH_LARGE_FILE_SUPPORT, use AC_SYS_LARGEFILE standard support, with new macros _FILE_OFFSET_BITS and _LARGE_FILES - removed definition of BASH_LARGE_FILE_SUPPORT doc/bashref.texi - document new `--enable-largefile' configure option lib/readline/readline.c - change rl_set_prompt to call rl_expand_prompt unconditionally, so local_prompt and local_prompt_prefix get set correctly 6/6 --- lib/readline/complete.c - don't append `/' or ` ' to a match when completing a symlink that resolves to a directory, unless the match doesn't add anything to the word. This means that a tab will complete the word up to the full name, but not add anything, and a subsequent tab will add a slash. Change to append_to_match; callers changed hashlib.c - new function, hash_table_nentries (table), returns the number of items in TABLE hashlib.h - extern declaration for hash_table_nentries configure.in - configure without bash malloc on openbsd; they claim it needs eight-bit alignment (which the bash malloc provides, but...) 7/2 --- stringlib.c - only call RESIZE_MALLOCED_BUFFER from strsub() if the replacement string length is > 0, avoid possible hangs if replacement is null subst.c - don't include input.h; no longer needed configure.in - remove calls to AC_SYS_RESTARTABLE_SYSCALLS and BASH_SYS_RESTARTABLE_SYSCALLS; the results are no longer used config.h.in - remove define for HAVE_RESTARTABLE_SYSCALLS aclocal.m4 - removed definition of BASH_SYS_RESTARTABLE_SYSCALLS; no longer used execute_cmd.c - changed select command so `return' no longer terminates the select command, so it can be used to return from an enclosing function. This is as ksh (88 and 93) does it lib/readline/vi_mode.c - fix trivial typo in declaration of vi_motion; `t' appears twice; the second instance should be `T' 7/3 --- configure.in - don't add -static to LDFLAGS on Solaris 2.x. This means that the auxiliary programs will be built as dynamic executables, but that should do no harm 7/5 --- lib/glob/fnmatch.c - fix the code that processes **(pattern) to short-circuit if the pattern is ill-formed or lacks a trailing `)' -- this fixes the segfault on **(/*) Makefile.in, builtins/Makefile.in - split CCFLAGS into CCFLAGS_FOR_BUILD and CFLAGS, to aid in cross-compilation - build programs that use $(CC_FOR_BUILD) using $(CCFLAGS_FOR_BUILD) configure.in, config.h.in - check for getaddrinfo(3), define HAVE_GETADDRINFO if found lib/sh/netopen.c - implemented a version of _netopen (_netopen6) that uses getaddrinfo(3) if available, use if HAVE_GETADDRINFO is defined. old _netopen is _netopen4; _netopen now calls either _netopen6 or _netopen4 as appropriate 7/9 --- builtins/exit.def - don't source ~/.bash_logout if subshell_environment is non-zero execute_command.c - in execute_until_or_while, handle the case where `breaking' is set in the loop test (e.g., by the job control code when a job is stopped with SIGTSTP), but the return value from the test is something that would cause the loop to break. Need to decrement `breaking' in this case 7/10 ---- execute_cmd.c - in execute_in_subshell, make sure a command of type cm_subshell inherits its `enclosing' command's CMD_IGNORE_RETURN flag variables.c - in maybe_make_export_env, don't allow restricted shells to put exported functions in the export environment 7/11 ---- lib/glob/strmatch.h - renamed old fnmatch.h - changed guard #ifdef to _STRMATCH_H - include system if HAVE_LIBC_FNM_EXTMATCH is defined lib/glob/strmatch.c - renamed old fnmatch.c - include "strmatch.h" - if HAVE_LIBC_FNM_EXTMATCH is defined, define a dummy version of strmatch() that just calls fnmatch(3) lib/glob/glob.c - include "strmatch.h" - fnmatch -> strmatch Makefile.in, lib/glob/Makefile.in - fnmatch -> strmatch {bashhist,execute_cmd,pathexp,pcomplete,shell,stringlib,subst,test}.c, pathexp.h,builtins/help.def - include - fnmatch -> strmatch execute_cmd.c - broke the code that parses the interpreter name from a #! line out from execute_shell_script to a new function, getinterp() - call getinterp from execute_shell_script - use return value from getinterp in error message about bad #! interpreter in shell_execve 7/12 ---- lib/readline/isearch.c - the last isearch string is now remembered in a new static variable, last_isearch_string - if ^R^R is typed, readline now searches for the remembered isearch string, if one exists 7/24 ---- pcomplete.h - extern declaration for completions_to_stringlist() 7/25 ---- builtins/complete.def - make compgen handle -o default option - make compgen return success only if sl->list_len is non-zero, indicating that there are items on the list 7/31 ---- execute_cmd.c - in execute_connection, force stdin to /dev/null for asynchronous commands if job control is not active, not just if the shell is running a shell script (since you can run `set -m' in a script) lib/readline/rltty.c - make sure _rl_tty_restore_signals resets `tty_sigs_disabled' on successful restoration of the terminal modes - make sure _rl_tty_disable_signals turns off IXON so that ^S and ^Q can be read by rl_quoted_insert 8/1 --- aclocal.m4 - new check for FNM_EXTMATCH being defined in , as Ullrich Drepper intends to do for new versions of GNU libc config.h.in - new definition for HAVE_LIBC_FNM_EXTMATCH configure.in - check for fnmatch, but don't define anything in config.h - call BASH_FUNC_FNMATCH_EXTMATCH to check for FNM_EXTMATCH 8/2 --- alias.h - remove bogus extern declaration for xmalloc() - include "stdc.h" - add prototype declarations for all extern function declarations xmalloc.c,lib/readline/xmalloc.c - fix xmalloc to return a PTR_T - fix xrealloc to return a PTR_T and take a PTR_T as first argument include/ansi_stdlib.h - extern declarations for malloc and realloc have them return PTR_T xmalloc.h - new file, with extern declarations for functions in xmalloc.c general.h - removed extern declarations for functions in xmalloc.c - include xmalloc.h Makefile.in,builtins/Makefile.in - update dependencies to include xmalloc.h parse.y,{alias,array,bashline,bracecomp,execute_cmd,findcmd,flags,general, hashcmd,locale,mailcheck,make_cmd,pathexp,pcomplete,print_cmd,stringlib, subst,unwind_prot,variables}.c builtins/{common,evalfile}.c builtins/{cd,command,enable,exec,printf,read,set}.def lib/sh/{makepath,netopen,pathphys,setlinebuf,shquote,snprintf,stringlist, strtrans,tmpfile}.c lib/readline/{util,terminal,shell,readline,macro,kill,isearch,input, histfile,histexpand,display,complete,bind}.c - make sure all calls to xmalloc are cast to the right return value siglist.c - include xmalloc.h parse.y,{alias,bashline,bracecomp,expr,make_cmd,nojobs,print_cmd,subst}.c builtins/{fc,printf,read}.def lib/sh/snprintf.c, lib/tilde/tilde.c lib/readline/{bind,display,histexpand,isearch,macro,util,vi_mode}.c - make sure all calls to xrealloc are cast to the right return value lib/sh/{netopen,setlinebuf,shquote,snprintf}.c, lib/tilde/tilde.c - include xmalloc.h, remove extern declaration of xmalloc lib/readline/xmalloc.h - xmalloc and xrealloc should return PTR_T lib/readline/rldefs.h - don't include an extern declaration for xmalloc 8/7 --- support/shobj-conf - fixed up commented-out stanzas for HP's unbundled C compiler on HP/UX support/bashbug.sh - force the subject to be changed from the default lib/readline/doc/{rluser.texinfo,readline.3}, doc/bash.1 - document that transpose-words swaps the last two words on the line if point is at the end of the line 8/9 --- stringlib.c - fix possible infinite recursion problem with null pattern in strsub() hashlib.c - new function copy_hash_table to copy a hash table using a caller- supplied function to copy item data (defaults to savestring()) hashlib.h - new extern declaration for copy_hash_table builtins/declare.def - changes so that declare [-a] var=value assigns `value' to element 0 of array variable `var' like ksh93 - change so that declare [-a] var[N]=value assigns `value' to element N of array variable `var' like ksh93 8/13 ---- arrayfunc.c - new file, for miscellaneous array functions arrayfunc.h - new file, extern declarations for functions in arrayfunc.c variables.c - move convert_var_to_array, bind_array_variable, assign_array_from_string, assign_array_var_from_word_list, assign_array_var_from_string, quote_array_assignment_chars, skipsubscript, unbind_array_element, print_array_assignment to arrayfunc.c shell.h - include arrayfunc.h after variables.h variables.h - remove above extern function declarations moved to arrayfunc.h - add extern declaration for var_lookup Makefile.in - add arrayfunc.c, arrayfunc.h in appropriate places - add arrayfunc.h to dependencies subst.c - move valid_array_reference, array_expand_index, array_variable_part, array_value_internal, array_value (now global), get_array_value, do_array_element_assignment to arrayfunc.c subst.h - extern declarations for functions above moved to arrayfunc.h arrayfunc.h - extern declarations for above functions from subst.c subst.[ch] - string_list_dollar_star and string_list_dollar_at are now global functions - quote_escapes is now a global function subst.c - maybe_expand_string -> expand_string_if_necessary - expand_string_to_string -> expand_string_to_string_internal - new functions: expand_string_to_string and expand_string_unsplit_to_string, which call expand_string_to_string_internal with expand_string and expand_string_unsplit as the FUNC arguments, respectively arrayfunc.c - change array_expand_index to call expand_string_to_string instead of maybe_expand_string 8/14 ---- shell.c - in execute_env_file, call expand_string_unsplit_to_string mailcheck.c - in check_mail, call expand_string_to_string variables.c - in assign_in_env, call expand_string_unsplit_to_string arrayfunc.c - new function, array_variable_name, splits an array reference into a name (which is returned as a new string) and subscript - change array_variable_part to just call array_variable_name and look up the string returned with find_variable - new function, find_or_make_array_variable (name, flags) which will look up an array variable and convert a string variable to an array if necessary. The FLAGS argument, if non-zero, says to check the readonly and noassign attributes and fail if either is set builtins/read.def - make `read -a aname' honor any readonly status of `aname' - read -a now calls find_or_make_array_variable with FLAGS value 1 arrayfunc.[ch], subst.c, builtins/{declare,read}.def - do_array_element_assignment -> assign_array_element 8/20 ---- parse.y - changed `for' command grammar to allow missing word list after `IN' token, like latest POSIX drafts require lib/sh/tmpfile.c - in sh_mktmpname(), check for filenum == 0 and init to non-zero number in this case. it can happen on arithmetic overflow support/mkversion.sh - added `[0-9].[0-9][0-9][a-z]' as an acceptable value for a distribution to allow for intermediate versions, like 2.05a support/config.guess - removed the addition of the output of `/usr/bin/objformat' when creating the canonical name on FreeBSD machines, so the canonical name is once again `freebsd4.2' instead of `freebsdelf4.2' 8/22 ---- lib/readline/{rlstdc,history,keymaps,readline,rldefs,rlprivate,rlshell, rltypedefs,xmalloc}.h lib/readline/{bind,compat,complete,display,funmap,histexpand,histsearch, input,isearch,kill,nls,parens,readline,rltty,search,shell,signals,vi_mode - changed __P to PARAMS lib/tilde/tilde.[ch] - changed __P to PARAMS {Makefile,configure}.in - changed the version number to 2.05a - changed the release status to `alpha1' 8/23 ---- support/shobj-conf - support for building shared libraries on Darwin/MacOS X siglist.h - extern declaration for strsignal() to compensate for lack of a definition in some system include files jobs.c - remove casts from strsignal() calls [bash-2.05a-alpha1 frozen] 8/27 ---- [bash-2.05a-alpha1 released] 8/27 ---- execute_cmd.c - fix eval_arith_for_expr to handle the case where the expanded word list is NULL, returning 0 in this case print_cmd.c - in print_function_def, make sure that func_redirects is assigned a value before being used 8/28 ---- alias.c - include for definition of isalpha() bashhist.h - add prototypes for extern function declarations flags.c - include bashhist.h for extern function declarations mksyntax.c - include if HAVE_UNISTD_H is defined in config.h parse.y - include test.h for extern function declarations externs.h - change extern declaration for setlinebuf to sh_setlinebuf stringlib.c - include for extern function declarations variables.h - add function prototypes for all of the sv_* functions builtins/common.h - add extern declarations for set_shellopts() and parse_shellopts() from builtins/set.def variables.c - include "hashcmd.h" for extern declaration for flush_hashed_filenames - include "pathexp.h" for extern declaration for setup_glob_ignore lib/malloc/malloc.c - cast to `long' instead of `int' in memalign for 64-bit machines {pcomplete,trap}.c - changed printf escape sequences used to print pointers to %p lib/readline/undo.c - include "xmalloc.h" for extern function declaration input.h - add function prototypes to extern declarations for getc_with_restart and ungetc_with_restart variables.[ch] - changed type of `function' member of `struct name_and_function' to `sv_func_t', which is defined and prototyped in variables.h - map_over now takes an `sh_var_map_func_t *' shell.h - start of a set of function pointer typedefs like those in lib/readline/rltypedefs.h hashlib.[ch] - second paramter to flush_hash_table is now an `sh_free_func_t *' trap.c - parameter to reset_or_restore_signal_handlers is now an `sh_resetsig_func_t *' pcomplete.h, pcomplib.c - function pointer argument to print_all_compspecs is now an `sh_csprint_func_t *' - function pointer `list_getter' element of an `ITEMLIST' is now prototyped with __P((...)) instead of using `Function *' jobs.[ch] - `j_cleanup' member of a JOB is now an `sh_vptrfunc_t *' alias.c - map_over_aliases now takes an `sh_alias_map_func_t *' - free_alias_data now takes a `PTR_T' pathexp.c - function pointer argument to ignore_globbed_names is now an `sh_ignore_func_t *' bashline.c - function pointer argument to _ignore_completion_names is now an `sh_ignore_func_t *' pathexp.h,{bashhist,bashline.c - `item_func' member of a `struct ignorevar' is now an `sh_iv_item_func_t *' builtins/evalfile.c - `errfunc' is now an `sh_vmsg_func_t *' jobs.c - map_over_job now takes an `sh_job_map_func_t *' as its first argument array.[ch] - function pointer argument to array_walk is now an `sh_ae_map_func_t *' general.c - tilde_expansion_preexpansion_hook has type `tilde_hook_func_t *', and so the assignment in tilde_initialize doesn't need a cast list.c - map_over_words now takes an `sh_icpfunc_t *' as its second argument input.h - the `getter' and `ungetter' function pointer members of a BASH_INPUT are now of types `sh_cget_func_t *' and `sh_cunget_func_t *' respectively - init_yy_io now takes an `sh_cget_func_t *' as its first argument and an `sh_cunget_func_t *' as its second parse.y - init_yy_io now takes an `sh_cget_func_t *' as its first argument and an `sh_cunget_func_t *' as its second - initialize_bash_input casts bash_input.getter and bash_input.ungetter appropriately builtins/mkbuiltins.c - make the extern function definitions written to builtext.h have prototypes with __P((...)) - include "stdc.h" - change Function to mk_handler_func_t - fixed comment_handler to take the right number of args - prototyped all the handler functions with __P((...)) builtins.h - the `function' member of a struct builtin is now of type `sh_builtin_func_t *' builtins/common.[ch] - last_shell_builtin, this_shell_builtin are now of type `sh_builtin_func_t *' - find_shell_builtin, builtin_address, find_special_builtin now return `sh_builtin_func_t *' builtins/exit.def, {execute_cmd,jobs,nojobs,variables}.c, parse.y - changed all declarations of last_shell_builtin and this_shell_builtin execute_cmd.c - execute_builtin, execute_builtin_or_function, execute_subshell_builtin_or_function now take an `sh_builtin_func_t *' instead of a `Function *' for argument - changed appropriate variables from `Function *' to `sh_builtin_func_t *' builtins/{bind,builtin,enable,read,setattr}.def - replaced uses of `Function *' in variable declarations with appropriate types (sh_builtin_func_t * or rl_command_func_t *) builtins/set.def - set_func and get_func members of binary_o_options are now of types `setopt_set_func_t *' and `setopt_get_func_t *', which are prototyped builtins/shopt.def - set_func member of shopt_vars is now of type `shopt_set_func_t *' bashline.c - enable_hostname_completion now returns `int' (the old value of perform_hostname_completion) [The only use of Function and VFunction now is for unwind-protects] 9/4 --- lib/sh/getcwd.c - use const define from config.h rather than `CONST' - use PTR_T define from xmalloc.h rather than `PTR' - include xmalloc.h for PTR_T - remove PATH_MAX define, rely on value from maxpath.h {general,mailcheck}.c, lib/sh/{pathcanon,pathphys}.c - don't include maxpath.h directly; it's already included by shell.h lib/sh/mailstat.c - new `mailstat()' implementation, to stat a mailbox file for mail checking. handles maildir-style mail directories with one file per message and creates a dummy stat struct from them lib/sh/Makefile.in - add mailstat.c and mailstat.o in the appropriate places lib/malloc/malloc.c - augmented implementation with wrapper functions that pass in file and line number information from cpp. currently unused, but a placeholder for future debugging and use tracking lib/malloc/shmalloc.h - new file, extern declarations for allocation wrapper functions for use by the shell (and others, I guess) xmalloc.[ch] - wrapper functions for xmalloc, xfree, xrealloc (sh_ prefixed) that pass cpp line number information through to the malloc functions, if USING_BASH_MALLOC is defined 9/5 --- lib/malloc/gmalloc.c - removed; no longer part of distribution lib/malloc/Makefile.in - removed references to gmalloc.[co] configure.in, doc/bashref.texi - removed references to `--with-glibc-malloc' configure option {configure,Makefile}.in - changed the way bash malloc is configured into the Makefile, making it more like how readline is configured. If the bash malloc is not configured in, nothing in lib/malloc will be built 9/6 --- lib/malloc/imalloc.h - new file, some internal malloc definitions lib/malloc/mstats.h - new file, definitions for malloc statistics structs and functions lib/malloc/trace.c - new file, malloc tracing functions (currently just print messages to stderr), code is #ifdef MALLOC_TRACE lib/malloc/stats.c - new file, moved malloc stats code from malloc.c to here lib/malloc/malloc.c - moved some definitions to imalloc.h - moved stats code to stats.c - malloc tracing calls added to internal_{malloc,realloc,free}, all #ifdef MALLOC_TRACE lib/malloc/Makefile.in, Makefile.in - added {imalloc,mstats}.h, {trace,stats}.c parse.y - changed decode_prompt_string to save and restore $? (last_command_exit_value) around calls to expand_prompt_string(), so command substitutions in PS1, etc. don't change $? {array,subst}.c - a couple more arrayind_t fixes from Paul Eggert configure.in - remove redundant check for wait3(2) redir.h - fixed a typo (stdin_redirs -> stdin_redirects) 9/10 ---- execute_cmd.c - remove check for \n and \r from WHITESPACE macro, since those chars are not whitespace as returned by the whitespace(c) macro - getinterp now takes a `char *' as first arg, not unsigned char * - execute_shell_script now takes a `char *' as first arg, not unsigned char * - fix typo in forward declaration for `initialize_subshell' general.[ch] - check_binary_file now takes a (char *) argument, not unsigned char * - pass unsigned char to isspace and isprint because of ISO C fuckup - bash_tilde_expand now takes a `const char *' as its argument builtins/evalfile.c, shell.c - buffer passed to check_binary_file is char, not unsigned char parse.y - fix extern declaration for yyerror() - yyerror now takes a `const char *' as first arg {error,jobs}.c - fixes to printf-style functions to handle pids wider than an int lib/readline/{isearch,vi_mode}.c - fix call to rl_message in rl_display_search (remove extra arg) variables.c - fix missing argument to builtin_error in make_local_variable builtins/getopts.def - since getopts takes no options, change while loop calling internal_getopts to a simple `if' check builtins/printf.def - since printf takes no options, change while loop calling internal_getopts to a simple `if' check lib/readline/bind.c - remove _SET_BELL macro, expand code inline lib/readline/input.c - change _rl_input_available to use either select or FIONREAD, but not both lib/readline/readline.c - fix rl_digit_loop to remove unreachable code at end of loop {bashhist,bashline,expr,jobs,redir,shell}.c, builtins/fc.def, lib/sh/snprintf.c - bracket unused functions with #ifdef INCLUDE_UNUSED/#endif - remove some unused variables execute_cmd.c - remove #ifdef'd code that allowed `return' to terminate a select statement expr.c - remove some extraneous tests from strlong() array.h - arrayind_t is now a long, since shell arithmetic is performed as longs - remove second declaration of new_array_element builtins/printf.def - in mklong, xrealloc cannot return NULL, so don't check for it - remove some #if 0 code - fix core dump triggered by a format specification with more than one `*' - remove `foundmod', since its value mirrors `modchar != 0' - include "common.h" for builtin_{error,usage} declarations Makefile.in,builtins/Makefile.in - updated some dependencies due to new include files pcomplete.c - include "execute_cmd.h" for declaration of execute_shell_function arrayfunc.c - include for printf - include "builtins/common.h" for builtin_error declaration builtins/evalstring.c - include "../trap.h" for run_trap_cleanup declaration builtins/help.def - include "common.h" instead of locally declaring builtin_error and builtin_usage error.h - add extern declaration for itrace() - add prototype to extern declaration of get_name_for_error - file_error now takes a `const char *' as first argument externs.h - added prototype for sh_setlinebuf declaration, bracketed with NEED_SH_SETLINEBUF_DECL so we don't need stdio.h everywhere - add extern declaration for parse.y:return_EOF() shell.c - add NEED_SH_SETLINEBUF_DECL before including shell.h lib/readline/callback.c - include or "ansi_stdlib.h" for abort declaration quit.h - remove declaration of throw_to_top_level subst.c - remove unused extern declaration for getopts_reset lib/sh/netopen.c - include for legal_number, etc. - add prototype for inet_aton extern declaration lib/sh/clock.c - include for __P declaration - add extern declaration for get_clk_tck support/mkversion.sh - changed so that extern function declarations for functions in version.c (moved from externs.h) are in the generated version.h shell.h - include version.h version.c - various `char *' version variables are now `const char *' general.h - add prototype for same_file, bracketed with _POSIXSTAT_H #ifdef, since that's what include/posixstat.h defines builtins/common.[ch] - _evalfile, maybe_execute_file, source_file, and fc_execute_file now take a `const char *' as their first argument eval.c - removed extern declaration of yyparse; it's in externs.h parse.y - added prototypes to static forward function declarations - changed local `all_digits' variable in read_token_word () to all_digit_token to avoid clash with all_digits() function in general.c {bashhist,copy_cmd,make_cmd,hashlib,mailcheck}.c - added prototypes for static function declarations shell.h - add extern declarations for interactive, interactive_shell, changed c files with extern declarations pcomplete.c - changed it_init_aliases to avoid shadowing global variable `aliases' bashline.c,pathexp.c,general.h - sh_ignore_func_t is now a pointer to a function taking a `const char *'; users changed configure.in - test for config.h.in - add #undef HAVE_STRINGS_H bashansi.h - change like recommended in autoconf manual 9/11 ---- [a date which will live in infamy. prayers for the victims.] execute_cmd.c - don't use an absolute index into abuf in mkfmt, use sizeof(abuf) to compute last index builtins/common.c - fix read_octal to do a better job of detecting overflow while iterating through the string builtins/umask.def - change octal-print mode to print 4 digits, like other shells - cast umask to unsigned long to avoid problems on systems where it's wider than an int (POSIX doesn't guarantee that mode_t is no wider than an int, but real-world systems use int) builtins/printf.def - mklong can never return NULL (it uses xrealloc), so the mainline doesn't need to check for NULL returns - new function, getldouble (long double *), to get long doubles - mklong now takes a `char *' as its second argument, the modifier(s) to use - changed use of `modchar' to handle more than a single modifier character - changed to handle `long double' and `L' formats better, rather than discarding long double information - since printf now follows the POSIX.2 rules for conversion errors, we can dispense with the status returns from the get* functions - make the get* functions as similar in structure as possible, removing type casts, etc. lib/sh/timeval.c,execute_cmd.c - change some instances of `long' to `time_t', for systems where a time_t is bigger than a long jobs.c - include "posixtime.h" instead of config.h.in - add defines for HAVE_DECL_CONFSTR, HAVE_DECL_STRTOLD, HAVE_DECL_SBRK, HAVE_DECL_PRINTF - remove defines for SBRK_DECLARED and PRINTF_DECLARED - add _GNU_SOURCE define configure.in - add AC_CHECK_DECLS for strtold, confstr, sbrk, printf - remove call to BASH_FUNC_SBRK_DECLARED - remove call to BASH_FUNC_PRINTF xmalloc.c, lib/malloc/malloc.c - change check of SBRK_DECLARED to HAVE_SBRK_DECL print_cmd.c - change PRINTF_DECLARED to HAVE_DECL_PRINTF builtins/evalstring.c, builtins/common.h - parse_and_execute now takes a `const char *' as its second argument input.h,parse.y - with_input_from_* functions now take a `const char *' as their second argument - init_yy_io now takes a `const char *' as its fourth argument parse.y,externs.h - parse_string_to_word_list now takes a `const char *' as its second argument tests/builtins.right - change output to account for extra digit in umask output pcomplib.c - free_progcomp now takes a PTR_T argument builtins/bashgetopt.h - include - add prototypes to extern declarations builtins/shopt.def - add prototypes to static function declarations builtins/{fc,umask,wait}.def, builtins/{bashgetopt,common}.c - include for isdigit macro (referenced by `digit(x)') lib/readline/complete.c - added more static function declarations with prototypes 9/12 ---- lib/sh/tmpfile.c - use `^' instead of `*' in sh_mktmpname to make filenames a bit more random include/stdc.h,lib/readline/rldstdc.h - add __attribute__ definition builtins/common.h - add printf __attribute__ to declaration of builtin_error error.h - add printf __attribute__ to declaration of programming_error, report_error, parser_error, fatal_error, sys_error, internal_error, internal_warning lib/readline/readline.h - add printf __attribute__ to declaration of rl_message pcomplete.c - add printf __attribute__ to declaration of debug_printf print_cmd.c - add printf __attribute__ to declarations of cprintf, xprintf include/chartypes.h - new file, includes and defines macros that check for safe (ascii) arguments before calling the regular ctype macros {alias,bashline,execute_cmd,expr,findcmd,general,locale,mksyntax,stringlib,subst,variables}.c parse.y builtins/{bashgetopt,common}.c builtins/{fc,printf,umask,wait}.def lib/glob/strmatch.c lib/sh/{oslib,pathcanon,pathphys,snprintf,strcasecmp,strindex,stringvec,strtod,strtol,strtrans}.c examples/loadables/{head,sleep}.c - include "chartypes.h" or instead of Makefile.in,{builtins,lib/{glob,sh}}/Makefile.in - update dependencies to include chartypes.h lib/sh/inet_aton.c - use `unsigned char' instead of `char' to pass to ctype.h functions lib/sh/netopen.c - check for '0' <= host[0] <= '9' in _getaddr instead of using isdigit subst.c,lib/sh/shquote.c - change array subscripts into sh_syntaxtab from `char' to `unsigned char' {alias,bashline,execute_cmd,expr,general,subst}.c, parse.y builtins/{fc,printf,umask,wait}.def builtins/{bashgetopt,common}.c lib/sh/{pathcanon,pathphys,snprintf,strcasecmp,strindex,strtod,strtol,strtrans}.c examples/loadables/{head,sleep}.c - change to use some of the new macros in chartypes.h - remove old local macro definitions now provided by chartypes.h general.h - remove definition of isletter, ISOCTAL, digit, digit_value - change legal_variable_starter and legal_variable_char to use chartypes.h macros - change ABSPATH to use chartypes.h macros lib/readline/util.c - change to use Paul Eggert's FUNCTION_FOR_MACRO define to define function replacements for macros in chardefs.h lib/readline/chardefs.h - added some of the same macros as in chartypes.h - change _rl_lowercase_p, _rl_uppercase_p, _rl_digit_p, _rl_to_upper, _rl_to_lower to use new IS* macros - added _rl_isident macro from vi_mode.c:isident lib/readline/{bind,complete,nls}.c - change to use some of the new macros from chardefs.h lib/readline/vi_mode.c - isident -> _rl_isident - remove local defines of macros in chardefs.h lib/sh/strtol.c - updated to new version, modified from glibc 2.2.4 and sh-utils-2.0. This one can do strtoll and strtoull, if necessary 9/13 ---- builtins/ulimit.def - changed get_limit so it retrieves both hard and soft limits instead of one or the other - changed callers of get_limit - changed getmaxvm to take soft limit, hard limit as arguments - changed getmaxuprc to just take a single argument, the value - changed calls to printone() to pass soft limit or hard limit depending on `mode' instead of using old current_limit variable - moved check for out-of-range limits in ulimit_internal into the block that converts a string argument to a value of type rlim_t - changed RESOURCE_LIMITS struct to break the description into a description string and separate scale factor string - changed print_all_limits to print a single error message if get_limit fails, including limits[i].description now that the scale factor has been removed from the description string - removed DESCFMT define, since it's now used only in printone() - changed printone to print the option character associated with a particular limit if we're printing multiple limits - changed calls to builtin_error to print the description associated with a limit if setting or getting the limit fails - added support for new POSIX 1003.1-200x rlim_t values: RLIM_SAVED_CUR and RLIM_SAVED_MAX, which expand to the current soft and hard limits, whatever they are - changed printone to print `hard' or `soft' if the current limit is RLIM_SAVED_MAX or RLIM_SAVED_CUR, respectively - changed ulimit_internal to handle new `hard' and `soft' arguments - changed help text do describe the special limit arguments `hard', `soft', and `unlimited' doc/{bash.1,bashref.texi} - documented new `hard' and `soft' limit arguments to `ulimit' hashlib.[ch] - find_hash_item now takes a `const char *' is its first argument - hash_string now takes a `const char *' is its first argument - remove_hash_item now takes a `const char *' as its first argument pcomplib.c - removed cast from first argument to find_hash_item in find_compspec general.[ch] - absolute_program now takes a `const char *' as its argument - absolute_pathname now takes a `const char *' as its argument lib/glob/glob.[ch] - glob_pattern_p now takes a `const char *' as its argument bashline.c - removed cast from first argument to absolute_program in command_word_completion_function - removed cast from first argument to glob_pattern_p in attempt_shell_completion findcmd.[ch] - find_absolute_program, find_user_command, find_path_file, search_for_command, user_command_matches now take a `const char *' as their first argument - file_status, executable_file, is_directory, executable_or_directory now take a `const char *' as their argument - _find_user_command_internal, find_user_command_internal, find_user_command_in_path lib/sh/makepath.c, externs.h - changed sh_makepath so it takes `const char *' for its first two arguments hashcmd.[ch] - find_hashed_filename now takes a `const char *' as its first arg - remove_hashed_filename now takes a `const char *' as its first arg variables.[ch] - new_shell_variable, var_lookup, shell_var_from_env_string, find_name_in_env_array, bind_function, makunbound, bind_name_in_env_array, bind_tempenv_variable, bind_variable now take a `const char *' as their first arg - find_function, make_new_variable, find_tempenv_variable, find_variable_internal, find_variable, set_func_read_only, set_func_auto_export, all_variables_matching_prefix, assign_in_env, assignment, kill_local_variable, make_local_variable, unbind_variable now take a `const char *' as their arg - mk_env_string now takes `const char *' arguments arrayfunc.[ch] - skipsubscript now takes a `const char *' as its argument 9/17 ---- lib/readline/complete.c - attempt to preserve case of what the user typed in compute_lcd_of_matches if we're ignoring case in completion builtins/{let,pushd}.def,{execute_cmd,expr}.c - change some 0L constants to 0 and let the compiler sort it out 9/18 ---- lib/malloc/alloca.c - alloca now takes a `size_t' argument include/memalloc.h - if we're providing an extern function declaration for alloca, use `void *' and prototype if __STDC__ is defined - if HAVE_ALLOCA_H is defined, but C_ALLOCA is defined, don't define HAVE_ALLOCA 9/19 ---- subst.c - do_assignment_internal, do_assignment, and do_assignment_no_expand now take a `const char *' as their first argument general.h - a `sh_assign_func_t' is now a function taking a `const char *' and returning int hashcmd.c - free_filename_data now takes a `PTR_T' argument to agree with the typedef for `sh_free_func_t' lib/sh/snprintf.c - use TYPE_MAXIMUM define like strtol.c instead of huge constants 9/20 ---- lib/sh/snprintf.c - don't bother to compile the bulk of the body unless HAVE_SNPRINTF or HAVE_ASPRINTF is not defined 9/24 ---- flags.c - ignore `set -n' if the shell was started interactively lib/readline/readline.c - initialize readline_echoing_p to 0; let the terminal-specific code in rltty.c set it appropriately lib/malloc/malloc.c - changed internal_memalign() slightly to avoid compiler warnings about negating an unsigned variable (-alignment -> (~alignment + 1)) 9/27 ---- lib/readline/readline.c - changed rl_newline to set _rl_history_saved_point appropriately for the {previous,next}_history code lib/readline/rlprivate.h - extern declaration for _rl_history_preserve_point lib/readline/bind.c - new bindable variable, `history-preserve-point', sets value of _rl_history_preserve_point 10/1 ---- lib/malloc/table.c - new file, with a map of allocated (and freed) memory for debugging multiple frees, etc. Indexed by hash on values returned by malloc(); holds size, file and line number info for last alloc or free and a couple of statistics pointers lib/malloc/malloc.c - a few cleanups; added calls for registering allocations and frees if MALLOC_REGISTER is defined - replaced MALLOC_RETURN with explicit MALLOC_NOTRACE define - reordered fields in `struct...minfo' in `union mhead' to restore eight-byte alignment - added explicit checks for underflow in free and realloc since checking mh_magic2 is not sufficient to detect everything (it's no longer the last field in the struct, and thus not the bytes immediately preceding what's returned to the user) - new function, xbotch, for printing file and line number info for the failed assertion before calling botch() (programming_error()) configure.in - replaced call to BASH_C_LONG_LONG with call to AC_CHECK_TYPES([long long]) - moved the C compiler tests before the tests for various system types, so we can know whether we have `long long' before testing for 64-bit types - if we have `long long', check for sizeof(long long) and save value aclocal.m4 - changed BASH_TYPE_BITS64_T to check `long long' before `long', but after `double' 10/2 ---- lib/malloc/malloc.c - made malloc and realloc both agree on the rounding for a request of size N (round up to nearest multiple of 8 after adjusting for malloc overhead); uses new ALLOCATED_BYTES macro - realloc and free now use new IN_BUCKET macro for underflow checks execute_cmd.c - fixed time_command() to use `time_t' instead of `long' to hold time stamps lib/sh/clock.c - clock_t_to_secs now takes a `time_t *' second argument - fixed print_clock_t to call clock_t_to_secs with right arguments lib/sh/timeval.c - fixed print_timeval to make `minutes' a `long' and make its structure identical to print_clock_t redir.c - changed redirection_error to check for EBADF and use the file descriptor being redirected from in the error message if it is >= 0 Makefile.in - changed release status to `beta1' lib/glob/collsyms.h - added a few ASCII symbols to the posix_collsyms array 10/3 ---- aclocal.m4 - fixed typo in BASH_TYPE_BITS64_T configure.in - added check for unsigned chars with AC_C_CHAR_UNSIGNED config.h.in - added PROTOTYPES and __CHAR_UNSIGNED__ #defines general.h - if CHAR_MAX is not define by , provide a definition builtins/printf.def - change tescape() to mask \0 and \x escape sequences with 0xFF - change tescape() to process at most two hex digits after a `\x' lib/sh/strtrans.c - change strtrans() to mask \0 and \x escape sequences with 0xFF - change strtrans() to process at most two hex digits after a `\x'. This affects `echo -e' and $'...' processing lib/readline/bind.c - changed rl_translate_keyseq() to process at most two hex digits after a `\x' lib/readline/doc/{rluser.texinfo,readline.3}, doc/bash.1 - changed documentation for key binding escape sequences to specify that at most two hex digits after \x are translated - changed documentation for key binding to specify that the result of \nnn or \xhh escapes is an eight-bit value, not just ASCII doc/{bash.1,bashref.texi} - changed documentation of $'...' to specify that at most two hex digits after \x are translated - changed `echo' documentation to specify that at most two hex digits after \x are translated - changed documentation for `echo' and $'...' to specify that the result of \nnn or \xhh escapes is an eight-bit value, not just ASCII 10/4 ---- lib/malloc/malloc.c - changed interface for xbotch to pass memory address and error code as two additional arguments - call mregister_describe_mem from xbotch to get the last allocation or free before the botch configure.in - call AC_CHECK_DECLS([strsignal]) config.h.in - add HAVE_DECL_STRSIGNAL siglist.h - make declaration of strsignal() dependent on !HAVE_DECL_STRSIGNAL 10/5 ---- support/texi2html - upgraded to version 1.64 10/9 ---- aclocal.m4 - added check for `long long' to BASH_TYPE_PTRDIFF_T configure.in - replaced call to BASH_HAVE_TIOCGWINSZ with AC_HEADER_TIOCGWINSZ aclocal.m4 - replaced body of BASH_STRUCT_TERMIOS_LDISC with call to AC_CHECK_MEMBER(struct termios.c_line, ...) - replaced body of BASH_STRUCT_TERMIO_LDISC with call to AC_CHECK_MEMBER(struct termios.c_line, ...) [bash-2.05a-beta1 frozen] 10/10 ----- lib/sh/snprintf.c - fixed exponent() to not smash the trailing zeros in the fraction when using %g or %G with an `alternate form' - fixed exponent() to handle the optional precision with %g and %G correctly (number of significant digits before the exponent) 10/11 ----- expr.c - fixed strlong() to correct the values of `@' and `_' when translating base-64 constants (64#@ == 62 and 64#_ == 64), for compatibility with ksh lib/sh/itos.c - added a slightly more flexible fmtlong() function that takes a base argument and flags (for future use) - rewrote itos and inttostr in terms of fmtlong lib/sh/fmtulong.c - new file, converts unsigned long to string. hooks for `unsigned long long' in the future. unused as yet 10/15 ----- lib/readline/rltty.c - change the SET_SPECIAL macro to avoid possible (but highly unlikely) negative array subscripts error.h - add __attribute__ to extern declaration of itrace (even though the function isn't defined in released versions of bash) bashansi.h - include if HAVE_STRINGS_H is defined, to get any extra function declarations provided therein copy_cmd.c - fix typo in forward declaration for copy_arith_for_command lib/malloc/stats.c - make the accumulators in _print_malloc_stats be `unsigned long' instead of `int' externs.h, sig.h - add `__noreturn__' gcc attribute to exit_shell and jump_to_top_level declarations lib/sh/mailstat.c, support/bashversion.c - include for some string function declarations lib/malloc/shmalloc.h - added extern declarations of functions that do malloc debugging lib/readline/{isearch,readline,vi_mode}.c - make sure we index into _rl_keymap with a non-negative index parse.y - make sure we index into sh_syntaxtab with a non-negative index lib/readline/vi_mode.c - bound the vi_mark_chars array with the number of characters between 'a' and 'z' rather than using a fixed amount - don't use _rl_lowercase_p when deciding whether the char read by rl_vi_set_mark is a valid mark; just use 'a' <= char <= 'z' lib/readline/chardefs.h - conditionally include memory.h and strings.h as in general.h - replace ISASCII with IN_CTYPE_DOMAIN like other GNU software - add defines for ISPRINT(c), ISLOWER(c) and ISUPPER(c) - fix defines for _rl_lowercase_p, _rl_uppercase_p, _rl_digit_p, _rl_pure_alphabetic, ALPHABETIC, _rl_to_upper, _rl_to_lower, and _rl_isident to work on systems with signed chars include/chartypes.h - replace ISASCII with IN_CTYPE_DOMAIN like other GNU software lib/sh/{strcasecmp,strtod,strtol}.c - don't pass possibly-negative characters to tolower() or toupper() lib/glob/strmatch.c - don't bother testing for isupper in FOLD; rely on TOLOWER macro from to do it - don't use local definitions of isblank, et al.; rely on macros from lib/readline/{display,readline}.c, mksyntax.c - use new ISPRINT macro instead of isprint() builtins/{kill.def,mkbuiltins.c},{error,execute_cmd,jobs,nojobs,subst}.c - don't assume that a pid_t fits into an int for printing and other uses variables.[ch] - the unused put_gnu_argv_flags_into_env now takes a `long' pid argument configure.in, config.h.in - call AC_STRUCT_ST_BLOCKS, define HAVE_STRUCT_STAT_ST_BLOCKS if found - check for strtoull(), define HAVE_STRTOULL if found - check for uintmax_t, define to `unsigned long' if not found lib/sh/mailstat.c - don't use st_blocks member of struct stat unless HAVE_STRUCT_STAT_ST_BLOCKS is defined; otherwise use the st_nlink field to return the total number of messages in a maildir-style mail directory general.h,{alias,expr,general,subst,variables}.c builtins/{printf,read}.def lib/readline/{bind,complete,nls}.c lib/sh/{pathcanon,pathphys,shquote,snprintf,strindex,strtod,strtol,strtrans}.c - cast args to ctype macros to unsigned char for systems with signed chars; other fixes for signed chars lib/sh/{fmtullong,strtoull.c} - new files, more support for `long long' Makefile.in, lib/sh/Makefile.in - make fmtullong.o and strtoull.o part of libsh lib/sh/itos.c - remove local copy of fmtlong; use fmtulong instead - new functions: uitos, uinttostr work on `unsigned long' lib/sh/snprintf.c - fixes to make `unsigned long long' work (%llu) - fixes to make unsigned formats not print the sign when given an unsigned long that is greater than LONG_MAX externs.h - extern declarations for fmtulong, fmtulloing, strtoull - extern declarations for uitos, uinttostr 10/16 ----- configure.in - move header checks before function checks - move c compiler tests before header checks - check for with BASH_HEADER_INTTYPES - change type checks for intmax_t, uintmax_t to not attempt to include - check for strtoimax, strtoumax, strtoll, strtol, strtoull, strtoul with BASH_CHECK_DECL (for declarations in header files) and AC_REPLACE_FUNCS (for availability and LIBOBJS substitution) - remove check for have_long_long around sizeof check for long long (since autoconf will give it a size of 0 if the type isn't found) config.h.in - add a define for HAVE_INTTYPES_H - add a define for HAVE_UNSIGNED_LONG_LONG - add defines for HAVE_STRTOIMAX, HAVE_STRTOUMAX, HAVE_STRTOLL aclocal.m4 - new func, BASH_HEADER_INTTYPES, which just calls AC_CHECK_HEADERS on ; separate so it can be AC_REQUIREd - AC_REQUIRE([BASH_HEADER_INTTYPES]) in BASH_CHECK_TYPE - include in BASH_CHECK_TYPE if HAVE_INTTYPES_H is defined - change AC_DEFINE to AC_DEFINE_UNQUOTED in BASH_CHECK_TYPE - new `long long' checking macros: BASH_TYPE_LONG_LONG and BASH_TYPE_UNSIGNED_LONG_LONG - new BASH_CHECK_DECL lib/sh/{strto[iu]max,strtoll}.c, lib/sh/Makefile.in, Makefile.in - new files externs.h - extern declarations for strtoll, strtoimax, strtoumax lib/malloc/alloca.c - include for size_t builtins/printf.def - new functions: getllong, getullong, getintmax, getuintmax; return long long, unsigned long long, intmax_t, uintmax_t respectively - builtin printf now handles `ll' and `j' length modifiers directly lib/sh/Makefile.in - use LIBOBJS to decide whether or not the strto* functions are needed 10/17 ----- configure.in - call AC_REPLACE_FUNCS(rename) - move getcwd, strpbrk, strcasecmp, strerror, strtod from AC_CHECK_FUNCS to AC_REPLACE_FUNCS - only call BASH_FUNC_GETCWD if $ac_func_getcwd == "yes" - call BASH_CHECK_SYS_SIGLIST - if we don't have vprintf but have _doprnt, call AC_LIBOBJ(vprint) lib/sh/Makefile.in - remove rename, getcwd, inet_aton, strpbrk, strcasecmp, strerror, strtod, vprint from OBJECTS; picked up from LIBOBJS aclocal.m4 - change BASH_FUNC_GETCWD to call AC_LIBOBJ(getcwd) if the libc getcwd(3) calls popen(3) - change BASH_FUNC_INET_ATON to call AC_LIBOBJ(inet_aton) if it's not found in libc or as a #define even with the special includes - BASH_KERNEL_RLIMIT_CHECK -> BASH_CHECK_KERNEL_RLIMIT - BASH_DEFAULT_MAILDIR -> BASH_SYS_DEFAULT_MAILDIR - BASH_JOB_CONTROL_MISSING -> BASH_SYS_JOB_CONTROL_MISSING - BASH_REINSTALL_SIGHANDLERS -> BASH_SYS_REINSTALL_SIGHANDLERS - BASH_SIGNAL_CHECK -> BASH_SYS_SIGNAL_VINTAGE - BASH_DUP2_CLOEXEC_CHECK -> BASH_FUNC_DUP2_CLOEXEC_CHECK - BASH_PGRP_SYNC -> BASH_SYS_PGRP_SYNC - BASH_RLIMIT_TYPE -> BASH_TYPE_RLIMIT - BASH_FUNC_PRINTF -> BASH_DECL_PRINTF - BASH_FUNC_SBRK_DECLARED -> BASH_DECL_SBRK - BASH_MISC_SPEED_T -> BASH_CHECK_SPEED_T - BASH_CHECK_SOCKLIB -> BASH_CHECK_LIB_SOCKET - new macro, BASH_CHECK_SYS_SIGLIST, encapsulates all the checks for sys_siglist, _sys_siglist, and strsignal(), sets SIGLIST_O to siglist.o if appropriate Makefile.in - use SIGLIST_O variable to decide whether or not we need siglist.o {execute_cmd,subst}.c - change a couple of instances of ISDIGIT to DIGIT, where we really, really only want ascii digits ansi_stdlib.h - don't need a declaration for atol() 10/18 ----- aclocal.m4 - new macro, BASH_FUNC_PRINTF_A_FORMAT, checks for printf support for %a, %A conversion specifiers, defines HAVE_PRINTF_A_FORMAT if successful configure.in - call AC_CHECK_FUNCS for isascii - call BASH_FUNC_PRINTF_A_FORMAT config.h.in - add a define for HAVE_ISASCII - add a define for HAVE_PRINTF_A_FORMAT lib/sh/snprintf.c - for long double output, fall back to sprintf using ldfallback() function for floating point formats - support %a, %A using dfallback() or ldfallback() if HAVE_PRINTF_A_FORMAT is defined - fix bug in vasprintf that returned wrong value in its first argument if the buffer holding the result string got reallocated - fixed PUT_CHAR macro to increment the counter even if we've exceeded the buffer size, for the return value from vsnprintf/snprintf - fix vsnprintf_internal to not use counter < length as a loop condition, but always process the entire format string (for the return value from vsnprintf/snprintf) builtins/printf.def - support %a, %A if HAVE_PRINTF_A_FORMAT is defined include/typemax.h - new file, with the TYPE_MAXIMUM stuff that's duplicated in several files in lib/sh lib/sh/{fmtulong,strtol,snprintf}.c - include instead of having the definitions in each file lib/sh/Makefile.in - updated dependencies for typemax.h 10/22 ----- configure.in - call AC_CHECK_FUNCS on ctype.h functions/macros that bash redefines in chartypes.h config.h.in - defines for HAVE_IS{ASCII,BLANK,GRAPH,PRINT,SPACE,XDIGIT} include/chartypes.h, lib/glob/strmatch.c, lib/readline/chardefs.h - don't redefine some is* ctype macros/functions if HAVE_ISXXX is defined (meaning that an appropriate function, but not a macro, exists) lib/sh/strtrans.c - new function, ansic_shouldquote, returns 1 if argument string contains non-printing chars that should be quoted with $'...' externs.h - new declaration for ansic_shouldquote() variables.c - change print_var_value to ansi C quote the string if we're not in posix mode and the variable's value contains non-printing chars, to use the regular shell single quoting if the value contains shell meta-characters, and to just output the string otherwise lib/sh/shquote.c - add `break' to `case '~':' to avoid fallthrough and extra test doc/bashref.texi - note that in POSIX mode, `set' displays variable values that include nonprinting characters without quoting, unless they contain shell metacharacters builtins/printf.def, lib/sh/snprintf.c - handle `F' conversion specifier as equivalent to 'f' parse.y, {nojobs,variables}.c - a couple of cleanups for when building a minimal configuration nojobs.c - new function: stop_making_children(), just sets already_making_children to 0 (like stop_pipeline) subst.c - call stop_making_children from subst.c:command_substitute if JOB_CONTROL is not defined. This fixes the bug where the wrong process is waited for (and its status returned) when using command substitution in a null command in a shell function builtins/printf.def - new variable `tw' used to keep track of the total number of characters written by a single call to `printf' -- to be used for the `%n' conversion, which will be added later. It gets reset each time we reuse the format string, which is what ksh93 seems to do 10/23 ----- variables.c - new function, bind_var_to_int (char *var, long val) variables.h - extern declaration for bind_var_to_int lib/sh/netopen.c - use gai_strerror() for error messages when getaddrinfo() fails - use PF_INET if DEBUG is defined, since IPv6 doesn't work for me Makefile.in - pass DEBUG=${DEBUG} down to makes in some subdirectories {builtins,lib{glob,sh}}/Makefile.in - append ${DEBUG} to LOCAL_CFLAGS value, passed by top-level Makefile builtins/printf.def - added support for %n format conversion char (number of chars printed so far from current format string) 10/24 ----- variables.c - if posixly_correct is set, the default value of $MAILCHECK is 600 - use legal_number instead of atoi in adjust_shell_level - treat non-numeric assignments to SECONDS as 0 in assign_seconds - new function, init_funcname_var; sets FUNCNAME as a dynamic variable if it's not set in the initial environment - new function, init_groups_var; sets GROUPS as a dynamic array variable if it's not set in the initial environment - new function, init_dirstack_var; sets DIRSTACK as a dynamic array variable if it's not set in the initial environment - new function, init_seconds_var; sets SECONDS as a dynamic variable using any valid integer value in the initial environment as the initial value, as if an assignment had been performed - call init_funcname_var, init_groups_var, init_dirstack_var, init_seconds_var from initialize_dynamic_variables - non-numeric values assigned to LINENO are treated as 0 - change initialize_shell_variables to not auto-export PATH or TERM - change set_home_var to not auto-export HOME - change set_shell_var to not auto-export SHELL - broke the code that sets HOSTNAME, HOSTTYPE, MACHTYPE, OSTYPE out into a separate function, set_machine_vars; none of those variables are auto-exported - bash no longer un-exports SSH_CLIENT or SSH2_CLIENT shell.c - changed isnetconn() to check SSH_CLIENT and SSH2_CLIENT only if SSH_SOURCE_BASHRC is defined in config-top.h config-top.h - added a commented-out definition for SSH_SOURCE_BASHRC 10/25 ----- Makefile.in - changed RELSTATUS to `rc1' (release candidate 1) 10/29 ----- locale.c - fixed an `=' vs. `==' typo in set_locale_var when parsing LC_NUMERIC doc/{bash.1,bashref.texi} - document what bash does with $POSIXLY_CORRECT doc/builtins.1 - some updates builtins/psize.sh - some mktemp(1) changes lib/readline/readline.c - change rl_backward to check for rl_point < 0 and reset to 0 if so lib/readline/util.c - don't compile in _rl_strpbrk if HAVE_STRPBRK is defined lib/readline/rlprivate.h - remove extern declaration of _rl_strpbrk lib/readline/rldefs.h - #define _rl_strpbrk as strpbrk if HAVE_STRPBRK is define, otherwise add extern declaration of _rl_strpbrk from rlprivate.h {mailcheck,shell,variables}.c - make sure to include posixtime.h to get any prototype for time(3) in scope {array,eval,execute_cmd,mksyntax,subst}.c, parse.y builtins/common.c lib/sh/pathcanon.c - a few changes as the result of `gcc -Wall' patches from solar designer builtins/read.def, parse.y - change some calls to free() to xfree() builtins/set.def - make sure unset_builtin() resets unset_array to 0 each time through the loop, because it's set (and used) depending on the current argument shell.h - new define, USE_VAR, to force the compiler to not put a particular variable in a register -- helpful if registers are not restored by setjmp/longjmp builtins/{evalfile.c,{read,wait}.def}, {eval,execute_cmd,shell,test}.c - use USE_VAR for some variables subst.c - fixed a case in expand_word_internal where a NULL pointer could have been passed to free() (though free() should ignore it) - fixed a case at the end of expand_word_internal where LIST could have been used uninitialized (it makes gcc happy, though it doesn't happen in practice) test.c - give test_syntax_error(), beyond(), and integer_expected_error() the `__noreturn__' attribute for gcc unwind_prot.c - in clear_unwind_protect_list(), convert `flags' to `long' (via assignment to a `long' variable) before casting to `char *', in case pointers and longs are 64 bits and ints are 32 (makes no difference on 32-bit machines) 10/30 ----- print_cmd.c - fixed cprintf to avoid gcc warning about assigning const pointer to non-const (discarding type qualifier) {make_cmd,pcomplete,test}.c,parse.y - some minor changes to shut up gcc warnings lib/sh/tmpfile.c - fixed sh_mktmpfp to avoid file descriptor leaks in the case that sh_mktmpfd succeeds but fdopen fails for some reason - change sh_mktmpfd to use the same scheme for computing `filenum' as sh_mktmpname - change get_sys_tmpdir to prefer P_tmpdir if P_tmpdir is defined - changed sh_mktmpname and sh_mktmpfd to avoid trying to assign to `nameroot' if `nameroot == 0' (duh) - add code to sh_mktmpfd to use mkstemp(3) if USE_MKSTEMP is defined - add code to sh_mktmpname to use mktemp(3) if USE_MKTEMP is defined support/{fixlinks,mkclone} - use mktemp if it's available for the symlink test - use $TMPDIR instead of hardcoding /tmp; default to /tmp - use a better filename for the symlink test instead of `z' support/bashbug.sh - more changes inspired by a patch from solar designer lib/malloc/Makefile.in - new target `alloca', which builds libmalloc.a with alloca.o only (for systems without alloca that are configured --without-bash-malloc) configure.in - if we don't have a working alloca and are not configured to build the bash malloc library, make a malloc library containing only alloca.o aclocal.m4 - slight change to RL_LIB_READLINE_VERSION to deal with minor version numbers with a letter appended (like 4.2a) 10/31 ----- doc/{bash.1,bashref.texi} - slight change to note that only interactive shells resend a SIGHUP to all jobs before exiting externs.h - declare strto[ui]max only if NEED_STRTOIMAX_DECL is defined. This keeps picky compilers from choking because intmax_t is not defined (MacOS X 10.1) builtins/printf.def - #define NEED_STRTOIMAX_DECL before including shell.h 11/1 ---- general.c - check in bash_tilde_expand() for an unquoted tilde-prefix; don't bother passing the string to tilde_expand unless the prefix is unquoted shell.c - fix a problem with $LINENO when executing commands supplied with the -c invocation option when ONESHOT is defined [bash-2.05a-rc1 frozen] builtins/printf.def - fix the %n conversion to require that the variable name supplied be a valid shell identifier variables.c - improve random number generator slightly by using the upper 16 bits of the running random number instead of the lower 16, which are incrementally more random 11/2 ---- configure.in - if RL_INCLUDEDIR ends up being /usr/include, don't put -I$(RL_INCLUDEDIR) into CFLAGS 11/5 ---- doc/{bash.1,bashref.texi} - correct description of POSIXLY_CORRECT to note that the shell enters posix mode *before* the startup files are read if POSIXLY_CORRECT is in the initial environment variables.c - fix function prologues for init_dirstack_var and init_groups_var to agree with caller (no arguments) jobs.c - fix forward function declarations for pipe_read and pipe_close subst.c - removed `inline' attribute from skip_double_quoted because it can potentially be called recursively bashline.c - quick fix to bashline.c:attempt_shell_completion programmable completion code to just punt if the end of the command word found by find_cmd_end is <= the start found by find_cmd_start (the bug is probably in find_cmd_start -- fix later) pcomplete.c - fix gen_matches_from_itemlist to return if the stringlist is null after any cleaning or initialization, before trying to use it - fix GEN_COMPS to only bother to try to append the STRINGLIST returned by gen_matches_from_itemlist to `glist' if it's non-NULL lib/sh/stringlist.c - make copy_stringlist return NULL if the STRINGLIST * passed as an argument is NULL - make append_stringlist call copy_stringlist only if M2 is non-NULL; otherwise just return NULL if m1 is NULL - make word_list_to_stringlist return 0 immediately if the passed LIST argument is NULL - make realloc_stringlist call alloc_stringlist if the passed STRINGLIST argument (`sl') is 0, just like realloc calls malloc subst.c - in skip_to_delim(), if we have an unclosed ${, and it's at the end of the string (string[i] == '{', string[i+1] == '{' and string[i+2] == 0, return si (i +2) immediately without bothering to call extract_dollar_brace_string or extract_delimited_string - in skip_to_delim(), if string[i] is 0 after a call to extract_dollar_brace_string or extract_delimited_string (meaning we have an unclosed ${ or other expansion, return i immediately without doing a `continue' (which will increment i past the end of string) - in split_at_delims, don't increment te by 1 if it's pointing to a delimiter. this has the effect of skipping the first delimiter char in a possibly multi-character delimiter, and ignoring single-char delimiters like `>' configure.in - use AC_CHECK_MEMBERS([struct stat.st_blocks]) instead of a call to AC_STRUCT_ST_BLOCKS to avoid configure changing LIBOBJS if the test fails general.c - introduce two new variables: bash_tilde_{prefixes,suffixes}, set to the additional prefixes and suffixes bash wants to pass to the tilde expansion code (reserved for post-bash-2.05a fix) aclocal.m4 - add missing `test' in BASH_CHECK_SYS_SIGLIST 11/7 ---- lib/readline/vi_mode.c - fix rl_vi_goto_mark to explicitly check that the desired mark is between 'a' and 'z', since some locales have lowercase letters outside that range, which could cause a negative subscript include/chartypes.h - remove superfluous `#undef ISASCII' lib/sh/strto[iu]max.c - changes from Paul Eggert to work around buggy compilers and catch configuration errors at compile time aclocal.m4 - new macro, BASH_C_LONG_DOUBLE, identical to AC_C_LONG_DOUBLE but with a fix for Irix 5.3 (not called, since I'm not sure it's the right thing to do -- the C standard allows double and long double to be the same size) lib/sh/snprintf.c - only try to write the trailing NUL in vsnprintf_internal if data->length is >= 0, since if it's not, we probably don't have a buffer Makefile.in - changed RELSTATUS to `release' 11/8 ---- lib/sh/strtol.c - make sure chars passed to toupper are cast to unsigned unwind_prot.c - change clear_unwind_protect_list to not require a cast from `int' to `char *' lib/readline/chardefs.h - make _rl_digit_p succeed only for ascii digits, since that's what most callers assume bash-2.05a/CWRU/sh-redir-hack100664 436 12 546 5564440246 14255 0ustar chetlstaffAdd to `subshell' production in parse.y and recompile -DREDIRECTION_HACK to get `< xx (command)' sh compatibility. | redirections '(' list ')' { #if defined (REDIRECTION_HACK) /* XXX - C News sh compatibility hack - XXX */ $3->redirects = $1; $3->flags |= CMD_WANT_SUBSHELL; $$ = $3; #else yyerror (); YYABORT; #endif } bash-2.05a/CWRU/mh-folder-comp100644 436 0 30432 5747231557 14310 0ustar chetwheelFrom jwe@che.utexas.edu Wed Sep 21 17:23:40 1994 Flags: 10 Return-Path: jwe@che.utexas.edu Received: from po.CWRU.Edu (root@po.CWRU.Edu [129.22.4.2]) by odin.INS.CWRU.Edu with ESMTP (8.6.8.1+cwru/CWRU-2.1-ins) id RAA04010; Wed, 21 Sep 1994 17:23:39 -0400 (from jwe@che.utexas.edu for ) Received: from life.ai.mit.edu (life.ai.mit.edu [128.52.32.80]) by po.CWRU.Edu with SMTP (8.6.8.1+cwru/CWRU-2.2) id RAA02121; Wed, 21 Sep 1994 17:23:28 -0400 (from jwe@che.utexas.edu for ) Received: from schoch.che.utexas.edu by life.ai.mit.edu (4.1/AI-4.10) for chet@po.cwru.edu id AA09989; Wed, 21 Sep 94 17:23:17 EDT Received: from localhost (jwe@localhost) by schoch.che.utexas.edu (8.6.8.1/8.6) with SMTP id QAA05737; Wed, 21 Sep 1994 16:22:01 -0500 Message-Id: <199409212122.QAA05737@schoch.che.utexas.edu> To: march@tudor.com Cc: bug-bash@prep.ai.mit.edu Subject: Re: Completion feature possible? In-Reply-To: Your message of 21 Sep 94 13:30:22 EDT Date: Wed, 21 Sep 94 16:22:00 EDT From: John Eaton Gregory F. March wrote: : I was having a discussion about MH with one of my friends the other : day and I got to thinking that the +folder/subfolder scheme for naming : mail folders is a real pain because completion doesn't work on : them. Someone then mentioned that zsh (I think) has the ability to : specify how to complete (I guess where to look for the files) for : different prefixes. Bash right now knows about '@', '~', and '$' (any : others?). It would be really helpful if one could define something : like: : : completion '+' "$HOME/Mail" : : in a config file someplace. Would this be easy? Is there a list of : TODO item that someone might want to add this to? It would be nice to have a general completion feature like this. Until that happens, maybe you will find the following patch useful. It makes MH folder name completion work with bash. The diffs are relative to version 1.14.2. I realize that changes to readline.c and and complete.c are not good since they add some MH-specific stuff to the readline code and not to bash, but when I first wrote this, I had no idea what else to do. Chet, would you consider adding this if it were cleaned up a bit? Made optional with cpp conditionals? This feature has been very useful to me for the last several years (since about 1.05 or 1.06, I think). Thanks, -- John W. Eaton | 4.3BSD is not perfect. -- Leffler, et al. (1989). jwe@che.utexas.edu | -------------------------------cut here------------------------------- diff -rc bash-1.14.2/bashline.c bash-1.14.2.local/bashline.c *** bash-1.14.2/bashline.c Wed Aug 3 09:32:45 1994 --- bash-1.14.2.local/bashline.c Wed Sep 21 15:39:04 1994 *************** *** 58,63 **** --- 58,64 ---- static char *hostname_completion_function (); static char *command_word_completion_function (); static char *command_subst_completion_function (); + static char *mh_folder_completion_function (); static void snarf_hosts_from_file (), add_host_name (); static void sort_hostname_list (); *************** *** 90,95 **** --- 91,98 ---- bash_complete_username_internal (), bash_complete_hostname (), bash_possible_hostname_completions (), bash_complete_hostname_internal (), + bash_complete_mh_folder (), bash_possible_mh_folder_completions (), + bash_complete_mh_folder_internal (), bash_complete_variable (), bash_possible_variable_completions (), bash_complete_variable_internal (), bash_complete_command (), bash_possible_command_completions (), *************** *** 134,140 **** rl_terminal_name = get_string_value ("TERM"); rl_instream = stdin; rl_outstream = stderr; ! rl_special_prefixes = "$@"; /* Allow conditional parsing of the ~/.inputrc file. */ rl_readline_name = "Bash"; --- 137,143 ---- rl_terminal_name = get_string_value ("TERM"); rl_instream = stdin; rl_outstream = stderr; ! rl_special_prefixes = "$@+"; /* Allow conditional parsing of the ~/.inputrc file. */ rl_readline_name = "Bash"; *************** *** 193,198 **** --- 196,207 ---- rl_bind_key_in_map ('@', bash_possible_hostname_completions, emacs_ctlx_keymap); + rl_add_defun ("complete-mh-folder", bash_complete_mh_folder, META('+')); + rl_add_defun ("possible-mh-folder-completions", + bash_possible_mh_folder_completions, -1); + rl_bind_key_in_map ('+', bash_possible_mh_folder_completions, + emacs_ctlx_keymap); + rl_add_defun ("complete-variable", bash_complete_variable, -1); rl_bind_key_in_map ('$', bash_complete_variable, emacs_meta_keymap); rl_add_defun ("possible-variable-completions", *************** *** 656,661 **** --- 665,677 ---- if (!matches && *text == '@') matches = completion_matches (text, hostname_completion_function); + /* Another one. Why not? If the word starts in '+', then look for + matching mh folders for completion first. */ + if (!matches && *text == '+') + { + matches = completion_matches (text, mh_folder_completion_function); + } + /* And last, (but not least) if this word is in a command position, then complete over possible command names, including aliases, functions, and command names. */ *************** *** 1077,1082 **** --- 1093,1185 ---- return ((char *)NULL); } + /* How about a completion function for mh folders? */ + static char * + mh_folder_completion_function (text, state) + int state; + char *text; + { + extern int rl_filename_completion_desired; + + extern char *get_mh_path (); + + static char *mh_path = (char *)NULL; + static int len; + static int istate; + static char *val; + char *hint; + + static char *mh_folder_hint = (char *)NULL; + + /* If we don't have any state, make some. */ + if (!state) + { + val = (char *)NULL; + + if (mh_path) + free (mh_path); + + mh_path = get_mh_path (); + if (!mh_path && !(hint[1] == '/' || hint[1] == '.')) + return ((char *)NULL); + + len = strlen (mh_path); + } + + if (mh_folder_hint) + free (mh_folder_hint); + + hint = text; + if (*hint == '+') + hint++; + + mh_folder_hint = (char *)xmalloc (2 + len + strlen (hint)); + if (*hint == '/' || *hint == '.') { + len = -1; + sprintf (mh_folder_hint, "%s", hint); + } else + sprintf (mh_folder_hint, "%s/%s", mh_path, hint); + + istate = (val != (char *)NULL); + + again: + val = filename_completion_function (mh_folder_hint, istate); + istate = 1; + + if (!val) + { + return ((char *)NULL); + } + else + { + char *ptr = val + len + 1, *temp; + struct stat sb; + int status = stat (val, &sb); + + if (status != 0) + return ((char *)NULL); + + if ((sb.st_mode & S_IFDIR) == S_IFDIR) + { + temp = (char *)xmalloc (2 + strlen (ptr)); + *temp = '+'; + strcpy (temp + 1, ptr); + + free (val); + val = ""; + + rl_filename_completion_desired = 1; + + return (temp); + } + else + { + free (val); + } + goto again; + } + } + /* History and alias expand the line. */ static char * history_expand_line_internal (line) *************** *** 1628,1633 **** --- 1731,1773 ---- { bash_specific_completion (what_to_do, (Function *)username_completion_function); + } + + static void + bash_complete_mh_folder (ignore, ignore2) + int ignore, ignore2; + { + bash_complete_mh_folder_internal (TAB); + } + + static void + bash_possible_mh_folder_completions (ignore, ignore2) + int ignore, ignore2; + { + bash_complete_mh_folder_internal ('?'); + } + + static void + bash_complete_mh_folder_internal (what_to_do) + int what_to_do; + { + Function *orig_func; + CPPFunction *orig_attempt_func; + char *orig_rl_completer_word_break_characters; + extern char *rl_completer_word_break_characters; + + orig_func = rl_completion_entry_function; + orig_attempt_func = rl_attempted_completion_function; + orig_rl_completer_word_break_characters = rl_completer_word_break_characters; + rl_completion_entry_function = (Function *)mh_folder_completion_function; + rl_attempted_completion_function = (CPPFunction *)NULL; + rl_completer_word_break_characters = " \t\n\"\'"; + + rl_complete_internal (what_to_do); + + rl_completion_entry_function = orig_func; + rl_attempted_completion_function = orig_attempt_func; + rl_completer_word_break_characters = orig_rl_completer_word_break_characters; } static void Only in bash-1.14.2.local: bashline.c.orig diff -rc bash-1.14.2/lib/readline/complete.c bash-1.14.2.local/lib/readline/complete.c *** bash-1.14.2/lib/readline/complete.c Tue Jul 26 12:59:57 1994 --- bash-1.14.2.local/lib/readline/complete.c Wed Sep 21 15:41:19 1994 *************** *** 733,751 **** if (rl_filename_completion_desired) { struct stat finfo; ! char *filename = tilde_expand (matches[0]); ! if ((stat (filename, &finfo) == 0) && S_ISDIR (finfo.st_mode)) { ! if (rl_line_buffer[rl_point] != '/') ! rl_insert_text ("/"); } ! else { ! if (rl_point == rl_end) ! rl_insert_text (temp_string); } - free (filename); } else { --- 733,768 ---- if (rl_filename_completion_desired) { struct stat finfo; ! char *tilde_expand (); ! char *plus_expand (); ! char *filename = (char *) NULL; ! switch (*matches[0]) { ! case '+': ! filename = plus_expand (matches[0]); ! break; ! case '~': ! default: ! filename = tilde_expand (matches[0]); ! break; } ! ! if (filename) { ! if ((stat (filename, &finfo) == 0) ! && S_ISDIR (finfo.st_mode)) ! { ! if (rl_line_buffer[rl_point] != '/') ! rl_insert_text ("/"); ! } ! else ! { ! if (rl_point == rl_end) ! rl_insert_text (temp_string); ! } ! free (filename); } } else { Only in bash-1.14.2.local/lib/readline: diffs diff -rc bash-1.14.2/lib/readline/readline.c bash-1.14.2.local/lib/readline/readline.c *** bash-1.14.2/lib/readline/readline.c Fri Aug 12 12:47:46 1994 --- bash-1.14.2.local/lib/readline/readline.c Wed Sep 21 15:36:07 1994 *************** *** 23,28 **** --- 23,29 ---- #define READLINE_LIBRARY #include + #include #include #include #if !defined (NO_SYS_FILE) *************** *** 3518,3523 **** --- 3519,3616 ---- } #endif /* TEST */ + + #define cr_whitespace(c) ((c) == '\r' || (c) == '\n' || whitespace(c)) + + char * + get_mh_path () + { + static FILE *fp = (FILE *)NULL; + char buf[512]; /* XXX */ + char profile[512]; /* XXX */ + char *bp; + char *temp_home; + char *temp_path; + + temp_home = (char *)getenv ("HOME"); + if (!temp_home) + return ((char *)NULL); + + strcpy (profile, temp_home); + strcat (profile, "/.mh_profile"); + + if (fp) + fclose (fp); + + fp = fopen (profile, "r"); + if (fp == (FILE *)NULL) + return ((char *)NULL); + + while (fgets (buf, 512, fp) != (char *)NULL) /* XXX */ + { + if ((bp = strstr (buf, "Path:")) != (char *)NULL) + { + bp += 5; + while (whitespace (*bp)) + bp++; + + if (*bp == '\0') + return ((char *)NULL); + + temp_path = (char *)xmalloc (3 + strlen (bp) + strlen (temp_home)); + + strcpy (temp_path, temp_home); + strcat (temp_path, "/"); + strcat (temp_path, bp); + + bp = temp_path; + + while (!(cr_whitespace (*bp))) + bp++; + + *bp = '\0'; + + return temp_path; + } + } + + return ((char *)NULL); + } + + /* Expand FILENAME if it begins with a plus. This always returns + a new string. */ + char * + plus_expand (filename) + char *filename; + { + static char *dirname = (char *)NULL; + + if (filename && *filename == '+') + { + char *mh_path = get_mh_path (); + + if (filename[1] == '/' || filename[1] == '.') + { + dirname = (char *)xmalloc (1 + strlen (filename)); + + strcpy(dirname, filename+1); + + return dirname; + } + + if (mh_path) + { + dirname = (char *)xmalloc (1 + strlen (filename) + strlen (mh_path)); + + strcpy (dirname, mh_path); + strcat (dirname, "/"); + strcat (dirname, filename+1); + + return dirname; + } + } + return (char *)NULL; + } /* bash-2.05a/builtins/ 40775 436 0 0 7373775235 12513 5ustar chetwheelbash-2.05a/builtins/Makefile.in100664 436 0 64574 7365333662 14710 0ustar chetwheel# This Makefile for building libbuiltins.a is in -*- text -*- for Emacs. # # Copyright (C) 1996 Free Software Foundation, Inc. # This program is free software; you can redistribute it and/or modify # it under the terms of the GNU General Public License as published by # the Free Software Foundation; either version 2, or (at your option) # any later version. # This program is distributed in the hope that it will be useful, # but WITHOUT ANY WARRANTY; without even the implied warranty of # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the # GNU General Public License for more details. # You should have received a copy of the GNU General Public License # along with this program; if not, write to the Free Software # Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111 USA. # SHELL = @MAKE_SHELL@ RANLIB = @RANLIB@ CC = @CC@ CC_FOR_BUILD = @CC_FOR_BUILD@ AR = @AR@ ARFLAGS = @ARFLAGS@ RM = rm -f CP = cp EXEEXT = @EXEEXT@ srcdir = @srcdir@ VPATH = .:@srcdir@ topdir = @top_srcdir@ includedir = @includedir@ BUILD_DIR = @BUILD_DIR@ PROFILE_FLAGS = @PROFILE_FLAGS@ CFLAGS = @CFLAGS@ LOCAL_CFLAGS = @LOCAL_CFLAGS@ ${DEBUG} CPPFLAGS = @CPPFLAGS@ DEFS = @DEFS@ LOCAL_DEFS = @LOCAL_DEFS@ LDFLAGS = @LDFLAGS@ $(LOCAL_LDFLAGS) $(CFLAGS) LOCAL_LDFLAGS = @LOCAL_LDFLAGS@ LIBS = @LIBS@ BASHINCDIR = ${topdir}/include RL_INCLUDEDIR = @RL_INCLUDEDIR@ INCLUDES = -I. -I.. @RL_INCLUDE@ -I$(topdir) -I$(BASHINCDIR) -I$(topdir)/lib -I$(srcdir) CCFLAGS_FOR_BUILD = ${PROFILE_FLAGS} $(DEFS) $(LOCAL_DEFS) $(SYSTEM_FLAGS) \ $(CPPFLAGS) ${INCLUDES} $(LOCAL_CFLAGS) CCFLAGS = $(CCFLAGS_FOR_BUILD) $(CFLAGS) GCC_LINT_FLAGS = -Wall -Wshadow -Wpointer-arith -Wcast-qual \ -Wcast-align -Wstrict-prototypes -Wconversion \ -Wmissing-prototypes -Wtraditional -Wredundant-decls -pedantic MKBUILTINS = mkbuiltins$(EXEEXT) DIRECTDEFINE = -D $(srcdir) # xxx this is bad style RL_LIBSRC = $(topdir)/lib/readline .SUFFIXES: .SUFFIXES: .def .c .o # How to make a .o file from a .def file. .def.o: $(RM) $@ ./$(MKBUILTINS) $(DIRECTDEFINE) $< $(CC) -c $(CCFLAGS) $*.c || ( $(RM) $*.c ; exit 1 ) $(RM) $*.c # How to make a .c file from a .def file. .def.c: $(RM) $@ ./$(MKBUILTINS) $(DIRECTDEFINE) $< # default rule for making a .o file from a .c file .c.o: $(RM) $@ $(CC) -c $(CCFLAGS) $< DEFSRC = $(srcdir)/alias.def $(srcdir)/bind.def $(srcdir)/break.def \ $(srcdir)/builtin.def $(srcdir)/cd.def $(srcdir)/colon.def \ $(srcdir)/command.def $(srcdir)/declare.def $(srcdir)/echo.def \ $(srcdir)/enable.def $(srcdir)/eval.def $(srcdir)/getopts.def \ $(srcdir)/exec.def $(srcdir)/exit.def $(srcdir)/fc.def \ $(srcdir)/fg_bg.def $(srcdir)/hash.def $(srcdir)/help.def \ $(srcdir)/history.def $(srcdir)/jobs.def $(srcdir)/kill.def \ $(srcdir)/let.def $(srcdir)/read.def $(srcdir)/return.def \ $(srcdir)/set.def $(srcdir)/setattr.def $(srcdir)/shift.def \ $(srcdir)/source.def $(srcdir)/suspend.def $(srcdir)/test.def \ $(srcdir)/times.def $(srcdir)/trap.def $(srcdir)/type.def \ $(srcdir)/ulimit.def $(srcdir)/umask.def $(srcdir)/wait.def \ $(srcdir)/reserved.def $(srcdir)/pushd.def $(srcdir)/shopt.def \ $(srcdir)/printf.def $(srcdir)/complete.def STATIC_SOURCE = common.c evalstring.c evalfile.c getopt.c bashgetopt.c \ getopt.h OFILES = builtins.o \ alias.o bind.o break.o builtin.o cd.o colon.o command.o \ common.o declare.o echo.o enable.o eval.o evalfile.o \ evalstring.o exec.o \ exit.o fc.o fg_bg.o hash.o help.o history.o jobs.o kill.o let.o \ pushd.o read.o return.o set.o setattr.o shift.o source.o \ suspend.o test.o times.o trap.o type.o ulimit.o umask.o \ wait.o getopts.o shopt.o printf.o getopt.o bashgetopt.o complete.o CREATED_FILES = builtext.h builtins.c psize.aux pipesize.h all: $(MKBUILTINS) libbuiltins.a libbuiltins.a: $(MKBUILTINS) $(OFILES) builtins.o $(RM) $@ $(AR) $(ARFLAGS) $@ $(OFILES) -$(RANLIB) $@ builtext.h builtins.c: $(MKBUILTINS) $(DEFSRC) @-if test -f builtins.c; then mv -f builtins.c old-builtins.c; fi @-if test -f builtext.h; then mv -f builtext.h old-builtext.h; fi ./$(MKBUILTINS) -externfile builtext.h -structfile builtins.c \ -noproduction $(DIRECTDEFINE) $(DEFSRC) @-if cmp -s old-builtext.h builtext.h 2>/dev/null; then \ mv old-builtext.h builtext.h; \ else \ $(RM) old-builtext.h; \ fi @-if cmp -s old-builtins.c builtins.c 2>/dev/null; then \ mv old-builtins.c builtins.c; \ else \ $(RM) old-builtins.c; \ fi mkbuiltins.o: ../config.h mkbuiltins.o: mkbuiltins.c $(RM) $@ $(CC_FOR_BUILD) -c $(CCFLAGS_FOR_BUILD) $< mkbuiltins$(EXEEXT): mkbuiltins.o $(CC_FOR_BUILD) $(PROFILE_FLAGS) $(LDFLAGS) -o $(MKBUILTINS) mkbuiltins.o $(LIBS) # rules for deficient makes, like SunOS mkbuiltins.o: mkbuiltins.c builtins.o: builtins.c common.o: common.c bashgetopt.o: bashgetopt.c getopt.o: getopt.c evalstring.o: evalstring.c evalfile.o: evalfile.c ulimit.o: pipesize.h pipesize.h: psize.aux $(SHELL) $(srcdir)/psize.sh > $@ psize.aux: psize.c $(CC_FOR_BUILD) $(CCFLAGS_FOR_BUILD) -o $@ $(srcdir)/psize.c documentation: builtins.texi $(OFILES): $(MKBUILTINS) ../config.h builtins.texi: $(MKBUILTINS) ./$(MKBUILTINS) -documentonly $(DEFSRC) clean: $(RM) $(OFILES) $(CREATED_FILES) $(MKBUILTINS) mkbuiltins.o libbuiltins.a mostlyclean: $(RM) $(OFILES) libbuiltins.a distclean maintainer-clean: clean $(RM) Makefile alias.o: alias.def bind.o: bind.def break.o: break.def builtin.o: builtin.def cd.o: cd.def colon.o: colon.def command.o: command.def declare.o: declare.def echo.o: echo.def enable.o: enable.def eval.o: eval.def exec.o: exec.def exit.o: exit.def fc.o: fc.def fg_bg.o: fg_bg.def hash.o: hash.def help.o: help.def history.o: history.def jobs.o: jobs.def kill.o: kill.def let.o: let.def printf.o: printf.def pushd.o: pushd.def read.o: read.def return.o: return.def set.o: set.def setattr.o: setattr.def shift.o: shift.def shopt.o: shopt.def source.o: source.def suspend.o: suspend.def test.o: test.def times.o: times.def trap.o: trap.def type.o: type.def ulimit.o: ulimit.def umask.o: umask.def wait.o: wait.def getopts.o: getopts.def reserved.o: reserved.def complete.o: complete.def # C files bashgetopt.o: ../config.h $(topdir)/bashansi.h $(BASHINCDIR)/ansi_stdlib.h bashgetopt.o: $(topdir)/shell.h $(topdir)/syntax.h $(topdir)/bashjmp.h bashgetopt.o: $(topdir)/command.h $(topdir)/general.h $(topdir)/xmalloc.h $(topdir)/error.h bashgetopt.o: $(topdir)/variables.h $(topdir)/conftypes.h $(topdir)/quit.h $(BASHINCDIR)/maxpath.h bashgetopt.o: $(topdir)/unwind_prot.h $(topdir)/dispose_cmd.h bashgetopt.o: $(topdir)/make_cmd.h $(topdir)/subst.h $(topdir)/sig.h bashgetopt.o: $(topdir)/pathnames.h $(topdir)/externs.h $(srcdir)/common.h bashgetopt.o: $(BASHINCDIR)/chartypes.h common.o: $(topdir)/bashtypes.h $(BASHINCDIR)/posixstat.h $(topdir)/bashansi.h $(BASHINCDIR)/ansi_stdlib.h common.o: $(topdir)/shell.h $(topdir)/syntax.h ../config.h $(topdir)/bashjmp.h $(BASHINCDIR)/posixjmp.h common.o: $(topdir)/sig.h $(topdir)/command.h common.o: $(topdir)/general.h $(topdir)/xmalloc.h $(BASHINCDIR)/stdc.h $(BASHINCDIR)/memalloc.h common.o: $(topdir)/variables.h $(topdir)/conftypes.h $(topdir)/input.h common.o: $(topdir)/siglist.h $(topdir)/bashhist.h $(topdir)/quit.h common.o: $(topdir)/unwind_prot.h $(BASHINCDIR)/maxpath.h $(topdir)/jobs.h common.o: $(topdir)/builtins.h $(topdir)/dispose_cmd.h $(topdir)/make_cmd.h common.o: $(topdir)/subst.h $(topdir)/execute_cmd.h $(topdir)/error.h common.o: $(topdir)/externs.h $(topdir)/pathnames.h ./builtext.h common.o: $(BASHINCDIR)/chartypes.h evalfile.o: $(topdir)/bashtypes.h $(BASHINCDIR)/posixstat.h ${BASHINCDIR}/filecntl.h evalfile.o: $(topdir)/bashansi.h $(BASHINCDIR)/ansi_stdlib.h evalfile.o: $(topdir)/shell.h $(topdir)/syntax.h ../config.h $(topdir)/bashjmp.h evalfile.o: $(topdir)/command.h $(topdir)/general.h $(topdir)/xmalloc.h $(topdir)/error.h evalfile.o: $(topdir)/variables.h $(topdir)/conftypes.h $(topdir)/quit.h $(BASHINCDIR)/maxpath.h evalfile.o: $(topdir)/unwind_prot.h $(topdir)/dispose_cmd.h evalfile.o: $(topdir)/make_cmd.h $(topdir)/subst.h $(topdir)/sig.h evalfile.o: $(topdir)/pathnames.h $(topdir)/externs.h evalfile.o: $(topdir)/jobs.h $(topdir)/builtins.h $(topdir)/flags.h evalfile.o: $(topdir)/input.h $(topdir)/execute_cmd.h evalfile.o: $(topdir)/bashhist.h $(srcdir)/common.h evalstring.o: ../config.h $(topdir)/bashansi.h $(BASHINCDIR)/ansi_stdlib.h evalstring.o: $(topdir)/shell.h $(topdir)/syntax.h $(topdir)/bashjmp.h $(BASHINCDIR)/posixjmp.h evalstring.o: $(topdir)/sig.h $(topdir)/command.h $(topdir)/siglist.h evalstring.o: $(BASHINCDIR)/memalloc.h $(topdir)/variables.h $(topdir)/conftypes.h $(topdir)/input.h evalstring.o: $(topdir)/quit.h $(topdir)/unwind_prot.h evalstring.o: $(BASHINCDIR)/maxpath.h $(topdir)/jobs.h $(topdir)/builtins.h evalstring.o: $(topdir)/dispose_cmd.h $(topdir)/make_cmd.h $(topdir)/subst.h evalstring.o: $(topdir)/externs.h $(topdir)/jobs.h $(topdir)/builtins.h evalstring.o: $(topdir)/flags.h $(topdir)/input.h $(topdir)/execute_cmd.h evalstring.o: $(topdir)/bashhist.h $(srcdir)/common.h evalstring.o: $(topdir)/trap.h $(topdir)/redir.h getopt.o: ../config.h $(BASHINCDIR)/memalloc.h getopt.o: $(topdir)/shell.h $(topdir)/syntax.h $(topdir)/bashjmp.h $(topdir)/command.h getopt.o: $(topdir)/general.h $(topdir)/xmalloc.h $(topdir)/error.h $(topdir)/variables.h $(topdir)/conftypes.h getopt.o: $(topdir)/quit.h $(BASHINCDIR)/maxpath.h $(topdir)/unwind_prot.h getopt.o: $(topdir)/dispose_cmd.h $(topdir)/make_cmd.h $(topdir)/subst.h getopt.o: $(topdir)/sig.h $(topdir)/pathnames.h $(topdir)/externs.h getopt.o: $(srcdir)/getopt.h mkbuiltins.o: ../config.h $(topdir)/bashtypes.h $(BASHINCDIR)/posixstat.h mkbuiltins.o: ${BASHINCDIR}/filecntl.h mkbuiltins.o: $(topdir)/bashansi.h $(BASHINCDIR)/ansi_stdlib.h # def files alias.o: $(topdir)/command.h ../config.h $(BASHINCDIR)/memalloc.h alias.o: $(topdir)/error.h $(topdir)/general.h $(topdir)/xmalloc.h $(BASHINCDIR)/maxpath.h alias.o: $(topdir)/quit.h $(topdir)/dispose_cmd.h $(topdir)/make_cmd.h alias.o: $(topdir)/subst.h $(topdir)/externs.h $(srcdir)/common.h alias.o: $(topdir)/shell.h $(topdir)/syntax.h $(topdir)/unwind_prot.h $(topdir)/variables.h $(topdir)/conftypes.h bind.o: $(topdir)/command.h ../config.h $(BASHINCDIR)/memalloc.h $(topdir)/error.h bind.o: $(topdir)/quit.h $(topdir)/dispose_cmd.h $(topdir)/make_cmd.h bind.o: $(topdir)/subst.h $(topdir)/externs.h $(srcdir)/bashgetopt.h bind.o: $(topdir)/general.h $(topdir)/xmalloc.h $(BASHINCDIR)/maxpath.h $(topdir)/bashline.h bind.o: $(topdir)/shell.h $(topdir)/syntax.h $(topdir)/unwind_prot.h $(topdir)/variables.h $(topdir)/conftypes.h break.o: $(topdir)/command.h ../config.h $(BASHINCDIR)/memalloc.h break.o: $(topdir)/error.h $(topdir)/general.h $(topdir)/xmalloc.h break.o: $(topdir)/quit.h $(topdir)/dispose_cmd.h $(topdir)/make_cmd.h break.o: $(topdir)/subst.h $(topdir)/externs.h $(BASHINCDIR)/maxpath.h break.o: $(topdir)/shell.h $(topdir)/syntax.h $(topdir)/unwind_prot.h $(topdir)/variables.h $(topdir)/conftypes.h builtin.o: $(topdir)/command.h ../config.h $(BASHINCDIR)/memalloc.h builtin.o: $(topdir)/error.h $(topdir)/general.h $(topdir)/xmalloc.h $(topdir)/externs.h builtin.o: $(topdir)/quit.h $(srcdir)/common.h $(BASHINCDIR)/maxpath.h builtin.o: $(topdir)/dispose_cmd.h $(topdir)/make_cmd.h $(topdir)/subst.h builtin.o: $(topdir)/shell.h $(topdir)/syntax.h $(topdir)/unwind_prot.h $(topdir)/variables.h $(topdir)/conftypes.h cd.o: $(topdir)/command.h ../config.h $(BASHINCDIR)/memalloc.h $(topdir)/error.h cd.o: $(topdir)/general.h $(topdir)/xmalloc.h $(topdir)/quit.h $(topdir)/dispose_cmd.h cd.o: $(topdir)/make_cmd.h $(topdir)/subst.h $(topdir)/externs.h cd.o: $(topdir)/shell.h $(topdir)/syntax.h $(topdir)/unwind_prot.h $(topdir)/variables.h $(topdir)/conftypes.h cd.o: $(srcdir)/common.h $(BASHINCDIR)/maxpath.h command.o: $(topdir)/command.h ../config.h $(BASHINCDIR)/memalloc.h command.o: $(topdir)/error.h $(topdir)/general.h $(topdir)/xmalloc.h $(topdir)/externs.h command.o: $(topdir)/quit.h $(srcdir)/bashgetopt.h $(BASHINCDIR)/maxpath.h command.o: $(topdir)/dispose_cmd.h $(topdir)/make_cmd.h $(topdir)/subst.h command.o: $(topdir)/shell.h $(topdir)/syntax.h $(topdir)/unwind_prot.h $(topdir)/variables.h $(topdir)/conftypes.h declare.o: $(topdir)/command.h ../config.h $(BASHINCDIR)/memalloc.h declare.o: $(topdir)/error.h $(topdir)/general.h $(topdir)/xmalloc.h declare.o: $(topdir)/quit.h $(topdir)/dispose_cmd.h $(topdir)/make_cmd.h declare.o: $(topdir)/subst.h $(topdir)/externs.h $(BASHINCDIR)/maxpath.h declare.o: $(topdir)/shell.h $(topdir)/syntax.h $(topdir)/unwind_prot.h $(topdir)/variables.h $(topdir)/conftypes.h declare.o: $(topdir)/arrayfunc.h echo.o: $(topdir)/command.h ../config.h $(BASHINCDIR)/memalloc.h $(topdir)/error.h echo.o: $(topdir)/general.h $(topdir)/xmalloc.h $(topdir)/subst.h $(topdir)/externs.h echo.o: $(topdir)/quit.h $(topdir)/dispose_cmd.h $(topdir)/make_cmd.h echo.o: $(topdir)/shell.h $(topdir)/syntax.h $(topdir)/unwind_prot.h $(topdir)/variables.h $(topdir)/conftypes.h echo.o: $(BASHINCDIR)/maxpath.h enable.o: $(topdir)/command.h ../config.h $(BASHINCDIR)/memalloc.h enable.o: $(topdir)/error.h $(topdir)/general.h $(topdir)/xmalloc.h enable.o: $(topdir)/quit.h $(topdir)/dispose_cmd.h $(topdir)/make_cmd.h enable.o: $(topdir)/subst.h $(topdir)/externs.h enable.o: $(topdir)/shell.h $(topdir)/syntax.h $(topdir)/unwind_prot.h $(topdir)/variables.h $(topdir)/conftypes.h enable.o: $(BASHINCDIR)/maxpath.h enable.o: $(topdir)/pcomplete.h eval.o: $(topdir)/command.h ../config.h $(BASHINCDIR)/memalloc.h eval.o: $(topdir)/error.h $(topdir)/general.h $(topdir)/xmalloc.h eval.o: $(topdir)/quit.h $(topdir)/dispose_cmd.h $(topdir)/make_cmd.h eval.o: $(topdir)/subst.h $(topdir)/externs.h eval.o: $(topdir)/shell.h $(topdir)/syntax.h $(topdir)/unwind_prot.h $(topdir)/variables.h $(topdir)/conftypes.h eval.o: $(BASHINCDIR)/maxpath.h exec.o: $(topdir)/bashtypes.h exec.o: $(topdir)/command.h ../config.h $(BASHINCDIR)/memalloc.h exec.o: $(topdir)/error.h $(topdir)/general.h $(topdir)/xmalloc.h exec.o: $(topdir)/quit.h $(topdir)/dispose_cmd.h $(topdir)/make_cmd.h exec.o: $(topdir)/subst.h $(topdir)/externs.h $(topdir)/flags.h exec.o: $(topdir)/shell.h $(topdir)/syntax.h $(topdir)/unwind_prot.h $(topdir)/variables.h $(topdir)/conftypes.h exec.o: $(srcdir)/common.h $(topdir)/execute_cmd.h $(BASHINCDIR)/maxpath.h exec.o: $(topdir)/findcmd.h exit.o: $(topdir)/bashtypes.h exit.o: $(topdir)/command.h ../config.h $(BASHINCDIR)/memalloc.h exit.o: $(topdir)/error.h $(topdir)/general.h $(topdir)/xmalloc.h exit.o: $(topdir)/quit.h $(topdir)/dispose_cmd.h $(topdir)/make_cmd.h exit.o: $(topdir)/subst.h $(topdir)/externs.h exit.o: $(topdir)/shell.h $(topdir)/syntax.h $(topdir)/unwind_prot.h $(topdir)/variables.h $(topdir)/conftypes.h exit.o: $(BASHINCDIR)/maxpath.h ./builtext.h fc.o: $(topdir)/bashtypes.h $(BASHINCDIR)/posixstat.h fc.o: $(topdir)/builtins.h $(topdir)/command.h $(srcdir)/bashgetopt.h fc.o: $(topdir)/bashhist.h fc.o: $(topdir)/command.h ../config.h $(BASHINCDIR)/memalloc.h $(topdir)/error.h fc.o: $(topdir)/general.h $(topdir)/xmalloc.h $(BASHINCDIR)/maxpath.h fc.o: $(topdir)/quit.h $(topdir)/dispose_cmd.h $(topdir)/make_cmd.h fc.o: $(topdir)/subst.h $(topdir)/externs.h $(topdir)/shell.h $(topdir)/syntax.h fc.o: $(topdir)/flags.h $(topdir)/unwind_prot.h $(topdir)/variables.h $(topdir)/conftypes.h fc.o: $(topdir)/bashansi.h $(BASHINCDIR)/ansi_stdlib.h $(BASHINCDIR)/chartypes.h fg_bg.o: $(topdir)/bashtypes.h fg_bg.o: $(topdir)/command.h ../config.h $(BASHINCDIR)/memalloc.h fg_bg.o: $(topdir)/error.h $(topdir)/general.h $(topdir)/xmalloc.h fg_bg.o: $(topdir)/quit.h $(topdir)/dispose_cmd.h $(topdir)/make_cmd.h fg_bg.o: $(topdir)/subst.h $(topdir)/externs.h $(BASHINCDIR)/maxpath.h fg_bg.o: $(topdir)/shell.h $(topdir)/syntax.h $(topdir)/unwind_prot.h $(topdir)/variables.h $(topdir)/conftypes.h getopts.o: $(topdir)/command.h ../config.h $(BASHINCDIR)/memalloc.h getopts.o: $(topdir)/error.h $(topdir)/general.h $(topdir)/xmalloc.h getopts.o: $(topdir)/quit.h $(topdir)/dispose_cmd.h $(topdir)/make_cmd.h getopts.o: $(topdir)/subst.h $(topdir)/externs.h $(BASHINCDIR)/maxpath.h getopts.o: $(topdir)/shell.h $(topdir)/syntax.h $(topdir)/unwind_prot.h $(topdir)/variables.h $(topdir)/conftypes.h hash.o: $(topdir)/builtins.h $(topdir)/command.h $(topdir)/quit.h hash.o: $(topdir)/findcmd.h $(topdir)/hashlib.h hash.o: $(topdir)/command.h ../config.h $(BASHINCDIR)/memalloc.h hash.o: $(topdir)/error.h $(topdir)/general.h $(topdir)/xmalloc.h hash.o: $(topdir)/shell.h $(topdir)/syntax.h $(topdir)/unwind_prot.h $(topdir)/variables.h $(topdir)/conftypes.h hash.o: $(srcdir)/common.h $(BASHINCDIR)/maxpath.h help.o: $(topdir)/command.h ../config.h $(BASHINCDIR)/memalloc.h help.o: $(topdir)/error.h $(topdir)/general.h $(topdir)/xmalloc.h help.o: $(topdir)/quit.h $(topdir)/dispose_cmd.h $(topdir)/make_cmd.h help.o: $(topdir)/subst.h $(topdir)/externs.h $(BASHINCDIR)/maxpath.h help.o: $(topdir)/shell.h $(topdir)/syntax.h $(topdir)/unwind_prot.h $(topdir)/variables.h $(topdir)/conftypes.h help.o: ${srcdir}/common.h ../version.h history.o: $(topdir)/bashtypes.h history.o: $(topdir)/command.h ../config.h $(BASHINCDIR)/memalloc.h history.o: $(topdir)/error.h $(topdir)/general.h $(topdir)/xmalloc.h history.o: $(topdir)/quit.h $(topdir)/dispose_cmd.h $(topdir)/make_cmd.h history.o: $(topdir)/subst.h $(topdir)/externs.h history.o: ${BASHINCDIR}/filecntl.h $(topdir)/shell.h $(topdir)/syntax.h $(topdir)/unwind_prot.h history.o: $(topdir)/variables.h $(topdir)/conftypes.h $(topdir)/bashhist.h $(BASHINCDIR)/maxpath.h inlib.o: $(topdir)/command.h ../config.h $(BASHINCDIR)/memalloc.h inlib.o: $(topdir)/error.h $(topdir)/general.h $(topdir)/xmalloc.h inlib.o: $(topdir)/shell.h $(topdir)/syntax.h $(topdir)/unwind_prot.h $(topdir)/variables.h $(topdir)/conftypes.h inlib.o: $(BASHINCDIR)/maxpath.h $(topdir)/subst.h $(topdir)/externs.h inlib.o: $(topdir)/quit.h $(topdir)/dispose_cmd.h $(topdir)/make_cmd.h jobs.o: $(topdir)/command.h ../config.h $(BASHINCDIR)/memalloc.h $(topdir)/error.h jobs.o: $(topdir)/general.h $(topdir)/xmalloc.h $(topdir)/quit.h $(srcdir)/bashgetopt.h jobs.o: $(BASHINCDIR)/maxpath.h $(topdir)/externs.h jobs.o: $(topdir)/dispose_cmd.h $(topdir)/make_cmd.h $(topdir)/subst.h jobs.o: $(topdir)/shell.h $(topdir)/syntax.h $(topdir)/unwind_prot.h $(topdir)/variables.h $(topdir)/conftypes.h kill.o: $(topdir)/command.h ../config.h $(BASHINCDIR)/memalloc.h $(topdir)/error.h kill.o: $(topdir)/general.h $(topdir)/xmalloc.h $(topdir)/subst.h $(topdir)/externs.h kill.o: $(topdir)/quit.h $(topdir)/dispose_cmd.h $(topdir)/make_cmd.h kill.o: $(topdir)/shell.h $(topdir)/syntax.h $(topdir)/trap.h $(topdir)/unwind_prot.h kill.o: $(topdir)/variables.h $(topdir)/conftypes.h $(BASHINCDIR)/maxpath.h let.o: $(topdir)/command.h ../config.h $(BASHINCDIR)/memalloc.h let.o: $(topdir)/error.h $(topdir)/general.h $(topdir)/xmalloc.h let.o: $(topdir)/quit.h $(topdir)/dispose_cmd.h $(topdir)/make_cmd.h let.o: $(topdir)/subst.h $(topdir)/externs.h $(BASHINCDIR)/maxpath.h let.o: $(topdir)/shell.h $(topdir)/syntax.h $(topdir)/unwind_prot.h $(topdir)/variables.h $(topdir)/conftypes.h printf.o: ../config.h $(BASHINCDIR)/memalloc.h $(topdir)/bashjmp.h printf.o: $(topdir)/command.h $(topdir)/error.h $(topdir)/general.h $(topdir)/xmalloc.h printf.o: $(topdir)/quit.h $(topdir)/dispose_cmd.h $(topdir)/make_cmd.h printf.o: $(topdir)/subst.h $(topdir)/externs.h $(topdir)/sig.h printf.o: $(topdir)/pathnames.h $(topdir)/shell.h $(topdir)/syntax.h $(topdir)/unwind_prot.h printf.o: $(topdir)/variables.h $(topdir)/conftypes.h $(BASHINCDIR)/stdc.h $(srcdir)/bashgetopt.h printf.o: $(topdir)/bashtypes.h ${srcdir}/common.h $(BASHINCDIR)/chartypes.h pushd.o: $(topdir)/command.h ../config.h $(BASHINCDIR)/memalloc.h pushd.o: $(topdir)/error.h $(topdir)/general.h $(topdir)/xmalloc.h pushd.o: $(topdir)/quit.h $(topdir)/dispose_cmd.h $(topdir)/make_cmd.h pushd.o: $(topdir)/subst.h $(topdir)/externs.h pushd.o: $(topdir)/shell.h $(topdir)/syntax.h $(topdir)/unwind_prot.h $(topdir)/variables.h $(topdir)/conftypes.h pushd.o: $(BASHINCDIR)/maxpath.h $(srcdir)/common.h ./builtext.h read.o: $(topdir)/command.h ../config.h $(BASHINCDIR)/memalloc.h read.o: $(topdir)/error.h $(topdir)/general.h $(topdir)/xmalloc.h read.o: $(topdir)/quit.h $(topdir)/dispose_cmd.h $(topdir)/make_cmd.h read.o: $(topdir)/subst.h $(topdir)/externs.h $(BASHINCDIR)/maxpath.h read.o: $(topdir)/shell.h $(topdir)/syntax.h $(topdir)/unwind_prot.h $(topdir)/variables.h $(topdir)/conftypes.h read.o: $(BASHINCDIR)/shtty.h read.o: $(topdir)/arrayfunc.h return.o: $(topdir)/command.h ../config.h $(BASHINCDIR)/memalloc.h return.o: $(topdir)/error.h $(topdir)/general.h $(topdir)/xmalloc.h return.o: $(topdir)/quit.h $(topdir)/dispose_cmd.h $(topdir)/make_cmd.h return.o: $(topdir)/subst.h $(topdir)/externs.h $(BASHINCDIR)/maxpath.h return.o: $(topdir)/shell.h $(topdir)/syntax.h $(topdir)/unwind_prot.h $(topdir)/variables.h $(topdir)/conftypes.h set.o: $(topdir)/command.h ../config.h $(BASHINCDIR)/memalloc.h set.o: $(topdir)/general.h $(topdir)/xmalloc.h $(topdir)/subst.h $(topdir)/externs.h set.o: $(topdir)/quit.h $(topdir)/dispose_cmd.h $(topdir)/make_cmd.h set.o: $(topdir)/shell.h $(topdir)/syntax.h $(topdir)/unwind_prot.h $(topdir)/variables.h $(topdir)/conftypes.h set.o: $(BASHINCDIR)/maxpath.h $(topdir)/error.h set.o: $(topdir)/arrayfunc.h setattr.o: $(topdir)/command.h ../config.h $(BASHINCDIR)/memalloc.h setattr.o: $(topdir)/error.h $(topdir)/general.h $(topdir)/xmalloc.h $(BASHINCDIR)/maxpath.h setattr.o: $(topdir)/quit.h $(srcdir)/common.h $(srcdir)/bashgetopt.h setattr.o: $(topdir)/dispose_cmd.h $(topdir)/make_cmd.h $(topdir)/subst.h setattr.o: $(topdir)/externs.h setattr.o: $(topdir)/shell.h $(topdir)/syntax.h $(topdir)/unwind_prot.h $(topdir)/variables.h $(topdir)/conftypes.h setattr.o: $(topdir)/arrayfunc.h shift.o: $(topdir)/command.h ../config.h $(BASHINCDIR)/memalloc.h shift.o: $(topdir)/error.h $(topdir)/general.h $(topdir)/xmalloc.h shift.o: $(topdir)/quit.h $(topdir)/dispose_cmd.h $(topdir)/make_cmd.h shift.o: $(topdir)/subst.h $(topdir)/externs.h $(BASHINCDIR)/maxpath.h shift.o: $(topdir)/shell.h $(topdir)/syntax.h $(topdir)/unwind_prot.h $(topdir)/variables.h $(topdir)/conftypes.h source.o: $(topdir)/command.h ../config.h $(BASHINCDIR)/memalloc.h source.o: $(topdir)/error.h $(topdir)/general.h $(topdir)/xmalloc.h $(topdir)/findcmd.h source.o: $(topdir)/quit.h $(topdir)/dispose_cmd.h $(topdir)/make_cmd.h source.o: $(topdir)/subst.h $(topdir)/externs.h $(BASHINCDIR)/maxpath.h source.o: $(topdir)/shell.h $(topdir)/syntax.h $(topdir)/unwind_prot.h $(topdir)/variables.h $(topdir)/conftypes.h suspend.o: $(topdir)/command.h ../config.h $(BASHINCDIR)/memalloc.h suspend.o: $(topdir)/error.h $(topdir)/general.h $(topdir)/xmalloc.h suspend.o: $(topdir)/quit.h $(topdir)/dispose_cmd.h $(topdir)/make_cmd.h suspend.o: $(topdir)/subst.h $(topdir)/externs.h $(BASHINCDIR)/maxpath.h suspend.o: $(topdir)/shell.h $(topdir)/syntax.h $(topdir)/unwind_prot.h $(topdir)/variables.h $(topdir)/conftypes.h test.o: $(topdir)/command.h ../config.h $(BASHINCDIR)/memalloc.h test.o: $(topdir)/error.h $(topdir)/general.h $(topdir)/xmalloc.h test.o: $(topdir)/quit.h $(topdir)/dispose_cmd.h $(topdir)/make_cmd.h test.o: $(topdir)/subst.h $(topdir)/externs.h $(BASHINCDIR)/maxpath.h test.o: $(topdir)/shell.h $(topdir)/syntax.h $(topdir)/unwind_prot.h $(topdir)/variables.h $(topdir)/conftypes.h test.o: $(topdir)/test.h times.o: $(topdir)/command.h ../config.h $(BASHINCDIR)/memalloc.h times.o: $(topdir)/error.h $(topdir)/general.h $(topdir)/xmalloc.h times.o: $(topdir)/quit.h $(topdir)/dispose_cmd.h $(topdir)/make_cmd.h times.o: $(topdir)/subst.h $(topdir)/externs.h $(BASHINCDIR)/maxpath.h times.o: $(topdir)/shell.h $(topdir)/syntax.h $(topdir)/unwind_prot.h $(topdir)/variables.h $(topdir)/conftypes.h times.o: $(BASHINCDIR)/posixtime.h trap.o: $(topdir)/command.h ../config.h $(BASHINCDIR)/memalloc.h trap.o: $(topdir)/error.h $(topdir)/general.h $(topdir)/xmalloc.h $(topdir)/externs.h trap.o: $(topdir)/quit.h $(srcdir)/common.h $(BASHINCDIR)/maxpath.h trap.o: $(topdir)/dispose_cmd.h $(topdir)/make_cmd.h $(topdir)/subst.h trap.o: $(topdir)/shell.h $(topdir)/syntax.h $(topdir)/unwind_prot.h $(topdir)/variables.h $(topdir)/conftypes.h trap.o: $(topdir)/findcmd.h type.o: $(topdir)/command.h ../config.h $(BASHINCDIR)/memalloc.h type.o: $(topdir)/error.h $(topdir)/general.h $(topdir)/xmalloc.h type.o: $(topdir)/quit.h $(srcdir)/common.h $(BASHINCDIR)/maxpath.h type.o: $(topdir)/dispose_cmd.h $(topdir)/make_cmd.h $(topdir)/subst.h type.o: $(topdir)/externs.h $(topdir)/hashcmd.h type.o: $(topdir)/shell.h $(topdir)/syntax.h $(topdir)/unwind_prot.h $(topdir)/variables.h $(topdir)/conftypes.h ulimit.o: $(topdir)/command.h ../config.h $(BASHINCDIR)/memalloc.h ulimit.o: $(topdir)/error.h $(topdir)/general.h $(topdir)/xmalloc.h ulimit.o: $(topdir)/quit.h $(topdir)/dispose_cmd.h $(topdir)/make_cmd.h ulimit.o: $(topdir)/subst.h $(topdir)/externs.h $(BASHINCDIR)/maxpath.h ulimit.o: $(topdir)/shell.h $(topdir)/syntax.h $(topdir)/unwind_prot.h $(topdir)/variables.h $(topdir)/conftypes.h umask.o: $(topdir)/command.h ../config.h $(BASHINCDIR)/memalloc.h umask.o: $(topdir)/error.h $(topdir)/general.h $(topdir)/xmalloc.h umask.o: $(topdir)/quit.h $(topdir)/dispose_cmd.h $(topdir)/make_cmd.h umask.o: $(topdir)/subst.h $(topdir)/externs.h $(BASHINCDIR)/maxpath.h umask.o: $(topdir)/shell.h $(topdir)/syntax.h $(topdir)/unwind_prot.h $(topdir)/variables.h $(topdir)/conftypes.h umask.o: $(BASHINCDIR)/chartypes.h wait.o: $(topdir)/command.h ../config.h $(BASHINCDIR)/memalloc.h wait.o: $(topdir)/error.h $(topdir)/general.h $(topdir)/xmalloc.h wait.o: $(topdir)/quit.h $(topdir)/dispose_cmd.h $(topdir)/make_cmd.h wait.o: $(topdir)/subst.h $(topdir)/externs.h $(BASHINCDIR)/maxpath.h wait.o: $(topdir)/shell.h $(topdir)/syntax.h $(topdir)/unwind_prot.h $(topdir)/variables.h $(topdir)/conftypes.h wait.o: $(BASHINCDIR)/chartypes.h shopt.o: $(topdir)/command.h ../config.h $(BASHINCDIR)/memalloc.h shopt.o: $(topdir)/error.h $(topdir)/general.h $(topdir)/xmalloc.h shopt.o: $(topdir)/quit.h $(topdir)/dispose_cmd.h $(topdir)/make_cmd.h shopt.o: $(topdir)/subst.h $(topdir)/externs.h $(BASHINCDIR)/maxpath.h shopt.o: $(topdir)/shell.h $(topdir)/syntax.h $(topdir)/unwind_prot.h $(topdir)/variables.h $(topdir)/conftypes.h shopt.o: $(srcdir)/common.h $(srcdir)/bashgetopt.h complete.o: ../config.h complete.o: ${topdir}/shell.h $(topdir)/syntax.h ${topdir}/bashjmp.h ${BASHINCDIR}/posixjmp.h ${topdir}/sig.h complete.o: ${topdir}/unwind_prot.h ${topdir}/variables.h complete.o: ${topdir}/bashtypes.h ${topdir}/bashansi.h ${BASHINCDIR}/ansi_stdlib.h complete.o: ${topdir}/builtins.h complete.o: ${topdir}/pcomplete.h complete.o: ${srcdir}/common.h ${srcdir}/bashgetopt.h #bind.o: $(RL_LIBSRC)chardefs.h $(RL_LIBSRC)readline.h $(RL_LIBSRC)keymaps.h bash-2.05a/builtins/alias.def100664 436 0 10505 7347462526 14377 0ustar chetwheelThis file is alias.def, from which is created alias.c It implements the builtins "alias" and "unalias" in Bash. Copyright (C) 1987, 1989, 1991 Free Software Foundation, Inc. This file is part of GNU Bash, the Bourne Again SHell. Bash is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 2, or (at your option) any later version. Bash is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with Bash; see the file COPYING. If not, write to the Free Software Foundation, 59 Temple Place, Suite 330, Boston, MA 02111 USA. $BUILTIN alias $FUNCTION alias_builtin $DEPENDS_ON ALIAS $PRODUCES alias.c $SHORT_DOC alias [-p] [name[=value] ... ] `alias' with no arguments or with the -p option prints the list of aliases in the form alias NAME=VALUE on standard output. Otherwise, an alias is defined for each NAME whose VALUE is given. A trailing space in VALUE causes the next word to be checked for alias substitution when the alias is expanded. Alias returns true unless a NAME is given for which no alias has been defined. $END #include #if defined (ALIAS) #if defined (HAVE_UNISTD_H) # ifdef _MINIX # include # endif # include #endif # include "../bashansi.h" # include # include "../shell.h" # include "../alias.h" # include "common.h" # include "bashgetopt.h" static void print_alias __P((alias_t *)); /* Hack the alias command in a Korn shell way. */ int alias_builtin (list) WORD_LIST *list; { int any_failed, offset, pflag; alias_t **alias_list, *t; char *name, *value; pflag = 0; reset_internal_getopt (); while ((offset = internal_getopt (list, "p")) != -1) { switch (offset) { case 'p': pflag = 1; break; 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]); free (alias_list); /* XXX - Do not free the strings. */ if (list == 0) return (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; add_alias (name, value); } else { t = find_alias (name); if (t) print_alias (t); else { builtin_error ("`%s' not found", name); any_failed++; } } list = list->next; } return (any_failed ? EXECUTION_FAILURE : EXECUTION_SUCCESS); } #endif /* ALIAS */ $BUILTIN unalias $FUNCTION unalias_builtin $DEPENDS_ON ALIAS $SHORT_DOC unalias [-a] [name ...] Remove NAMEs from the list of defined aliases. If the -a option is given, then remove all alias definitions. $END #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; default: builtin_usage (); return (EX_USAGE); } } list = loptend; if (aflag) { delete_all_aliases (); return (EXECUTION_SUCCESS); } aflag = 0; while (list) { alias = find_alias (list->word->word); if (alias) remove_alias (alias->name); else { builtin_error ("`%s': not an alias", 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) alias_t *alias; { char *value; value = sh_single_quote (alias->value); printf ("alias %s=%s\n", alias->name, value); free (value); fflush (stdout); } #endif /* ALIAS */ bash-2.05a/builtins/bind.def100644 436 0 17150 7342747327 14223 0ustar chetwheelThis file is bind.def, from which is created bind.c. It implements the builtin "bind" in Bash. Copyright (C) 1987, 1989, 1991 Free Software Foundation, Inc. This file is part of GNU Bash, the Bourne Again SHell. Bash is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 2, or (at your option) any later version. Bash is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with Bash; see the file COPYING. If not, write to the Free Software Foundation, 59 Temple Place, Suite 330, Boston, MA 02111 USA. $PRODUCES bind.c #include $BUILTIN bind $DEPENDS_ON READLINE $FUNCTION bind_builtin $SHORT_DOC bind [-lpvsPVS] [-m keymap] [-f filename] [-q name] [-u name] [-r keyseq] [-x keyseq:shell-command] [keyseq:readline-function] Bind a key sequence to a Readline function, or to a macro. The syntax is equivalent to that found in ~/.inputrc, but must be passed as a single argument: bind '"\C-x\C-r": re-read-init-file'. Arguments we accept: -m keymap Use `keymap' as the keymap for the duration of this command. Acceptable keymap names are emacs, emacs-standard, emacs-meta, emacs-ctlx, vi, vi-move, vi-command, and vi-insert. -l List names of functions. -P List function names and bindings. -p List functions and bindings in a form that can be reused as input. -r keyseq Remove the binding for KEYSEQ. -x keyseq:shell-command Cause SHELL-COMMAND to be executed when KEYSEQ is entered. -f filename Read key bindings from FILENAME. -q function-name Query about which keys invoke the named function. -u function-name Unbind all keys which are bound to the named function. -V List variable names and values -v List variable names and values in a form that can be reused as input. -S List key sequences that invoke macros and their values -s List key sequences that invoke macros and their values in a form that can be reused as input. $END #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 "../shell.h" #include "../bashline.h" #include "bashgetopt.h" #include "common.h" static int query_bindings __P((char *)); static int unbind_command __P((char *)); extern int no_line_editing; #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 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; if (no_line_editing) return (EXECUTION_FAILURE); kmap = saved_keymap = (Keymap) NULL; flags = 0; initfile = map_name = fun_name = unbind_name = remove_seq = (char *)NULL; return_code = EXECUTION_SUCCESS; if (!bash_readline_initialized) initialize_readline (); begin_unwind_frame ("bind_builtin"); unwind_protect_var (rl_outstream); rl_outstream = stdout; reset_internal_getopt (); while ((opt = internal_getopt (list, "lvpVPsSf:q:u:m:r:x:")) != EOF) { 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; 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) { 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) { builtin_error ("cannot read %s: %s", initfile, strerror (errno)); 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) { if (rl_set_key (remove_seq, (rl_command_func_t *)NULL, rl_get_keymap ()) != 0) { builtin_error ("cannot unbind %s", remove_seq); BIND_RETURN (EXECUTION_FAILURE); } } if (flags & XFLAG) return_code = bind_keyseq_to_unix_command (cmd_seq); /* Process the rest of the arguments as binding specifications. */ while (list) { rl_parse_and_bind (list->word->word); list = list->next; } bind_exit: if (saved_keymap) rl_set_keymap (saved_keymap); run_unwind_frame ("bind_builtin"); return (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 ("unknown function name `%s'", 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"); free_array (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 ("unknown function name `%s'", name); return EXECUTION_FAILURE; } rl_unbind_function_in_map (function, rl_get_keymap ()); return EXECUTION_SUCCESS; } #endif /* READLINE */ bash-2.05a/builtins/break.def100644 436 0 6171 7302265767 14353 0ustar chetwheelThis file is break.def, from which is created break.c. It implements the builtins "break" and "continue" in Bash. Copyright (C) 1987, 1989, 1991 Free Software Foundation, Inc. This file is part of GNU Bash, the Bourne Again SHell. Bash is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 2, or (at your option) any later version. Bash is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with Bash; see the file COPYING. If not, write to the Free Software Foundation, 59 Temple Place, Suite 330, Boston, MA 02111 USA. $PRODUCES break.c $BUILTIN break $FUNCTION break_builtin $SHORT_DOC break [n] Exit from within a FOR, WHILE or UNTIL loop. If N is specified, break N levels. $END #include #if defined (HAVE_UNISTD_H) # ifdef _MINIX # include # endif # include #endif #include "../shell.h" #include "common.h" extern char *this_command_name; extern int posixly_correct; static int check_loop_level __P((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; { long newbreak; if (check_loop_level () == 0) return (EXECUTION_SUCCESS); newbreak = get_numeric_arg (list, 1); if (newbreak <= 0) { builtin_error ("loop count must be > 0"); breaking = loop_level; return (EXECUTION_FAILURE); } if (newbreak > loop_level) newbreak = loop_level; breaking = newbreak; return (EXECUTION_SUCCESS); } $BUILTIN continue $FUNCTION continue_builtin $SHORT_DOC continue [n] Resume the next iteration of the enclosing FOR, WHILE or UNTIL loop. If N is specified, resume at the N-th enclosing loop. $END /* 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; { long newcont; if (check_loop_level () == 0) return (EXECUTION_SUCCESS); newcont = get_numeric_arg (list, 1); if (newcont <= 0) { builtin_error ("loop count must be > 0"); 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); } bash-2.05a/builtins/builtin.def100664 436 0 4060 7342747212 14724 0ustar chetwheelThis file is builtin.def, from which is created builtin.c. It implements the builtin "builtin" in Bash. Copyright (C) 1987, 1989, 1991 Free Software Foundation, Inc. This file is part of GNU Bash, the Bourne Again SHell. Bash is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 2, or (at your option) any later version. Bash is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with Bash; see the file COPYING. If not, write to the Free Software Foundation, 59 Temple Place, Suite 330, Boston, MA 02111 USA. $PRODUCES builtin.c $BUILTIN builtin $FUNCTION builtin_builtin $SHORT_DOC builtin [shell-builtin [arg ...]] Run a shell builtin. This is useful when you wish to rename a shell builtin to be a function, but need the functionality of the builtin within the function itself. $END #include #if defined (HAVE_UNISTD_H) # ifdef _MINIX # include # endif # include #endif #include "../shell.h" #include "common.h" extern char *this_command_name; /* 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 (!list) 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) { builtin_error ("%s: not a shell builtin", command); return (EXECUTION_FAILURE); } else { this_command_name = command; list = list->next; return ((*function) (list)); } } bash-2.05a/builtins/cd.def100644 436 0 26170 7347471226 13674 0ustar chetwheelThis file is cd.def, from which is created cd.c. It implements the builtins "cd" and "pwd" in Bash. Copyright (C) 1987, 1989, 1991 Free Software Foundation, Inc. This file is part of GNU Bash, the Bourne Again SHell. Bash is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 2, or (at your option) any later version. Bash is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with Bash; see the file COPYING. If not, write to the Free Software Foundation, 59 Temple Place, Suite 330, Boston, MA 02111 USA. $PRODUCES cd.c #include #if defined (HAVE_UNISTD_H) # ifdef _MINIX # include # endif # include #endif #include "../bashtypes.h" #include "posixdir.h" #include "posixstat.h" #ifndef _MINIX #include #endif #include #include "../bashansi.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 int posixly_correct; extern int array_needs_making; extern char *bash_getcwd_errstr; static int bindpwd __P((int)); static int change_to_directory __P((char *, int)); static char *cdspell __P((char *)); /* Change this to 1 to get cd spelling correction by default. */ int cdspelling = 0; int cdable_vars; $BUILTIN cd $FUNCTION cd_builtin $SHORT_DOC cd [-PL] [dir] Change the current directory to DIR. The variable $HOME is the default DIR. The variable CDPATH defines the search path for the directory containing DIR. Alternative directory names in CDPATH are separated by a colon (:). A null directory name is the same as the current directory, i.e. `.'. If DIR begins with a slash (/), then CDPATH is not used. If the directory is not found, and the shell option `cdable_vars' is set, then try the word as a variable name. If that variable has a value, then cd to the value of that variable. The -P option says to use the physical directory structure instead of following symbolic links; the -L option forces symbolic links to be followed. $END static int bindpwd (no_symlinks) int no_symlinks; { char *dirname, *pwdvar; int old_anm; SHELL_VAR *tvar; #define tcwd the_current_working_directory dirname = tcwd ? (no_symlinks ? sh_physpath (tcwd, 0) : tcwd) : get_working_directory ("cd"); #undef tcwd old_anm = array_needs_making; pwdvar = get_string_value ("PWD"); tvar = bind_variable ("OLDPWD", pwdvar); if (old_anm == 0 && array_needs_making && exported_p (tvar)) { update_export_env_inplace ("OLDPWD=", 7, pwdvar); array_needs_making = 0; } tvar = bind_variable ("PWD", dirname); if (old_anm == 0 && array_needs_making && exported_p (tvar)) { update_export_env_inplace ("PWD=", 4, dirname); array_needs_making = 0; } if (dirname && dirname != the_current_working_directory) free (dirname); return (EXECUTION_SUCCESS); } #define LCD_DOVARS 0x001 #define LCD_DOSPELL 0x002 #define LCD_PRINTPATH 0x004 #define LCD_FREEDIRNAME 0x010 /* This builtin is ultimately the way that all user-visible commands should change the current working directory. It is called by cd_to_string (), so the programming interface is simple, and it handles errors and restrictions properly. */ int cd_builtin (list) WORD_LIST *list; { char *dirname, *cdpath, *path, *temp; int path_index, no_symlinks, opt, lflag; #if defined (RESTRICTED_SHELL) if (restricted) { builtin_error ("restricted"); return (EXECUTION_FAILURE); } #endif /* RESTRICTED_SHELL */ no_symlinks = no_symbolic_links; reset_internal_getopt (); while ((opt = internal_getopt (list, "LP")) != -1) { switch (opt) { case 'P': no_symlinks = 1; break; case 'L': no_symlinks = 0; break; default: builtin_usage (); return (EXECUTION_FAILURE); } } list = loptend; lflag = (cdable_vars ? LCD_DOVARS : 0) | ((interactive && cdspelling) ? LCD_DOSPELL : 0); if (list == 0) { /* `cd' without arguments is equivalent to `cd $HOME' */ dirname = get_string_value ("HOME"); if (dirname == 0) { builtin_error ("HOME not set"); return (EXECUTION_FAILURE); } lflag = 0; } else if (list->word->word[0] == '-' && list->word->word[1] == '\0') { /* This is `cd -', equivalent to `cd $OLDPWD' */ dirname = get_string_value ("OLDPWD"); if (dirname == 0) { builtin_error ("OLDPWD not set"); return (EXECUTION_FAILURE); } lflag = interactive ? LCD_PRINTPATH : 0; } else if (absolute_pathname (list->word->word)) dirname = list->word->word; else if (cdpath = get_string_value ("CDPATH")) { dirname = list->word->word; /* Find directory in $CDPATH. */ path_index = 0; while (path = extract_colon_unit (cdpath, &path_index)) { /* OPT is 1 if the path element is non-empty */ opt = path[0] != '\0'; temp = sh_makepath (path, dirname, MP_DOTILDE); free (path); if (change_to_directory (temp, no_symlinks)) { /* POSIX.2 says that if a nonempty directory from CDPATH is used to find the directory to change to, the new directory name is echoed to stdout, whether or not the shell is interactive. */ if (opt) printf ("%s\n", no_symlinks ? temp : the_current_working_directory); free (temp); /* Posix.2 says that after using CDPATH, the resultant value of $PWD will not contain `.' or `..'. */ return (bindpwd (posixly_correct || no_symlinks)); } else free (temp); } /* 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); } } else dirname = list->word->word; /* When we get here, DIRNAME is the directory to change to. If we chdir successfully, just return. */ if (change_to_directory (dirname, no_symlinks)) { if (lflag & LCD_PRINTPATH) printf ("%s\n", dirname); return (bindpwd (no_symlinks)); } /* If the user requests it, then perhaps this is the name of a shell variable, whose value contains the directory to change to. */ if (lflag & LCD_DOVARS) { temp = get_string_value (dirname); if (temp && change_to_directory (temp, no_symlinks)) { printf ("%s\n", temp); return (bindpwd (no_symlinks)); } } /* If the user requests it, try to find a directory name similar in spelling to the one requested, in case the user made a simple typo. This is similar to the UNIX 8th and 9th Edition shells. */ if (lflag & LCD_DOSPELL) { temp = cdspell (dirname); if (temp && change_to_directory (temp, no_symlinks)) { printf ("%s\n", temp); return (bindpwd (no_symlinks)); } else FREE (temp); } builtin_error ("%s: %s", dirname, strerror (errno)); return (EXECUTION_FAILURE); } $BUILTIN pwd $FUNCTION pwd_builtin $SHORT_DOC pwd [-PL] Print the current working directory. With the -P option, pwd prints the physical directory, without any symbolic links; the -L option makes pwd follow symbolic links. $END /* Non-zero means that pwd always prints the physical directory, without symbolic links. */ static int verbatim_pwd; /* Print the name of the current working directory. */ int pwd_builtin (list) WORD_LIST *list; { char *directory; int opt; verbatim_pwd = no_symbolic_links; reset_internal_getopt (); while ((opt = internal_getopt (list, "LP")) != -1) { switch (opt) { case 'P': verbatim_pwd = 1; break; case 'L': verbatim_pwd = 0; break; default: builtin_usage (); return (EXECUTION_FAILURE); } } list = loptend; #define tcwd the_current_working_directory directory = tcwd ? (verbatim_pwd ? sh_physpath (tcwd, 0) : tcwd) : get_working_directory ("pwd"); #undef tcwd if (directory) { printf ("%s\n", directory); if (directory != the_current_working_directory) free (directory); fflush (stdout); if (ferror (stdout)) { builtin_error ("write error: %s", strerror (errno)); return (EXECUTION_FAILURE); } return (EXECUTION_SUCCESS); } else return (EXECUTION_FAILURE); } /* Do the work of changing to the directory NEWDIR. Handle symbolic link following, etc. This function *must* return with the_current_working_directory either set to NULL (in which case getcwd() will eventually be called), or set to a string corresponding to the working directory. Return 1 on success, 0 on failure. */ static int change_to_directory (newdir, nolinks) char *newdir; int nolinks; { char *t, *tdir; int err; 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); /* Use the canonicalized version of NEWDIR, or, if canonicalization failed, use the non-canonical form. */ if (tdir && *tdir) free (t); else { FREE (tdir); tdir = t; } /* If the chdir succeeds, update the_current_working_directory. */ if (chdir (nolinks ? newdir : tdir) == 0) { FREE (the_current_working_directory); the_current_working_directory = 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) return (0); err = errno; free (tdir); /* We're not in physical mode (nolinks == 0), but we failed to change to the canonicalized directory name (TDIR). Try what the user passed verbatim. If we succeed, reinitialize the_current_working_directory. */ if (chdir (newdir) == 0) { FREE (the_current_working_directory); the_current_working_directory = (char *)NULL; tdir = get_working_directory ("cd"); FREE (tdir); return (1); } else { errno = err; return (0); } } /* Code for cd spelling correction. Original patch submitted by Neil Russel (caret@c-side.com). */ static char * cdspell (dirname) char *dirname; { int n; char *guess; n = (strlen (dirname) * 3 + 1) / 2 + 1; guess = (char *)xmalloc (n); switch (spname (dirname, guess)) { case -1: default: free (guess); return (char *)NULL; case 0: case 1: return guess; } } bash-2.05a/builtins/colon.def100664 436 0 2655 7032737306 14377 0ustar chetwheelThis file is colon.def, from which is created colon.c. It implements the builtin ":" in Bash. Copyright (C) 1987, 1989, 1991 Free Software Foundation, Inc. This file is part of GNU Bash, the Bourne Again SHell. Bash is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 2, or (at your option) any later version. Bash is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with Bash; see the file COPYING. If not, write to the Free Software Foundation, 59 Temple Place, Suite 330, Boston, MA 02111 USA. $PRODUCES colon.c $BUILTIN : $DOCNAME colon_builtin $FUNCTION colon_builtin $SHORT_DOC : No effect; the command does nothing. A zero exit code is returned. $END $BUILTIN true $DOCNAME true_builtin $FUNCTION colon_builtin $SHORT_DOC true Return a successful result. $END $BUILTIN false $DOCNAME false_builtin $FUNCTION false_builtin $SHORT_DOC false Return an unsuccessful result. $END /* Return a successful result. */ int colon_builtin (ignore) char *ignore; { return (0); } /* Return an unsuccessful result. */ int false_builtin (ignore) char *ignore; { return (1); } bash-2.05a/builtins/command.def100664 436 0 13147 7347423300 14714 0ustar chetwheelThis file is command.def, from which is created command.c. It implements the builtin "command" in Bash. Copyright (C) 1987, 1989, 1991 Free Software Foundation, Inc. This file is part of GNU Bash, the Bourne Again SHell. Bash is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 2, or (at your option) any later version. Bash is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with Bash; see the file COPYING. If not, write to the Free Software Foundation, 59 Temple Place, Suite 330, Boston, MA 02111 USA. $PRODUCES command.c $BUILTIN command $FUNCTION command_builtin $SHORT_DOC command [-pVv] command [arg ...] Runs COMMAND with ARGS ignoring shell functions. If you have a shell function called `ls', and you wish to call the command `ls', you can say "command ls". If the -p option is given, a default value is used for PATH that is guaranteed to find all of the standard utilities. If the -V or -v option is given, a string is printed describing COMMAND. The -V option produces a more verbose description. $END #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 __P((int, char *, size_t)); #endif extern int subshell_environment; static void restore_path __P((char *)); static char *get_standard_path __P((void)); /* 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; char *old_path, *standard_path; COMMAND *command; verbose = use_standard_path = 0; reset_internal_getopt (); while ((opt = internal_getopt (list, "pvV")) != -1) { switch (opt) { case 'p': use_standard_path = 1; break; case 'V': verbose = 2; break; case 'v': verbose = 4; break; default: builtin_usage (); return (EX_USAGE); } } list = loptend; if (list == 0) return (EXECUTION_SUCCESS); if (verbose) { int found, any_found; for (any_found = 0; list; list = list->next) { found = describe_command (list->word->word, verbose, 0); if (found == 0) builtin_error ("%s: not found", list->word->word); any_found += found; } return (any_found ? EXECUTION_SUCCESS : EXECUTION_FAILURE); } #if defined (RESTRICTED_SHELL) if (use_standard_path && restricted) { builtin_error ("restricted: cannot use -p"); return (EXECUTION_FAILURE); } #endif begin_unwind_frame ("command_builtin"); /* 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. */ if (use_standard_path) { old_path = get_string_value ("PATH"); /* If old_path is NULL, $PATH is unset. If so, we want to make sure it's unset after this command completes. */ if (old_path) old_path = savestring (old_path); add_unwind_protect ((Function *)restore_path, old_path); standard_path = get_standard_path (); bind_variable ("PATH", standard_path ? standard_path : ""); FREE (standard_path); } #define COMMAND_BUILTIN_FLAGS (CMD_NO_FUNCTIONS | CMD_INHIBIT_EXPANSION | CMD_COMMAND_BUILTIN) 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; #if 0 /* This breaks for things like ( cd /tmp ; command z ababa ; echo next ) or $(command echo a ; command echo b;) or even { command echo a; command echo b; } & */ /* If we're in a subshell, see if we can get away without forking again, since we've already forked to run this builtin. */ if (subshell_environment) { command->flags |= CMD_NO_FORK; command->value.Simple->flags |= CMD_NO_FORK; } #endif add_unwind_protect ((char *)dispose_command, command); result = execute_command (command); run_unwind_frame ("command_builtin"); return (result); } /* Restore the value of the $PATH variable after replacing it when executing `command -p'. */ static void restore_path (var) char *var; { if (var) { bind_variable ("PATH", var); free (var); } else unbind_variable ("PATH"); } /* Return a value for PATH that is guaranteed to find all of the standard utilities. This uses Posix.2 configuration variables, if present. It uses a value defined in config.h as a last resort. */ static char * get_standard_path () { #if defined (_CS_PATH) && defined (HAVE_CONFSTR) char *p; size_t len; len = (size_t)confstr (_CS_PATH, (char *)NULL, (size_t)0); if (len > 0) { p = (char *)xmalloc (len + 2); *p = '\0'; confstr (_CS_PATH, p, len); return (p); } else return (savestring (STANDARD_UTILS_PATH)); #else /* !_CS_PATH || !HAVE_CONFSTR */ # if defined (CS_PATH) return (savestring (CS_PATH)); # else return (savestring (STANDARD_UTILS_PATH)); # endif /* !CS_PATH */ #endif /* !_CS_PATH || !HAVE_CONFSTR */ } bash-2.05a/builtins/complete.def100664 436 0 33362 7327616267 15125 0ustar chetwheelThis file is complete.def, from which is created complete.c. It implements the builtins "complete" and "compgen" in Bash. Copyright (C) 1999 Free Software Foundation, Inc. This file is part of GNU Bash, the Bourne Again SHell. Bash is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 2, or (at your option) any later version. Bash is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with Bash; see the file COPYING. If not, write to the Free Software Foundation, 59 Temple Place, Suite 330, Boston, MA 02111 USA. $PRODUCES complete.c $BUILTIN complete $DEPENDS_ON PROGRAMMABLE_COMPLETION $FUNCTION complete_builtin $SHORT_DOC complete [-abcdefgjkvu] [-pr] [-o option] [-A action] [-G globpat] [-W wordlist] [-P prefix] [-S suffix] [-X filterpat] [-F function] [-C command] [name ...] For each NAME, specify how arguments are to be completed. If the -p option is supplied, or if no options are supplied, existing completion specifications are printed in a way that allows them to be reused as input. The -r option removes a completion specification for each NAME, or, if no NAMEs are supplied, all completion specifications. $END #include #include #include "../bashtypes.h" #if defined (HAVE_UNISTD_H) # include #endif #include "../bashansi.h" #include "../shell.h" #include "../builtins.h" #include "../pcomplete.h" #include "common.h" #include "bashgetopt.h" #include #define STRDUP(x) ((x) ? savestring (x) : (char *)NULL) static int find_compact __P((char *)); static int find_compopt __P((char *)); static int build_actions __P((WORD_LIST *, int *, int *, unsigned long *, unsigned long *)); static int remove_cmd_completions __P((WORD_LIST *)); static void print_one_completion __P((char *, COMPSPEC *)); static void print_all_completions __P((void)); static int print_cmd_completions __P((WORD_LIST *)); static char *Aarg, *Garg, *Warg, *Parg, *Sarg, *Xarg, *Farg, *Carg; static struct _compacts { char *actname; int 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_BUILTIN, 0 }, /* for now */ { "hostname", CA_HOSTNAME, 0 }, { "group", CA_GROUP, 'g' }, { "job", CA_JOB, 'j' }, { "keyword", CA_KEYWORD, 'k' }, { "running", CA_RUNNING, 0 }, { "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 }, }; static struct _compopt { char *optname; int optflag; } compopts[] = { { "default", COPT_DEFAULT }, { "dirnames", COPT_DIRNAMES }, { "filenames",COPT_FILENAMES}, { (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 btmap 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, pp, rp, actp, optp) WORD_LIST *list; int *pp, *rp; unsigned long *actp, *optp; { int opt, ind, opt_given; unsigned long acts, copts; acts = copts = (unsigned long)0L; opt_given = 0; reset_internal_getopt (); while ((opt = internal_getopt (list, "abcdefgjko:pruvA:G:W:P:S:X:F:C:")) != -1) { opt_given = 1; switch (opt) { case 'r': if (rp) { *rp = 1; break; } else { builtin_error ("illegal option: -r"); builtin_usage (); return (EX_USAGE); } case 'p': if (pp) { *pp = 1; break; } else { builtin_error ("illegal option: -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 'u': acts |= CA_USER; break; case 'v': acts |= CA_VARIABLE; break; case 'o': ind = find_compopt (list_optarg); if (ind < 0) { builtin_error ("%s: invalid option name", 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 'F': Farg = list_optarg; 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; 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, pflag, rflag, rval; unsigned long acts, copts; char *cmd; COMPSPEC *cs; if (list == 0) { print_all_completions (); return (EXECUTION_SUCCESS); } opt_given = pflag = rflag = 0; acts = copts = (unsigned long)0L; Aarg = 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, &pflag, &rflag, &acts, &copts); if (rval == EX_USAGE) return (rval); opt_given = rval != EXECUTION_FAILURE; list = loptend; /* -p overrides everything else */ if (pflag || (list == 0 && opt_given == 0)) { if (list == 0) { print_all_completions (); return (EXECUTION_SUCCESS); } return (print_cmd_completions (list)); } /* next, -r overrides everything else. */ if (rflag) { if (list == 0) { clear_progcomps (); return (EXECUTION_SUCCESS); } return (remove_cmd_completions (list)); } if (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 = alloc_compspec (); 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 ; list; list = list->next) { /* Add CS as the compspec for the specified commands. */ cmd = list->word->word; if (add_progcomp (cmd, cs) == 0) rval = EXECUTION_FAILURE; } 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 (remove_progcomp (l->word->word) == 0) { builtin_error ("%s: no completion specification", l->word->word); ret = EXECUTION_FAILURE; } } return ret; } #define SQPRINTARG(a, f) \ do { \ if (a) \ { \ x = sh_single_quote (a); \ printf ("%s %s ", f, x); \ free (x); \ } \ } while (0) #define PRINTARG(a, f) \ do { \ if (a) \ printf ("%s %s ", f, a); \ } while (0) #define PRINTOPT(a, f) \ do { \ if (acts & a) \ printf ("%s ", f); \ } while (0) #define PRINTACT(a, f) \ do { \ if (acts & a) \ printf ("-A %s ", f); \ } while (0) #define PRINTCOMPOPT(a, f) \ do { \ if (copts & a) \ printf ("-o %s ", f); \ } while (0) static void print_one_completion (cmd, cs) char *cmd; COMPSPEC *cs; { unsigned long acts, copts; char *x; printf ("complete "); copts = cs->options; /* First, print the -o options. */ PRINTCOMPOPT (COPT_DEFAULT, "default"); PRINTCOMPOPT (COPT_DIRNAMES, "dirnames"); PRINTCOMPOPT (COPT_FILENAMES, "filenames"); acts = cs->actions; /* simple flags next */ PRINTOPT (CA_ALIAS, "-a"); PRINTOPT (CA_BUILTIN, "-b"); PRINTOPT (CA_COMMAND, "-c"); PRINTOPT (CA_DIRECTORY, "-d"); PRINTOPT (CA_EXPORT, "-e"); PRINTOPT (CA_FILE, "-f"); PRINTOPT (CA_GROUP, "-g"); PRINTOPT (CA_KEYWORD, "-k"); PRINTOPT (CA_JOB, "-j"); PRINTOPT (CA_USER, "-u"); PRINTOPT (CA_VARIABLE, "-v"); /* now the rest of the actions */ PRINTACT (CA_ARRAYVAR, "arrayvar"); PRINTACT (CA_BINDING, "binding"); PRINTACT (CA_DISABLED, "disabled"); PRINTACT (CA_ENABLED, "enabled"); PRINTACT (CA_FUNCTION, "function"); PRINTACT (CA_HELPTOPIC, "helptopic"); PRINTACT (CA_HOSTNAME, "hostname"); PRINTACT (CA_RUNNING, "running"); PRINTACT (CA_SETOPT, "setopt"); PRINTACT (CA_SHOPT, "shopt"); PRINTACT (CA_SIGNAL, "signal"); PRINTACT (CA_STOPPED, "stopped"); /* now the rest of the arguments */ /* arguments that require quoting */ SQPRINTARG (cs->globpat, "-G"); SQPRINTARG (cs->words, "-W"); SQPRINTARG (cs->prefix, "-P"); SQPRINTARG (cs->suffix, "-S"); SQPRINTARG (cs->filterpat, "-X"); /* simple arguments that don't require quoting */ PRINTARG (cs->funcname, "-F"); PRINTARG (cs->command, "-C"); printf ("%s\n", cmd); } static void print_all_completions () { print_all_compspecs (print_one_completion); } 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 = find_compspec (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 (ret); } $BUILTIN compgen $DEPENDS_ON PROGRAMMABLE_COMPLETION $FUNCTION compgen_builtin $SHORT_DOC compgen [-abcdefgjkvu] [-o option] [-A action] [-G globpat] [-W wordlist] [-P prefix] [-S suffix] [-X filterpat] [-F function] [-C command] [word] Display the possible completions depending on the options. Intended to be used from within a shell function generating possible completions. If the optional WORD argument is supplied, matches against WORD are generated. $END int compgen_builtin (list) WORD_LIST *list; { int rval; unsigned long acts, copts; COMPSPEC *cs; STRINGLIST *sl; char *word; if (list == 0) return (EXECUTION_SUCCESS); acts = copts = (unsigned long)0L; Aarg = 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, (int *)NULL, (int *)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) internal_warning ("compgen: -F option may not work as you expect"); if (Carg) internal_warning ("compgen: -C option may not work as you expect"); /* If we get here, we need to build a compspec and evaluate it. */ cs = alloc_compspec (); 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; sl = gen_compspec_completions (cs, "compgen", word, 0, 0); /* 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)) { char **matches; matches = rl_completion_matches (word, rl_filename_completion_function); sl = completions_to_stringlist (matches); free_array (matches); } if (sl) { if (sl->list && sl->list_len) { rval = EXECUTION_SUCCESS; print_stringlist (sl, (char *)NULL); } free_stringlist (sl); } free_compspec (cs); return (rval); } bash-2.05a/builtins/common.c100644 436 0 41767 7367316231 14267 0ustar chetwheel/* Copyright (C) 1987, 1989, 1991 Free Software Foundation, Inc. This file is part of GNU Bash, the Bourne Again SHell. Bash is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 2, or (at your option) any later version. Bash is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with Bash; see the file COPYING. If not, write to the Free Software Foundation, 59 Temple Place, Suite 330, Boston, MA 02111 USA. */ #include #if defined (HAVE_UNISTD_H) # ifdef _MINIX # include # endif # include #endif #include #include #include "../bashtypes.h" #include "posixstat.h" #include #include #if defined (PREFER_STDARG) # include #else # if defined (PREFER_VARARGS) # include # endif #endif #include "../bashansi.h" #include "../shell.h" #include "maxpath.h" #include "../flags.h" #include "../jobs.h" #include "../builtins.h" #include "../input.h" #include "../execute_cmd.h" #include "../trap.h" #include "bashgetopt.h" #include "common.h" #include "builtext.h" #include #if defined (HISTORY) # include "../bashhist.h" #endif #if !defined (errno) extern int errno; #endif /* !errno */ extern int no_symbolic_links; extern int indirection_level, startup_state, subshell_environment; extern int line_number; extern int last_command_exit_value; extern int running_trap; extern int posixly_correct; extern char *this_command_name, *shell_name; extern char *bash_getcwd_errstr; /* Used by some builtins and the mainline code. */ sh_builtin_func_t *last_shell_builtin = (sh_builtin_func_t *)NULL; sh_builtin_func_t *this_shell_builtin = (sh_builtin_func_t *)NULL; /* **************************************************************** */ /* */ /* Error reporting, usage, and option processing */ /* */ /* **************************************************************** */ /* This is a lot like report_error (), but it is for shell builtins instead of shell control structures, and it won't ever exit the shell. */ #if defined (USE_VARARGS) void #if defined (PREFER_STDARG) builtin_error (const char *format, ...) #else builtin_error (format, va_alist) const char *format; va_dcl #endif { va_list args; char *name; name = get_name_for_error (); fprintf (stderr, "%s: ", name); if (this_command_name && *this_command_name) fprintf (stderr, "%s: ", this_command_name); #if defined (PREFER_STDARG) va_start (args, format); #else va_start (args); #endif vfprintf (stderr, format, args); va_end (args); fprintf (stderr, "\n"); } #else /* !USE_VARARGS */ void builtin_error (format, arg1, arg2, arg3, arg4, arg5) char *format, *arg1, *arg2, *arg3, *arg4, *arg5; { if (this_command_name && *this_command_name) fprintf (stderr, "%s: ", this_command_name); fprintf (stderr, format, arg1, arg2, arg3, arg4, arg5); fprintf (stderr, "\n"); fflush (stderr); } #endif /* !USE_VARARGS */ /* Print a usage summary for the currently-executing builtin command. */ void builtin_usage () { if (this_command_name && *this_command_name) fprintf (stderr, "%s: usage: ", this_command_name); fprintf (stderr, "%s\n", current_builtin->short_doc); fflush (stderr); } /* Return if LIST is NULL else barf and jump to top_level. Used by some builtins that do not accept arguments. */ void no_args (list) WORD_LIST *list; { if (list) { builtin_error ("too many arguments"); jump_to_top_level (DISCARD); } } /* Function called when one of the builtin commands detects a bad option. */ void bad_option (s) char *s; { builtin_error ("unknown option: %s", s); } /* Check that no options were given to the currently-executing builtin, and return 0 if there were options. */ int no_options (list) WORD_LIST *list; { reset_internal_getopt (); if (internal_getopt (list, "") != -1) { builtin_usage (); return (1); } return (0); } /* **************************************************************** */ /* */ /* Shell positional parameter manipulation */ /* */ /* **************************************************************** */ /* Convert a WORD_LIST into a C-style argv. Return the number of elements in the list in *IP, if IP is non-null. A convenience function for loadable builtins; also used by `test'. */ char ** make_builtin_argv (list, ip) WORD_LIST *list; int *ip; { char **argv; argv = word_list_to_argv (list, 0, 1, ip); argv[0] = this_command_name; return argv; } /* Remember LIST in $0 ... $9, and REST_OF_ARGS. If DESTRUCTIVE is non-zero, then discard whatever the existing arguments are, else only discard the ones that are to be replaced. */ void remember_args (list, destructive) WORD_LIST *list; int destructive; { register int i; for (i = 1; i < 10; i++) { if ((destructive || list) && dollar_vars[i]) { free (dollar_vars[i]); dollar_vars[i] = (char *)NULL; } if (list) { dollar_vars[i] = savestring (list->word->word); list = list->next; } } /* If arguments remain, assign them to REST_OF_ARGS. Note that copy_word_list (NULL) returns NULL, and that dispose_words (NULL) does nothing. */ if (destructive || list) { dispose_words (rest_of_args); rest_of_args = copy_word_list (list); } if (destructive) set_dollar_vars_changed (); } /* **************************************************************** */ /* */ /* Pushing and Popping variable contexts */ /* */ /* **************************************************************** */ static WORD_LIST **dollar_arg_stack = (WORD_LIST **)NULL; static int dollar_arg_stack_slots; static int dollar_arg_stack_index; void push_context () { push_dollar_vars (); variable_context++; } void pop_context () { pop_dollar_vars (); kill_all_local_variables (); variable_context--; } /* Save the existing positional parameters on a stack. */ void push_dollar_vars () { if (dollar_arg_stack_index + 2 > dollar_arg_stack_slots) { dollar_arg_stack = (WORD_LIST **) xrealloc (dollar_arg_stack, (dollar_arg_stack_slots += 10) * sizeof (WORD_LIST **)); } dollar_arg_stack[dollar_arg_stack_index++] = list_rest_of_args (); dollar_arg_stack[dollar_arg_stack_index] = (WORD_LIST *)NULL; } /* Restore the positional parameters from our stack. */ void pop_dollar_vars () { if (!dollar_arg_stack || dollar_arg_stack_index == 0) return; remember_args (dollar_arg_stack[--dollar_arg_stack_index], 1); dispose_words (dollar_arg_stack[dollar_arg_stack_index]); dollar_arg_stack[dollar_arg_stack_index] = (WORD_LIST *)NULL; } void dispose_saved_dollar_vars () { if (!dollar_arg_stack || dollar_arg_stack_index == 0) return; dispose_words (dollar_arg_stack[dollar_arg_stack_index]); dollar_arg_stack[dollar_arg_stack_index] = (WORD_LIST *)NULL; } static int changed_dollar_vars; /* Have the dollar variables been reset to new values since we last checked? */ int dollar_vars_changed () { return (changed_dollar_vars); } void set_dollar_vars_unchanged () { changed_dollar_vars = 0; } void set_dollar_vars_changed () { changed_dollar_vars = 1; } /* **************************************************************** */ /* */ /* Validating numeric input and arguments */ /* */ /* **************************************************************** */ /* Read a numeric arg for this_command_name, the name of the shell builtin that wants it. LIST is the word list that the arg is to come from. Accept only the numeric argument; report an error if other arguments follow. If FATAL is true, call throw_to_top_level, which exits the shell; if not, call jump_to_top_level (DISCARD), which aborts the current command. */ long get_numeric_arg (list, fatal) WORD_LIST *list; int fatal; { long count = 1; if (list) { register char *arg; arg = list->word->word; if (!arg || (legal_number (arg, &count) == 0)) { builtin_error ("bad non-numeric arg `%s'", list->word->word); if (fatal) throw_to_top_level (); else jump_to_top_level (DISCARD); } no_args (list->next); } return (count); } /* Get an eight-bit status value from LIST */ int get_exitstat (list) WORD_LIST *list; { int status; long sval; char *arg; arg = list->word->word; if (arg == 0 || legal_number (arg, &sval) == 0) { builtin_error ("bad non-numeric arg `%s'", list->word->word); return 255; } no_args (list->next); status = sval & 255; return status; } /* Return the octal number parsed from STRING, or -1 to indicate that the string contained a bad number. */ int read_octal (string) char *string; { int result, digits; result = digits = 0; while (*string && ISOCTAL (*string)) { digits++; result = (result * 8) + (*string++ - '0'); if (result > 0777) return -1; } if (digits == 0 || *string) result = -1; return (result); } /* **************************************************************** */ /* */ /* Manipulating the current working directory */ /* */ /* **************************************************************** */ /* Return a consed string which is the current working directory. FOR_WHOM is the name of the caller for error printing. */ char *the_current_working_directory = (char *)NULL; char * get_working_directory (for_whom) char *for_whom; { char *directory; if (no_symbolic_links) { if (the_current_working_directory) free (the_current_working_directory); the_current_working_directory = (char *)NULL; } if (the_current_working_directory == 0) { the_current_working_directory = (char *)xmalloc (PATH_MAX); the_current_working_directory[0] = '\0'; directory = getcwd (the_current_working_directory, PATH_MAX); if (directory == 0) { fprintf (stderr, "%s: could not get current directory: %s: %s\n", (for_whom && *for_whom) ? for_whom : get_name_for_error (), bash_getcwd_errstr, strerror (errno)); free (the_current_working_directory); the_current_working_directory = (char *)NULL; return (char *)NULL; } } return (savestring (the_current_working_directory)); } /* Make NAME our internal idea of the current working directory. */ void set_working_directory (name) char *name; { FREE (the_current_working_directory); the_current_working_directory = savestring (name); } /* **************************************************************** */ /* */ /* Job control support functions */ /* */ /* **************************************************************** */ #if defined (JOB_CONTROL) /* Return the job spec found in LIST. */ int get_job_spec (list) WORD_LIST *list; { register char *word; int job, substring_search; if (list == 0) return (current_job); word = list->word->word; if (*word == '\0') return (current_job); if (*word == '%') word++; if (DIGIT (*word) && all_digits (word)) { job = atoi (word); return (job >= job_slots ? NO_JOB : job - 1); } substring_search = 0; switch (*word) { case 0: case '%': case '+': return (current_job); case '-': return (previous_job); case '?': /* Substring search requested. */ substring_search++; word++; /* FALLTHROUGH */ default: { register int i, wl; job = NO_JOB; wl = strlen (word); for (i = 0; i < job_slots; i++) { if (jobs[i]) { register PROCESS *p; p = jobs[i]->pipe; do { if ((substring_search && strindex (p->command, word)) || (STREQN (p->command, word, wl))) { if (job != NO_JOB) { builtin_error ("ambigious job spec: %s", word); return (DUP_JOB); } else job = i; } p = p->next; } while (p != jobs[i]->pipe); } } return (job); } } } #endif /* JOB_CONTROL */ int display_signal_list (list, forcecols) WORD_LIST *list; int forcecols; { register int i, column; char *name; int result; long signum; result = EXECUTION_SUCCESS; if (!list) { for (i = 1, column = 0; i < NSIG; i++) { name = signal_name (i); if (STREQN (name, "SIGJUNK", 7) || STREQN (name, "Unknown", 7)) continue; if (posixly_correct && !forcecols) printf ("%s%s", name, (i == NSIG - 1) ? "" : " "); else { printf ("%2d) %s", i, name); if (++column < 4) printf ("\t"); else { printf ("\n"); column = 0; } } } if ((posixly_correct && !forcecols) || column != 0) printf ("\n"); return result; } /* List individual signal names or numbers. */ while (list) { if (legal_number (list->word->word, &signum)) { /* This is specified by Posix.2 so that exit statuses can be mapped into signal numbers. */ if (signum > 128) signum -= 128; if (signum < 0 || signum >= NSIG) { builtin_error ("bad signal number: %s", list->word->word); result = EXECUTION_FAILURE; list = list->next; continue; } name = signal_name (signum); if (STREQN (name, "SIGJUNK", 7) || STREQN (name, "Unknown", 7)) { list = list->next; continue; } #if defined (JOB_CONTROL) /* POSIX.2 says that `kill -l signum' prints the signal name without the `SIG' prefix. */ printf ("%s\n", (this_shell_builtin == kill_builtin) ? name + 3 : name); #else printf ("%s\n", name); #endif } else { signum = decode_signal (list->word->word); if (signum == NO_SIG) { builtin_error ("%s: not a signal specification", list->word->word); result = EXECUTION_FAILURE; list = list->next; continue; } printf ("%ld\n", signum); } list = list->next; } return (result); } /* **************************************************************** */ /* */ /* Finding builtin commands and their functions */ /* */ /* **************************************************************** */ /* Perform a binary search and return the address of the builtin function whose name is NAME. If the function couldn't be found, or the builtin is disabled or has no function associated with it, return NULL. Return the address of the builtin. DISABLED_OKAY means find it even if the builtin is disabled. */ struct builtin * builtin_address_internal (name, disabled_okay) char *name; int disabled_okay; { int hi, lo, mid, j; hi = num_shell_builtins - 1; lo = 0; while (lo <= hi) { mid = (lo + hi) / 2; j = shell_builtins[mid].name[0] - name[0]; if (j == 0) j = strcmp (shell_builtins[mid].name, name); if (j == 0) { /* It must have a function pointer. It must be enabled, or we must have explicitly allowed disabled functions to be found, and it must not have been deleted. */ if (shell_builtins[mid].function && ((shell_builtins[mid].flags & BUILTIN_DELETED) == 0) && ((shell_builtins[mid].flags & BUILTIN_ENABLED) || disabled_okay)) return (&shell_builtins[mid]); else return ((struct builtin *)NULL); } if (j > 0) hi = mid - 1; else lo = mid + 1; } return ((struct builtin *)NULL); } /* Return the pointer to the function implementing builtin command NAME. */ sh_builtin_func_t * find_shell_builtin (name) char *name; { current_builtin = builtin_address_internal (name, 0); return (current_builtin ? current_builtin->function : (sh_builtin_func_t *)NULL); } /* Return the address of builtin with NAME, whether it is enabled or not. */ sh_builtin_func_t * builtin_address (name) char *name; { current_builtin = builtin_address_internal (name, 1); return (current_builtin ? current_builtin->function : (sh_builtin_func_t *)NULL); } /* Return the function implementing the builtin NAME, but only if it is a POSIX.2 special builtin. */ sh_builtin_func_t * find_special_builtin (name) char *name; { current_builtin = builtin_address_internal (name, 0); return ((current_builtin && (current_builtin->flags & SPECIAL_BUILTIN)) ? current_builtin->function : (sh_builtin_func_t *)NULL); } static int shell_builtin_compare (sbp1, sbp2) struct builtin *sbp1, *sbp2; { int result; if ((result = sbp1->name[0] - sbp2->name[0]) == 0) result = strcmp (sbp1->name, sbp2->name); return (result); } /* Sort the table of shell builtins so that the binary search will work in find_shell_builtin. */ void initialize_shell_builtins () { qsort (shell_builtins, num_shell_builtins, sizeof (struct builtin), (QSFUNC *)shell_builtin_compare); } bash-2.05a/builtins/declare.def100664 436 0 25150 7347463270 14704 0ustar chetwheelThis file is declare.def, from which is created declare.c. It implements the builtins "declare" and "local" in Bash. Copyright (C) 1987, 1989, 1991 Free Software Foundation, Inc. This file is part of GNU Bash, the Bourne Again SHell. Bash is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 2, or (at your option) any later version. Bash is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with Bash; see the file COPYING. If not, write to the Free Software Foundation, 59 Temple Place, Suite 330, Boston, MA 02111 USA. $PRODUCES declare.c $BUILTIN declare $FUNCTION declare_builtin $SHORT_DOC declare [-afFrxi] [-p] name[=value] ... Declare variables and/or give them attributes. If no NAMEs are given, then display the values of variables instead. The -p option will display the attributes and values of each NAME. The flags are: -a to make NAMEs arrays (if supported) -f to select from among function names only -F to display function names without definitions -r to make NAMEs readonly -x to make NAMEs export -i to make NAMEs have the `integer' attribute set Variables with the integer attribute have arithmetic evaluation (see `let') done when the variable is assigned to. When displaying values of variables, -f displays a function's name and definition. The -F option restricts the display to function name only. Using `+' instead of `-' turns off the given attribute instead. When used in a function, makes NAMEs local, as with the `local' command. $END $BUILTIN typeset $FUNCTION declare_builtin $SHORT_DOC typeset [-afFrxi] [-p] name[=value] ... Obsolete. See `declare'. $END #include #if defined (HAVE_UNISTD_H) # ifdef _MINIX # include # endif # include #endif #include #include "../bashansi.h" #include "../shell.h" #include "common.h" #include "builtext.h" extern int array_needs_making; static int declare_internal __P((register WORD_LIST *, int)); /* Declare or change variable attributes. */ int declare_builtin (list) register WORD_LIST *list; { return (declare_internal (list, 0)); } $BUILTIN local $FUNCTION local_builtin $SHORT_DOC local name[=value] ... Create a local variable called NAME, and give it VALUE. LOCAL can only be used within a function; it makes the variable NAME have a visible scope restricted to that function and its children. $END int local_builtin (list) register WORD_LIST *list; { if (variable_context) return (declare_internal (list, 1)); else { builtin_error ("can only be used in a function"); return (EXECUTION_FAILURE); } } /* The workhorse function. */ static int declare_internal (list, local_var) register WORD_LIST *list; int local_var; { int flags_on, flags_off, *flags, any_failed, assign_error, pflag, nodefs; char *t, *subscript_start; SHELL_VAR *var; flags_on = flags_off = any_failed = assign_error = pflag = nodefs = 0; while (list) { t = list->word->word; if (t[0] == '-' && t[1] == '-' && t[2] == '\0') { list = list->next; break; } if (*t != '+' && *t != '-') break; flags = (*t++ == '+') ? &flags_off : &flags_on; while (*t) { if (*t == 'p' && local_var == 0) pflag++, t++; else if (*t == 'F') { nodefs++; *flags |= att_function; t++; } else if (*t == 'f') *flags |= att_function, t++; else if (*t == 'x') *flags |= att_exported, t++, array_needs_making = 1; else if (*t == 'r') *flags |= att_readonly, t++; else if (*t == 'i') *flags |= att_integer, t++; #if defined (ARRAY_VARS) else if (*t == 'a') *flags |= att_array, t++; #endif else { builtin_error ("unknown option: `-%c'", *t); builtin_usage (); return (EX_USAGE); } } list = list->next; } /* If there are no more arguments left, then we just want to show some variables. */ if (list == 0) /* declare -[afFirx] */ { /* Show local variables defined at this context level if this is the `local' builtin. */ if (local_var) { register SHELL_VAR **vlist; register int i; vlist = map_over (variable_in_context, shell_variables); if (vlist) { for (i = 0; vlist[i]; i++) print_assignment (vlist[i]); free (vlist); } } else { if (flags_on == 0) set_builtin ((WORD_LIST *)NULL); else set_or_show_attributes ((WORD_LIST *)NULL, flags_on, nodefs); } fflush (stdout); return (EXECUTION_SUCCESS); } if (pflag) /* declare -p [-afFirx] name [name...] */ { for (any_failed = 0; list; list = list->next) { pflag = show_name_attributes (list->word->word, nodefs); if (pflag) { builtin_error ("%s: not found", list->word->word); any_failed++; } } return (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 [-afFirx] name [name ...] */ { char *value, *name; int offset; #if defined (ARRAY_VARS) int making_array_special, compound_array_assign, simple_array_assign; #endif name = savestring (list->word->word); offset = assignment (name); if (offset) /* declare [-afFirx] name=value */ { name[offset] = '\0'; value = name + offset + 1; } else value = ""; #if defined (ARRAY_VARS) compound_array_assign = simple_array_assign = 0; subscript_start = (char *)NULL; if (t = strchr (name, '[')) /* ] */ { subscript_start = t; *t = '\0'; making_array_special = 1; } else making_array_special = 0; #endif if (legal_identifier (name) == 0) { builtin_error ("`%s': not a valid identifier", 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. */ if (variable_context) { #if defined (ARRAY_VARS) if ((flags_on & att_array) || making_array_special) var = make_local_array_variable (name); else #endif var = make_local_variable (name); if (var == 0) { any_failed++; NEXT_VARIABLE (); } } /* 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 (); } /* declare -[Ff] name [name...] */ if (flags_on == att_function && flags_off == 0) { t = nodefs ? var->name : named_function_string (name, function_cell (var), 1); printf ("%s\n", t); } else /* declare -[fF] -[rx] name [name...] */ { VSETATTR (var, flags_on); VUNSETATTR (var, flags_off); } } else any_failed++; NEXT_VARIABLE (); } } else /* declare -[airx] name [name...] */ { var = find_variable (name); if (var == 0) { #if defined (ARRAY_VARS) if ((flags_on & att_array) || making_array_special) var = make_new_array_variable (name); else #endif var = bind_variable (name, ""); } /* Cannot use declare +r to turn off readonly attribute. */ if (readonly_p (var) && (flags_off & att_readonly)) { builtin_error ("%s: readonly variable", name); 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)) builtin_error ("%s: readonly variable", name); assign_error++; NEXT_VARIABLE (); } #if defined (ARRAY_VARS) if ((making_array_special || (flags_on & att_array) || array_p (var)) && offset) { if (value[0] == '(' && strchr (value, ')')) compound_array_assign = 1; else simple_array_assign = 1; } /* Cannot use declare +a name to remove an array variable. */ if ((flags_off & att_array) && array_p (var)) { builtin_error ("%s: cannot destroy array variables in this way", name); any_failed++; NEXT_VARIABLE (); } /* declare -a name makes name an array variable. */ if ((making_array_special || (flags_on & att_array)) && array_p (var) == 0) var = convert_var_to_array (var); #endif /* ARRAY_VARS */ VSETATTR (var, flags_on); VUNSETATTR (var, flags_off); #if defined (ARRAY_VARS) if (offset && compound_array_assign) assign_array_var_from_string (var, value); else if (simple_array_assign && subscript_start) { /* declare [-a] name[N]=value */ *subscript_start = '['; /* ] */ var = assign_array_element (name, value); *subscript_start = '\0'; } else if (simple_array_assign) /* let bind_array_variable take care of this. */ bind_array_variable (name, 0, value); else #endif /* bind_variable_value duplicates the essential internals of bind_variable() */ if (offset) bind_variable_value (var, value); /* 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. */ if ((flags_on & (att_exported|att_readonly)) && tempvar_p (var)) { SHELL_VAR *tv; tv = bind_variable (var->name, var->value ? var->value : ""); tv->attributes = var->attributes & ~att_tempvar; dispose_variable (var); } } stupidly_hack_special_variables (name); NEXT_VARIABLE (); } return (assign_error ? EX_BADASSIGN : ((any_failed == 0) ? EXECUTION_SUCCESS : EXECUTION_FAILURE)); } bash-2.05a/builtins/echo.def100664 436 0 10356 7026424270 14214 0ustar chetwheelThis file is echo.def, from which is created echo.c. It implements the builtin "echo" in Bash. Copyright (C) 1987, 1989, 1991 Free Software Foundation, Inc. This file is part of GNU Bash, the Bourne Again SHell. Bash is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 2, or (at your option) any later version. Bash is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with Bash; see the file COPYING. If not, write to the Free Software Foundation, 59 Temple Place, Suite 330, Boston, MA 02111 USA. $PRODUCES echo.c #include #if defined (HAVE_UNISTD_H) # include #endif #include "../bashansi.h" #include #include "../shell.h" $BUILTIN echo $FUNCTION echo_builtin $DEPENDS_ON V9_ECHO $SHORT_DOC echo [-neE] [arg ...] Output the ARGs. If -n is specified, the trailing newline is suppressed. If the -e option is given, interpretation of the following backslash-escaped characters is turned on: \a alert (bell) \b backspace \c suppress trailing newline \E escape character \f form feed \n new line \r carriage return \t horizontal tab \v vertical tab \\ backslash \num the character whose ASCII code is NUM (octal). You can explicitly turn off the interpretation of the above characters with the -E option. $END $BUILTIN echo $FUNCTION echo_builtin $DEPENDS_ON !V9_ECHO $SHORT_DOC echo [-n] [arg ...] Output the ARGs. If -n is specified, the trailing newline is suppressed. $END #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) 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; 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: 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 } if (do_v9 && temp) free (temp); list = list->next; if (i) { display_return = 0; break; } if (list) putchar(' '); } if (display_return) putchar ('\n'); fflush (stdout); if (ferror (stdout)) { clearerr (stdout); return (EXECUTION_FAILURE); } return (EXECUTION_SUCCESS); } bash-2.05a/builtins/enable.def100644 436 0 27101 7342747454 14533 0ustar chetwheelThis file is enable.def, from which is created enable.c. It implements the builtin "enable" in Bash. Copyright (C) 1987, 1989, 1991 Free Software Foundation, Inc. This file is part of GNU Bash, the Bourne Again SHell. Bash is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 2, or (at your option) any later version. Bash is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with Bash; see the file COPYING. If not, write to the Free Software Foundation, 59 Temple Place, Suite 330, Boston, MA 02111 USA. $PRODUCES enable.c $BUILTIN enable $FUNCTION enable_builtin $SHORT_DOC enable [-pnds] [-a] [-f filename] [name ...] Enable and disable builtin shell commands. This allows you to use a disk command which has the same name as a shell builtin without specifying a full pathname. If -n is used, the NAMEs become disabled; otherwise NAMEs are enabled. For example, to use the `test' found in $PATH instead of the shell builtin version, type `enable -n test'. On systems supporting dynamic loading, the -f option may be used to load new builtins from the shared object FILENAME. The -d option will delete a builtin previously loaded with -f. If no non-option names are given, or the -p option is supplied, a list of builtins is printed. The -a option means to print every builtin with an indication of whether or not it is enabled. The -s option restricts the output to the POSIX.2 `special' builtins. The -n option displays a list of all disabled builtins. $END #include #if defined (HAVE_UNISTD_H) # ifdef _MINIX # include # endif # include #endif #include #include "../bashansi.h" #include "../shell.h" #include "../builtins.h" #include "../flags.h" #include "common.h" #include "bashgetopt.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 __P((WORD_LIST *, int, char *)); #endif #if defined (HAVE_DLCLOSE) static int dyn_unload_builtin __P((char *)); static void delete_builtin __P((struct builtin *)); static int local_dlclose __P((void *)); #endif static void list_some_builtins __P((int)); static int enable_shell_command __P((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 */ default: builtin_usage (); return (EX_USAGE); } } list = loptend; #if defined (RESTRICTED_SHELL) /* Restricted shells cannot load new builtins. */ if (restricted && (flags & (FFLAG|DFLAG))) { builtin_error ("restricted"); 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) { builtin_error ("%s: not a shell builtin", 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; 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; char *struct_name, *name; struct builtin **new_builtins, *b, *new_shell_builtins, *old_builtin; if (list == 0) return (EXECUTION_FAILURE); #ifndef RTLD_LAZY #define RTLD_LAZY 1 #endif #if defined (_AIX) handle = dlopen (filename, RTLD_NOW|RTLD_GLOBAL); #else handle = dlopen (filename, RTLD_LAZY); #endif /* !_AIX */ if (handle == 0) { builtin_error ("cannot open shared object %s: %s", filename, dlerror ()); 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"); b = (struct builtin *)dlsym (handle, struct_name); if (b == 0) { builtin_error ("cannot find %s in shared object %s: %s", struct_name, filename, dlerror ()); free (struct_name); continue; } free (struct_name); b->flags &= ~STATIC_BUILTIN; if (flags & SPECIAL) b->flags |= SPECIAL_BUILTIN; b->handle = handle; if (old_builtin = builtin_address_internal (name, 1)) { 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; int ref, i; b = builtin_address_internal (name, 1); if (b == 0) { builtin_error ("%s: not a shell builtin", 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++; } /* 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 ("cannot delete %s: %s", name, dlerror ()); return (EXECUTION_FAILURE); } /* Now remove this entry from the builtin table and reinitialize. */ delete_builtin (b); return (EXECUTION_SUCCESS); } #endif bash-2.05a/builtins/eval.def100664 436 0 3034 6752274141 14205 0ustar chetwheelThis file is eval.def, from which is created eval.c. It implements the builtin "eval" in Bash. Copyright (C) 1987, 1989, 1991 Free Software Foundation, Inc. This file is part of GNU Bash, the Bourne Again SHell. Bash is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 2, or (at your option) any later version. Bash is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with Bash; see the file COPYING. If not, write to the Free Software Foundation, 59 Temple Place, Suite 330, Boston, MA 02111 USA. $PRODUCES eval.c $BUILTIN eval $FUNCTION eval_builtin $SHORT_DOC eval [arg ...] Read ARGs as input to the shell and execute the resulting command(s). $END #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); /* Note that parse_and_execute () frees the string it is passed. */ return (list ? parse_and_execute (string_list (list), "eval", SEVAL_NOHIST) : EXECUTION_SUCCESS); } bash-2.05a/builtins/evalfile.c100664 436 0 14200 7367321736 14554 0ustar chetwheel/* Copyright (C) 1996 Free Software Foundation, Inc. This file is part of GNU Bash, the Bourne Again SHell. Bash is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 2, or (at your option) any later version. Bash is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with Bash; see the file COPYING. If not, write to the Free Software Foundation, 59 Temple Place, Suite 330, Boston, MA 02111 USA. */ #include #if defined (HAVE_UNISTD_H) # include #endif #include "../bashtypes.h" #include "posixstat.h" #include "filecntl.h" #include #include #include #include "../bashansi.h" #include "../shell.h" #include "../jobs.h" #include "../builtins.h" #include "../flags.h" #include "../input.h" #include "../execute_cmd.h" #if defined (HISTORY) # include "../bashhist.h" #endif #include "common.h" #if !defined (errno) extern int errno; #endif /* Flags for _evalfile() */ #define FEVAL_ENOENTOK 0x001 #define FEVAL_BUILTIN 0x002 #define FEVAL_UNWINDPROT 0x004 #define FEVAL_NONINT 0x008 #define FEVAL_LONGJMP 0x010 #define FEVAL_HISTORY 0x020 #define FEVAL_CHECKBINARY 0x040 #define FEVAL_REGFILE 0x080 extern int posixly_correct; extern int indirection_level, startup_state, subshell_environment; extern int return_catch_flag, return_catch_value; extern int last_command_exit_value; /* How many `levels' of sourced files we have. */ int sourcelevel = 0; static int _evalfile (filename, flags) const char *filename; int flags; { volatile int old_interactive; procenv_t old_return_catch; int return_val, fd, result, pflags; char *string; struct stat finfo; size_t file_size; sh_vmsg_func_t *errfunc; USE_VAR(pflags); fd = open (filename, O_RDONLY); if (fd < 0 || (fstat (fd, &finfo) == -1)) { file_error_and_exit: if (((flags & FEVAL_ENOENTOK) == 0) || errno != ENOENT) file_error (filename); if (flags & FEVAL_LONGJMP) { last_command_exit_value = 1; jump_to_top_level (EXITPROG); } return ((flags & FEVAL_BUILTIN) ? EXECUTION_FAILURE : ((errno == ENOENT) ? 0 : -1)); } errfunc = ((flags & FEVAL_BUILTIN) ? builtin_error : internal_error); if (S_ISDIR (finfo.st_mode)) { (*errfunc) ("%s: is a directory", filename); return ((flags & FEVAL_BUILTIN) ? EXECUTION_FAILURE : -1); } else if ((flags & FEVAL_REGFILE) && S_ISREG (finfo.st_mode) == 0) { (*errfunc) ("%s: not a regular file", filename); return ((flags & FEVAL_BUILTIN) ? EXECUTION_FAILURE : -1); } file_size = (size_t)finfo.st_size; /* Check for overflow with large files. */ if (file_size != finfo.st_size || file_size + 1 < file_size) { (*errfunc) ("%s: file is too large", filename); return ((flags & FEVAL_BUILTIN) ? EXECUTION_FAILURE : -1); } #if defined (__CYGWIN__) && defined (O_TEXT) setmode (fd, O_TEXT); #endif string = (char *)xmalloc (1 + file_size); result = read (fd, string, file_size); string[result] = '\0'; return_val = errno; close (fd); errno = return_val; if (result < 0) /* XXX was != file_size, not < 0 */ { free (string); goto file_error_and_exit; } if (result == 0) { free (string); return ((flags & FEVAL_BUILTIN) ? EXECUTION_SUCCESS : 1); } if ((flags & FEVAL_CHECKBINARY) && check_binary_file (string, (result > 80) ? 80 : result)) { free (string); (*errfunc) ("%s: cannot execute binary file", filename); return ((flags & FEVAL_BUILTIN) ? EX_BINARY_FILE : -1); } if (flags & FEVAL_UNWINDPROT) { begin_unwind_frame ("_evalfile"); unwind_protect_int (return_catch_flag); unwind_protect_jmp_buf (return_catch); if (flags & FEVAL_NONINT) unwind_protect_int (interactive); unwind_protect_int (sourcelevel); } else { COPY_PROCENV (return_catch, old_return_catch); if (flags & FEVAL_NONINT) old_interactive = interactive; } if (flags & FEVAL_NONINT) interactive = 0; return_catch_flag++; sourcelevel++; /* set the flags to be passed to parse_and_execute */ pflags = (flags & FEVAL_HISTORY) ? 0 : SEVAL_NOHIST; if (flags & FEVAL_BUILTIN) result = EXECUTION_SUCCESS; return_val = setjmp (return_catch); /* If `return' was seen outside of a function, but in the script, then force parse_and_execute () to clean up. */ if (return_val) { parse_and_execute_cleanup (); result = return_catch_value; } else result = parse_and_execute (string, filename, pflags); if (flags & FEVAL_UNWINDPROT) run_unwind_frame ("_evalfile"); else { if (flags & FEVAL_NONINT) interactive = old_interactive; return_catch_flag--; sourcelevel--; COPY_PROCENV (old_return_catch, return_catch); } return ((flags & FEVAL_BUILTIN) ? result : 1); } int maybe_execute_file (fname, force_noninteractive) const char *fname; int force_noninteractive; { char *filename; int result, flags; filename = bash_tilde_expand (fname); flags = FEVAL_ENOENTOK; if (force_noninteractive) flags |= FEVAL_NONINT; result = _evalfile (filename, flags); free (filename); return result; } #if defined (HISTORY) int fc_execute_file (filename) const char *filename; { int flags; /* We want these commands to show up in the history list if remember_on_history is set. */ flags = FEVAL_ENOENTOK|FEVAL_HISTORY|FEVAL_REGFILE; return (_evalfile (filename, flags)); } #endif /* HISTORY */ int source_file (filename) const char *filename; { int flags; flags = FEVAL_BUILTIN|FEVAL_UNWINDPROT|FEVAL_NONINT; /* POSIX shells exit if non-interactive and file error. */ if (posixly_correct && !interactive_shell) flags |= FEVAL_LONGJMP; return (_evalfile (filename, flags)); } bash-2.05a/builtins/evalstring.c100644 436 0 21230 7347471412 15135 0ustar chetwheel/* Copyright (C) 1996 Free Software Foundation, Inc. This file is part of GNU Bash, the Bourne Again SHell. Bash is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 2, or (at your option) any later version. Bash is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with Bash; see the file COPYING. If not, write to the Free Software Foundation, 59 Temple Place, Suite 330, Boston, MA 02111 USA. */ #include #if defined (HAVE_UNISTD_H) # ifdef _MINIX # include # endif # include #endif #include #include #include #include "filecntl.h" #include "../bashansi.h" #include "../shell.h" #include "../jobs.h" #include "../builtins.h" #include "../flags.h" #include "../input.h" #include "../execute_cmd.h" #include "../redir.h" #include "../trap.h" #if defined (HISTORY) # include "../bashhist.h" #endif #include "common.h" #if !defined (errno) extern int errno; #endif #define IS_BUILTIN(s) (builtin_address_internal(s, 0) != (struct builtin *)NULL) extern int indirection_level, startup_state, subshell_environment; extern int line_number; extern int last_command_exit_value; extern int running_trap; extern int posixly_correct; int parse_and_execute_level = 0; static int cat_file __P((REDIRECT *)); /* How to force parse_and_execute () to clean up after itself. */ void parse_and_execute_cleanup () { if (running_trap) { run_trap_cleanup (running_trap - 1); unfreeze_jobs_list (); } run_unwind_frame ("parse_and_execute_top"); } /* Parse and execute the commands in STRING. Returns whatever execute_command () returns. This frees STRING. FLAGS is a flags word; look in common.h for the possible values. Actions are: (flags & SEVAL_NONINT) -> interactive = 0; (flags & SEVAL_INTERACT) -> interactive = 1; (flags & SEVAL_NOHIST) -> call bash_history_disable () */ int parse_and_execute (string, from_file, flags) char *string; const char *from_file; int flags; { int code, x; volatile int should_jump_to_top_level, last_result; char *orig_string; COMMAND *volatile command; orig_string = string; /* Unwind protect this invocation of parse_and_execute (). */ begin_unwind_frame ("parse_and_execute_top"); unwind_protect_int (parse_and_execute_level); unwind_protect_jmp_buf (top_level); unwind_protect_int (indirection_level); unwind_protect_int (line_number); if (flags & (SEVAL_NONINT|SEVAL_INTERACT)) unwind_protect_int (interactive); #if defined (HISTORY) unwind_protect_int (remember_on_history); /* can be used in scripts */ # if defined (BANG_HISTORY) if (interactive_shell) { unwind_protect_int (history_expansion_inhibited); } # endif /* BANG_HISTORY */ #endif /* HISTORY */ if (interactive_shell) { x = get_current_prompt_level (); add_unwind_protect (set_current_prompt_level, x); } add_unwind_protect (pop_stream, (char *)NULL); if (orig_string) add_unwind_protect (xfree, orig_string); end_unwind_frame (); parse_and_execute_level++; push_stream (1); /* reset the line number */ indirection_level++; if (flags & (SEVAL_NONINT|SEVAL_INTERACT)) interactive = (flags & SEVAL_NONINT) ? 0 : 1; #if defined (HISTORY) if (flags & SEVAL_NOHIST) bash_history_disable (); #endif /* HISTORY */ code = should_jump_to_top_level = 0; last_result = EXECUTION_SUCCESS; command = (COMMAND *)NULL; with_input_from_string (string, from_file); while (*(bash_input.location.string)) { if (interrupt_state) { last_result = EXECUTION_FAILURE; break; } /* Provide a location for functions which `longjmp (top_level)' to jump to. This prevents errors in substitution from restarting the reader loop directly, for example. */ code = setjmp (top_level); if (code) { should_jump_to_top_level = 0; switch (code) { case FORCE_EOF: case EXITPROG: run_unwind_frame ("pe_dispose"); /* Remember to call longjmp (top_level) after the old value for it is restored. */ should_jump_to_top_level = 1; goto out; case DISCARD: run_unwind_frame ("pe_dispose"); last_result = last_command_exit_value = EXECUTION_FAILURE; /* XXX */ if (subshell_environment) { should_jump_to_top_level = 1; goto out; } else { #if 0 dispose_command (command); /* pe_dispose does this */ #endif continue; } default: command_error ("parse_and_execute", CMDERR_BADJUMP, code, 0); break; } } if (parse_command () == 0) { if (interactive_shell == 0 && read_but_dont_execute) { last_result = EXECUTION_SUCCESS; dispose_command (global_command); global_command = (COMMAND *)NULL; } else if (command = global_command) { struct fd_bitmap *bitmap; bitmap = new_fd_bitmap (FD_BITMAP_SIZE); begin_unwind_frame ("pe_dispose"); add_unwind_protect (dispose_fd_bitmap, bitmap); add_unwind_protect (dispose_command, command); /* XXX */ global_command = (COMMAND *)NULL; #if defined (ONESHOT) /* * IF * we were invoked as `bash -c' (startup_state == 2) AND * parse_and_execute has not been called recursively AND * we have parsed the full command (string == '\0') AND * we have a simple command without redirections AND * the command is not being timed * THEN * tell the execution code that we don't need to fork */ if (startup_state == 2 && parse_and_execute_level == 1 && *bash_input.location.string == '\0' && command->type == cm_simple && !command->redirects && !command->value.Simple->redirects && ((command->flags & CMD_TIME_PIPELINE) == 0)) { command->flags |= CMD_NO_FORK; command->value.Simple->flags |= CMD_NO_FORK; } #endif /* ONESHOT */ /* See if this is a candidate for $( type == cm_simple && !command->redirects && (command->flags & CMD_TIME_PIPELINE) == 0 && command->value.Simple->words == 0 && command->value.Simple->redirects && command->value.Simple->redirects->next == 0 && command->value.Simple->redirects->instruction == r_input_direction) { int r; r = cat_file (command->value.Simple->redirects); last_result = (r < 0) ? EXECUTION_FAILURE : EXECUTION_SUCCESS; } else last_result = execute_command_internal (command, 0, NO_PIPE, NO_PIPE, bitmap); dispose_command (command); dispose_fd_bitmap (bitmap); discard_unwind_frame ("pe_dispose"); } } else { last_result = EXECUTION_FAILURE; /* Since we are shell compatible, syntax errors in a script abort the execution of the script. Right? */ break; } } out: run_unwind_frame ("parse_and_execute_top"); if (interrupt_state && parse_and_execute_level == 0) { /* An interrupt during non-interactive execution in an interactive shell (e.g. via $PROMPT_COMMAND) should not cause the shell to exit. */ interactive = interactive_shell; throw_to_top_level (); } if (should_jump_to_top_level) jump_to_top_level (code); return (last_result); } /* Handle a $( < file ) command substitution. This expands the filename, returning errors as appropriate, then just cats the file to the standard output. */ static int cat_file (r) REDIRECT *r; { char lbuf[128], *fn; int fd, rval; ssize_t nr; if (r->instruction != r_input_direction) return -1; /* Get the filename. */ if (posixly_correct && !interactive_shell) disallow_filename_globbing++; fn = redirection_expand (r->redirectee.filename); if (posixly_correct && !interactive_shell) disallow_filename_globbing--; if (fn == 0) { redirection_error (r, AMBIGUOUS_REDIRECT); return -1; } fd = open(fn, O_RDONLY); if (fd < 0) { file_error (fn); free (fn); return -1; } rval = 0; while (1) { nr = zread (fd, lbuf, sizeof(lbuf)); if (nr == 0) break; else if (nr < 0) { rval = -1; break; } if (zwrite (1, lbuf, nr) < 0) { rval = -1; break; } } free (fn); close (fd); return (rval); } bash-2.05a/builtins/exec.def100664 436 0 13020 7347463556 14231 0ustar chetwheelThis file is exec.def, from which is created exec.c. It implements the builtin "exec" in Bash. Copyright (C) 1987, 1989, 1991 Free Software Foundation, Inc. This file is part of GNU Bash, the Bourne Again SHell. Bash is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 2, or (at your option) any later version. Bash is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with Bash; see the file COPYING. If not, write to the Free Software Foundation, 59 Temple Place, Suite 330, Boston, MA 02111 USA. $PRODUCES exec.c $BUILTIN exec $FUNCTION exec_builtin $SHORT_DOC exec [-cl] [-a name] file [redirection ...] Exec FILE, replacing this shell with the specified program. If FILE is not specified, the redirections take effect in this shell. If the first argument is `-l', then place a dash in the zeroth arg passed to FILE, as login does. If the `-c' option is supplied, FILE is executed with a null environment. The `-a' option means to make set argv[0] of the executed process to NAME. If the file cannot be executed and the shell is not interactive, then the shell exits, unless the shell option `execfail' is set. $END #include #include "../bashtypes.h" #include "posixstat.h" #include #include #if defined (HAVE_UNISTD_H) # include #endif #include "../bashansi.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" /* Not all systems declare ERRNO in errno.h... and some systems #define it! */ #if !defined (errno) extern int errno; #endif /* !errno */ extern int subshell_environment; extern REDIRECT *redirection_undo_list; 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; char *argv0, *command, **args, **env, *newname, *com2; cleanenv = login = 0; 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; 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) { builtin_error ("restricted"); return (EXECUTION_FAILURE); } #endif /* RESTRICTED_SHELL */ args = word_list_to_argv (list, 1, 0, (int *)NULL); /* 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]); if (command == 0) { builtin_error ("%s: not found", 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); } 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 (cleanenv == 0) adjust_shell_level (-1); if (cleanenv) env = (char **)NULL; 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) if (subshell_environment == 0) end_job_control (); #endif /* JOB_CONTROL */ 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 (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: if (command) free (command); if (subshell_environment || (interactive == 0 && no_exit_on_failed_exec == 0)) exit_shell (exit_value); if (args) free_array (args); initialize_traps (); reinitialize_signals (); #if defined (JOB_CONTROL) restart_job_control (); #endif /* JOB_CONTROL */ return (exit_value); } bash-2.05a/builtins/exit.def100664 436 0 7010 7347463662 14236 0ustar chetwheelThis file is exit.def, from which is created exit.c. It implements the builtins "exit", and "logout" in Bash. Copyright (C) 1987, 1989, 1991 Free Software Foundation, Inc. This file is part of GNU Bash, the Bourne Again SHell. Bash is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 2, or (at your option) any later version. Bash is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with Bash; see the file COPYING. If not, write to the Free Software Foundation, 59 Temple Place, Suite 330, Boston, MA 02111 USA. $PRODUCES exit.c $BUILTIN exit $FUNCTION exit_builtin $SHORT_DOC exit [n] Exit the shell with a status of N. If N is omitted, the exit status is that of the last command executed. $END #include #include "../bashtypes.h" #include #if defined (HAVE_UNISTD_H) # include #endif #include "../shell.h" #include "../jobs.h" #include "common.h" #include "builtext.h" /* for jobs_builtin */ extern int last_command_exit_value; extern int subshell_environment; extern sh_builtin_func_t *this_shell_builtin; extern sh_builtin_func_t *last_shell_builtin; static int exit_or_logout __P((WORD_LIST *)); static int sourced_logout; int exit_builtin (list) WORD_LIST *list; { if (interactive) { fprintf (stderr, login_shell ? "logout\n" : "exit\n"); fflush (stderr); } return (exit_or_logout (list)); } $BUILTIN logout $FUNCTION logout_builtin $SHORT_DOC logout Logout of a login shell. $END /* How to logout. */ int logout_builtin (list) WORD_LIST *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; 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) { register int i; for (i = 0; i < job_slots; i++) if (jobs[i] && STOPPED (i)) { fprintf (stderr, "There are stopped jobs.\n"); /* 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. */ exit_value = list ? get_exitstat (list) : last_command_exit_value; /* 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 } last_command_exit_value = exit_value; /* Exit the program. */ jump_to_top_level (EXITPROG); /*NOTREACHED*/ } bash-2.05a/builtins/fc.def100664 436 0 36335 7347702745 13707 0ustar chetwheelThis file is fc.def, from which is created fc.c. It implements the builtin "fc" in Bash. Copyright (C) 1987, 1989, 1991 Free Software Foundation, Inc. This file is part of GNU Bash, the Bourne Again SHell. Bash is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 2, or (at your option) any later version. Bash is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with Bash; see the file COPYING. If not, write to the Free Software Foundation, 59 Temple Place, Suite 330, Boston, MA 02111 USA. $PRODUCES fc.c $BUILTIN fc $FUNCTION fc_builtin $DEPENDS_ON HISTORY $SHORT_DOC fc [-e ename] [-nlr] [first] [last] or fc -s [pat=rep] [cmd] fc is used to list or edit and re-execute commands from the history list. 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 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). With the `fc -s [pat=rep ...] [command]' format, the command is re-executed after the substitution OLD=NEW is performed. A useful alias to use with this is r='fc -s', so that typing `r cc' runs the last command beginning with `cc' and typing `r' re-executes the last command. $END #include #if defined (HISTORY) #ifndef _MINIX # include #endif #include "../bashtypes.h" #include "posixstat.h" #ifndef _MINIX # include #endif #if defined (HAVE_UNISTD_H) # include #endif #include #include #include "../bashansi.h" #include #include "../shell.h" #include "../builtins.h" #include "../flags.h" #include "../bashhist.h" #include "maxpath.h" #include #include "bashgetopt.h" #include "common.h" #if !defined (errno) extern int errno; #endif /* !errno */ extern int echo_input_at_read; extern int current_command_line_count; extern int literal_history; extern int unlink __P((const char *)); extern FILE *sh_mktmpfp __P((char *, int, char **)); /* **************************************************************** */ /* */ /* 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 __P((char *, REPL *)); static char *fc_gethist __P((char *, HIST_ENTRY **)); static int fc_gethnum __P((char *, HIST_ENTRY **)); static int fc_number __P((WORD_LIST *)); static void fc_replhist __P((char *)); #ifdef INCLUDE_UNUSED static char *fc_readline __P((FILE *)); static void fc_addhist __P((char *)); #endif /* String to execute on a file that we want to edit. */ #define FC_EDIT_COMMAND "${FCEDIT:-${EDITOR:-vi}}" 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; FILE *stream; REPL *rlist, *rl; char *ename, *command, *newcom; 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 = 1; break; case 'r': reverse = 1; break; case 's': execute = 1; break; case 'e': ename = list_optarg; break; 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. */ if (rlist && rlist->next) rlist = (REPL *)reverse_list ((GENERIC_LIST *) rlist); 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); 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 */ 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. */ last_hist = i - 1 - hist_last_line_added; if (list) { histbeg = fc_gethnum (list->word->word, hlist); list = list->next; if (list) histend = fc_gethnum (list->word->word, hlist); 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; if (histbeg < 0) histbeg = 0; } else /* For editing, it is the last history command. */ histbeg = histend = last_hist; } /* We print error messages for line specifications out of range. */ if ((histbeg < 0) || (histend < 0) || (histbeg > last_hist) || (histend > last_hist)) { builtin_error ("history specification out of range"); return (EXECUTION_FAILURE); } 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 ("cannot open temp file %s", fn ? fn : ""); 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) fprintf (stream, "\t%c", histdata (i) ? '*' : ' '); fprintf (stream, "%s\n", histline (i)); } if (listing) return (EXECUTION_SUCCESS); 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 { command = (char *)xmalloc (3 + strlen (FC_EDIT_COMMAND) + strlen (fn)); sprintf (command, "%s %s", FC_EDIT_COMMAND, fn); } retval = parse_and_execute (command, "fc", SEVAL_NOHIST); if (retval != EXECUTION_SUCCESS) { unlink (fn); free (fn); return (EXECUTION_FAILURE); } /* 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 ((Function *)xfree, fn); add_unwind_protect (unlink, fn); unwind_protect_int (echo_input_at_read); echo_input_at_read = 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, (long *)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. */ static int fc_gethnum (command, hlist) char *command; HIST_ENTRY **hlist; { int sign = 1, n, clen; register int i, j; register char *s; /* 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. */ i -= 1 + hist_last_line_added; /* No specification defaults to most recent command. */ if (command == NULL) return (i); /* 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; /* Anything specified greater than the last history element that we deal with is an error. */ if (n > i + history_base) return (-1); /* If the value is negative or zero, then it is an offset from the current history item. */ if (n < 0) return (i + n + 1); else if (n == 0) return (i); else return (n - history_base); } clen = strlen (command); for (j = i; j >= 0; j--) { if (STREQN (command, histline (j), clen)) return (j); } return (-1); } /* Locate the most recent history line which begins with COMMAND in HLIST, and return a malloc()'ed copy of it. */ static char * fc_gethist (command, hlist) char *command; HIST_ENTRY **hlist; { int i; if (!hlist) return ((char *)NULL); i = fc_gethnum (command, hlist); 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; { register int i; HIST_ENTRY **hlist, *histent, *discard; int n; if (command == 0 || *command == '\0') return; hlist = history_list (); if (hlist == NULL) return; for (i = 0; hlist[i]; i++); i--; /* History_get () takes a parameter that should be offset by history_base. */ histent = history_get (history_base + i); /* Don't free this */ if (histent == NULL) return; n = strlen (command); if (command[n - 1] == '\n') command[n - 1] = '\0'; if (command && *command) { discard = remove_history (i); if (discard) { FREE (discard->line); free ((char *) discard); } 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; n = strlen (line); if (line[n - 1] == '\n') line[n - 1] = '\0'; if (line && *line) maybe_add_history (line); } #endif #endif /* HISTORY */ bash-2.05a/builtins/fg_bg.def100644 436 0 7067 7277777517 14354 0ustar chetwheelThis file is fg_bg.def, from which is created fg_bg.c. It implements the builtins "bg" and "fg" in Bash. Copyright (C) 1987, 1989, 1991 Free Software Foundation, Inc. This file is part of GNU Bash, the Bourne Again SHell. Bash is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 2, or (at your option) any later version. Bash is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with Bash; see the file COPYING. If not, write to the Free Software Foundation, 59 Temple Place, Suite 330, Boston, MA 02111 USA. $PRODUCES fg_bg.c $BUILTIN fg $FUNCTION fg_builtin $DEPENDS_ON JOB_CONTROL $SHORT_DOC fg [job_spec] Place JOB_SPEC in the foreground, and make it the current job. If JOB_SPEC is not present, the shell's notion of the current job is used. $END #include #include "../bashtypes.h" #include #if defined (HAVE_UNISTD_H) # include #endif #include "../shell.h" #include "../jobs.h" #include "common.h" #if defined (JOB_CONTROL) extern char *this_command_name; static int fg_bg __P((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; if (job_control == 0) { builtin_error ("no job control"); return (EXECUTION_FAILURE); } if (no_options (list)) return (EX_USAGE); /* 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 */ $BUILTIN bg $FUNCTION bg_builtin $DEPENDS_ON JOB_CONTROL $SHORT_DOC bg [job_spec] Place JOB_SPEC in the background, as if it had been started with `&'. If JOB_SPEC is not present, the shell's notion of the current job is used. $END #if defined (JOB_CONTROL) /* How to put a job into the background. */ int bg_builtin (list) WORD_LIST *list; { if (job_control == 0) { builtin_error ("no job control"); return (EXECUTION_FAILURE); } if (no_options (list)) return (EX_USAGE); return (fg_bg (list, 0)); } /* 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; BLOCK_CHILD (set, oset); job = get_job_spec (list); if (job < 0 || job >= job_slots || jobs[job] == 0) { if (job != DUP_JOB) builtin_error ("%s: no such job", list ? list->word->word : "current"); goto failure; } /* Or if jobs[job]->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 = jobs[job]->pgrp; /* As per Posix.2 5.4.2 */ } status = start_job (job, foreground); if (status >= 0) { /* win: */ UNBLOCK_CHILD (oset); return (status); } else { if (foreground == 0) last_asynchronous_pid = old_async_pid; failure: UNBLOCK_CHILD (oset); return (EXECUTION_FAILURE); } } #endif /* JOB_CONTROL */ bash-2.05a/builtins/getopt.c100664 436 0 20546 6752273127 14276 0ustar chetwheel/* getopt for BASH. Copyright (C) 1993, 1994 Free Software Foundation, Inc. This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 2, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program; if not, write to the Free Software Foundation, 59 Temple Place, Suite 330, Boston, MA 02111 USA. */ #include #if defined (HAVE_UNISTD_H) # ifdef _MINIX # include # endif # include #endif #include #include "memalloc.h" #include "../shell.h" #include "getopt.h" /* For communication from `sh_getopt' to the caller. When `sh_getopt' finds an option that takes an argument, the argument value is returned here. */ char *sh_optarg = 0; /* Index in ARGV of the next element to be scanned. This is used for communication to and from the caller and for communication between successive calls to `sh_getopt'. On entry to `sh_getopt', zero means this is the first call; initialize. When `sh_getopt' returns EOF, this is the index of the first of the non-option elements that the caller should itself scan. Otherwise, `sh_optind' communicates from one call to the next how much of ARGV has been scanned so far. */ /* XXX 1003.2 says this must be 1 before any call. */ int sh_optind = 0; /* Index of the current argument. */ static int sh_curopt; /* The next char to be scanned in the option-element in which the last option character we returned was found. This allows us to pick up the scan where we left off. If this is zero, or a null string, it means resume the scan by advancing to the next ARGV-element. */ static char *nextchar; static int sh_charindex; /* Callers store zero here to inhibit the error message for unrecognized options. */ int sh_opterr = 1; /* Set to an option character which was unrecognized. This must be initialized on some systems to avoid linking in the system's own getopt implementation. */ int sh_optopt = '?'; /* Set to 1 when we see an illegal option; public so getopts can reset it. */ int sh_badopt = 0; /* Scan elements of ARGV (whose length is ARGC) for option characters given in OPTSTRING. If an element of ARGV starts with '-', and is not exactly "-" or "--", then it is an option element. The characters of this element (aside from the initial '-') are option characters. If `sh_getopt' is called repeatedly, it returns successively each of the option characters from each of the option elements. If `sh_getopt' finds another option character, it returns that character, updating `sh_optind' and `nextchar' so that the next call to `sh_getopt' can resume the scan with the following option character or ARGV-element. If there are no more option characters, `sh_getopt' returns `EOF'. Then `sh_optind' is the index in ARGV of the first ARGV-element that is not an option. OPTSTRING is a string containing the legitimate option characters. If an option character is seen that is not listed in OPTSTRING, return '?' after printing an error message. If you set `sh_opterr' to zero, the error message is suppressed but we still return '?'. If a char in OPTSTRING is followed by a colon, that means it wants an arg, so the following text in the same ARGV-element, or the text of the following ARGV-element, is returned in `sh_optarg'. */ /* 1003.2 specifies the format of this message. */ #define BADOPT(x) fprintf (stderr, "%s: illegal option -- %c\n", argv[0], x) #define NEEDARG(x) fprintf (stderr, "%s: option requires an argument -- %c\n", argv[0], x) int sh_getopt (argc, argv, optstring) int argc; char *const *argv; const char *optstring; { char c, *temp; sh_optarg = 0; if (sh_optind >= argc || sh_optind < 0) /* XXX was sh_optind > argc */ { sh_optind = argc; return (EOF); } /* Initialize the internal data when the first call is made. Start processing options with ARGV-element 1 (since ARGV-element 0 is the program name); the sequence of previously skipped non-option ARGV-elements is empty. */ if (sh_optind == 0) { sh_optind = 1; nextchar = (char *)NULL; } /* Do the increment of `sh_optind' we deferred because the last option was illegal. */ if (sh_badopt && (nextchar == 0 || *nextchar == '\0')) { sh_badopt = 0; sh_optind++; nextchar = (char *)NULL; } if (nextchar == 0 || *nextchar == '\0') { /* If we have done all the ARGV-elements, stop the scan. */ if (sh_optind >= argc) return EOF; temp = argv[sh_optind]; /* Special ARGV-element `--' means premature end of options. Skip it like a null option, and return EOF. */ if (temp[0] == '-' && temp[1] == '-' && temp[2] == '\0') { sh_optind++; return EOF; } /* If we have come to a non-option, either stop the scan or describe it to the caller and pass it by. This makes the pseudo-option `-' mean the end of options, but does not skip over it. */ if (temp[0] != '-' || temp[1] == '\0') return EOF; /* We have found another option-ARGV-element. Start decoding its characters. */ nextchar = argv[sh_curopt = sh_optind] + 1; sh_charindex = 1; } /* Look at and handle the next option-character. */ c = *nextchar++; sh_charindex++; temp = strchr (optstring, c); sh_optopt = c; /* If the option is illegal, return an error, but defer updating sh_optind until the next call so $OPTIND is correct. */ if (sh_badopt = (temp == NULL || c == ':')) { if (sh_opterr) BADOPT (c); return '?'; } /* Increment `sh_optind' when we start to process its last character. */ if (nextchar == 0 || *nextchar == '\0') { sh_optind++; nextchar = (char *)NULL; } if (temp[1] == ':') { if (nextchar && *nextchar) { /* This is an option that requires an argument. */ sh_optarg = nextchar; /* If we end this ARGV-element by taking the rest as an arg, we must advance to the next element now. */ sh_optind++; } else if (sh_optind == argc) { if (sh_opterr) NEEDARG (c); sh_optopt = c; sh_optarg = ""; /* Needed by getopts. */ c = (optstring[0] == ':') ? ':' : '?'; } else /* We already incremented `sh_optind' once; increment it again when taking next ARGV-elt as argument. */ sh_optarg = argv[sh_optind++]; nextchar = (char *)NULL; } return c; } void sh_getopt_restore_state (argv) char **argv; { if (nextchar) nextchar = argv[sh_curopt] + sh_charindex; } #if 0 void sh_getopt_debug_restore_state (argv) char **argv; { if (nextchar && nextchar != argv[sh_curopt] + sh_charindex) { itrace("sh_getopt_debug_restore_state: resetting nextchar"); nextchar = argv[sh_curopt] + sh_charindex; } } #endif #ifdef TEST /* Compile with -DTEST to make an executable for use in testing the above definition of `sh_getopt'. */ int main (argc, argv) int argc; char **argv; { int c; int digit_sh_optind = 0; while (1) { int this_option_sh_optind = sh_optind ? sh_optind : 1; c = sh_getopt (argc, argv, "abc:d:0123456789"); if (c == EOF) break; switch (c) { case '0': case '1': case '2': case '3': case '4': case '5': case '6': case '7': case '8': case '9': if (digit_sh_optind != 0 && digit_sh_optind != this_option_sh_optind) printf ("digits occur in two different argv-elements.\n"); digit_sh_optind = this_option_sh_optind; printf ("option %c\n", c); break; case 'a': printf ("option a\n"); break; case 'b': printf ("option b\n"); break; case 'c': printf ("option c with value `%s'\n", sh_optarg); break; case '?': break; default: printf ("?? sh_getopt returned character code 0%o ??\n", c); } } if (sh_optind < argc) { printf ("non-option ARGV-elements: "); while (sh_optind < argc) printf ("%s ", argv[sh_optind++]); printf ("\n"); } exit (0); } #endif /* TEST */ bash-2.05a/builtins/getopt.h100664 436 0 4135 7347201241 14244 0ustar chetwheel/* Declarations for getopt. Copyright (C) 1989, 1990, 1991, 1992, 1993 Free Software Foundation, Inc. This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 2, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program; if not, write to the Free Software Foundation, 59 Temple Place, Suite 330, Boston, MA 02111 USA. */ /* XXX THIS HAS BEEN MODIFIED FOR INCORPORATION INTO BASH XXX */ #ifndef _SH_GETOPT_H #define _SH_GETOPT_H 1 #include "stdc.h" /* For communication from `getopt' to the caller. When `getopt' finds an option that takes an argument, the argument value is returned here. Also, when `ordering' is RETURN_IN_ORDER, each non-option ARGV-element is returned here. */ extern char *sh_optarg; /* Index in ARGV of the next element to be scanned. This is used for communication to and from the caller and for communication between successive calls to `getopt'. On entry to `getopt', zero means this is the first call; initialize. When `getopt' returns EOF, this is the index of the first of the non-option elements that the caller should itself scan. Otherwise, `sh_optind' communicates from one call to the next how much of ARGV has been scanned so far. */ extern int sh_optind; /* Callers store zero here to inhibit the error message `getopt' prints for unrecognized options. */ extern int sh_opterr; /* Set to an option character which was unrecognized. */ extern int sh_optopt; /* Set to 1 when an unrecognized option is encountered. */ extern int sh_badopt; extern int sh_getopt __P((int, char *const *, const char *)); extern void sh_getopt_restore_state __P((char **)); #endif /* _SH_GETOPT_H */ bash-2.05a/builtins/getopts.def100664 436 0 17665 7347465040 15003 0ustar chetwheelThis file is getopts.def, from which is created getopts.c. It implements the builtin "getopts" in Bash. Copyright (C) 1987, 1989, 1991 Free Software Foundation, Inc. This file is part of GNU Bash, the Bourne Again SHell. Bash is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 2, or (at your option) any later version. Bash is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with Bash; see the file COPYING. If not, write to the Free Software Foundation, 59 Temple Place, Suite 330, Boston, MA 02111 USA. $PRODUCES getopts.c $BUILTIN getopts $FUNCTION getopts_builtin $SHORT_DOC getopts optstring name [arg] Getopts is used by shell procedures to parse positional parameters. OPTSTRING contains the option letters to be recognized; if a letter is followed by a colon, the option is expected to have an argument, which should be separated from it by white space. Each time it is invoked, getopts will place the next option in the shell variable $name, initializing name if it does not exist, and the index of the next argument to be processed into the shell variable OPTIND. OPTIND is initialized to 1 each time the shell or a shell script is invoked. When an option requires an argument, getopts places that argument into the shell variable OPTARG. getopts reports errors in one of two ways. If the first character of OPTSTRING is a colon, getopts uses silent error reporting. In this mode, no error messages are printed. If an illegal option is seen, getopts places the option character found into OPTARG. If a required argument is not found, getopts places a ':' into NAME and sets OPTARG to the option character found. If getopts is not in silent mode, and an illegal option is seen, getopts places '?' into NAME and unsets OPTARG. If a required option is not found, a '?' is placed in NAME, OPTARG is unset, and a diagnostic message is printed. If the shell variable OPTERR has the value 0, getopts disables the printing of error messages, even if the first character of OPTSTRING is not a colon. OPTERR has the value 1 by default. Getopts normally parses the positional parameters ($0 - $9), but if more arguments are given, they are parsed instead. $END #include #include #if defined (HAVE_UNISTD_H) # ifdef _MINIX # include # endif # include #endif #include "../bashansi.h" #include "../shell.h" #include "common.h" #include "bashgetopt.h" #include "getopt.h" #define G_EOF -1 #define G_ILLEGAL_OPT -2 #define G_ARG_MISSING -3 extern char *this_command_name; /* 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_bind_variable (name, value) char *name, *value; { SHELL_VAR *v; if (legal_identifier (name)) { v = bind_variable (name, value); return (v && (readonly_p (v) == 0)) ? EXECUTION_SUCCESS : EXECUTION_FAILURE; } else { builtin_error ("`%s': not a valid identifier", 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 illegal option characters. The handling is as follows. ILLEGAL 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; for (i = 0; i < 10 && dollar_vars[i]; i++) ; for (words = rest_of_args; words; words = words->next, i++) ; v = alloc_array (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. */ 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); /* 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 illegal 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_ILLEGAL_OPT; else if (sh_optarg[0] == '\0') ret = G_ARG_MISSING; } if (ret == G_EOF) { getopts_bind_variable (name, "?"); return (EXECUTION_FAILURE); } if (ret == G_ILLEGAL_OPT) { /* Illegal option encountered. */ ret = getopts_bind_variable (name, "?"); if (special_error) { strval[0] = (char)sh_optopt; strval[1] = '\0'; bind_variable ("OPTARG", strval); } else makunbound ("OPTARG", shell_variables); 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); } else { ret = getopts_bind_variable (name, "?"); makunbound ("OPTARG", shell_variables); } return (ret); } bind_variable ("OPTARG", sh_optarg); 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 (internal_getopt (list, "") != -1) { builtin_usage (); return (EX_USAGE); } list = loptend; av = make_builtin_argv (list, &ac); ret = dogetopts (ac, av); free ((char *)av); return (ret); } bash-2.05a/builtins/hash.def100664 436 0 13566 7276264643 14244 0ustar chetwheelThis file is hash.def, from which is created hash.c. It implements the builtin "hash" in Bash. Copyright (C) 1987, 1989, 1991 Free Software Foundation, Inc. This file is part of GNU Bash, the Bourne Again SHell. Bash is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 2, or (at your option) any later version. Bash is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with Bash; see the file COPYING. If not, write to the Free Software Foundation, 59 Temple Place, Suite 330, Boston, MA 02111 USA. $PRODUCES hash.c $BUILTIN hash $FUNCTION hash_builtin $SHORT_DOC hash [-r] [-p pathname] [-t] [name ...] For each NAME, the full pathname of the command is determined and remembered. If the -p option is supplied, PATHNAME is used as the full pathname of NAME, and no path search is performed. The -r option causes the shell to forget all remembered locations. If the -t option is supplied the full pathname to which each NAME corresponds is printed. If multiple NAME arguments are supplied with -t, the NAME is printed before the hashed full pathname. If no arguments are given, information about remembered commands is displayed. $END #include #include #include "../bashtypes.h" #if defined (HAVE_UNISTD_H) # include #endif #include #include "../bashansi.h" #include "../shell.h" #include "../builtins.h" #include "../flags.h" #include "../findcmd.h" #include "../hashcmd.h" #include "common.h" #include "bashgetopt.h" extern int dot_found_in_search; extern char *this_command_name; static int add_hashed_command __P((char *, int)); static int print_hashed_commands __P((void)); static int list_hashed_filename_targets __P((WORD_LIST *)); /* 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, opt; char *w, *pathname; if (hashing_enabled == 0) { builtin_error ("hashing disabled"); return (EXECUTION_FAILURE); } expunge_hash_table = list_targets = 0; pathname = (char *)NULL; reset_internal_getopt (); while ((opt = internal_getopt (list, "rp:t")) != -1) { switch (opt) { case 'r': expunge_hash_table = 1; break; case 'p': pathname = list_optarg; break; case 't': list_targets = 1; break; default: builtin_usage (); return (EX_USAGE); } } list = loptend; /* hash -t requires at least one argument. */ if (list == 0 && list_targets) { builtin_error("-t: argument required"); return (EXECUTION_FAILURE); } /* We want hash -r to be silent, but hash -- to print hashing info. That is the reason for the test of expunge_hash_table. */ if (list == 0 && expunge_hash_table == 0) { if (print_hashed_commands () == 0) printf ("%s: hash table empty\n", this_command_name); return (EXECUTION_SUCCESS); } if (expunge_hash_table) flush_hashed_filenames (); /* If someone runs `hash -r -t xyz' he will be disappointed. */ if (list_targets) { return (list_hashed_filename_targets (list)); } #if defined (RESTRICTED_SHELL) if (restricted && pathname && strchr (pathname, '/')) { builtin_error ("%s: restricted", pathname); return (EXECUTION_FAILURE); } #endif for (opt = EXECUTION_SUCCESS; list; list = list->next) { /* Add or rehash the specified commands. */ w = list->word->word; 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 remember_filename (w, pathname, 0, 0); } else if (absolute_program (w)) continue; 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) { full_path = find_user_command (w); if (full_path && executable_file (full_path)) remember_filename (w, full_path, dot_found_in_search, 0); else { if (quiet == 0) builtin_error ("%s: not found", w); rv++; } if (full_path) free (full_path); } return (rv); } /* Print information about current hashed info. */ static int print_hashed_commands () { BUCKET_CONTENTS *item_list; int bucket, any_printed; if (hashed_filenames == 0) return (0); for (bucket = any_printed = 0; bucket < hashed_filenames->nbuckets; bucket++) { item_list = get_hash_bucket (bucket, hashed_filenames); if (item_list == 0) continue; if (any_printed == 0) { printf ("hits\tcommand\n"); any_printed++; } for ( ; item_list; item_list = item_list->next) printf ("%4d\t%s\n", item_list->times_found, pathdata(item_list)->path); } return (any_printed); } static int list_hashed_filename_targets (list) WORD_LIST *list; { int all_found, multiple; char *target; WORD_LIST *l; all_found = 1; multiple = list->next != 0; for (l = list; l; l = l->next) { target = find_hashed_filename (l->word->word); if (target == 0) { all_found = 0; builtin_error ("%s: not found", l->word->word); continue; } if (multiple) printf ("%s\t", l->word->word); printf ("%s\n", target); } return (all_found ? EXECUTION_SUCCESS : EXECUTION_FAILURE); } bash-2.05a/builtins/help.def100644 436 0 10026 7347143052 14220 0ustar chetwheelThis file is help.def, from which is created help.c. It implements the builtin "help" in Bash. Copyright (C) 1987, 1989, 1991 Free Software Foundation, Inc. This file is part of GNU Bash, the Bourne Again SHell. Bash is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 2, or (at your option) any later version. Bash is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with Bash; see the file COPYING. If not, write to the Free Software Foundation, 59 Temple Place, Suite 330, Boston, MA 02111 USA. $PRODUCES help.c $BUILTIN help $FUNCTION help_builtin $DEPENDS_ON HELP_BUILTIN $SHORT_DOC help [-s] [pattern ...] Display helpful information about builtin commands. If PATTERN is specified, gives detailed help on all commands matching PATTERN, otherwise a list of the builtins is printed. The -s option restricts the output for each builtin command matching PATTERN to a short usage synopsis. $END #include #if defined (HELP_BUILTIN) #include #if defined (HAVE_UNISTD_H) # ifdef _MINIX # include # endif # include #endif #include "../shell.h" #include "../builtins.h" #include "../pathexp.h" #include "common.h" #include "bashgetopt.h" #include #include static void show_builtin_command_help __P((void)); /* 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, j; char *pattern, *name; int plen, match_found, sflag; sflag = 0; reset_internal_getopt (); while ((i = internal_getopt (list, "s")) != -1) { switch (i) { case 's': sflag = 1; break; 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)) { printf ("Shell commands matching keyword%s `", list->next ? "s" : ""); print_word_list (list, ", "); printf ("'\n\n"); } for (match_found = 0, pattern = ""; list; list = list->next) { pattern = list->word->word; plen = strlen (pattern); for (i = 0; name = shell_builtins[i].name; i++) { QUIT; if ((strncmp (pattern, name, plen) == 0) || (strmatch (pattern, name, FNMATCH_EXTFLAG) != FNM_NOMATCH)) { printf ("%s: %s\n", name, shell_builtins[i].short_doc); if (sflag == 0) for (j = 0; shell_builtins[i].long_doc[j]; j++) printf (" %s\n", shell_builtins[i].long_doc[j]); match_found++; } } } if (match_found == 0) { builtin_error ("no help topics match `%s'. Try `help help'.", pattern); return (EXECUTION_FAILURE); } fflush (stdout); return (EXECUTION_SUCCESS); } static void show_builtin_command_help () { int i, j; char blurb[36]; 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\ \n\ A star (*) next to a name means that the command is disabled.\n\ \n"); for (i = 0; i < num_shell_builtins; i++) { QUIT; blurb[0] = (shell_builtins[i].flags & BUILTIN_ENABLED) ? ' ' : '*'; strncpy (blurb + 1, shell_builtins[i].short_doc, 34); blurb[35] = '\0'; printf ("%s", blurb); if (i % 2) printf ("\n"); else for (j = strlen (blurb); j < 35; j++) putc (' ', stdout); } if (i % 2) printf ("\n"); } #endif /* HELP_BUILTIN */ bash-2.05a/builtins/let.def100664 436 0 6047 7351434006 14043 0ustar chetwheelThis file is let.def, from which is created let.c. It implements the builtin "let" in Bash. Copyright (C) 1987, 1989, 1991 Free Software Foundation, Inc. This file is part of GNU Bash, the Bourne Again SHell. Bash is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 2, or (at your option) any later version. Bash is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with Bash; see the file COPYING. If not, write to the Free Software Foundation, 59 Temple Place, Suite 330, Boston, MA 02111 USA. $BUILTIN let $FUNCTION let_builtin $PRODUCES let.c $SHORT_DOC let arg [arg ...] Each ARG is an arithmetic expression to be evaluated. Evaluation is done in long integers with no check for overflow, though division by 0 is trapped and flagged as an error. The following list of operators is grouped into levels of equal-precedence operators. The levels are listed in order of decreasing precedence. -, + unary minus, plus !, ~ logical and bitwise negation *, /, % multiplication, division, remainder +, - addition, subtraction <<, >> left and right bitwise shifts <=, >=, <, > comparison ==, != equality, inequality & bitwise AND ^ bitwise XOR | bitwise OR && logical AND || logical OR expr ? expr : expr conditional expression =, *=, /=, %=, +=, -=, <<=, >>=, &=, ^=, |= assignment Shell variables are allowed as operands. The name of the variable is replaced by its value (coerced to a long integer) within an expression. The variable need not have its integer attribute turned on to be used in an expression. Operators are evaluated in order of precedence. Sub-expressions in parentheses are evaluated first and may override the precedence rules above. If the last ARG evaluates to 0, let returns 1; 0 is returned otherwise. $END #include #if defined (HAVE_UNISTD_H) # ifdef _MINIX # include # endif # include #endif #include "../shell.h" #include "common.h" /* Arithmetic LET function. */ int let_builtin (list) WORD_LIST *list; { long ret; int expok; if (list == 0) { builtin_error ("expression expected"); return (EXECUTION_FAILURE); } for (; list; list = list->next) { ret = evalexp (list->word->word, &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; int ret, expok; if (list == 0) { builtin_error ("expression expected"); return (EXECUTION_FAILURE); } exp = string_list (list); ret = evalexp (exp, &expok); (void)free (exp); return (((ret == 0) || (expok == 0)) ? EXECUTION_FAILURE : EXECUTION_SUCCESS); } #endif bash-2.05a/builtins/history.def100644 436 0 17740 7302266551 15004 0ustar chetwheelThis file is history.def, from which is created history.c. It implements the builtin "history" in Bash. Copyright (C) 1987, 1989, 1991 Free Software Foundation, Inc. This file is part of GNU Bash, the Bourne Again SHell. Bash is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 2, or (at your option) any later version. Bash is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with Bash; see the file COPYING. If not, write to the Free Software Foundation, 59 Temple Place, Suite 330, Boston, MA 02111 USA. $PRODUCES history.c $BUILTIN history $FUNCTION history_builtin $DEPENDS_ON HISTORY $SHORT_DOC history [-c] [-d offset] [n] or history -awrn [filename] or history -ps arg [arg...] Display the history list with line numbers. Lines listed with with a `*' have been modified. Argument of N says to list only the last N lines. The `-c' option causes the history list to be cleared by deleting all of the entries. The `-d' option deletes the history entry at offset OFFSET. The `-w' option writes out the current history to the history file; `-r' means to read the file and append the contents to the history list instead. `-a' means to append history lines from this session to the history file. Argument `-n' means to read all history lines not already read from the history file and append them to the history list. If FILENAME is given, then that is used as the history file else if $HISTFILE has a value, that is used, else ~/.bash_history. If the -s option is supplied, the non-option ARGs are appended to the history list as a single entry. The -p option means to perform history expansion on each ARG and display the result, without storing anything in the history list. $END #include #if defined (HISTORY) #include "../bashtypes.h" #ifndef _MINIX # include #endif #include "posixstat.h" #include "filecntl.h" #include #include #if defined (HAVE_UNISTD_H) # include #endif #include "../bashansi.h" #include "../shell.h" #include "../bashhist.h" #include #include "bashgetopt.h" #include "common.h" #if !defined (errno) extern int errno; #endif static void display_history __P((WORD_LIST *)); static int delete_histent __P((int)); static int delete_last_history __P((void)); static void push_history __P((WORD_LIST *)); static int expand_and_print_history __P((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; char *filename, *delete_arg; long 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; 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) { 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 (EXECUTION_SUCCESS); } #endif else if (flags & DFLAG) { if ((legal_number (delete_arg, &delete_offset) == 0) || (delete_offset < history_base) || (delete_offset > (history_base + history_length))) { builtin_error ("%s: not a valid history position", delete_arg); return (EXECUTION_FAILURE); } opt = delete_offset; result = 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) { display_history (list); return (EXECUTION_SUCCESS); } filename = list ? list->word->word : get_string_value ("HISTFILE"); result = EXECUTION_SUCCESS; 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); else if (flags & NFLAG) /* Read `new' history from file. */ { /* Read all of the lines in the file that we haven't already read. */ using_history (); result = read_history_range (filename, history_lines_in_file, -1); using_history (); history_lines_in_file = where_history (); } 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 void display_history (list) WORD_LIST *list; { register int i; long limit; HIST_ENTRY **hlist; if (list) { limit = get_numeric_arg (list, 0); 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; while (hlist[i]) { QUIT; printf ("%5d%c %s\n", i + history_base, histdata(i) ? '*' : ' ', histline(i)); i++; } } } /* Delete and free the history list entry at offset I. */ static int delete_histent (i) int i; { HIST_ENTRY *discard; discard = remove_history (i); if (discard) { if (discard->line) free (discard->line); free ((char *) discard); } return 1; } static int delete_last_history () { register int i; HIST_ENTRY **hlist, *histent; hlist = history_list (); if (hlist == NULL) return 0; for (i = 0; hlist[i]; i++) ; i--; /* History_get () takes a parameter that must be offset by history_base. */ histent = history_get (history_base + i); /* Don't free this */ if (histent == NULL) return 0; return (delete_histent (i)); } /* 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; if (hist_last_line_added && delete_last_history () == 0) return; s = string_list (list); maybe_add_history (s); /* Obeys HISTCONTROL setting. */ 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_added && 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 */ bash-2.05a/builtins/jobs.def100644 436 0 16050 7347464111 14232 0ustar chetwheelThis file is jobs.def, from which is created jobs.c. It implements the builtins "jobs" and "disown" in Bash. Copyright (C) 1987, 1989, 1991, 1992 Free Software Foundation, Inc. This file is part of GNU Bash, the Bourne Again SHell. Bash is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 2, or (at your option) any later version. Bash is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with Bash; see the file COPYING. If not, write to the Free Software Foundation, 59 Temple Place, Suite 330, Boston, MA 02111 USA. $PRODUCES jobs.c $BUILTIN jobs $FUNCTION jobs_builtin $DEPENDS_ON JOB_CONTROL $SHORT_DOC jobs [-lnprs] [jobspec ...] or jobs -x command [args] Lists the active jobs. The -l option lists process id's in addition to the normal information; the -p option lists process id's only. If -n is given, only processes that have changed status since the last notification are printed. JOBSPEC restricts output to that job. The -r and -s options restrict output to running and stopped jobs only, respectively. Without options, the status of all active jobs is printed. If -x is given, COMMAND is run after all job specifications that appear in ARGS have been replaced with the process ID of that job's process group leader. $END #include #if defined (JOB_CONTROL) #include "../bashtypes.h" #include #if defined (HAVE_UNISTD_H) # include #endif #include "../bashansi.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 __P((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; if (job_control == 0 && interactive_shell == 0) return (EXECUTION_SUCCESS); 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 ("Other options not allowed with `-x'"); return (EXECUTION_FAILURE); } execute++; break; case 'r': state = JSTATE_RUNNING; break; case 's': state = JSTATE_STOPPED; break; 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 || !jobs[job]) { builtin_error ("no such job %s", 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; /* 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 (job < 0 || job >= job_slots || !jobs[job]) continue; free (l->word->word); l->word->word = itos (jobs[job]->pgrp); } } /* Next make a new simple command and execute it. */ begin_unwind_frame ("jobs_builtin"); { COMMAND *command = (COMMAND *)NULL; add_unwind_protect (dispose_command, command); 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; result = execute_command (command); } run_unwind_frame ("jobs_builtin"); return (result); } #endif /* JOB_CONTROL */ $BUILTIN disown $FUNCTION disown_builtin $DEPENDS_ON JOB_CONTROL $SHORT_DOC disown [-h] [-ar] [jobspec ...] By default, removes each JOBSPEC argument from the table of active jobs. If the -h option is given, the job is not removed from the table, but is marked so that SIGHUP is not sent to the job if the shell receives a SIGHUP. The -a option, when JOBSPEC is not supplied, means to remove all jobs from the job table; the -r option means to remove only running jobs. $END #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; long 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; 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) : get_job_spec (list); if (job == NO_JOB || jobs == 0 || job < 0 || job >= job_slots || jobs[job] == 0) { builtin_error ("%s: no such job", 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 */ bash-2.05a/builtins/kill.def100644 436 0 13421 7362615624 14233 0ustar chetwheelThis file is kill.def, from which is created kill.c. It implements the builtin "kill" in Bash. Copyright (C) 1987, 1989, 1991 Free Software Foundation, Inc. This file is part of GNU Bash, the Bourne Again SHell. Bash is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 2, or (at your option) any later version. Bash is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with Bash; see the file COPYING. If not, write to the Free Software Foundation, 59 Temple Place, Suite 330, Boston, MA 02111 USA. $PRODUCES kill.c $BUILTIN kill $FUNCTION kill_builtin $DEPENDS_ON JOB_CONTROL $SHORT_DOC kill [-s sigspec | -n signum | -sigspec] [pid | job]... or kill -l [sigspec] Send the processes named by PID (or JOB) the signal SIGSPEC. If SIGSPEC is not present, then SIGTERM is assumed. An argument of `-l' lists the signal names; if arguments follow `-l' they are assumed to be signal numbers for which names should be listed. Kill is a shell builtin for two reasons: it allows job IDs to be used instead of process IDs, and, if you have reached the limit on processes that you can create, you don't have to start a process to kill another one. $END #include #include #include #if defined (HAVE_UNISTD_H) # ifdef _MINIX # include # endif # include #endif #include "../bashansi.h" #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 */ #if defined (JOB_CONTROL) extern int posixly_correct; #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 signal, any_succeeded, listing, saw_signal; char *sigspec, *word; pid_t pid; long pid_value; if (list == 0) { builtin_usage (); return (EXECUTION_FAILURE); } any_succeeded = listing = saw_signal = 0; signal = SIGTERM; sigspec = "TERM"; /* Process options. */ while (list) { word = list->word->word; if (ISOPTION (word, 'l')) { listing++; list = list->next; } else if (ISOPTION (word, 's') || ISOPTION (word, 'n')) { list = list->next; if (list) { sigspec = list->word->word; if (sigspec[0] == '0' && sigspec[1] == '\0') signal = 0; else signal = decode_signal (sigspec); list = list->next; } else { builtin_error ("%s requires an argument", word); return (EXECUTION_FAILURE); } } else if (ISOPTION (word, '-')) { list = list->next; break; } else if (ISOPTION (word, '?')) { builtin_usage (); return (EXECUTION_SUCCESS); } /* 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) { sigspec = word + 1; signal = decode_signal (sigspec); saw_signal++; list = list->next; } else break; } if (listing) return (display_signal_list (list, 0)); /* OK, we are killing processes. */ if (signal == NO_SIG) { builtin_error ("bad signal spec `%s'", sigspec); return (EXECUTION_FAILURE); } if (list == 0) { builtin_usage (); return (EXECUTION_FAILURE); } while (list) { word = list->word->word; if (*word == '-') word++; if (*word && legal_number (word, &pid_value) && (pid_value == (pid_t)pid_value)) { /* Use the entire argument in case of minus sign presence. */ pid = (pid_t) pid_value; if (kill_pid (pid, signal, 0) < 0) goto signal_error; else any_succeeded++; } else if (*list->word->word && *list->word->word != '%') { builtin_error ("%s: no such pid", list->word->word); CONTINUE_OR_FAIL; } else if (*word && (interactive || job_control)) /* 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; BLOCK_CHILD (set, oset); job = get_job_spec (list); if (job < 0 || job >= job_slots || !jobs[job]) { if (job != DUP_JOB) builtin_error ("%s: no such job", list->word->word); UNBLOCK_CHILD (oset); CONTINUE_OR_FAIL; } /* 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) ? jobs[job]->pgrp : jobs[job]->pipe->pid; UNBLOCK_CHILD (oset); if (kill_pid (pid, signal, 1) < 0) { signal_error: if (errno == EINVAL) builtin_error ("Invalid signal %d", signal); else builtin_error ("(%ld) - %s", (long)pid, strerror (errno)); CONTINUE_OR_FAIL; } else any_succeeded++; } else { builtin_error ("`%s': not a pid or valid job spec", list->word->word); CONTINUE_OR_FAIL; } continue_killing: list = list->next; } return (any_succeeded ? EXECUTION_SUCCESS : EXECUTION_FAILURE); } #endif /* JOB_CONTROL */ bash-2.05a/builtins/mkbuiltins.c100644 436 0 105520 7362615677 15177 0ustar chetwheel/* mkbuiltins.c - Create builtins.c, builtext.h, and builtdoc.c from a single source file called builtins.def. */ /* Copyright (C) 1987, 1989, 1991 Free Software Foundation, Inc. This file is part of GNU Bash, the Bourne Again SHell. Bash is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 2, or (at your option) any later version. Bash is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with Bash; see the file COPYING. If not, write to the Free Software Foundation, 59 Temple Place, Suite 330, Boston, MA 02111 USA. */ #include #if defined (HAVE_UNISTD_H) # ifdef _MINIX # include # endif # include #endif #ifndef _MINIX #include "../bashtypes.h" #include #endif #include "posixstat.h" #include "filecntl.h" #include "../bashansi.h" #include #include "stdc.h" #define DOCFILE "builtins.texi" static char *xmalloc (), *xrealloc (); #if !defined (__STDC__) && !defined (strcpy) extern char *strcpy (); #endif /* !__STDC__ && !strcpy */ #define savestring(x) strcpy (xmalloc (1 + strlen (x)), (x)) #define whitespace(c) (((c) == ' ') || ((c) == '\t')) /* Flag values that builtins can have. */ #define BUILTIN_FLAG_SPECIAL 0x01 #define BUILTIN_FLAG_ASSIGNMENT 0x02 /* If this stream descriptor is non-zero, then write texinfo documentation to it. */ FILE *documentation_file = (FILE *)NULL; /* Non-zero means to only produce documentation. */ int only_documentation = 0; /* Non-zero means to not do any productions. */ int inhibit_production = 0; #if !defined (OLDCODE) int no_long_document = 0; #endif /* !OLDCODE */ /* The name of a directory to precede the filename when reporting errors. */ char *error_directory = (char *)NULL; /* The name of the structure file. */ char *struct_filename = (char *)NULL; /* The name of the external declaration file. */ char *extern_filename = (char *)NULL; /* Here is a structure for manipulating arrays of data. */ typedef struct { int size; /* Number of slots allocated to array. */ int sindex; /* Current location in array. */ int width; /* Size of each element. */ int growth_rate; /* How fast to grow. */ char **array; /* The array itself. */ } ARRAY; /* Here is a structure defining a single BUILTIN. */ typedef struct { char *name; /* The name of this builtin. */ char *function; /* The name of the function to call. */ char *shortdoc; /* The short documentation for this builtin. */ char *docname; /* Possible name for documentation string. */ ARRAY *longdoc; /* The long documentation for this builtin. */ ARRAY *dependencies; /* Null terminated array of #define names. */ int flags; /* Flags for this builtin. */ } BUILTIN_DESC; /* Here is a structure which defines a DEF file. */ typedef struct { char *filename; /* The name of the input def file. */ ARRAY *lines; /* The contents of the file. */ int line_number; /* The current line number. */ char *production; /* The name of the production file. */ FILE *output; /* Open file stream for PRODUCTION. */ ARRAY *builtins; /* Null terminated array of BUILTIN_DESC *. */ } DEF_FILE; /* The array of all builtins encountered during execution of this code. */ ARRAY *saved_builtins = (ARRAY *)NULL; /* The Posix.2 so-called `special' builtins. */ char *special_builtins[] = { ":", ".", "source", "break", "continue", "eval", "exec", "exit", "export", "readonly", "return", "set", "shift", "trap", "unset", (char *)NULL }; /* The builtin commands that take assignment statements as arguments. */ char *assignment_builtins[] = { "alias", "declare", "export", "local", "readonly", "typeset", (char *)NULL }; /* Forward declarations. */ static int is_special_builtin (); static int is_assignment_builtin (); #if !defined (HAVE_RENAME) static int rename (); #endif void extract_info (); void file_error (); void line_error (); void write_file_headers (); void write_file_footers (); void write_ifdefs (); void write_endifs (); void write_documentation (); void write_longdocs (); void write_builtins (); void free_defs (); void add_documentation (); void must_be_building (); void remove_trailing_whitespace (); /* For each file mentioned on the command line, process it and write the information to STRUCTFILE and EXTERNFILE, while creating the production file if neccessary. */ int main (argc, argv) int argc; char **argv; { int arg_index = 1; FILE *structfile, *externfile; char *documentation_filename, *temp_struct_filename; structfile = externfile = (FILE *)NULL; documentation_filename = DOCFILE; temp_struct_filename = (char *)NULL; while (arg_index < argc && argv[arg_index][0] == '-') { char *arg = argv[arg_index++]; if (strcmp (arg, "-externfile") == 0) extern_filename = argv[arg_index++]; else if (strcmp (arg, "-structfile") == 0) struct_filename = argv[arg_index++]; else if (strcmp (arg, "-noproduction") == 0) inhibit_production = 1; else if (strcmp (arg, "-document") == 0) documentation_file = fopen (documentation_filename, "w"); else if (strcmp (arg, "-D") == 0) { int len; if (error_directory) free (error_directory); error_directory = xmalloc (2 + strlen (argv[arg_index])); strcpy (error_directory, argv[arg_index]); len = strlen (error_directory); if (len && error_directory[len - 1] != '/') strcat (error_directory, "/"); arg_index++; } else if (strcmp (arg, "-documentonly") == 0) { only_documentation = 1; documentation_file = fopen (documentation_filename, "w"); } #if !defined (OLDCODE) else if (strcmp (arg, "-nodocument") == 0) no_long_document = 1; #endif /* !OLDCODE */ else { fprintf (stderr, "%s: Unknown flag %s.\n", argv[0], arg); exit (2); } } /* If there are no files to process, just quit now. */ if (arg_index == argc) exit (0); if (!only_documentation) { /* Open the files. */ if (struct_filename) { temp_struct_filename = xmalloc (15); sprintf (temp_struct_filename, "mk-%ld", (long) getpid ()); structfile = fopen (temp_struct_filename, "w"); if (!structfile) file_error (temp_struct_filename); } if (extern_filename) { externfile = fopen (extern_filename, "w"); if (!externfile) file_error (extern_filename); } /* Write out the headers. */ write_file_headers (structfile, externfile); } if (documentation_file) { fprintf (documentation_file, "@c Table of builtins created with %s.\n", argv[0]); fprintf (documentation_file, "@ftable @asis\n"); } /* Process the .def files. */ while (arg_index < argc) { register char *arg; arg = argv[arg_index++]; extract_info (arg, structfile, externfile); } /* Close the files. */ if (!only_documentation) { /* Write the footers. */ write_file_footers (structfile, externfile); if (structfile) { write_longdocs (structfile, saved_builtins); fclose (structfile); rename (temp_struct_filename, struct_filename); } if (externfile) fclose (externfile); } if (documentation_file) { fprintf (documentation_file, "@end ftable\n"); fclose (documentation_file); } exit (0); } /* **************************************************************** */ /* */ /* Array Functions and Manipulators */ /* */ /* **************************************************************** */ /* Make a new array, and return a pointer to it. The array will contain elements of size WIDTH, and is initialized to no elements. */ ARRAY * array_create (width) int width; { ARRAY *array; array = (ARRAY *)xmalloc (sizeof (ARRAY)); array->size = 0; array->sindex = 0; array->width = width; /* Default to increasing size in units of 20. */ array->growth_rate = 20; array->array = (char **)NULL; return (array); } /* Copy the array of strings in ARRAY. */ ARRAY * copy_string_array (array) ARRAY *array; { register int i; ARRAY *copy; if (!array) return (ARRAY *)NULL; copy = array_create (sizeof (char *)); copy->size = array->size; copy->sindex = array->sindex; copy->width = array->width; copy->array = (char **)xmalloc ((1 + array->sindex) * sizeof (char *)); for (i = 0; i < array->sindex; i++) copy->array[i] = savestring (array->array[i]); copy->array[i] = (char *)NULL; return (copy); } /* Add ELEMENT to ARRAY, growing the array if neccessary. */ void array_add (element, array) char *element; ARRAY *array; { if (array->sindex + 2 > array->size) array->array = (char **)xrealloc (array->array, (array->size += array->growth_rate) * array->width); #if defined (HAVE_BCOPY) bcopy (&element, (char *) &(array->array[array->sindex]), array->width); array->sindex++; bzero ((char *) &(array->array[array->sindex]), array->width); #else array->array[array->sindex++] = element; array->array[array->sindex] = (char *)NULL; #endif /* !HAVE_BCOPY */ } /* Free an allocated array and data pointer. */ void array_free (array) ARRAY *array; { if (array->array) free (array->array); free (array); } /* **************************************************************** */ /* */ /* Processing a DEF File */ /* */ /* **************************************************************** */ /* The definition of a function. */ typedef int Function (); typedef int mk_handler_func_t __P((char *, DEF_FILE *, char *)); /* Structure handles processor directives. */ typedef struct { char *directive; mk_handler_func_t *function; } HANDLER_ENTRY; extern int builtin_handler __P((char *, DEF_FILE *, char *)); extern int function_handler __P((char *, DEF_FILE *, char *)); extern int short_doc_handler __P((char *, DEF_FILE *, char *)); extern int comment_handler __P((char *, DEF_FILE *, char *)); extern int depends_on_handler __P((char *, DEF_FILE *, char *)); extern int produces_handler __P((char *, DEF_FILE *, char *)); extern int end_handler __P((char *, DEF_FILE *, char *)); extern int docname_handler __P((char *, DEF_FILE *, char *)); HANDLER_ENTRY handlers[] = { { "BUILTIN", builtin_handler }, { "DOCNAME", docname_handler }, { "FUNCTION", function_handler }, { "SHORT_DOC", short_doc_handler }, { "$", comment_handler }, { "COMMENT", comment_handler }, { "DEPENDS_ON", depends_on_handler }, { "PRODUCES", produces_handler }, { "END", end_handler }, { (char *)NULL, (mk_handler_func_t *)NULL } }; /* Return the entry in the table of handlers for NAME. */ HANDLER_ENTRY * find_directive (directive) char *directive; { register int i; for (i = 0; handlers[i].directive; i++) if (strcmp (handlers[i].directive, directive) == 0) return (&handlers[i]); return ((HANDLER_ENTRY *)NULL); } /* Non-zero indicates that a $BUILTIN has been seen, but not the corresponding $END. */ static int building_builtin = 0; /* Non-zero means to output cpp line and file information before printing the current line to the production file. */ int output_cpp_line_info = 0; /* The main function of this program. Read FILENAME and act on what is found. Lines not starting with a dollar sign are copied to the $PRODUCES target, if one is present. Lines starting with a dollar sign are directives to this program, specifying the name of the builtin, the function to call, the short documentation and the long documentation strings. FILENAME can contain multiple $BUILTINs, but only one $PRODUCES target. After the file has been processed, write out the names of builtins found in each $BUILTIN. Plain text found before the $PRODUCES is ignored, as is "$$ comment text". */ void extract_info (filename, structfile, externfile) char *filename; FILE *structfile, *externfile; { register int i; DEF_FILE *defs; struct stat finfo; size_t file_size; char *buffer, *line; int fd, nr; if (stat (filename, &finfo) == -1) file_error (filename); fd = open (filename, O_RDONLY, 0666); if (fd == -1) file_error (filename); file_size = (size_t)finfo.st_size; buffer = xmalloc (1 + file_size); if ((nr = read (fd, buffer, file_size)) < 0) file_error (filename); /* This is needed on WIN32, and does not hurt on Unix. */ if (nr < file_size) file_size = nr; close (fd); if (nr == 0) { fprintf (stderr, "mkbuiltins: %s: skipping zero-length file\n", filename); return; } /* Create and fill in the initial structure describing this file. */ defs = (DEF_FILE *)xmalloc (sizeof (DEF_FILE)); defs->filename = filename; defs->lines = array_create (sizeof (char *)); defs->line_number = 0; defs->production = (char *)NULL; defs->output = (FILE *)NULL; defs->builtins = (ARRAY *)NULL; /* Build the array of lines. */ i = 0; while (i < file_size) { array_add (&buffer[i], defs->lines); while (buffer[i] != '\n' && i < file_size) i++; buffer[i++] = '\0'; } /* Begin processing the input file. We don't write any output until we have a file to write output to. */ output_cpp_line_info = 1; /* Process each line in the array. */ for (i = 0; line = defs->lines->array[i]; i++) { defs->line_number = i; if (*line == '$') { register int j; char *directive; HANDLER_ENTRY *handler; /* Isolate the directive. */ for (j = 0; line[j] && !whitespace (line[j]); j++); directive = xmalloc (j); strncpy (directive, line + 1, j - 1); directive[j -1] = '\0'; /* Get the function handler and call it. */ handler = find_directive (directive); if (!handler) { line_error (defs, "Unknown directive `%s'", directive); free (directive); continue; } else { /* Advance to the first non-whitespace character. */ while (whitespace (line[j])) j++; /* Call the directive handler with the FILE, and ARGS. */ (*(handler->function)) (directive, defs, line + j); } free (directive); } else { if (building_builtin) add_documentation (defs, line); else if (defs->output) { if (output_cpp_line_info) { /* If we're handed an absolute pathname, don't prepend the directory name. */ if (defs->filename[0] == '/') fprintf (defs->output, "#line %d \"%s\"\n", defs->line_number + 1, defs->filename); else fprintf (defs->output, "#line %d \"%s%s\"\n", defs->line_number + 1, error_directory ? error_directory : "./", defs->filename); output_cpp_line_info = 0; } fprintf (defs->output, "%s\n", line); } } } /* Close the production file. */ if (defs->output) fclose (defs->output); /* The file has been processed. Write the accumulated builtins to the builtins.c file, and write the extern definitions to the builtext.h file. */ write_builtins (defs, structfile, externfile); free (buffer); free_defs (defs); } #define free_safely(x) if (x) free (x) static void free_builtin (builtin) BUILTIN_DESC *builtin; { register int i; free_safely (builtin->name); free_safely (builtin->function); free_safely (builtin->shortdoc); free_safely (builtin->docname); if (builtin->longdoc) array_free (builtin->longdoc); if (builtin->dependencies) { for (i = 0; builtin->dependencies->array[i]; i++) free (builtin->dependencies->array[i]); array_free (builtin->dependencies); } } /* Free all of the memory allocated to a DEF_FILE. */ void free_defs (defs) DEF_FILE *defs; { register int i; register BUILTIN_DESC *builtin; if (defs->production) free (defs->production); if (defs->lines) array_free (defs->lines); if (defs->builtins) { for (i = 0; builtin = (BUILTIN_DESC *)defs->builtins->array[i]; i++) { free_builtin (builtin); free (builtin); } array_free (defs->builtins); } free (defs); } /* **************************************************************** */ /* */ /* The Handler Functions Themselves */ /* */ /* **************************************************************** */ /* Strip surrounding whitespace from STRING, and return a pointer to the start of it. */ char * strip_whitespace (string) char *string; { while (whitespace (*string)) string++; remove_trailing_whitespace (string); return (string); } /* Remove only the trailing whitespace from STRING. */ void remove_trailing_whitespace (string) char *string; { register int i; i = strlen (string) - 1; while (i > 0 && whitespace (string[i])) i--; string[++i] = '\0'; } /* Ensure that there is a argument in STRING and return it. FOR_WHOM is the name of the directive which needs the argument. DEFS is the DEF_FILE in which the directive is found. If there is no argument, produce an error. */ char * get_arg (for_whom, defs, string) char *for_whom, *string; DEF_FILE *defs; { char *new; new = strip_whitespace (string); if (!*new) line_error (defs, "%s requires an argument", for_whom); return (savestring (new)); } /* Error if not building a builtin. */ void must_be_building (directive, defs) char *directive; DEF_FILE *defs; { if (!building_builtin) line_error (defs, "%s must be inside of a $BUILTIN block", directive); } /* Return the current builtin. */ BUILTIN_DESC * current_builtin (directive, defs) char *directive; DEF_FILE *defs; { must_be_building (directive, defs); if (defs->builtins) return ((BUILTIN_DESC *)defs->builtins->array[defs->builtins->sindex - 1]); else return ((BUILTIN_DESC *)NULL); } /* Add LINE to the long documentation for the current builtin. Ignore blank lines until the first non-blank line has been seen. */ void add_documentation (defs, line) DEF_FILE *defs; char *line; { register BUILTIN_DESC *builtin; builtin = current_builtin ("(implied LONGDOC)", defs); remove_trailing_whitespace (line); if (!*line && !builtin->longdoc) return; if (!builtin->longdoc) builtin->longdoc = array_create (sizeof (char *)); array_add (line, builtin->longdoc); } /* How to handle the $BUILTIN directive. */ int builtin_handler (self, defs, arg) char *self; DEF_FILE *defs; char *arg; { BUILTIN_DESC *new; char *name; /* If we are already building a builtin, we cannot start a new one. */ if (building_builtin) { line_error (defs, "%s found before $END", self); return (-1); } output_cpp_line_info++; /* Get the name of this builtin, and stick it in the array. */ name = get_arg (self, defs, arg); /* If this is the first builtin, create the array to hold them. */ if (!defs->builtins) defs->builtins = array_create (sizeof (BUILTIN_DESC *)); new = (BUILTIN_DESC *)xmalloc (sizeof (BUILTIN_DESC)); new->name = name; new->function = (char *)NULL; new->shortdoc = (char *)NULL; new->docname = (char *)NULL; new->longdoc = (ARRAY *)NULL; new->dependencies = (ARRAY *)NULL; new->flags = 0; if (is_special_builtin (name)) new->flags |= BUILTIN_FLAG_SPECIAL; if (is_assignment_builtin (name)) new->flags |= BUILTIN_FLAG_ASSIGNMENT; array_add ((char *)new, defs->builtins); building_builtin = 1; return (0); } /* How to handle the $FUNCTION directive. */ int function_handler (self, defs, arg) char *self; DEF_FILE *defs; char *arg; { register BUILTIN_DESC *builtin; builtin = current_builtin (self, defs); if (builtin == 0) { line_error (defs, "syntax error: no current builtin for $FUNCTION directive"); exit (1); } if (builtin->function) line_error (defs, "%s already has a function (%s)", builtin->name, builtin->function); else builtin->function = get_arg (self, defs, arg); return (0); } /* How to handle the $DOCNAME directive. */ int docname_handler (self, defs, arg) char *self; DEF_FILE *defs; char *arg; { register BUILTIN_DESC *builtin; builtin = current_builtin (self, defs); if (builtin->docname) line_error (defs, "%s already had a docname (%s)", builtin->name, builtin->docname); else builtin->docname = get_arg (self, defs, arg); return (0); } /* How to handle the $SHORT_DOC directive. */ int short_doc_handler (self, defs, arg) char *self; DEF_FILE *defs; char *arg; { register BUILTIN_DESC *builtin; builtin = current_builtin (self, defs); if (builtin->shortdoc) line_error (defs, "%s already has short documentation (%s)", builtin->name, builtin->shortdoc); else builtin->shortdoc = get_arg (self, defs, arg); return (0); } /* How to handle the $COMMENT directive. */ int comment_handler (self, defs, arg) char *self; DEF_FILE *defs; char *arg; { return (0); } /* How to handle the $DEPENDS_ON directive. */ int depends_on_handler (self, defs, arg) char *self; DEF_FILE *defs; char *arg; { register BUILTIN_DESC *builtin; char *dependent; builtin = current_builtin (self, defs); dependent = get_arg (self, defs, arg); if (!builtin->dependencies) builtin->dependencies = array_create (sizeof (char *)); array_add (dependent, builtin->dependencies); return (0); } /* How to handle the $PRODUCES directive. */ int produces_handler (self, defs, arg) char *self; DEF_FILE *defs; char *arg; { /* If just hacking documentation, don't change any of the production files. */ if (only_documentation) return (0); output_cpp_line_info++; if (defs->production) line_error (defs, "%s already has a %s definition", defs->filename, self); else { defs->production = get_arg (self, defs, arg); if (inhibit_production) return (0); defs->output = fopen (defs->production, "w"); if (!defs->output) file_error (defs->production); fprintf (defs->output, "/* %s, created from %s. */\n", defs->production, defs->filename); } return (0); } /* How to handle the $END directive. */ int end_handler (self, defs, arg) char *self; DEF_FILE *defs; char *arg; { must_be_building (self, defs); building_builtin = 0; return (0); } /* **************************************************************** */ /* */ /* Error Handling Functions */ /* */ /* **************************************************************** */ /* Produce an error for DEFS with FORMAT and ARGS. */ void line_error (defs, format, arg1, arg2) DEF_FILE *defs; char *format, *arg1, *arg2; { if (defs->filename[0] != '/') fprintf (stderr, "%s", error_directory ? error_directory : "./"); fprintf (stderr, "%s:%d:", defs->filename, defs->line_number + 1); fprintf (stderr, format, arg1, arg2); fprintf (stderr, "\n"); fflush (stderr); } /* Print error message for FILENAME. */ void file_error (filename) char *filename; { perror (filename); exit (2); } /* **************************************************************** */ /* */ /* xmalloc and xrealloc () */ /* */ /* **************************************************************** */ static void memory_error_and_abort (); static char * xmalloc (bytes) int bytes; { char *temp = (char *)malloc (bytes); if (!temp) memory_error_and_abort (); return (temp); } static char * xrealloc (pointer, bytes) char *pointer; int bytes; { char *temp; if (!pointer) temp = (char *)malloc (bytes); else temp = (char *)realloc (pointer, bytes); if (!temp) memory_error_and_abort (); return (temp); } static void memory_error_and_abort () { fprintf (stderr, "mkbuiltins: out of virtual memory\n"); abort (); } /* **************************************************************** */ /* */ /* Creating the Struct and Extern Files */ /* */ /* **************************************************************** */ /* Return a pointer to a newly allocated builtin which is an exact copy of BUILTIN. */ BUILTIN_DESC * copy_builtin (builtin) BUILTIN_DESC *builtin; { BUILTIN_DESC *new; new = (BUILTIN_DESC *)xmalloc (sizeof (BUILTIN_DESC)); new->name = savestring (builtin->name); new->shortdoc = savestring (builtin->shortdoc); new->longdoc = copy_string_array (builtin->longdoc); new->dependencies = copy_string_array (builtin->dependencies); new->function = builtin->function ? savestring (builtin->function) : (char *)NULL; new->docname = builtin->docname ? savestring (builtin->docname) : (char *)NULL; return (new); } /* How to save away a builtin. */ void save_builtin (builtin) BUILTIN_DESC *builtin; { BUILTIN_DESC *newbuiltin; newbuiltin = copy_builtin (builtin); /* If this is the first builtin to be saved, create the array to hold it. */ if (!saved_builtins) saved_builtins = array_create (sizeof (BUILTIN_DESC *)); array_add ((char *)newbuiltin, saved_builtins); } /* Flags that mean something to write_documentation (). */ #define STRING_ARRAY 1 #define TEXINFO 2 char *structfile_header[] = { "/* 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, 1991, 1992 Free Software Foundation, Inc.", "", " This file is part of GNU Bash, the Bourne Again SHell.", "", " Bash is free software; you can redistribute it and/or modify it", " under the terms of the GNU General Public License as published by", " the Free Software Foundation; either version 2, or (at your option)", " any later version.", "", " Bash is distributed in the hope that it will be useful, but WITHOUT", " ANY WARRANTY; without even the implied warranty of MERCHANTABILITY", " or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public", " License for more details.", "", " You should have received a copy of the GNU General Public License", " along with Bash; see the file COPYING. If not, write to the Free", " Software Foundation, 59 Temple Place, Suite 330, Boston, MA 02111 USA. */", "", "/* 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. */", "", "#include \"../builtins.h\"", (char *)NULL }; char *structfile_footer[] = { " { (char *)0x0, (sh_builtin_func_t *)0x0, 0, (char **)0x0, (char *)0x0 }", "};", "", "struct builtin *shell_builtins = static_shell_builtins;", "struct builtin *current_builtin;", "", "int num_shell_builtins =", "\tsizeof (static_shell_builtins) / sizeof (struct builtin) - 1;", (char *)NULL }; /* Write out any neccessary opening information for STRUCTFILE and EXTERNFILE. */ void write_file_headers (structfile, externfile) FILE *structfile, *externfile; { register int i; if (structfile) { for (i = 0; structfile_header[i]; i++) fprintf (structfile, "%s\n", structfile_header[i]); fprintf (structfile, "#include \"%s\"\n", extern_filename ? extern_filename : "builtext.h"); fprintf (structfile, "\nstruct builtin static_shell_builtins[] = {\n"); } if (externfile) fprintf (externfile, "/* %s - The list of builtins found in libbuiltins.a. */\n", extern_filename ? extern_filename : "builtext.h"); } /* Write out any necessary closing information for STRUCTFILE and EXTERNFILE. */ void write_file_footers (structfile, externfile) FILE *structfile, *externfile; { register int i; /* Write out the footers. */ if (structfile) { for (i = 0; structfile_footer[i]; i++) fprintf (structfile, "%s\n", structfile_footer[i]); } } /* Write out the information accumulated in DEFS to STRUCTFILE and EXTERNFILE. */ void write_builtins (defs, structfile, externfile) DEF_FILE *defs; FILE *structfile, *externfile; { register int i; /* Write out the information. */ if (defs->builtins) { register BUILTIN_DESC *builtin; for (i = 0; i < defs->builtins->sindex; i++) { builtin = (BUILTIN_DESC *)defs->builtins->array[i]; /* Write out any #ifdefs that may be there. */ if (!only_documentation) { if (builtin->dependencies) { write_ifdefs (externfile, builtin->dependencies->array); write_ifdefs (structfile, builtin->dependencies->array); } /* Write the extern definition. */ if (externfile) { if (builtin->function) fprintf (externfile, "extern int %s __P((WORD_LIST *));\n", builtin->function); fprintf (externfile, "extern char *%s_doc[];\n", builtin->docname ? builtin->docname : builtin->name); } /* Write the structure definition. */ if (structfile) { fprintf (structfile, " { \"%s\", ", builtin->name); if (builtin->function) fprintf (structfile, "%s, ", builtin->function); else fprintf (structfile, "(sh_builtin_func_t *)0x0, "); fprintf (structfile, "%s%s%s, %s_doc,\n", "BUILTIN_ENABLED | STATIC_BUILTIN", (builtin->flags & BUILTIN_FLAG_SPECIAL) ? " | SPECIAL_BUILTIN" : "", (builtin->flags & BUILTIN_FLAG_ASSIGNMENT) ? " | ASSIGNMENT_BUILTIN" : "", builtin->docname ? builtin->docname : builtin->name); fprintf (structfile, " \"%s\", (char *)NULL },\n", builtin->shortdoc ? builtin->shortdoc : builtin->name); /* Save away this builtin for later writing of the long documentation strings. */ save_builtin (builtin); } /* Write out the matching #endif, if neccessary. */ if (builtin->dependencies) { if (externfile) write_endifs (externfile, builtin->dependencies->array); if (structfile) write_endifs (structfile, builtin->dependencies->array); } } if (documentation_file) { fprintf (documentation_file, "@item %s\n", builtin->name); write_documentation (documentation_file, builtin->longdoc->array, 0, TEXINFO); } } } } /* Write out the long documentation strings in BUILTINS to STREAM. */ void write_longdocs (stream, builtins) FILE *stream; ARRAY *builtins; { register int i; register BUILTIN_DESC *builtin; for (i = 0; i < builtins->sindex; i++) { builtin = (BUILTIN_DESC *)builtins->array[i]; if (builtin->dependencies) write_ifdefs (stream, builtin->dependencies->array); /* Write the long documentation strings. */ fprintf (stream, "char *%s_doc[] =", builtin->docname ? builtin->docname : builtin->name); write_documentation (stream, builtin->longdoc->array, 0, STRING_ARRAY); if (builtin->dependencies) write_endifs (stream, builtin->dependencies->array); } } /* Write an #ifdef string saying what needs to be defined (or not defined) in order to allow compilation of the code that will follow. STREAM is the stream to write the information to, DEFINES is a null terminated array of define names. If a define is preceded by an `!', then the sense of the test is reversed. */ void write_ifdefs (stream, defines) FILE *stream; char **defines; { register int i; if (!stream) return; fprintf (stream, "#if "); for (i = 0; defines[i]; i++) { char *def = defines[i]; if (*def == '!') fprintf (stream, "!defined (%s)", def + 1); else fprintf (stream, "defined (%s)", def); if (defines[i + 1]) fprintf (stream, " && "); } fprintf (stream, "\n"); } /* Write an #endif string saying what defines controlled the compilation of the immediately preceding code. STREAM is the stream to write the information to. DEFINES is a null terminated array of define names. */ void write_endifs (stream, defines) FILE *stream; char **defines; { register int i; if (!stream) return; fprintf (stream, "#endif /* "); for (i = 0; defines[i]; i++) { fprintf (stream, "%s", defines[i]); if (defines[i + 1]) fprintf (stream, " && "); } fprintf (stream, " */\n"); } /* Write DOCUMENTAION to STREAM, perhaps surrounding it with double-quotes and quoting special characters in the string. */ void write_documentation (stream, documentation, indentation, flags) FILE *stream; char **documentation; int indentation, flags; { register int i, j; register char *line; int string_array, texinfo; if (!stream) return; string_array = flags & STRING_ARRAY; if (string_array) fprintf (stream, " {\n#if defined (HELP_BUILTIN)\n"); #if !defined (OLDCODE) /* XXX -- clean me up; for experiment only */ if (no_long_document) goto end_of_document; #endif /* !OLDCODE */ for (i = 0, texinfo = (flags & TEXINFO); line = documentation[i]; i++) { /* Allow #ifdef's to be written out verbatim. */ if (*line == '#') { if (string_array) fprintf (stream, "%s\n", line); continue; } if (string_array) fprintf (stream, " \""); if (indentation) for (j = 0; j < indentation; j++) fprintf (stream, " "); if (string_array) { for (j = 0; line[j]; j++) { switch (line[j]) { case '\\': case '"': fprintf (stream, "\\%c", line[j]); break; default: fprintf (stream, "%c", line[j]); } } fprintf (stream, "\",\n"); } else if (texinfo) { for (j = 0; line[j]; j++) { switch (line[j]) { case '@': case '{': case '}': fprintf (stream, "@%c", line[j]); break; default: fprintf (stream, "%c", line[j]); } } fprintf (stream, "\n"); } else fprintf (stream, "%s\n", line); } #if !defined (OLDCODE) end_of_document: #endif /* !OLDCODE */ if (string_array) fprintf (stream, "#endif /* HELP_BUILTIN */\n (char *)NULL\n};\n"); } static int _find_in_table (name, name_table) char *name, *name_table[]; { register int i; for (i = 0; name_table[i]; i++) if (strcmp (name, name_table[i]) == 0) return 1; return 0; } static int is_special_builtin (name) char *name; { return (_find_in_table (name, special_builtins)); } static int is_assignment_builtin (name) char *name; { return (_find_in_table (name, assignment_builtins)); } #if !defined (HAVE_RENAME) static int rename (from, to) char *from, *to; { unlink (to); if (link (from, to) < 0) return (-1); unlink (from); return (0); } #endif /* !HAVE_RENAME */ bash-2.05a/builtins/printf.def100664 436 0 53137 7370304155 14605 0ustar chetwheelThis file is printf.def, from which is created printf.c. It implements the builtin "printf" in Bash. Copyright (C) 1997 Free Software Foundation, Inc. This file is part of GNU Bash, the Bourne Again SHell. Bash is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 2, or (at your option) any later version. Bash is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with Bash; see the file COPYING. If not, write to the Free Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307, USA $PRODUCES printf.c $BUILTIN printf $FUNCTION printf_builtin $SHORT_DOC printf format [arguments] printf formats and prints ARGUMENTS under control of the FORMAT. FORMAT is a character string which contains three types of objects: plain characters, which are simply copied to standard output, character escape sequences which are converted and copied to the standard output, and format specifications, each of which causes printing of the next successive argument. In addition to the standard printf(1) formats, %b means to expand backslash escape sequences in the corresponding argument, and %q means to quote the argument in a way that can be reused as shell input. $END #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 #include #include #ifdef HAVE_INTTYPES_H # include #endif #include "../bashansi.h" #define NEED_STRTOIMAX_DECL #include "../shell.h" #include "stdc.h" #include "bashgetopt.h" #include "common.h" /* This should use the ISO C constant format strings; I'll do that later. */ #if SIZEOF_LONG < SIZEOF_LONG_LONG # define INTMAX_CONV "ll" #else # define INTMAX_CONV "l" #endif #if !defined (errno) extern int errno; #endif #define PF(f, func) \ do { \ if (have_fieldwidth && have_precision) \ tw += printf(f, fieldwidth, precision, func); \ else if (have_fieldwidth) \ tw += printf(f, fieldwidth, func); \ else if (have_precision) \ tw += printf(f, precision, func); \ else \ tw += printf(f, func); \ } while (0) /* We free the buffer used by mklong() if it's `too big'. */ #define PRETURN(value) \ do \ { \ if (conv_bufsize > 4096 ) \ { \ free(conv_buf); \ conv_bufsize = 0; \ conv_buf = 0; \ } \ fflush (stdout); \ return (value); \ } \ while (0) #define SKIP1 "#'-+ 0" #define LENMODS "hjlLtz" static void printstr __P((char *, char *, int, int, int)); static int tescape __P((char *, int, char *, int *)); static char *bexpand __P((char *, int, int *, int *)); static char *mklong __P((char *, char *)); static int getchr __P((void)); static char *getstr __P((void)); static int getint __P((void)); static long getlong __P((void)); static unsigned long getulong __P((void)); #if defined (HAVE_LONG_LONG) static long long getllong __P((void)); static unsigned long long getullong __P((void)); #endif static intmax_t getintmax __P((void)); static uintmax_t getuintmax __P((void)); static double getdouble __P((void)); #if defined (HAVE_LONG_DOUBLE) && HAVE_DECL_STRTOLD static long double getldouble __P((void)); #endif static int asciicode __P((void)); static WORD_LIST *garglist; static int retval; static int conversion_error; 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; long tw; char convch, thisch, nextch, *format, *modstart, *fmt, *start; conversion_error = 0; retval = EXECUTION_SUCCESS; reset_internal_getopt (); if (internal_getopt (list, "") != -1) { builtin_usage(); return (EX_USAGE); } list = loptend; if (list == 0) { builtin_usage (); return (EX_USAGE); } if (list->word->word == 0 || list->word->word[0] == '\0') return (EXECUTION_SUCCESS); format = list->word->word; garglist = 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 fourth argument to tescape means to not do special processing for \c. */ fmt += tescape (fmt, 1, &nextch, (int *)NULL); putchar (nextch); fmt--; /* for loop will increment it for us again */ continue; } if (*fmt != '%') { putchar (*fmt); continue; } /* ASSERT(*fmt == '%') */ start = fmt++; if (*fmt == '%') /* %% prints a % */ { putchar ('%'); 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 while (DIGIT (*fmt)) fmt++; } /* skip possible format modifiers */ modstart = fmt; while (*fmt && strchr (LENMODS, *fmt)) fmt++; if (*fmt == 0) { builtin_error ("`%s': missing format character", start); PRETURN (EXECUTION_FAILURE); } convch = *fmt; thisch = modstart[0]; nextch = modstart[1]; modstart[0] = convch; modstart[1] = '\0'; switch(convch) { case 'c': { char p; p = getchr (); PF(start, p); break; } case 's': { char *p; p = getstr (); PF(start, p); break; } case 'n': { char *var; var = getstr (); if (var && *var) { if (legal_identifier (var)) bind_var_to_int (var, tw); else { builtin_error ("%s: invalid variable name", var); PRETURN (EXECUTION_FAILURE); } } break; } case 'b': /* expand escapes in argument */ { char *p, *xp; int rlen; p = getstr (); ch = rlen = 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. */ printstr (start, xp, rlen, fieldwidth, precision); free (xp); } if (ch) PRETURN (retval); break; } case 'q': /* print with shell quoting */ { char *p, *xp; p = getstr (); xp = sh_backslash_quote (p); if (xp) { /* Use printstr to get fieldwidth and precision right. */ printstr (start, xp, strlen (xp), fieldwidth, precision); free (xp); } break; } case 'd': case 'i': { char *f; #if defined (HAVE_LONG_LONG) if (thisch == 'l' && nextch == 'l') { long long p; p = getllong (); f = mklong (start, "ll"); PF(f, p); } else #endif if (thisch == 'j') { intmax_t p; p = getintmax (); f = mklong (start, INTMAX_CONV); PF(f, p); } else { long p; p = getlong (); f = mklong (start, "l"); PF(f, p); } break; } case 'o': case 'u': case 'x': case 'X': { char *f; #if defined (HAVE_LONG_LONG) if (thisch == 'l' && nextch == 'l') { unsigned long long p; p = getullong (); f = mklong (start, "ll"); PF(f, p); } else #endif if (thisch == 'j') { uintmax_t p; p = getuintmax (); f = mklong (start, INTMAX_CONV); PF(f, p); } else { unsigned long p; p = getulong (); f = mklong (start, "l"); 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; #if defined (HAVE_LONG_DOUBLE) && HAVE_DECL_STRTOLD if (thisch == 'L') { long double p; p = getldouble (); f = mklong (start, "L"); PF (f, p); } else #endif { double p; p = getdouble (); f = mklong (start, ""); 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; } } while (garglist && garglist != list->next); if (conversion_error) retval = EXECUTION_FAILURE; PRETURN (retval); } /* We duplicate a lot of what printf(3) does here. */ static void 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 */ if (string == 0 || *string == '\0') return; #if 0 s = fmt; #endif if (*fmt == '%') fmt++; ljust = fw = 0; pr = -1; /* skip flags */ while (strchr (SKIP1, *fmt)) { if (*fmt == '-') ljust = 1; fmt++; } /* get fieldwidth, if present */ if (*fmt == '*') { fmt++; fw = fieldwidth; if (fw < 0) { fw = -fw; ljust = 1; } } else if (DIGIT (*fmt)) { fw = *fmt++ - '0'; while (DIGIT (*fmt)) fw = (fw * 10) + (*fmt++ - '0'); } /* get precision, if present */ if (*fmt == '.') { fmt++; if (*fmt == '*') { fmt++; pr = precision; } else if (DIGIT (*fmt)) { pr = *fmt++ - '0'; while (DIGIT (*fmt)) pr = (pr * 10) + (*fmt++ - '0'); } } #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--) putchar (' '); /* output NC characters from STRING */ for (i = 0; i < nc; i++) putchar (string[i]); /* output any necessary trailing padding */ for (; padlen < 0; padlen++) putchar (' '); } /* Convert STRING by expanding the escape sequences specified by the POSIX standard for printf's `%b' format string. If SAWC is non-null, 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. */ static int tescape (estart, trans_squote, cp, sawc) char *estart; int trans_squote; char *cp; int *sawc; { register char *p; int temp, c, evalue; p = estart; 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; /* %b octal constants are `\0' followed by one, two, or three octal digits... */ case '0': for (temp = 3, evalue = 0; ISOCTAL (*p) && temp--; p++) evalue = (evalue * 8) + OCTVALUE (*p); *cp = evalue & 0xFF; break; /* but, as an extension, the other echo-like octal escape sequences are supported as well. */ case '1': case '2': case '3': case '4': case '5': case '6': case '7': for (temp = 2, evalue = c - '0'; ISOCTAL (*p) && temp--; p++) evalue = (evalue * 8) + OCTVALUE (*p); *cp = evalue & 0xFF; break; /* And, as another extension, we allow \xNNN, 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 (temp == 2) { builtin_error ("missing hex digit for \\x"); *cp = '\\'; return 0; } *cp = evalue & 0xFF; break; case '\\': /* \\ -> \ */ *cp = c; break; case '\'': /* TRANS_SQUOTE != 0 means \' -> ' */ if (trans_squote) *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 (string == 0 || *string == '\0') { if (sawc) *sawc = 0; if (lenp) *lenp = 0; return ((char *)NULL); } ret = (char *)xmalloc (len + 1); for (r = ret, s = string; s && *s; ) { c = *s++; if (c != '\\' || *s == '\0') { *r++ = c; continue; } temp = 0; s += tescape (s, 0, &c, &temp); if (temp) { if (sawc) *sawc = 1; break; } *r++ = c; } *r = '\0'; if (lenp) *lenp = r - ret; return ret; } static char * mklong (str, modifiers) char *str; char *modifiers; { size_t len, slen, mlen; slen = strlen (str); mlen = strlen (modifiers); 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 () { long ret; ret = getlong (); if (ret > INT_MAX) { builtin_error ("warning: %s: %s", garglist->word->word, strerror(ERANGE)); ret = INT_MAX; } else if (ret < INT_MIN) { builtin_error ("warning: %s: %s", garglist->word->word, strerror(ERANGE)); ret = INT_MIN; } return ((int)ret); } static long getlong () { long ret; char *ep; if (garglist == 0) return (0); if (garglist->word->word[0] == '\'' || garglist->word->word[0] == '"') return asciicode (); errno = 0; ret = strtol (garglist->word->word, &ep, 0); if (*ep) { builtin_error ("%s: invalid number", 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. */ ret = 0; conversion_error = 1; } else if (errno == ERANGE) builtin_error ("warning: %s: %s", garglist->word->word, strerror(ERANGE)); garglist = garglist->next; return (ret); } static unsigned long getulong () { unsigned long ret; char *ep; if (garglist == 0) return (0); if (garglist->word->word[0] == '\'' || garglist->word->word[0] == '"') return asciicode (); errno = 0; ret = strtoul (garglist->word->word, &ep, 0); if (*ep) { builtin_error ("%s: invalid number", garglist->word->word); /* Same thing about POSIX.2 conversion error requirements as getlong(). */ ret = 0; conversion_error = 1; } else if (errno == ERANGE) builtin_error ("warning: %s: %s", garglist->word->word, strerror(ERANGE)); garglist = garglist->next; return (ret); } #if defined (HAVE_LONG_LONG) static long long getllong () { long long ret; char *ep; if (garglist == 0) return (0); if (garglist->word->word[0] == '\'' || garglist->word->word[0] == '"') return asciicode (); errno = 0; ret = strtoll (garglist->word->word, &ep, 0); if (*ep) { builtin_error ("%s: invalid number", 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. */ ret = 0; conversion_error = 1; } else if (errno == ERANGE) builtin_error ("warning: %s: %s", garglist->word->word, strerror(ERANGE)); garglist = garglist->next; return (ret); } static unsigned long long getullong () { unsigned long long ret; char *ep; if (garglist == 0) return (0); if (garglist->word->word[0] == '\'' || garglist->word->word[0] == '"') return asciicode (); errno = 0; ret = strtoull (garglist->word->word, &ep, 0); if (*ep) { builtin_error ("%s: invalid number", garglist->word->word); /* Same thing about POSIX.2 conversion error requirements as getlong(). */ ret = 0; conversion_error = 1; } else if (errno == ERANGE) builtin_error ("warning: %s: %s", garglist->word->word, strerror(ERANGE)); garglist = garglist->next; return (ret); } #endif /* HAVE_LONG_LONG */ 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) { builtin_error ("%s: invalid number", 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. */ ret = 0; conversion_error = 1; } else if (errno == ERANGE) builtin_error ("warning: %s: %s", garglist->word->word, strerror(ERANGE)); 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) { builtin_error ("%s: invalid number", garglist->word->word); /* Same thing about POSIX.2 conversion error requirements as getlong(). */ ret = 0; conversion_error = 1; } else if (errno == ERANGE) builtin_error ("warning: %s: %s", garglist->word->word, strerror(ERANGE)); garglist = garglist->next; return (ret); } static double getdouble () { double ret; char *ep; if (garglist == 0) return (0); if (garglist->word->word[0] == '\'' || garglist->word->word[0] == '"') return asciicode (); errno = 0; ret = strtod (garglist->word->word, &ep); if (*ep) { builtin_error ("%s: invalid number", garglist->word->word); /* Same thing about POSIX.2 conversion error requirements. */ ret = 0; conversion_error = 1; } else if (errno == ERANGE) builtin_error ("warning: %s: %s", garglist->word->word, strerror(ERANGE)); garglist = garglist->next; return (ret); } #if defined (HAVE_LONG_DOUBLE) && HAVE_DECL_STRTOLD static long double getldouble () { long double ret; char *ep; if (garglist == 0) return (0); if (garglist->word->word[0] == '\'' || garglist->word->word[0] == '"') return (asciicode ()); errno = 0; ret = strtold (garglist->word->word, &ep); if (*ep) { builtin_error ("%s: invalid number", garglist->word->word); /* Same thing about POSIX.2 conversion error requirements. */ ret = 0; conversion_error = 1; } else if (errno == ERANGE) builtin_error ("warning: %s: %s", garglist->word->word, strerror(ERANGE)); garglist = garglist->next; return (ret); } #endif /* HAVE_LONG_DOUBLE && HAVE_DECL_STRTOLD */ /* NO check is needed for garglist here. */ static int asciicode () { register int ch; ch = garglist->word->word[1]; garglist = garglist->next; return (ch); } bash-2.05a/builtins/pushd.def100644 436 0 47060 7351433364 14426 0ustar chetwheelThis file is pushd.def, from which is created pushd.c. It implements the builtins "pushd", "popd", and "dirs" in Bash. Copyright (C) 1987, 1989, 1991 Free Software Foundation, Inc. This file is part of GNU Bash, the Bourne Again SHell. Bash is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 2, or (at your option) any later version. Bash is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with Bash; see the file COPYING. If not, write to the Free Software Foundation, 59 Temple Place, Suite 330, Boston, MA 02111 USA. $PRODUCES pushd.c $BUILTIN pushd $FUNCTION pushd_builtin $DEPENDS_ON PUSHD_AND_POPD $SHORT_DOC pushd [dir | +N | -N] [-n] Adds a directory to the top of the directory stack, or rotates the stack, making the new top of the stack the current working directory. With no arguments, exchanges the top two directories. +N Rotates the stack so that the Nth directory (counting from the left of the list shown by `dirs', starting with zero) is at the top. -N Rotates the stack so that the Nth directory (counting from the right of the list shown by `dirs', starting with zero) is at the top. -n suppress the normal change of directory when adding directories to the stack, so only the stack is manipulated. dir adds DIR to the directory stack at the top, making it the new current working directory. You can see the directory stack with the `dirs' command. $END $BUILTIN popd $FUNCTION popd_builtin $DEPENDS_ON PUSHD_AND_POPD $SHORT_DOC popd [+N | -N] [-n] Removes entries from the directory stack. With no arguments, removes the top directory from the stack, and cd's to the new top directory. +N removes the Nth entry counting from the left of the list shown by `dirs', starting with zero. For example: `popd +0' removes the first directory, `popd +1' the second. -N removes the Nth entry counting from the right of the list shown by `dirs', starting with zero. For example: `popd -0' removes the last directory, `popd -1' the next to last. -n suppress the normal change of directory when removing directories from the stack, so only the stack is manipulated. You can see the directory stack with the `dirs' command. $END $BUILTIN dirs $FUNCTION dirs_builtin $DEPENDS_ON PUSHD_AND_POPD $SHORT_DOC dirs [-clpv] [+N] [-N] Display the list of currently remembered directories. Directories find their way onto the list with the `pushd' command; you can get back up through the list with the `popd' command. The -l flag specifies that `dirs' should not print shorthand versions of directories which are relative to your home directory. This means that `~/bin' might be displayed as `/homes/bfox/bin'. The -v flag causes `dirs' to print the directory stack with one entry per line, prepending the directory name with its position in the stack. The -p flag does the same thing, but the stack position is not prepended. The -c flag clears the directory stack by deleting all of the elements. +N displays the Nth entry counting from the left of the list shown by dirs when invoked without options, starting with zero. -N displays the Nth entry counting from the right of the list shown by dirs when invoked without options, starting with zero. $END #include #if defined (PUSHD_AND_POPD) #include #ifndef _MINIX # include #endif #if defined (HAVE_UNISTD_H) # ifdef _MINIX # include # endif # include #endif #include "../bashansi.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 */ static char *m_badarg = "%s: bad argument"; /* 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 __P((int, char *)); static void clear_directory_stack __P((void)); static int cd_to_string __P((char *)); static int change_to_temp __P((char *)); static void add_dirstack_element __P((char *)); static int get_dirstack_index __P((long, int, int *)); #define NOCD 0x01 #define ROTATE 0x02 #define LONGFORM 0x04 #define CLEARSTAK 0x08 int pushd_builtin (list) WORD_LIST *list; { char *temp, *current_directory, *top; int j, flags; long num; char direction; /* 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; 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) { builtin_error (m_badarg, list->word->word); builtin_usage (); return (EXECUTION_FAILURE); } 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 == '-') { bad_option (list->word->word); builtin_usage (); return (EXECUTION_FAILURE); } 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 (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; long which; int flags; char direction; char *which_word; 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) { builtin_error (m_badarg, list->word->word); builtin_usage (); return (EXECUTION_FAILURE); } which_word = list->word->word; } else if (*list->word->word == '-') { bad_option (list->word->word); builtin_usage (); return (EXECUTION_FAILURE); } else break; } if (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; 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; long i; char *temp, *w; 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) { builtin_error (m_badarg, list->word->word); builtin_usage (); return (EXECUTION_FAILURE); } sign = (*list->word->word == '+') ? 1 : -1; desired_index = get_dirstack_index (i, sign, &index_flag); } else { bad_option (list->word->word); builtin_usage (); return (EXECUTION_FAILURE); } } 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 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'); fflush (stdout); return (EXECUTION_SUCCESS); } static void pushd_error (offset, arg) int offset; char *arg; { if (offset == 0) builtin_error ("directory stack empty"); else if (arg) builtin_error ("%s: bad directory stack index", arg); else builtin_error ("bad 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; int result; tlist = make_word_list (make_word (name), NULL); 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; { int j; if (directory_list_offset == directory_list_size) { j = (directory_list_size += 10) * sizeof (char *); pushd_directory_list = (char **)xrealloc (pushd_directory_list, j); } pushd_directory_list[directory_list_offset++] = dir; } static int get_dirstack_index (ind, sign, indexp) long 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; long 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) long 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) long 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 () { register int i; WORD_LIST *ret; char *d, *t; for (ret = (WORD_LIST *)NULL, i = 0; i < directory_list_offset; i++) { d = polite_directory_format (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 = polite_directory_format (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 static char *dirs_doc[] = { "Display the list of currently remembered directories. Directories", "find their way onto the list with the `pushd' command; you can get", "back up through the list with the `popd' command.", "", "The -l flag specifies that `dirs' should not print shorthand versions", "of directories which are relative to your home directory. This means", "that `~/bin' might be displayed as `/homes/bfox/bin'. The -v flag", "causes `dirs' to print the directory stack with one entry per line,", "prepending the directory name with its position in the stack. The -p", "flag does the same thing, but the stack position is not prepended.", "The -c flag clears the directory stack by deleting all of the elements.", "", "+N displays the Nth entry counting from the left of the list shown by", " dirs when invoked without options, starting with zero.", "", "-N displays the Nth entry counting from the right of the list shown by", " dirs when invoked without options, starting with zero.", (char *)NULL }; static char *pushd_doc[] = { "Adds a directory to the top of the directory stack, or rotates", "the stack, making the new top of the stack the current working", "directory. With no arguments, exchanges the top two directories.", "", "+N Rotates the stack so that the Nth directory (counting", " from the left of the list shown by `dirs', starting with", " zero) is at the top.", "", "-N Rotates the stack so that the Nth directory (counting", " from the right of the list shown by `dirs', starting with", " zero) is at the top.", "", "-n suppress the normal change of directory when adding directories", " to the stack, so only the stack is manipulated.", "", "dir adds DIR to the directory stack at the top, making it the", " new current working directory.", "", "You can see the directory stack with the `dirs' command.", (char *)NULL }; static char *popd_doc[] = { "Removes entries from the directory stack. With no arguments,", "removes the top directory from the stack, and cd's to the new", "top directory.", "", "+N removes the Nth entry counting from the left of the list", " shown by `dirs', starting with zero. For example: `popd +0'", " removes the first directory, `popd +1' the second.", "", "-N removes the Nth entry counting from the right of the list", " shown by `dirs', starting with zero. For example: `popd -0'", " removes the last directory, `popd -1' the next to last.", "", "-n suppress the normal change of directory when removing directories", " from the stack, so only the stack is manipulated.", "", "You can see the directory stack with the `dirs' command.", (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 */ bash-2.05a/builtins/read.def100664 436 0 40734 7370014550 14212 0ustar chetwheelThis file is read.def, from which is created read.c. It implements the builtin "read" in Bash. Copyright (C) 1987, 1989, 1991 Free Software Foundation, Inc. This file is part of GNU Bash, the Bourne Again SHell. Bash is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 2, or (at your option) any later version. Bash is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with Bash; see the file COPYING. If not, write to the Free Software Foundation, 59 Temple Place, Suite 330, Boston, MA 02111 USA. $PRODUCES read.c $BUILTIN read $FUNCTION read_builtin $SHORT_DOC read [-ers] [-t timeout] [-p prompt] [-a array] [-n nchars] [-d delim] [name ...] One line is read from the standard input, and the first word is assigned to the first NAME, the second word to the second NAME, and so on, with leftover words assigned to the last NAME. Only the characters found in $IFS are recognized as word delimiters. If no NAMEs are supplied, the line read is stored in the REPLY variable. If the -r option is given, this signifies `raw' input, and backslash escaping is disabled. The -d option causes read to continue until the first character of DELIM is read, rather than newline. If the `-p' option is supplied, the string PROMPT is output without a trailing newline before attempting to read. If -a is supplied, the words read are assigned to sequential indices of ARRAY, starting at zero. If -e is supplied and the shell is interactive, readline is used to obtain the line. If -n is supplied with a non-zero NCHARS argument, read returns after NCHARS characters have been read. The -s option causes input coming from a terminal to not be echoed. The -t option causes read to time out and return failure if a complete line of input is not read within TIMEOUT seconds. The return code is zero, unless end-of-file is encountered or read times out. $END #include #include "bashtypes.h" #include "posixstat.h" #include #if defined (HAVE_UNISTD_H) # include #endif #include #include #ifdef __CYGWIN__ # include # include #endif #include "../shell.h" #include "common.h" #include "bashgetopt.h" #include #if defined (READLINE) #include "../bashline.h" #include #endif #if !defined(errno) extern int errno; #endif #define issep(c) (strchr (ifs_chars, (c))) extern int interrupt_immediately; #if defined (READLINE) static char *edit_line __P((char *)); static void set_eol_delim __P((int)); static void reset_eol_delim __P((char *)); #endif static SHELL_VAR *bind_read_variable __P((char *, char *)); static sighandler sigalrm __P((int)); static void reset_alarm __P((void)); static procenv_t alrmbuf; static SigHandler *old_alrm; static unsigned char delim; static sighandler sigalrm (s) int s; { longjmp (alrmbuf, 1); } static void reset_alarm () { set_signal_handler (SIGALRM, old_alrm); alarm (0); } /* Read the value of the shell variables whose names follow. The reading is done from the current input stream, whatever that may be. Successive words of the input line are assigned to the variables mentioned in LIST. The last variable in LIST gets the remainder of the words on the line. If no variables are mentioned in LIST, then the default variable is $REPLY. */ int read_builtin (list) WORD_LIST *list; { register char *varname; int size, i, pass_next, saw_escape, eof, opt, retval, code; int input_is_tty, input_is_pipe, unbuffered_read; int raw, edit, nchars, silent, have_timeout; unsigned int tmout; long timeoutval, ncharsval; char c; char *input_string, *orig_input_string, *ifs_chars, *prompt, *arrayname; char *e, *t, *t1; struct stat tsb; SHELL_VAR *var; #if defined (ARRAY_VARS) WORD_LIST *alist; #endif #if defined (READLINE) char *rlbuf; int rlind; #endif USE_VAR(size); USE_VAR(i); USE_VAR(pass_next); USE_VAR(saw_escape); USE_VAR(input_is_pipe); /* USE_VAR(raw); */ USE_VAR(edit); USE_VAR(tmout); USE_VAR(nchars); USE_VAR(silent); USE_VAR(ifs_chars); USE_VAR(prompt); USE_VAR(arrayname); #if defined (READLINE) USE_VAR(rlbuf); USE_VAR(rlind); #endif USE_VAR(list); i = 0; /* Index into the string that we are reading. */ raw = edit = 0; /* Not reading raw input by default. */ silent = 0; arrayname = prompt = (char *)NULL; #if defined (READLINE) rlbuf = (char *)0; rlind = 0; #endif tmout = 0; /* no timeout */ nchars = input_is_tty = input_is_pipe = unbuffered_read = have_timeout = 0; delim = '\n'; /* read until newline */ reset_internal_getopt (); while ((opt = internal_getopt (list, "erp:a:d:t:n:s")) != -1) { switch (opt) { case 'r': raw = 1; break; case 'p': prompt = list_optarg; break; case 's': silent = 1; break; case 'e': #if defined (READLINE) edit = 1; #endif break; #if defined (ARRAY_VARS) case 'a': arrayname = list_optarg; break; #endif case 't': code = legal_number (list_optarg, &timeoutval); if (code == 0 || timeoutval < 0 || timeoutval != (unsigned int)timeoutval) { builtin_error ("%s: invalid timeout specification", list_optarg); return (EXECUTION_FAILURE); } else { have_timeout = 1; tmout = timeoutval; } break; case 'n': code = legal_number (list_optarg, &ncharsval); if (code == 0 || ncharsval < 0 || ncharsval != (int)ncharsval) { builtin_error ("%s: invalid number specification", list_optarg); return (EXECUTION_FAILURE); } else nchars = ncharsval; break; case 'd': delim = *list_optarg; break; default: builtin_usage (); return (EX_USAGE); } } list = loptend; /* `read -t 0 var' returns failure immediately. */ if (have_timeout && tmout == 0) return (EXECUTION_FAILURE); /* IF IFS is unset, we use the default of " \t\n". */ var = find_variable ("IFS"); ifs_chars = var ? value_cell (var) : " \t\n"; if (ifs_chars == 0) /* XXX */ ifs_chars = ""; /* XXX */ input_string = (char *)xmalloc (size = 128); begin_unwind_frame ("read_builtin"); #if defined (READLINE) add_unwind_protect (xfree, rlbuf); #endif input_is_tty = isatty (0); if (input_is_tty == 0) #ifndef __CYGWIN__ input_is_pipe = (lseek (0, 0L, SEEK_CUR) < 0) && (errno == ESPIPE); #else input_is_pipe = 1; #endif /* If the -p, -e or -s flags were given, but input is not coming from the terminal, turn them off. */ if ((prompt || edit || silent) && input_is_tty == 0) { prompt = (char *)NULL; edit = silent = 0; } if (prompt && edit == 0) { fprintf (stderr, "%s", prompt); fflush (stderr); } pass_next = 0; /* Non-zero signifies last char was backslash. */ saw_escape = 0; /* Non-zero signifies that we saw an escape char */ if (tmout > 0) { /* Turn off the timeout if stdin is a regular file (e.g. from input redirection). */ if ((fstat (0, &tsb) < 0) || S_ISREG (tsb.st_mode)) tmout = 0; } if (tmout > 0) { code = setjmp (alrmbuf); if (code) { run_unwind_frame ("read_builtin"); return (EXECUTION_FAILURE); } old_alrm = set_signal_handler (SIGALRM, sigalrm); add_unwind_protect (reset_alarm, (char *)NULL); alarm (tmout); } /* If we've been asked to read only NCHARS chars, or we're using some character other than newline to terminate the line, do the right thing to readline or the tty. */ if (nchars > 0 || delim != '\n') { #if defined (READLINE) if (edit) { if (nchars > 0) { unwind_protect_int (rl_num_chars_to_read); rl_num_chars_to_read = nchars; } if (delim != '\n') { set_eol_delim (delim); add_unwind_protect (reset_eol_delim, (char *)NULL); } } else #endif if (input_is_tty) { ttsave (); if (silent) ttcbreak (); else ttonechar (); add_unwind_protect ((Function *)ttrestore, (char *)NULL); } } else if (silent) /* turn off echo but leave term in canonical mode */ { ttsave (); ttnoecho (); add_unwind_protect ((Function *)ttrestore, (char *)NULL); } /* This *must* be the top unwind-protect on the stack, so the manipulation of the unwind-protect stack after the realloc() works right. */ add_unwind_protect (xfree, input_string); interrupt_immediately++; unbuffered_read = (nchars > 0) || (delim != '\n') || input_is_pipe; #if defined (__CYGWIN__) && defined (O_TEXT) setmode (0, O_TEXT); #endif for (eof = 0;;) { #if defined (READLINE) if (edit) { if (rlbuf && rlbuf[rlind] == '\0') { xfree (rlbuf); rlbuf = (char *)0; } if (rlbuf == 0) { rlbuf = edit_line (prompt ? prompt : ""); rlind = 0; } if (rlbuf == 0) { eof = 1; break; } c = rlbuf[rlind++]; } else { #endif if (unbuffered_read) retval = zread (0, &c, 1); else retval = zreadc (0, &c); if (retval <= 0) { eof = 1; break; } #if defined (READLINE) } #endif if (i + 2 >= size) { input_string = (char *)xrealloc (input_string, size += 128); remove_unwind_protect (); add_unwind_protect (xfree, input_string); } /* If the next character is to be accepted verbatim, a backslash newline pair still disappears from the input. */ if (pass_next) { if (c == '\n') i--; /* back up over the CTLESC */ else input_string[i++] = c; pass_next = 0; continue; } if (c == '\\' && raw == 0) { pass_next++; saw_escape++; input_string[i++] = CTLESC; continue; } if ((unsigned char)c == delim) break; if (c == CTLESC || c == CTLNUL) { saw_escape++; input_string[i++] = CTLESC; } input_string[i++] = c; if (nchars > 0 && i >= nchars) break; } input_string[i] = '\0'; if (tmout > 0) reset_alarm (); if (nchars > 0 || delim != '\n') { #if defined (READLINE) if (edit) { if (nchars > 0) rl_num_chars_to_read = 0; if (delim != '\n') reset_eol_delim ((char *)NULL); } else #endif if (input_is_tty) ttrestore (); } else if (silent) ttrestore (); if (unbuffered_read == 0) zsyncfd (0); interrupt_immediately--; discard_unwind_frame ("read_builtin"); retval = eof ? EXECUTION_FAILURE : EXECUTION_SUCCESS; #if defined (ARRAY_VARS) /* If -a was given, take the string read, break it into a list of words, an assign them to `arrayname' in turn. */ if (arrayname) { var = find_or_make_array_variable (arrayname, 1); if (var == 0) return EXECUTION_FAILURE; /* readonly or noassign */ empty_array (array_cell (var)); alist = list_string (input_string, ifs_chars, 0); if (alist) { assign_array_var_from_word_list (var, alist); dispose_words (alist); } xfree (input_string); return (retval); } #endif /* ARRAY_VARS */ /* If there are no variables, save the text of the line read to the variable $REPLY. ksh93 strips leading and trailing IFS whitespace, so that `read x ; echo "$x"' and `read ; echo "$REPLY"' behave the same way, but I believe that the difference in behaviors is useful enough to not do it. Without the bash behavior, there is no way to read a line completely without interpretation or modification unless you mess with $IFS (e.g., setting it to the empty string). If you disagree, change the occurrences of `#if 0' to `#if 1' below. */ if (list == 0) { #if 0 orig_input_string = input_string; for (t = input_string; ifs_chars && *ifs_chars && spctabnl(*t) && issep(*t); t++) ; input_string = t; input_string = strip_trailing_ifs_whitespace (input_string, ifs_chars, saw_escape); #endif if (saw_escape) { t = dequote_string (input_string); var = bind_variable ("REPLY", t); free (t); } else var = bind_variable ("REPLY", input_string); VUNSETATTR (var, att_invisible); free (input_string); return (retval); } /* This code implements the Posix.2 spec for splitting the words read and assigning them to variables. */ orig_input_string = input_string; /* Remove IFS white space at the beginning of the input string. If $IFS is null, no field splitting is performed. */ for (t = input_string; ifs_chars && *ifs_chars && spctabnl(*t) && issep(*t); t++) ; input_string = t; for (; list->next; list = list->next) { varname = list->word->word; #if defined (ARRAY_VARS) if (legal_identifier (varname) == 0 && valid_array_reference (varname) == 0) #else if (legal_identifier (varname) == 0) #endif { builtin_error ("`%s': not a valid identifier", varname); xfree (orig_input_string); return (EXECUTION_FAILURE); } /* If there are more variables than words read from the input, the remaining variables are set to the empty string. */ if (*input_string) { /* This call updates INPUT_STRING. */ t = get_word_from_string (&input_string, ifs_chars, &e); if (t) *e = '\0'; /* Don't bother to remove the CTLESC unless we added one somewhere while reading the string. */ if (t && saw_escape) { t1 = dequote_string (t); var = bind_read_variable (varname, t1); xfree (t1); } else var = bind_read_variable (varname, t); } else { t = (char *)0; var = bind_read_variable (varname, ""); } FREE (t); if (var == 0) { xfree (orig_input_string); return (EXECUTION_FAILURE); } stupidly_hack_special_variables (varname); VUNSETATTR (var, att_invisible); } /* Now assign the rest of the line to the last variable argument. */ #if defined (ARRAY_VARS) if (legal_identifier (list->word->word) == 0 && valid_array_reference (list->word->word) == 0) #else if (legal_identifier (list->word->word) == 0) #endif { builtin_error ("`%s': not a valid identifier", list->word->word); xfree (orig_input_string); return (EXECUTION_FAILURE); } /* This has to be done this way rather than using string_list and list_string because Posix.2 says that the last variable gets the remaining words and their intervening separators. */ input_string = strip_trailing_ifs_whitespace (input_string, ifs_chars, saw_escape); if (saw_escape) { t = dequote_string (input_string); var = bind_read_variable (list->word->word, t); xfree (t); } else var = bind_read_variable (list->word->word, input_string); stupidly_hack_special_variables (list->word->word); if (var) VUNSETATTR (var, att_invisible); xfree (orig_input_string); return (retval); } static SHELL_VAR * bind_read_variable (name, value) char *name, *value; { #if defined (ARRAY_VARS) if (valid_array_reference (name) == 0) return (bind_variable (name, value)); else return (assign_array_element (name, value)); #else /* !ARRAY_VARS */ return bind_variable (name, value); #endif /* !ARRAY_VARS */ } #if defined (READLINE) static char * edit_line (p) char *p; { char *ret; int len; if (!bash_readline_initialized) initialize_readline (); ret = readline (p); if (ret == 0) return ret; len = strlen (ret); ret = (char *)xrealloc (ret, len + 2); ret[len++] = delim; ret[len] = '\0'; return ret; } static int old_delim_ctype; static rl_command_func_t *old_delim_func; static int old_newline_ctype; static rl_command_func_t *old_newline_func; static unsigned char delim_char; static void set_eol_delim (c) int c; { Keymap cmap; if (bash_readline_initialized == 0) initialize_readline (); cmap = rl_get_keymap (); /* Change newline to self-insert */ old_newline_ctype = cmap[RETURN].type; old_newline_func = cmap[RETURN].function; cmap[RETURN].type = ISFUNC; cmap[RETURN].function = rl_insert; /* Bind the delimiter character to accept-line. */ old_delim_ctype = cmap[c].type; old_delim_func = cmap[c].function; cmap[c].type = ISFUNC; cmap[c].function = rl_newline; delim_char = c; } static void reset_eol_delim (cp) char *cp; { Keymap cmap; cmap = rl_get_keymap (); cmap[RETURN].type = old_newline_ctype; cmap[RETURN].function = old_newline_func; cmap[delim_char].type = old_delim_ctype; cmap[delim_char].function = old_delim_func; } #endif bash-2.05a/builtins/reserved.def100644 436 0 15707 7354626073 15131 0ustar chetwheelThis file is reserved.def, in which the shell reserved words are defined. It has no direct C file production, but defines builtins for the Bash builtin help command. Copyright (C) 1987, 1989, 1991, 1992 Free Software Foundation, Inc. This file is part of GNU Bash, the Bourne Again SHell. Bash is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 2, or (at your option) any later version. Bash is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with Bash; see the file COPYING. If not, write to the Free Software Foundation, 59 Temple Place, Suite 330, Boston, MA 02111 USA. $BUILTIN for $SHORT_DOC for NAME [in WORDS ... ;] do COMMANDS; done The `for' loop executes a sequence of commands for each member in a list of items. If `in WORDS ...;' is not present, then `in "$@"' is assumed. For each element in WORDS, NAME is set to that element, and the COMMANDS are executed. $END $BUILTIN select $SHORT_DOC select NAME [in WORDS ... ;] do COMMANDS; done The WORDS are expanded, generating a list of words. The set of expanded words is printed on the standard error, each preceded by a number. If `in WORDS' is not present, `in "$@"' is assumed. The PS3 prompt is then displayed and a line read from the standard input. If the line consists of the number corresponding to one of the displayed words, then NAME is set to that word. If the line is empty, WORDS and the prompt are redisplayed. If EOF is read, the command completes. Any other value read causes NAME to be set to null. The line read is saved in the variable REPLY. COMMANDS are executed after each selection until a break or return command is executed. $END $BUILTIN time $SHORT_DOC time [-p] PIPELINE Execute PIPELINE and print a summary of the real time, user CPU time, and system CPU time spent executing PIPELINE when it terminates. The return status is the return status of PIPELINE. The `-p' option prints the timing summary in a slightly different format. This uses the value of the TIMEFORMAT variable as the output format. $END $BUILTIN case $SHORT_DOC case WORD in [PATTERN [| PATTERN]...) COMMANDS ;;]... esac Selectively execute COMMANDS based upon WORD matching PATTERN. The `|' is used to separate multiple patterns. $END $BUILTIN if $SHORT_DOC if COMMANDS; then COMMANDS; [ elif COMMANDS; then COMMANDS; ]... [ else COMMANDS; ] fi The if COMMANDS are executed. If the exit status is zero, then the then COMMANDS are executed. Otherwise, each of the elif COMMANDS are executed in turn, and if the exit status is zero, the corresponding then COMMANDS are executed and the if command completes. Otherwise, the else COMMANDS are executed, if present. The exit status is the exit status of the last command executed, or zero if no condition tested true. $END $BUILTIN while $SHORT_DOC while COMMANDS; do COMMANDS; done Expand and execute COMMANDS as long as the final command in the `while' COMMANDS has an exit status of zero. $END $BUILTIN until $SHORT_DOC until COMMANDS; do COMMANDS; done Expand and execute COMMANDS as long as the final command in the `until' COMMANDS has an exit status which is not zero. $END $BUILTIN function $SHORT_DOC function NAME { COMMANDS ; } or NAME () { COMMANDS ; } Create a simple command invoked by NAME which runs COMMANDS. Arguments on the command line along with NAME are passed to the function as $0 .. $n. $END $BUILTIN { ... } $DOCNAME grouping_braces $SHORT_DOC { COMMANDS ; } Run a set of commands in a group. This is one way to redirect an entire set of commands. $END $BUILTIN % $DOCNAME fg_percent $SHORT_DOC %[DIGITS | WORD] [&] This is similar to the `fg' command. Resume a stopped or background job. If you specifiy DIGITS, then that job is used. If you specify WORD, then the job whose name begins with WORD is used. Following the job specification with a `&' places the job in the background. $END $BUILTIN variables $DOCNAME variable_help $SHORT_DOC variables - Some variable names and meanings BASH_VERSION Version information for this Bash. CDPATH A colon separated list of directories to search when the argument to `cd' is not found in the current directory. GLOBIGNORE A colon-separated list of patterns describing filenames to be ignored by pathname expansion. #if defined (HISTORY) HISTFILE The name of the file where your command history is stored. HISTFILESIZE The maximum number of lines this file can contain. HISTSIZE The maximum number of history lines that a running shell can access. #endif /* HISTORY */ HOME The complete pathname to your login directory. HOSTNAME The name of the current host. HOSTTYPE The type of CPU this version of Bash is running under. IGNOREEOF Controls the action of the shell on receipt of an EOF character as the sole input. If set, then the value of it is the number of EOF characters that can be seen in a row on an empty line before the shell will exit (default 10). When unset, EOF signifies the end of input. MACHTYPE A string describing the current system Bash is running on. MAILCHECK How often, in seconds, Bash checks for new mail. MAILPATH A colon-separated list of filenames which Bash checks for new mail. OSTYPE The version of Unix this version of Bash is running on. PATH A colon-separated list of directories to search when looking for commands. PROMPT_COMMAND A command to be executed before the printing of each primary prompt. PS1 The primary prompt string. PS2 The secondary prompt string. PWD The full pathname of the current directory. SHELLOPTS A colon-separated list of enabled shell options. TERM The name of the current terminal type. TIMEFORMAT The output format for timing statistics displayed by the `time' reserved word. auto_resume Non-null means a command word appearing on a line by itself is first looked for in the list of currently stopped jobs. If found there, that job is foregrounded. A value of `exact' means that the command word must exactly match a command in the list of stopped jobs. A value of `substring' means that the command word must match a substring of the job. Any other value means that the command must be a prefix of a stopped job. #if defined (HISTORY) # if defined (BANG_HISTORY) histchars Characters controlling history expansion and quick substitution. The first character is the history substitution character, usually `!'. The second is the `quick substitution' character, usually `^'. The third is the `history comment' character, usually `#'. # endif /* BANG_HISTORY */ HISTIGNORE A colon-separated list of patterns used to decide which commands should be saved on the history list. #endif /* HISTORY */ $END bash-2.05a/builtins/return.def100664 436 0 3513 7274035311 14571 0ustar chetwheelThis file is return.def, from which is created return.c. It implements the builtin "return" in Bash. Copyright (C) 1987, 1989, 1991 Free Software Foundation, Inc. This file is part of GNU Bash, the Bourne Again SHell. Bash is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 2, or (at your option) any later version. Bash is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with Bash; see the file COPYING. If not, write to the Free Software Foundation, 59 Temple Place, Suite 330, Boston, MA 02111 USA. $PRODUCES return.c $BUILTIN return $FUNCTION return_builtin $SHORT_DOC return [n] Causes a function to exit with the return value specified by N. If N is omitted, the return status is that of the last command. $END #include #if defined (HAVE_UNISTD_H) # ifdef _MINIX # include # endif # include #endif #include "../shell.h" #include "common.h" extern int last_command_exit_value; extern int subshell_environment; extern int return_catch_flag, return_catch_value; /* 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; { return_catch_value = list ? get_exitstat (list) : last_command_exit_value; if (return_catch_flag) longjmp (return_catch, 1); else { builtin_error ("can only `return' from a function or sourced script"); return (EXECUTION_FAILURE); } } bash-2.05a/builtins/set.def100644 436 0 52277 7367320373 14106 0ustar chetwheelThis file is set.def, from which is created set.c. It implements the "set" and "unset" builtins in Bash. Copyright (C) 1987, 1989, 1991 Free Software Foundation, Inc. This file is part of GNU Bash, the Bourne Again SHell. Bash is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 2, or (at your option) any later version. Bash is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with Bash; see the file COPYING. If not, write to the Free Software Foundation, 59 Temple Place, Suite 330, Boston, MA 02111 USA. $PRODUCES set.c #include #if defined (HAVE_UNISTD_H) # ifdef _MINIX # include # endif # include #endif #include #include "../bashansi.h" #include "../shell.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 extern int noclobber, posixly_correct, ignoreeof, eof_encountered_limit; #if defined (HISTORY) extern int dont_save_function_defs; #endif #if defined (READLINE) extern int no_line_editing; #endif /* READLINE */ $BUILTIN set $FUNCTION set_builtin $SHORT_DOC set [--abefhkmnptuvxBCHP] [-o option] [arg ...] -a Mark variables which are modified or created for export. -b Notify of job termination immediately. -e Exit immediately if a command exits with a non-zero status. -f Disable file name generation (globbing). -h Remember the location of commands as they are looked up. -i Force the shell to be an "interactive" one. Interactive shells always read `~/.bashrc' on startup. -k All assignment arguments are placed in the environment for a command, not just those that precede the command name. -m Job control is enabled. -n Read commands but do not execute them. -o option-name Set the variable corresponding to option-name: allexport same as -a braceexpand same as -B #if defined (READLINE) emacs use an emacs-style line editing interface #endif /* READLINE */ errexit same as -e hashall same as -h #if defined (BANG_HISTORY) histexpand same as -H #endif /* BANG_HISTORY */ #if defined (HISTORY) history enable command history #endif ignoreeof the shell will not exit upon reading EOF interactive-comments allow comments to appear in interactive commands keyword same as -k monitor same as -m noclobber same as -C noexec same as -n noglob same as -f nolog currently accepted but ignored notify same as -b nounset same as -u onecmd same as -t physical same as -P posix change the behavior of bash where the default operation differs from the 1003.2 standard to match the standard privileged same as -p verbose same as -v #if defined (READLINE) vi use a vi-style line editing interface #endif /* READLINE */ xtrace same as -x -p Turned on whenever the real and effective user ids do not match. Disables processing of the $ENV file and importing of shell functions. Turning this option off causes the effective uid and gid to be set to the real uid and gid. -t Exit after reading and executing one command. -u Treat unset variables as an error when substituting. -v Print shell input lines as they are read. -x Print commands and their arguments as they are executed. #if defined (BRACE_EXPANSION) -B the shell will perform brace expansion #endif /* BRACE_EXPANSION */ -C If set, disallow existing regular files to be overwritten by redirection of output. #if defined (BANG_HISTORY) -H Enable ! style history substitution. This flag is on by default. #endif /* BANG_HISTORY */ -P If set, do not follow symbolic links when executing commands such as cd which change the current directory. Using + rather than - causes these flags to be turned off. The flags can also be used upon invocation of the shell. The current set of flags may be found in $-. The remaining n ARGs are positional parameters and are assigned, in order, to $1, $2, .. $n. If no ARGs are given, all shell variables are printed. $END static void print_minus_o_option __P((char *, int, int)); static void print_all_shell_variables __P((void)); static int set_ignoreeof __P((int, char *)); static int set_posix_mode __P((int, char *)); #if defined (READLINE) static int set_edit_mode __P((int, char *)); static int get_edit_mode __P((char *)); #endif #if defined (HISTORY) static int bash_set_history __P((int, char *)); #endif static char *on = "on"; static char *off = "off"; /* An a-list used to match long options for set -o to the corresponding option letter. */ struct { char *name; int letter; } o_options[] = { { "allexport", 'a' }, #if defined (BRACE_EXPANSION) { "braceexpand",'B' }, #endif { "errexit", 'e' }, { "hashall", 'h' }, #if defined (BANG_HISTORY) { "histexpand", 'H' }, #endif /* BANG_HISTORY */ { "keyword", 'k' }, { "monitor", 'm' }, { "noclobber", 'C' }, { "noexec", 'n' }, { "noglob", 'f' }, #if defined (JOB_CONTROL) { "notify", 'b' }, #endif /* JOB_CONTROL */ { "nounset", 'u' }, { "onecmd", 't' }, { "physical", 'P' }, { "privileged", 'p' }, { "verbose", 'v' }, { "xtrace", 'x' }, {(char *)NULL, 0 }, }; typedef int setopt_set_func_t __P((int, char *)); typedef int setopt_get_func_t __P((char *)); struct { char *name; int *variable; setopt_set_func_t *set_func; setopt_get_func_t *get_func; } binary_o_options[] = { #if defined (HISTORY) { "history", &remember_on_history, bash_set_history, (setopt_get_func_t *)NULL }, #endif { "ignoreeof", &ignoreeof, set_ignoreeof, (setopt_get_func_t *)NULL }, { "interactive-comments", &interactive_comments, (setopt_set_func_t *)NULL, (setopt_get_func_t *)NULL }, #if defined (HISTORY) { "nolog", &dont_save_function_defs, (setopt_set_func_t *)NULL, (setopt_get_func_t *)NULL }, #endif { "posix", &posixly_correct, set_posix_mode, (setopt_get_func_t *)NULL }, #if defined (READLINE) { "emacs", (int *)NULL, set_edit_mode, get_edit_mode }, { "vi", (int *)NULL, set_edit_mode, get_edit_mode }, #endif { (char *)NULL, (int *)NULL, (setopt_set_func_t *)NULL, (setopt_get_func_t *)NULL } }; #define GET_BINARY_O_OPTION_VALUE(i, name) \ ((binary_o_options[i].get_func) ? (*binary_o_options[i].get_func) (name) \ : (*binary_o_options[i].variable)) #define SET_BINARY_O_OPTION_VALUE(i, onoff, name) \ ((binary_o_options[i].set_func) ? (*binary_o_options[i].set_func) (onoff, name) \ : (*binary_o_options[i].variable = (onoff == FLAG_ON))) int minus_o_option_value (name) char *name; { register int i; int *on_or_off; for (i = 0; o_options[i].name; i++) { if (STREQ (name, o_options[i].name)) { on_or_off = find_flag (o_options[i].letter); return ((on_or_off == FLAG_UNKNOWN) ? -1 : *on_or_off); } } for (i = 0; binary_o_options[i].name; i++) { if (STREQ (name, binary_o_options[i].name)) return (GET_BINARY_O_OPTION_VALUE (i, name)); } return (-1); } #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 (value = i = 0; o_options[i].name; i++) { 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); } for (i = 0; binary_o_options[i].name; i++) { value = GET_BINARY_O_OPTION_VALUE (i, binary_o_options[i].name); if (mode == -1 || mode == value) print_minus_o_option (binary_o_options[i].name, value, reusable); } } char ** get_minus_o_opts () { char **ret; int n, i, ind; n = (sizeof (o_options) / sizeof (o_options[0])) + (sizeof (binary_o_options) / sizeof (binary_o_options[0])); ret = alloc_array (n + 1); for (i = ind = 0; o_options[i].name; i++) ret[ind++] = o_options[i].name; for (i = 0; binary_o_options[i].name; i++) ret[ind++] = binary_o_options[i].name; ret[ind] = (char *)NULL; return ret; } static int set_ignoreeof (on_or_off, option_name) int on_or_off; char *option_name; { ignoreeof = on_or_off == FLAG_ON; unbind_variable ("ignoreeof"); if (ignoreeof) bind_variable ("IGNOREEOF", "10"); else unbind_variable ("IGNOREEOF"); sv_ignoreeof ("IGNOREEOF"); return 0; } static int set_posix_mode (on_or_off, option_name) int on_or_off; char *option_name; { posixly_correct = on_or_off == FLAG_ON; if (posixly_correct == 0) unbind_variable ("POSIXLY_CORRECT"); else bind_variable ("POSIXLY_CORRECT", "y"); 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) { bash_history_enable (); if (history_lines_this_session == 0) load_history (); } else bash_history_disable (); return (1 - remember_on_history); } #endif int set_minus_o_option (on_or_off, option_name) int on_or_off; char *option_name; { int option_char; register int i; for (i = 0; binary_o_options[i].name; i++) { if (STREQ (option_name, binary_o_options[i].name)) { SET_BINARY_O_OPTION_VALUE (i, on_or_off, option_name); return (EXECUTION_SUCCESS); } } for (i = 0, option_char = -1; o_options[i].name; i++) { if (STREQ (option_name, o_options[i].name)) { option_char = o_options[i].letter; break; } } if (option_char == -1) { builtin_error ("%s: unknown option name", option_name); return (EXECUTION_FAILURE); } if (change_flag (option_char, on_or_off) == FLAG_ERROR) { bad_option (option_name); return (EXECUTION_FAILURE); } 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; int vsize, i, vptr, *ip, exported; SHELL_VAR *v; for (vsize = i = 0; o_options[i].name; i++) { ip = find_flag (o_options[i].letter); if (ip && *ip) vsize += strlen (o_options[i].name) + 1; } for (i = 0; binary_o_options[i].name; i++) if (GET_BINARY_O_OPTION_VALUE (i, binary_o_options[i].name)) vsize += strlen (binary_o_options[i].name) + 1; value = (char *)xmalloc (vsize + 1); for (i = vptr = 0; o_options[i].name; i++) { ip = find_flag (o_options[i].letter); if (ip && *ip) { strcpy (value + vptr, o_options[i].name); vptr += strlen (o_options[i].name); value[vptr++] = ':'; } } for (i = 0; binary_o_options[i].name; i++) if (GET_BINARY_O_OPTION_VALUE (i, binary_o_options[i].name)) { strcpy (value + vptr, binary_o_options[i].name); vptr += strlen (binary_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); /* 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)) ? (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 () { #if defined (HISTORY) remember_on_history = 1; #endif ignoreeof = 0; } /* 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; WORD_LIST *l; register char *arg; if (list == 0) { print_all_shell_variables (); return (EXECUTION_SUCCESS); } /* Check validity of flag arguments. */ if (*list->word->word == '-' || *list->word->word == '+') { for (l = list; l && (arg = l->word->word); l = l->next) { char c; if (arg[0] != '-' && arg[0] != '+') break; /* `-' or `--' signifies end of flag arguments. */ if (arg[0] == '-' && (!arg[1] || (arg[1] == '-' && !arg[2]))) break; while (c = *++arg) { if (find_flag (c) == FLAG_UNKNOWN && c != 'o') { char s[2]; s[0] = c; s[1] = '\0'; bad_option (s); if (c == '?') builtin_usage (); return (c == '?' ? EXECUTION_SUCCESS : EXECUTION_FAILURE); } } } } /* 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 == '+')); 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 (set_minus_o_option (on_or_off, option_name) != EXECUTION_SUCCESS) { set_shellopts (); return (EXECUTION_FAILURE); } } else if (change_flag (flag_name, on_or_off) == FLAG_ERROR) { char opt[3]; opt[0] = on_or_off; opt[1] = flag_name; opt[2] = '\0'; bad_option (opt); 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 (EXECUTION_SUCCESS); } $BUILTIN unset $FUNCTION unset_builtin $SHORT_DOC unset [-f] [-v] [name ...] For each NAME, remove the corresponding variable or function. Given the `-v', unset will only act on variables. Given the `-f' flag, unset will only act on functions. With neither flag, unset first tries to unset a variable, and if that fails, then tries to unset a function. Some variables cannot be unset; also see readonly. $END #define NEXT_VARIABLE() any_failed++; list = list->next; continue; int unset_builtin (list) WORD_LIST *list; { int unset_function, unset_variable, unset_array, opt, any_failed; char *name; unset_function = unset_variable = unset_array = any_failed = 0; reset_internal_getopt (); while ((opt = internal_getopt (list, "fv")) != -1) { switch (opt) { case 'f': unset_function = 1; break; case 'v': unset_variable = 1; break; default: builtin_usage (); return (EX_USAGE); } } list = loptend; if (unset_function && unset_variable) { builtin_error ("cannot simultaneously unset a function and a variable"); return (EXECUTION_FAILURE); } while (list) { SHELL_VAR *var; int tem; #if defined (ARRAY_VARS) char *t; #endif name = list->word->word; #if defined (ARRAY_VARS) unset_array = 0; if (!unset_function && valid_array_reference (name)) { t = strchr (name, '['); *t++ = '\0'; unset_array++; } #endif /* 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 && posixly_correct) || !unset_function) && legal_identifier (name) == 0) { builtin_error ("`%s': not a valid identifier", name); NEXT_VARIABLE (); } var = unset_function ? find_function (name) : find_variable (name); if (var && !unset_function && non_unsettable_p (var)) { builtin_error ("%s: cannot unset", name); NEXT_VARIABLE (); } /* Posix.2 says that unsetting readonly variables is an error. */ if (var && readonly_p (var)) { builtin_error ("%s: cannot unset: readonly %s", 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) { if (array_p (var) == 0) { builtin_error ("%s: not an array variable", name); NEXT_VARIABLE (); } else tem = unbind_array_element (var, t); } else #endif /* ARRAY_VARS */ tem = makunbound (name, unset_function ? shell_functions : shell_variables); /* This is what Posix.2 draft 11+ 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 && !unset_function && !unset_variable) tem = makunbound (name, shell_functions); if (tem == -1) any_failed++; else if (!unset_function) stupidly_hack_special_variables (name); list = list->next; } return (any_failed ? EXECUTION_FAILURE : EXECUTION_SUCCESS); } bash-2.05a/builtins/setattr.def100644 436 0 23475 7342751365 15001 0ustar chetwheelThis file is setattr.def, from which is created setattr.c. It implements the builtins "export" and "readonly", in Bash. Copyright (C) 1987, 1989, 1991 Free Software Foundation, Inc. This file is part of GNU Bash, the Bourne Again SHell. Bash is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 2, or (at your option) any later version. Bash is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with Bash; see the file COPYING. If not, write to the Free Software Foundation, 59 Temple Place, Suite 330, Boston, MA 02111 USA. $PRODUCES setattr.c #include #if defined (HAVE_UNISTD_H) # ifdef _MINIX # include # endif # include #endif #include #include "../bashansi.h" #include "../shell.h" #include "common.h" #include "bashgetopt.h" extern int posixly_correct; extern int array_needs_making; extern char *this_command_name; extern sh_builtin_func_t *this_shell_builtin; #ifdef ARRAY_VARS extern int declare_builtin (); #endif #define READONLY_OR_EXPORT \ (this_shell_builtin == readonly_builtin || this_shell_builtin == export_builtin) $BUILTIN export $FUNCTION export_builtin $SHORT_DOC export [-nf] [name ...] or export -p NAMEs are marked for automatic export to the environment of subsequently executed commands. If the -f option is given, the NAMEs refer to functions. If no NAMEs are given, or if `-p' is given, a list of all names that are exported in this shell is printed. An argument of `-n' says to remove the export property from subsequent NAMEs. An argument of `--' disables further option processing. $END /* 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)); } $BUILTIN readonly $FUNCTION readonly_builtin $SHORT_DOC readonly [-anf] [name ...] or readonly -p The given NAMEs are marked readonly and the values of these NAMEs may not be changed by subsequent assignment. If the -f option is given, then functions corresponding to the NAMEs are so marked. If no arguments are given, or if `-p' is given, a list of all readonly names is printed. An argument of `-n' says to remove the readonly property from subsequent NAMEs. The `-a' option means to treat each NAME as an array variable. An argument of `--' disables further option processing. $END /* 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)); } /* 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. */ int set_or_show_attributes (list, attribute, nodefs) register WORD_LIST *list; int attribute, nodefs; { register SHELL_VAR *var; int assign, undo, functions_only, arrays_only, any_failed, assign_error, opt; char *name; #if defined (ARRAY_VARS) WORD_LIST *nlist, *tlist; WORD_DESC *w; #endif undo = functions_only = arrays_only = any_failed = assign_error = 0; /* Read arguments from the front of the list. */ reset_internal_getopt (); while ((opt = internal_getopt (list, "anfp")) != -1) { switch (opt) { case 'n': undo = 1; break; case 'f': functions_only = 1; break; #if defined (ARRAY_VARS) case 'a': arrays_only = 1; break; #endif case 'p': break; 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 SETVARATTR (var, attribute, undo); list = list->next; continue; } /* xxx [-np] name[=value] */ assign = assignment (name); if (assign) name[assign] = '\0'; if (legal_identifier (name) == 0) { builtin_error ("`%s': not a valid identifier", name); if (assign) assign_error++; else any_failed++; list = list->next; continue; } if (assign) /* xxx [-np] name=value */ { name[assign] = '='; #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) { tlist = list->next; list->next = (WORD_LIST *)NULL; w = make_word ("-ra"); 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'; } set_var_attribute (name, attribute, undo); 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; } #endif if (variable_list) { for (i = 0; var = variable_list[i]; i++) { #if defined (ARRAY_VARS) if (arrays_only && array_p (var) == 0) continue; #endif #if 0 if ((var->attributes & attribute) && invisible_p (var) == 0) #else if ((var->attributes & attribute)) #endif show_var_attributes (var, READONLY_OR_EXPORT, nodefs); } free (variable_list); } } return (assign_error ? EX_BADASSIGN : ((any_failed == 0) ? EXECUTION_SUCCESS : EXECUTION_FAILURE)); } /* 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[6], *x; 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'; #endif if (function_p (var)) flags[i++] = 'f'; if (integer_p (var)) flags[i++] = 'i'; if (readonly_p (var)) flags[i++] = 'r'; if (exported_p (var)) flags[i++] = 'x'; } else { #if defined (ARRAY_VARS) if (array_p (var)) flags[i++] = 'a'; #endif if (function_p (var)) flags[i++] = 'f'; } flags[i] = '\0'; 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 (array_p (var)) print_array_assignment (var, 1); else #endif /* force `readline' 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), 1)); else if (invisible_p (var)) printf ("%s\n", var->name); else { x = sh_double_quote (value_cell (var) ? 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_tempenv_variable (name); if (var == 0) var = find_variable (name); if (var && invisible_p (var) == 0) { show_var_attributes (var, READONLY_OR_EXPORT, nodefs); if (tempvar_p (var)) dispose_variable (var); return (0); } else return (1); } void set_var_attribute (name, attribute, undo) char *name; int attribute, undo; { SHELL_VAR *var, *tv; if (undo) var = find_variable (name); else { if (tv = find_tempenv_variable (name)) { var = bind_variable (tv->name, tv->value ? tv->value : ""); dispose_variable (tv); } else var = find_variable (name); if (var == 0) { var = bind_variable (name, (char *)NULL); VSETATTR (var, att_invisible); } } if (var) SETVARATTR (var, attribute, undo); if (var && (exported_p (var) || (attribute & att_exported))) array_needs_making++; /* XXX */ } bash-2.05a/builtins/shift.def100664 436 0 4643 7302265724 14401 0ustar chetwheelThis file is shift.def, from which is created shift.c. It implements the builtin "shift" in Bash. Copyright (C) 1987, 1989, 1991 Free Software Foundation, Inc. This file is part of GNU Bash, the Bourne Again SHell. Bash is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 2, or (at your option) any later version. Bash is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with Bash; see the file COPYING. If not, write to the Free Software Foundation, 59 Temple Place, Suite 330, Boston, MA 02111 USA. $PRODUCES shift.c #include #if defined (HAVE_UNISTD_H) # ifdef _MINIX # include # endif # include #endif #include "../bashansi.h" #include "../shell.h" #include "common.h" $BUILTIN shift $FUNCTION shift_builtin $SHORT_DOC shift [n] The positional parameters from $N+1 ... are renamed to $1 ... If N is not given, it is assumed to be 1. $END 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; { long times; register int count; WORD_LIST *temp; times = get_numeric_arg (list, 0); if (times == 0) return (EXECUTION_SUCCESS); else if (times < 0) { builtin_error ("shift count must be >= 0"); return (EXECUTION_FAILURE); } else if (times > number_of_args ()) { if (print_shift_error) builtin_error ("shift count must be <= $#"); return (EXECUTION_FAILURE); } while (times-- > 0) { if (dollar_vars[1]) free (dollar_vars[1]); for (count = 1; count < 9; count++) dollar_vars[count] = dollar_vars[count + 1]; if (rest_of_args) { temp = rest_of_args; dollar_vars[9] = savestring (temp->word->word); rest_of_args = rest_of_args->next; temp->next = (WORD_LIST *)NULL; dispose_words (temp); } else dollar_vars[9] = (char *)NULL; } return (EXECUTION_SUCCESS); } bash-2.05a/builtins/shopt.def100664 436 0 31340 7347466032 14437 0ustar chetwheelThis file is shopt.def, from which is created shopt.c. It implements the Bash `shopt' builtin. Copyright (C) 1994 Free Software Foundation, Inc. This file is part of GNU Bash, the Bourne Again SHell. Bash is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 2, or (at your option) any later version. Bash is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with Bash; see the file COPYING. If not, write to the Free Software Foundation, 59 Temple Place, Suite 330, Boston, MA 02111 USA. $PRODUCES shopt.c $BUILTIN shopt $DOCNAME shopt_builtin $FUNCTION shopt_builtin $SHORT_DOC shopt [-pqsu] [-o long-option] optname [optname...] Toggle the values of variables controlling optional behavior. The -s flag means to enable (set) each OPTNAME; the -u flag unsets each OPTNAME. The -q flag suppresses output; the exit status indicates whether each OPTNAME is set or unset. The -o option restricts the OPTNAMEs to those defined for use with `set -o'. With no options, or with the -p option, a list of all settable options is displayed, with an indication of whether or not each is set. $END #include #if defined (HAVE_UNISTD_H) # ifdef _MINIX # include # endif # include #endif #include #include "../shell.h" #include "../flags.h" #include "common.h" #include "bashgetopt.h" #define UNSETOPT 0 #define SETOPT 1 #define OPTFMT "%-15s\t%s\n" extern int allow_null_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, interactive_comments; extern int cdspelling, expand_aliases; extern int check_window_size; extern int glob_ignore_case; extern int hup_on_exit; extern int xpg_echo; #if defined (EXTENDED_GLOB) extern int extended_glob; #endif #if defined (HISTORY) extern int literal_history, command_oriented_history; extern int force_append_history; #endif #if defined (READLINE) extern int hist_verify, history_reediting, perform_hostname_completion; extern int no_empty_command_completion; extern int enable_hostname_completion __P((int)); #endif #if defined (PROGRAMMABLE_COMPLETION) extern int prog_completion_enabled; #endif #if defined (RESTRICTED_SHELL) extern int restricted_shell; extern char *shell_name; #endif static int set_interactive_comments __P((int)); #if defined (RESTRICTED_SHELL) static int set_restricted_shell __P((int)); #endif static int shopt_login_shell; typedef int shopt_set_func_t __P((int)); static struct { char *name; int *value; shopt_set_func_t *set_func; } shopt_vars[] = { { "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 }, { "checkwinsize", &check_window_size, (shopt_set_func_t *)NULL }, #if defined (HISTORY) { "cmdhist", &command_oriented_history, (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 (EXTENDED_GLOB) { "extglob", &extended_glob, (shopt_set_func_t *)NULL }, #endif #if defined (READLINE) { "histreedit", &history_reediting, (shopt_set_func_t *)NULL }, #endif #if defined (HISTORY) { "histappend", &force_append_history, (shopt_set_func_t *)NULL }, #endif #if defined (READLINE) { "histverify", &hist_verify, (shopt_set_func_t *)NULL }, { "hostcomplete", &perform_hostname_completion, enable_hostname_completion }, #endif { "huponexit", &hup_on_exit, (shopt_set_func_t *)NULL }, { "interactive_comments", &interactive_comments, set_interactive_comments }, #if defined (HISTORY) { "lithist", &literal_history, (shopt_set_func_t *)NULL }, #endif { "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 }, { "nullglob", &allow_null_glob_expansion, (shopt_set_func_t *)NULL }, #if defined (PROGRAMMABLE_COMPLETION) { "progcomp", &prog_completion_enabled, (shopt_set_func_t *)NULL }, #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 }, { "xpg_echo", &xpg_echo, (shopt_set_func_t *)NULL }, { (char *)0, (int *)0, (shopt_set_func_t *)NULL } }; static char *on = "on"; static char *off = "off"; static int find_shopt __P((char *)); static int toggle_shopts __P((int, WORD_LIST *, int)); static void print_shopt __P((char *, int, int)); static int list_shopts __P((WORD_LIST *, int)); static int list_some_shopts __P((int, int)); static int list_shopt_o_options __P((WORD_LIST *, int)); static int list_some_o_options __P((int, int)); static int set_shopt_o_options __P((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; 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. */ void reset_shopt_options () { allow_null_glob_expansion = glob_dot_filenames = 0; cdable_vars = mail_warning = 0; no_exit_on_failed_exec = print_shift_error = 0; check_hashed_filenames = cdspelling = expand_aliases = check_window_size = 0; source_uses_path = promptvars = 1; #if defined (EXTENDED_GLOB) extended_glob = 0; #endif #if defined (HISTORY) literal_history = force_append_history = 0; command_oriented_history = 1; #endif #if defined (READLINE) hist_verify = history_reediting = 0; perform_hostname_completion = 1; #endif 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; } #define SHOPT_ERROR(str) builtin_error ("%s: unknown shell option name", str) static int toggle_shopts (mode, list, quiet) int mode; WORD_LIST *list; int quiet; { WORD_LIST *l; int ind, rval; 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) (mode); } } 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 (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 (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 (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 (EXECUTION_SUCCESS); } for (l = list, rval = EXECUTION_SUCCESS; l; l = l->next) { val = minus_o_option_value (l->word->word); if (val == -1) { builtin_error ("%s: unknown option name", 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 (rval); } static int list_some_o_options (mode, flags) int mode, flags; { if ((flags & QFLAG) == 0) list_minus_o_opts (mode, (flags & PFLAG)); return (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_interactive_comments (mode) int mode; { set_shellopts (); return (0); } #if defined (RESTRICTED_SHELL) /* Don't allow the value of restricted_shell to be modified. */ static int set_restricted_shell (mode) 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 (mode) 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 = alloc_array (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 (EXECUTION_SUCCESS); } bash-2.05a/builtins/source.def100644 436 0 7753 7164126420 14562 0ustar chetwheelThis file is source.def, from which is created source.c. It implements the builtins "." and "source" in Bash. Copyright (C) 1987, 1989, 1991 Free Software Foundation, Inc. This file is part of GNU Bash, the Bourne Again SHell. Bash is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 2, or (at your option) any later version. Bash is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with Bash; see the file COPYING. If not, write to the Free Software Foundation, 59 Temple Place, Suite 330, Boston, MA 02111 USA. $PRODUCES source.c $BUILTIN source $FUNCTION source_builtin $SHORT_DOC source filename Read and execute commands from FILENAME and return. The pathnames in $PATH are used to find the directory containing FILENAME. $END $BUILTIN . $DOCNAME dot $FUNCTION source_builtin $SHORT_DOC . filename Read and execute commands from FILENAME and return. The pathnames in $PATH are used to find the directory containing FILENAME. $END /* source.c - Implements the `.' and `source' builtins. */ #include #include "../bashtypes.h" #include "posixstat.h" #include "filecntl.h" #ifndef _MINIX # include #endif #include #if defined (HAVE_UNISTD_H) # include #endif #include "../bashansi.h" #include "../shell.h" #include "../findcmd.h" #include "common.h" #if !defined (errno) extern int errno; #endif /* !errno */ #if defined (RESTRICTED_SHELL) extern int restricted; #endif /* 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 ()) { dispose_saved_dollar_vars (); set_dollar_vars_unchanged (); } else pop_dollar_vars (); } /* 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; if (list == 0) { builtin_error ("filename argument required"); builtin_usage (); return (EX_USAGE); } if (no_options (list)) return (EX_USAGE); #if defined (RESTRICTED_SHELL) if (restricted && strchr (list->word->word, '/')) { builtin_error ("%s: restricted", list->word->word); return (EXECUTION_FAILURE); } #endif filename = (char *)NULL; if (source_uses_path) filename = find_path_file (list->word->word); if (filename == 0) { if (source_searches_cwd == 0) { builtin_error ("%s: file not found", list->word->word); return (EXECUTION_FAILURE); } else filename = savestring (list->word->word); } begin_unwind_frame ("source"); add_unwind_protect ((Function *)xfree, filename); if (list->next) { push_dollar_vars (); add_unwind_protect ((Function *)maybe_pop_dollar_vars, (char *)NULL); remember_args (list->next, 1); } set_dollar_vars_unchanged (); result = source_file (filename); run_unwind_frame ("source"); return (result); } bash-2.05a/builtins/suspend.def100644 436 0 5224 7347464346 14751 0ustar chetwheelThis file is suspend.def, from which is created suspend.c. It implements the builtin "suspend" in Bash. Copyright (C) 1987, 1989, 1991 Free Software Foundation, Inc. This file is part of GNU Bash, the Bourne Again SHell. Bash is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 2, or (at your option) any later version. Bash is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with Bash; see the file COPYING. If not, write to the Free Software Foundation, 59 Temple Place, Suite 330, Boston, MA 02111 USA. $PRODUCES suspend.c $BUILTIN suspend $DEPENDS_ON JOB_CONTROL $FUNCTION suspend_builtin $SHORT_DOC suspend [-f] Suspend the execution of this shell until it receives a SIGCONT signal. The `-f' if specified says not to complain about this being a login shell if it is; just suspend anyway. $END #include #if defined (JOB_CONTROL) #if defined (HAVE_UNISTD_H) # ifdef _MINIX # include # endif # include #endif #include "../bashtypes.h" #include #include "../shell.h" #include "../jobs.h" #include "common.h" #include "bashgetopt.h" static SigHandler *old_cont; #if 0 static SigHandler *old_stop; #endif /* Continue handler. */ 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; default: builtin_usage (); return (EX_USAGE); } list = loptend; if (job_control == 0) { builtin_error ("cannot suspend a shell without job control"); return (EXECUTION_FAILURE); } if (force == 0) { no_args (list); if (login_shell) { builtin_error ("cannot suspend a login shell"); return (EXECUTION_FAILURE); } } 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 */ bash-2.05a/builtins/test.def100664 436 0 11021 7305170413 14240 0ustar chetwheelThis file is test.def, from which is created test.c. It implements the builtin "test" in Bash. Copyright (C) 1987, 1989, 1991 Free Software Foundation, Inc. This file is part of GNU Bash, the Bourne Again SHell. Bash is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 2, or (at your option) any later version. Bash is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with Bash; see the file COPYING. If not, write to the Free Software Foundation, 59 Temple Place, Suite 330, Boston, MA 02111 USA. $PRODUCES test.c $BUILTIN test $FUNCTION test_builtin $SHORT_DOC test [expr] Exits with a status of 0 (trueness) or 1 (falseness) depending on the evaluation of EXPR. Expressions may be unary or binary. Unary expressions are often used to examine the status of a file. There are string operators as well, and numeric comparison operators. File operators: -a FILE True if file exists. -b FILE True if file is block special. -c FILE True if file is character special. -d FILE True if file is a directory. -e FILE True if file exists. -f FILE True if file exists and is a regular file. -g FILE True if file is set-group-id. -h FILE True if file is a symbolic link. -L FILE True if file is a symbolic link. -k FILE True if file has its `sticky' bit set. -p FILE True if file is a named pipe. -r FILE True if file is readable by you. -s FILE True if file exists and is not empty. -S FILE True if file is a socket. -t FD True if FD is opened on a terminal. -u FILE True if the file is set-user-id. -w FILE True if the file is writable by you. -x FILE True if the file is executable by you. -O FILE True if the file is effectively owned by you. -G FILE True if the file is effectively owned by your group. -N FILE True if the file has been modified since it was last read. FILE1 -nt FILE2 True if file1 is newer than file2 (according to modification date). FILE1 -ot FILE2 True if file1 is older than file2. FILE1 -ef FILE2 True if file1 is a hard link to file2. String operators: -z STRING True if string is empty. -n STRING STRING True if string is not empty. STRING1 = STRING2 True if the strings are equal. STRING1 != STRING2 True if the strings are not equal. STRING1 < STRING2 True if STRING1 sorts before STRING2 lexicographically. STRING1 > STRING2 True if STRING1 sorts after STRING2 lexicographically. Other operators: -o OPTION True if the shell option OPTION is enabled. ! EXPR True if expr is false. EXPR1 -a EXPR2 True if both expr1 AND expr2 are true. EXPR1 -o EXPR2 True if either expr1 OR expr2 is true. arg1 OP arg2 Arithmetic tests. OP is one of -eq, -ne, -lt, -le, -gt, or -ge. Arithmetic binary operators return true if ARG1 is equal, not-equal, less-than, less-than-or-equal, greater-than, or greater-than-or-equal than ARG2. $END $BUILTIN [ $DOCNAME test_bracket $FUNCTION test_builtin $SHORT_DOC [ arg... ] This is a synonym for the "test" builtin, but the last argument must be a literal `]', to match the opening `['. $END #include #if defined (HAVE_UNISTD_H) # ifdef _MINIX # include # endif # include #endif #include "../bashansi.h" #include "../shell.h" #include "../test.h" #include "common.h" extern char *this_command_name; /* 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); } bash-2.05a/builtins/times.def100644 436 0 5007 6756037066 14406 0ustar chetwheelThis file is times.def, from which is created times.c. It implements the builtin "times" in Bash. Copyright (C) 1987, 1989, 1991 Free Software Foundation, Inc. This file is part of GNU Bash, the Bourne Again SHell. Bash is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 2, or (at your option) any later version. Bash is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with Bash; see the file COPYING. If not, write to the Free Software Foundation, 59 Temple Place, Suite 330, Boston, MA 02111 USA. $PRODUCES times.c $BUILTIN times $FUNCTION times_builtin $SHORT_DOC times Print the accumulated user and system times for processes run from the shell. $END #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; 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; 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 */ printf ("0.00 0.00\n0.00 0.00\n"); # endif /* HAVE_TIMES */ #endif /* !HAVE_TIMES */ return (EXECUTION_SUCCESS); } bash-2.05a/builtins/trap.def100664 436 0 14153 7347464446 14262 0ustar chetwheelThis file is trap.def, from which is created trap.c. It implements the builtin "trap" in Bash. Copyright (C) 1987, 1989, 1991 Free Software Foundation, Inc. This file is part of GNU Bash, the Bourne Again SHell. Bash is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 2, or (at your option) any later version. Bash is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with Bash; see the file COPYING. If not, write to the Free Software Foundation, 59 Temple Place, Suite 330, Boston, MA 02111 USA. $PRODUCES trap.c $BUILTIN trap $FUNCTION trap_builtin $SHORT_DOC trap [arg] [signal_spec ...] or trap -l The command ARG is to be read and executed when the shell receives signal(s) SIGNAL_SPEC. If ARG is absent all specified signals are reset to their original values. If ARG is the null string each SIGNAL_SPEC is ignored by the shell and by the commands it invokes. If a SIGNAL_SPEC is EXIT (0) the command ARG is executed on exit from the shell. If a SIGNAL_SPEC is DEBUG, ARG is executed after every command. If ARG is `-p' then the trap commands associated with each SIGNAL_SPEC are displayed. If no arguments are supplied or if only `-p' is given, trap prints the list of commands associated with each signal number. Each SIGNAL_SPEC is either a signal name in or a signal number. `trap -l' prints a list of signal names and their corresponding numbers. Note that a signal can be sent to the shell with "kill -signal $$". $END #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 __P((int)); static int display_traps __P((WORD_LIST *)); /* The trap command: trap trap trap -l trap -p [sigspec ...] trap [--] Set things up so that ARG is executed when SIGNAL(s) N is recieved. 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. */ extern int posixly_correct; 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; default: builtin_usage (); return (EX_USAGE); } } list = loptend; if (list_signal_names) return (display_signal_list ((WORD_LIST *)NULL, 1)); else if (display || list == 0) return (display_traps (list)); else { char *first_arg; int operation, sig; operation = SET; first_arg = list->word->word; if (first_arg && *first_arg && (*first_arg != '-' || first_arg[1]) && signal_object_p (first_arg)) operation = REVERT; else { list = list->next; if (*first_arg == '\0') operation = IGNORE; else if (first_arg[0] == '-' && !first_arg[1]) operation = REVERT; } while (list) { sig = decode_signal (list->word->word); if (sig == NO_SIG) { builtin_error ("%s: not a signal specification", 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: if (interactive) set_signal_handler (SIGINT, sigint_sighandler); else set_signal_handler (SIGINT, termination_unwind_protect); 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) int i; { char *t, *p, *sn; p = trap_list[i]; if (p == (char *)DEFAULT_SIG) return; 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); FREE (t); } static int display_traps (list) WORD_LIST *list; { int result, i; if (list == 0) { for (i = 0; i < BASH_NSIG; i++) showtrap (i); return (EXECUTION_SUCCESS); } for (result = EXECUTION_SUCCESS; list; list = list->next) { i = decode_signal (list->word->word); if (i == NO_SIG) { result = EXECUTION_FAILURE; builtin_error ("%s: not a signal specification", list->word->word); } else showtrap (i); } return (result); } bash-2.05a/builtins/type.def100664 436 0 22253 7300001054 14240 0ustar chetwheelThis file is type.def, from which is created type.c. It implements the builtin "type" in Bash. Copyright (C) 1987, 1989, 1991, 1992 Free Software Foundation, Inc. This file is part of GNU Bash, the Bourne Again SHell. Bash is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 2, or (at your option) any later version. Bash is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with Bash; see the file COPYING. If not, write to the Free Software Foundation, 59 Temple Place, Suite 330, Boston, MA 02111 USA. $PRODUCES type.c $BUILTIN type $FUNCTION type_builtin $SHORT_DOC type [-apt] name [name ...] For each NAME, indicate how it would be interpreted if used as a command name. If the -t option is used, `type' outputs a single word which is one of `alias', `keyword', `function', `builtin', `file' or `', if NAME is an alias, shell reserved word, shell function, shell builtin, disk file, or unfound, respectively. If the -p flag is used, `type' either returns the name of the disk file that would be executed, or nothing if `type -t NAME' would not return `file'. If the -a flag is used, `type' displays all of the places that contain an executable named `file'. This includes aliases and functions, if and only if the -p flag is not also used. $END #include #include "../bashtypes.h" #include "posixstat.h" #if defined (HAVE_UNISTD_H) # include #endif #include #include "../bashansi.h" #include "../shell.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 __P((char *)); extern char *this_command_name; /* 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. Order of evaluation: alias keyword function builtin file */ int type_builtin (list) WORD_LIST *list; { int path_only, type_only, all, verbose; int successful_finds, opt; WORD_LIST *prev, *this; if (list == 0) return (EXECUTION_SUCCESS); path_only = type_only = all = 0; successful_finds = 0; /* Handle the obsolescent `-type', `-path', and `-all' by prescanning the arguments and removing those options from the list before calling internal_getopt. Recognize `--type', `--path', and `--all' also. THIS SHOULD REALLY GO AWAY. */ for (this = list; this && this->word->word[0] == '-'; ) { char *flag = &(this->word->word[1]); if (STREQ (flag, "type") || STREQ (flag, "-type")) { type_only = 1; path_only = 0; } else if (STREQ (flag, "path") || STREQ (flag, "-path")) { path_only = 1; type_only = 0; } else if (STREQ (flag, "all") || STREQ (flag, "-all")) all = 1; else { prev = this; this = this->next; continue; } /* We found a long option; remove it from the argument list. Don't free it if it's the head of the argument list, though -- the argument list will be freed by the caller. */ if (this == list) this = list = list->next; else { prev->next = this->next; this->next = (WORD_LIST *)NULL; dispose_words (this); this = prev->next; } } reset_internal_getopt (); while ((opt = internal_getopt (list, "apt")) != -1) { switch (opt) { case 't': type_only = 1; path_only = 0; break; case 'p': path_only = 1; type_only = 0; break; case 'a': all = 1; break; default: builtin_usage (); return (EX_USAGE); } } list = loptend; if (type_only) verbose = 1; else if (path_only == 0) verbose = 2; else if (path_only) verbose = 3; else verbose = 0; while (list) { int found; found = describe_command (list->word->word, verbose, all); if (!found && !path_only && !type_only) builtin_error ("%s: not found", list->word->word); successful_finds += found; list = list->next; } fflush (stdout); return ((successful_finds != 0) ? EXECUTION_SUCCESS : EXECUTION_FAILURE); } /* * Describe COMMAND as required by the type builtin. * * If VERBOSE == 0, don't print anything * If VERBOSE == 1, print short description as for `type -t' * If VERBOSE == 2, print long description as for `type' and `command -V' * If VERBOSE == 3, print path name only for disk files * If VERBOSE == 4, print string used to invoke COMMAND, for `command -v' * * ALL says whether or not to look for all occurrences of COMMAND, or * return after finding it once. */ int describe_command (command, verbose, all) char *command; int verbose, all; { int found, i, found_file, f; char *full_path, *x; SHELL_VAR *func; #if defined (ALIAS) alias_t *alias; #endif found = found_file = 0; full_path = (char *)NULL; #if defined (ALIAS) /* Command is an alias? */ alias = find_alias (command); if (alias) { if (verbose == 1) puts ("alias"); else if (verbose == 2) printf ("%s is aliased to `%s'\n", command, alias->value); else if (verbose == 4) { 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? */ i = find_reserved_word (command); if (i >= 0) { if (verbose == 1) puts ("keyword"); else if (verbose == 2) printf ("%s is a shell keyword\n", command); else if (verbose == 4) printf ("%s\n", command); found = 1; if (all == 0) return (1); } /* Command is a function? */ func = find_function (command); if (func) { if (verbose == 1) puts ("function"); else if (verbose == 2) { #define PRETTY_PRINT_FUNC 1 char *result; printf ("%s is a function\n", command); /* We're blowing away THE_PRINTED_COMMAND here... */ result = named_function_string (command, (COMMAND *) function_cell (func), PRETTY_PRINT_FUNC); printf ("%s\n", result); #undef PRETTY_PRINT_FUNC } else if (verbose == 4) printf ("%s\n", command); found = 1; if (all == 0) return (1); } /* Command is a builtin? */ if (find_shell_builtin (command)) { if (verbose == 1) puts ("builtin"); else if (verbose == 2) printf ("%s is a shell builtin\n", command); else if (verbose == 4) 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 (verbose == 1) puts ("file"); else if (verbose == 2) printf ("%s is %s\n", command, command); else if (verbose == 3 || verbose == 4) 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) { if ((full_path = find_hashed_filename (command)) != (char *)NULL) { if (verbose == 1) puts ("file"); else if (verbose == 2) printf ("%s is hashed (%s)\n", command, full_path); else if (verbose == 3 || verbose == 4) printf ("%s\n", full_path); free (full_path); return (1); } } /* Now search through $PATH. */ while (1) { 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) 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. */ if (STREQ (full_path, command)) { f = file_status (full_path); if ((f & FS_EXECABLE) == 0) { free (full_path); full_path = (char *)NULL; if (all == 0) break; } else if (verbose >= 2) full_path = sh_makepath ((char *)NULL, full_path, MP_DOCWD); } found_file++; found = 1; if (verbose == 1) puts ("file"); else if (verbose == 2) printf ("%s is %s\n", command, full_path); else if (verbose == 3 || verbose == 4) printf ("%s\n", full_path); free (full_path); full_path = (char *)NULL; if (all == 0) break; } return (found); } bash-2.05a/builtins/ulimit.def100644 436 0 42327 7350175536 14612 0ustar chetwheelThis file is ulimit.def, from which is created ulimit.c. It implements the builtin "ulimit" in Bash. Copyright (C) 1987, 1989, 1991 Free Software Foundation, Inc. This file is part of GNU Bash, the Bourne Again SHell. Bash is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 2, or (at your option) any later version. Bash is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with Bash; see the file COPYING. If not, write to the Free Software Foundation, 59 Temple Place, Suite 330, Boston, MA 02111 USA. $PRODUCES ulimit.c $BUILTIN ulimit $FUNCTION ulimit_builtin $DEPENDS_ON !_MINIX $SHORT_DOC ulimit [-SHacdflmnpstuv] [limit] Ulimit provides control over the resources available to processes started by the shell, on systems that allow such control. If an option is given, it is interpreted as follows: -S use the `soft' resource limit -H use the `hard' resource limit -a all current limits are reported -c the maximum size of core files created -d the maximum size of a process's data segment -f the maximum size of files created by the shell -l the maximum size a process may lock into memory -m the maximum resident set size -n the maximum number of open file descriptors -p the pipe buffer size -s the maximum stack size -t the maximum amount of cpu time in seconds -u the maximum number of user processes -v the size of virtual memory If LIMIT is given, it is the new value of the specified resource; the special LIMIT values `soft', `hard', and `unlimited' stand for the current soft limit, the current hard limit, and no limit, respectively. Otherwise, the current value of the specified resource is printed. If no option is given, then -f is assumed. Values are in 1024-byte increments, except for -t, which is in seconds, -p, which is in increments of 512 bytes, and -u, which is an unscaled number of processes. $END #if !defined (_MINIX) #include #include "../bashtypes.h" #ifndef _MINIX # include #endif #if defined (HAVE_UNISTD_H) # include #endif #include #include #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 #else # 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 (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 /* 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 */ /* 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 (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 static int _findlim __P((int)); static int ulimit_internal __P((int, char *, int, int)); static int get_limit __P((int, RLIMTYPE *, RLIMTYPE *)); static int set_limit __P((int, RLIMTYPE, int)); static void printone __P((int, RLIMTYPE, int)); static void print_all_limits __P((int)); static int set_all_limits __P((int, RLIMTYPE)); static int filesize __P((RLIMTYPE *)); static int pipesize __P((RLIMTYPE *)); static int getmaxuprc __P((RLIMTYPE *)); static int getmaxvm __P((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. */ char *description; /* Descriptive string to output. */ char *units; /* scale */ } RESOURCE_LIMITS; static RESOURCE_LIMITS limits[] = { #ifdef RLIMIT_CORE { 'c', RLIMIT_CORE, 1024, "core file size", "blocks" }, #endif #ifdef RLIMIT_DATA { 'd', RLIMIT_DATA, 1024, "data seg size", "kbytes" }, #endif { 'f', RLIMIT_FILESIZE, 1024, "file size", "blocks" }, #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_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 { -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 '?': 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 ("invalid limit argument: %s", 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 (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 ("bad command: `%c'", 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 ("cannot get %s 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 = limits[limind].block_factor; real_limit = limit * block_factor; if ((real_limit / block_factor) != limit) { builtin_error ("limit out of range: %s", cmdarg); return (EXECUTION_FAILURE); } } else { builtin_error ("bad non-numeric arg `%s'", cmdarg); return (EXECUTION_FAILURE); } if (set_limit (limind, real_limit, mode) < 0) { builtin_error ("cannot modify %s 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 (PIPESIZE) /* This is defined by running a program from the Makefile. */ *valuep = (RLIMTYPE) PIPESIZE; return 0; # else errno = EINVAL; return -1; # endif /* PIPESIZE */ #endif /* PIPE_BUF */ } static int getmaxuprc (valuep) RLIMTYPE *valuep; { # if defined (HAVE_SYSCONF) && defined (_SC_CHILD_MAX) long maxchild; maxchild = sysconf (_SC_CHILD_MAX); if (maxchild < 0) return -1; else *valuep = (RLIMTYPE) maxchild; return 0; # else /* !HAVE_SYSCONF || !_SC_CHILD_MAX */ # if defined (MAXUPRC) *valuep = (RLIMTYPE) MAXUPRC; return 0; # else /* MAXUPRC */ errno = EINVAL; return -1; # endif /* !MAXUPRC */ # endif /* !HAVE_SYSCONF || !_SC_CHILD_MAX */ } 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) builtin_error ("cannot get %s limit: %s", limits[i].description, strerror (errno)); else printone (i, (mode & LIMIT_SOFT) ? softlim : hardlim, 1); } } static void printone (limind, curlim, pdesc) int limind; RLIMTYPE curlim; int pdesc; { char unitstr[64]; if (pdesc) { if (limits[limind].units) sprintf (unitstr, "(%s, -%c) ", limits[limind].units, limits[limind].option); else sprintf (unitstr, "(-%c) ", limits[limind].option); printf ("%-18s %16s", 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 / limits[limind].block_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 ("cannot modify %s limit: %s", limits[i].description, strerror (errno)); retval = 1; } return retval; } #endif /* !_MINIX */ bash-2.05a/builtins/umask.def100644 436 0 15610 7352441205 14411 0ustar chetwheelThis file is umask.def, from which is created umask.c. It implements the builtin "umask" in Bash. Copyright (C) 1987, 1989, 1991 Free Software Foundation, Inc. This file is part of GNU Bash, the Bourne Again SHell. Bash is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 2, or (at your option) any later version. Bash is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with Bash; see the file COPYING. If not, write to the Free Software Foundation, 59 Temple Place, Suite 330, Boston, MA 02111 USA. $PRODUCES umask.c $BUILTIN umask $FUNCTION umask_builtin $SHORT_DOC umask [-p] [-S] [mode] The user file-creation mask is set to MODE. If MODE is omitted, or if `-S' is supplied, the current value of the mask is printed. The `-S' option makes the output symbolic; otherwise an octal number is output. If `-p' is supplied, and MODE is omitted, the output is in a form that may be used as input. If MODE begins with a digit, it is interpreted as an octal number, otherwise it is a symbolic mode string like that accepted by chmod(1). $END #include #include "../bashtypes.h" #include "filecntl.h" #ifndef _MINIX # include #endif #if defined (HAVE_UNISTD_H) #include #endif #include #include #include "../shell.h" #include "posixstat.h" #include "common.h" #include "bashgetopt.h" #ifdef __LCC__ #define mode_t int #endif /* **************************************************************** */ /* */ /* UMASK Builtin and Helpers */ /* */ /* **************************************************************** */ static void print_symbolic_umask __P((mode_t)); static int symbolic_umask __P((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; 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) { builtin_error ("`%s' is not an octal number from 000 to 777", list->word->word); 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); } fflush (stdout); return (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 print_symbolic_umask (um) mode_t um; { 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 ("bad symbolic mode operator: %c", 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 '=': bits &= ~who; bits |= perm; break; /* No other values are possible. */ } if (*s == '\0') break; else s++; /* skip past ',' */ } else { builtin_error ("bad character in symbolic mode: %c", *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); if (bits == -1) return (-1); um = ~bits & 0777; return (um); } bash-2.05a/builtins/wait.def100664 436 0 11554 7367321740 14251 0ustar chetwheelThis file is wait.def, from which is created wait.c. It implements the builtin "wait" in Bash. Copyright (C) 1987, 1989, 1991 Free Software Foundation, Inc. This file is part of GNU Bash, the Bourne Again SHell. Bash is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 2, or (at your option) any later version. Bash is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with Bash; see the file COPYING. If not, write to the Free Software Foundation, 59 Temple Place, Suite 330, Boston, MA 02111 USA. $BUILTIN wait $FUNCTION wait_builtin $DEPENDS_ON JOB_CONTROL $PRODUCES wait.c $SHORT_DOC wait [n] Wait for the specified process and report its termination status. If N is not given, all currently active child processes are waited for, and the return code is zero. N may be a process ID or a job specification; if a job spec is given, all processes in the job's pipeline are waited for. $END $BUILTIN wait $FUNCTION wait_builtin $DEPENDS_ON !JOB_CONTROL $SHORT_DOC wait [n] Wait for the specified process and report its termination status. If N is not given, all currently active child processes are waited for, and the return code is zero. N is a process ID; if it is not given, all child processes of the shell are waited for. $END #include #include "../bashtypes.h" #include #if defined (HAVE_UNISTD_H) # include #endif #include #include "../bashansi.h" #include "../shell.h" #include "../jobs.h" #include "common.h" #include "bashgetopt.h" extern int interrupt_immediately; procenv_t wait_intr_buf; /* 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 \ { \ interrupt_immediately = old_interrupt_immediately;\ return (s);\ } \ while (0) int wait_builtin (list) WORD_LIST *list; { int status, code; volatile int old_interrupt_immediately; USE_VAR(list); if (no_options (list)) return (EX_USAGE); if (list != loptend) list = loptend; old_interrupt_immediately = interrupt_immediately; interrupt_immediately++; /* 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. */ code = setjmp (wait_intr_buf); if (code) { status = 128 + SIGINT; WAIT_RETURN (status); } /* We support jobs or pids. wait [pid-or-job ...] */ /* 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 (); WAIT_RETURN (EXECUTION_SUCCESS); } status = EXECUTION_SUCCESS; while (list) { pid_t pid; char *w; long 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); } else { builtin_error ("`%s' is not a pid or valid job spec", w); WAIT_RETURN (EXECUTION_FAILURE); } } #if defined (JOB_CONTROL) else if (job_control && *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 (job < 0 || job >= job_slots || !jobs[job]) { if (job != DUP_JOB) builtin_error ("%s: no such job", list->word->word); UNBLOCK_CHILD (oset); status = 127; /* As per Posix.2, section 4.70.2 */ list = list->next; continue; } /* Job spec used. Wait for the last pid in the pipeline. */ UNBLOCK_CHILD (oset); status = wait_for_job (job); } else if (job_control == 0 && *w == '%') { /* can't use jobspecs as arguments if job control is not active. */ builtin_error ("job control not enabled"); status = EXECUTION_FAILURE; } #endif /* JOB_CONTROL */ else { builtin_error ("`%s' is not a pid or valid job spec", w); status = EXECUTION_FAILURE; } list = list->next; } WAIT_RETURN (status); } bash-2.05a/builtins/psize.c100644 436 0 3254 6752274356 14106 0ustar chetwheel/* psize.c - Find pipe size. */ /* Copyright (C) 1987, 1991 Free Software Foundation, Inc. This file is part of GNU Bash, the Bourne Again SHell. Bash is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 2, or (at your option) any later version. Bash is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with Bash; see the file COPYING. If not, write to the Free Software Foundation, 59 Temple Place, Suite 330, Boston, MA 02111 USA. */ /* Write output in 128-byte chunks until we get a sigpipe or write gets an EPIPE. Then report how many bytes we wrote. We assume that this is the pipe size. */ #include #if defined (HAVE_UNISTD_H) # ifdef _MINIX # include # endif # include #endif #include #ifndef _MINIX #include "../bashtypes.h" #endif #include #include #include "../command.h" #include "../general.h" #include "../sig.h" extern int errno; int nw; sighandler sigpipe (sig) int sig; { fprintf (stderr, "%d\n", nw); exit (0); } int main (argc, argv) int argc; char **argv; { char buf[128]; register int i; for (i = 0; i < 128; i++) buf[i] = ' '; signal (SIGPIPE, sigpipe); nw = 0; for (;;) { int n; n = write (1, buf, 128); nw += n; } return (0); } bash-2.05a/builtins/psize.sh100664 436 0 2063 7370270357 14267 0ustar chetwheel#! /bin/sh # # psize.sh -- determine this system's pipe size, and write a define to # pipesize.h so ulimit.c can use it. : ${TMPDIR:=/tmp} # try to use mktemp(1) if the system supports it { TMPFILE="`mktemp $TMPDIR/pipsize.XXXXXX 2>/dev/null`"; } 2>/dev/null used_mktemp=true if [ -z "$TMPFILE" ]; then TMPNAME=pipsize.$$ TMPFILE=$TMPDIR/$TMPNAME used_mktemp=false fi trap 'rm -f "$TMPFILE" ; exit 1' 1 2 3 6 15 trap 'rm -f "$TMPFILE"' 0 echo "/*" echo " * pipesize.h" echo " *" echo " * This file is automatically generated by psize.sh" echo " * Do not edit!" echo " */" echo "" # # Try to avoid tempfile races. We can't really check for the file's # existance before we run psize.aux, because `test -e' is not portable, # `test -h' (test for symlinks) is not portable, and `test -f' only # checks for regular files. If we used mktemp(1), we're ahead of the # game. # $used_mktemp || rm -f "$TMPFILE" ./psize.aux 2>"$TMPFILE" | sleep 3 if [ -s "$TMPFILE" ]; then echo "#define PIPESIZE `cat "$TMPFILE"`" else echo "#define PIPESIZE 512" fi exit 0 bash-2.05a/builtins/inlib.def100664 436 0 4105 6752274302 14352 0ustar chetwheelThis file is inlib.def, from which is created inlib.c. It implements the Apollo-specific builtin "inlib" in Bash. Copyright (C) 1987, 1989, 1991 Free Software Foundation, Inc. This file is part of GNU Bash, the Bourne Again SHell. Bash is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 2, or (at your option) any later version. Bash is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with Bash; see the file COPYING. If not, write to the Free Software Foundation, 59 Temple Place, Suite 330, Boston, MA 02111 USA. $PRODUCES inlib.c #include #include #include "../shell.h" $BUILTIN inlib $FUNCTION inlib_builtin $DEPENDS_ON apollo $SHORT_DOC inlib pathname [pathname...] Install a user-supplied library specified by pathname in the current shell process. The library is used to resolve external references in programs and libraries loaded after its installation. Note that the library is not loaded into the address space unless it is needed to resolve an external reference. The list of inlibed libraries is passed to all children of the current shell. $END #if defined (apollo) #include #include inlib_builtin (list) WORD_LIST *list; { status_$t status; int return_value; short len; if (!list) { builtin_error ("usage: inlib pathname [pathname...]"); 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 ("inlib failed for %s", list->word->word); return_value = EXECUTION_FAILURE; } list = list->next; } return (return_value); } #endif /* apollo */ bash-2.05a/builtins/bashgetopt.c100664 436 0 10317 7347702661 15130 0ustar chetwheel/* bashgetopt.c -- `getopt' for use by the builtins. */ /* Copyright (C) 1992 Free Software Foundation, Inc. This file is part of GNU Bash, the Bourne Again SHell. Bash is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 2, or (at your option) any later version. Bash is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with Bash; see the file COPYING. If not, write to the Free Software Foundation, 59 Temple Place, Suite 330, Boston, MA 02111 USA. */ #include #if defined (HAVE_UNISTD_H) # include #endif #include "../bashansi.h" #include #include #include "../shell.h" #include "common.h" #define ERR(S, C) builtin_error("%s%c", (S), (C)) static int sp; char *list_optarg; int list_optopt; static WORD_LIST *lhead = (WORD_LIST *)NULL; WORD_LIST *lcurrent = (WORD_LIST *)NULL; WORD_LIST *loptend; /* Points to the first non-option argument in the list */ int internal_getopt(list, opts) WORD_LIST *list; char *opts; { register int c; register char *cp; int plus; /* nonzero means to handle +option */ if (*opts == '+') { plus = 1; opts++; } else plus = 0; if (list == 0) { list_optarg = (char *)NULL; loptend = (WORD_LIST *)NULL; /* No non-option arguments */ return -1; } if (list != lhead || lhead == 0) { /* Hmmm.... called with a different word list. Reset. */ sp = 1; lcurrent = lhead = list; loptend = (WORD_LIST *)NULL; } if (sp == 1) { if (lcurrent == 0 || (lcurrent->word->word[0] != '-' || lcurrent->word->word[1] == '\0')) { lhead = (WORD_LIST *)NULL; loptend = lcurrent; return(-1); } else if (lcurrent->word->word[0] == '-' && lcurrent->word->word[1] == '-' && lcurrent->word->word[2] == 0) { lhead = (WORD_LIST *)NULL; loptend = lcurrent->next; return(-1); } } list_optopt = c = lcurrent->word->word[sp]; if (c == ':' || (cp = strchr(opts, c)) == NULL) { ERR("illegal option: -", c); if (lcurrent->word->word[++sp] == '\0') { lcurrent = lcurrent->next; sp = 1; } list_optarg = NULL; if (lcurrent) loptend = lcurrent->next; return('?'); } if (*++cp == ':' || *cp == ';') { /* `:': Option requires an argument. */ /* `;': option argument may be missing */ /* We allow -l2 as equivalent to -l 2 */ if (lcurrent->word->word[sp+1]) { list_optarg = lcurrent->word->word + sp + 1; lcurrent = lcurrent->next; /* If the specifier is `;', don't set optarg if the next argument looks like another option. */ } else if (lcurrent->next && (*cp == ':' || lcurrent->next->word->word[0] != '-')) { lcurrent = lcurrent->next; list_optarg = lcurrent->word->word; lcurrent = lcurrent->next; } else if (*cp == ';') { list_optarg = (char *)NULL; lcurrent = lcurrent->next; } else { /* lcurrent->next == NULL */ ERR("option requires an argument: -", c); sp = 1; list_optarg = (char *)NULL; return('?'); } sp = 1; } else if (*cp == '#') { /* optional numeric argument */ if (lcurrent->word->word[sp+1]) { if (DIGIT(lcurrent->word->word[sp+1])) { list_optarg = lcurrent->word->word + sp + 1; lcurrent = lcurrent->next; } else list_optarg = (char *)NULL; } else { if (lcurrent->next && legal_number(lcurrent->next->word->word, (long *)0)) { lcurrent = lcurrent->next; list_optarg = lcurrent->word->word; lcurrent = lcurrent->next; } else list_optarg = (char *)NULL; } } else { /* No argument, just return the option. */ if (lcurrent->word->word[++sp] == '\0') { sp = 1; lcurrent = lcurrent->next; } list_optarg = (char *)NULL; } return(c); } /* * reset_internal_getopt -- force the in[ft]ernal getopt to reset */ void reset_internal_getopt () { lhead = lcurrent = loptend = (WORD_LIST *)NULL; sp = 1; } #ifdef INCLUDE_UNUSED void report_bad_option () { char s[3]; s[0] = '-'; s[1] = list_optopt; s[2] = '\0'; bad_option (s); } #endif bash-2.05a/builtins/common.h100664 436 0 10520 7347665304 14263 0ustar chetwheel/* common.h -- extern declarations for functions defined in common.c. */ /* Copyright (C) 1993 Free Software Foundation, Inc. This file is part of GNU Bash, the Bourne Again SHell. Bash is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 2, or (at your option) any later version. Bash is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with Bash; see the file COPYING. If not, write to the Free Software Foundation, 59 Temple Place, Suite 330, Boston, MA 02111 USA. */ #if !defined (__COMMON_H) # define __COMMON_H #include "stdc.h" #define ISOPTION(s, c) (s[0] == '-' && !s[2] && s[1] == c) /* Flag values for parse_and_execute () */ #define SEVAL_NONINT 0x01 #define SEVAL_INTERACT 0x02 #define SEVAL_NOHIST 0x04 /* Functions from common.c */ extern void builtin_error __P((const char *, ...)) __attribute__((__format__ (printf, 1, 2))); extern void builtin_usage __P((void)); extern void no_args __P((WORD_LIST *)); extern void bad_option __P((char *)); extern int no_options __P((WORD_LIST *)); extern char **make_builtin_argv __P((WORD_LIST *, int *)); extern void remember_args __P((WORD_LIST *, int)); extern void push_context __P((void)); extern void pop_context __P((void)); extern void push_dollar_vars __P((void)); extern void pop_dollar_vars __P((void)); extern void dispose_saved_dollar_vars __P((void)); extern int dollar_vars_changed __P((void)); extern void set_dollar_vars_unchanged __P((void)); extern void set_dollar_vars_changed __P((void)); extern long get_numeric_arg __P((WORD_LIST *, int)); extern int get_exitstat __P((WORD_LIST *)); extern int read_octal __P((char *)); /* Keeps track of the current working directory. */ extern char *the_current_working_directory; extern char *get_working_directory __P((char *)); extern void set_working_directory __P((char *)); #if defined (JOB_CONTROL) extern int get_job_spec __P((WORD_LIST *)); #endif extern int display_signal_list __P((WORD_LIST *, int)); /* It's OK to declare a function as returning a Function * without providing a definition of what a `Function' is. */ extern struct builtin *builtin_address_internal __P((char *, int)); extern sh_builtin_func_t *find_shell_builtin __P((char *)); extern sh_builtin_func_t *builtin_address __P((char *)); extern sh_builtin_func_t *find_special_builtin __P((char *)); extern void initialize_shell_builtins __P((void)); /* Functions from getopts.def */ extern void getopts_reset __P((int)); /* Functions from set.def */ extern int minus_o_option_value __P((char *)); extern void list_minus_o_opts __P((int, int)); extern char **get_minus_o_opts __P((void)); extern int set_minus_o_option __P((int, char *)); extern void set_shellopts __P((void)); extern void parse_shellopts __P((char *)); extern void initialize_shell_options __P((int)); extern void reset_shell_options __P((void)); /* Functions from shopt.def */ extern void reset_shopt_options __P((void)); extern char **get_shopt_options __P((void)); extern int shopt_setopt __P((char *, int)); extern int shopt_listopt __P((char *, int)); extern int set_login_shell __P((int)); /* Functions from type.def */ extern int describe_command __P((char *, int, int)); /* Functions from setattr.def */ extern int set_or_show_attributes __P((WORD_LIST *, int, int)); extern int show_var_attributes __P((SHELL_VAR *, int, int)); extern int show_name_attributes __P((char *, int)); extern void set_var_attribute __P((char *, int, int)); /* Functions from pushd.def */ extern char *get_dirstack_from_string __P((char *)); extern char *get_dirstack_element __P((long, int)); extern void set_dirstack_element __P((long, int, char *)); extern WORD_LIST *get_directory_stack __P((void)); /* Functions from evalstring.c */ extern int parse_and_execute __P((char *, const char *, int)); extern void parse_and_execute_cleanup __P((void)); /* Functions from evalfile.c */ extern int maybe_execute_file __P((const char *, int)); extern int source_file __P((const char *)); extern int fc_execute_file __P((const char *)); #endif /* !__COMMON_H */ bash-2.05a/builtins/bashgetopt.h100664 436 0 2421 7347462473 15116 0ustar chetwheel/* bashgetopt.h -- extern declarations for stuff defined in bashgetopt.c. */ /* Copyright (C) 1993 Free Software Foundation, Inc. This file is part of GNU Bash, the Bourne Again SHell. Bash is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 2, or (at your option) any later version. Bash is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with Bash; see the file COPYING. If not, write to the Free Software Foundation, 59 Temple Place, Suite 330, Boston, MA 02111 USA. */ /* See getopt.h for the explanation of these variables. */ #if !defined (__BASH_GETOPT_H) # define __BASH_GETOPT_H #include extern char *list_optarg; extern int list_optopt; extern WORD_LIST *lcurrent; extern WORD_LIST *loptend; extern int internal_getopt __P((WORD_LIST *, char *)); extern void reset_internal_getopt __P((void)); extern void report_bad_option __P((void)); #endif /* !__BASH_GETOPT_H */ bash-2.05a/cross-build/ 40775 436 0 0 7373775235 13110 5ustar chetwheelbash-2.05a/cross-build/cygwin32.cache100644 436 0 31150 7374236775 15657 0ustar chetwheel# This file is a shell script that caches the results of configure # tests run on this system so they can be shared between configure # scripts and configure runs, see configure's option --config-cache. # It is not useful on other systems. If it contains results you don't # want to keep, you may remove or edit it. # # config.status only pays attention to the cache file if you give it # the --recheck option to rerun configure. # # `ac_cv_env_foo' variables (set or unset) will be overriden when # loading this file, other *unset* `ac_cv_foo' will be assigned the # following values. ac_cv_build=${ac_cv_build='i686-pc-cygwin'} ac_cv_build_alias=${ac_cv_build_alias='i686-pc-cygwin'} ac_cv_c_bigendian=${ac_cv_c_bigendian='no'} ac_cv_c_char_unsigned=${ac_cv_c_char_unsigned='no'} ac_cv_c_compiler_gnu=${ac_cv_c_compiler_gnu='yes'} ac_cv_c_const=${ac_cv_c_const='yes'} ac_cv_c_inline=${ac_cv_c_inline='inline'} ac_cv_c_long_double=${ac_cv_c_long_double='yes'} ac_cv_c_stringize=${ac_cv_c_stringize='yes'} ac_cv_decl_sys_siglist=${ac_cv_decl_sys_siglist='no'} ac_cv_exeext=${ac_cv_exeext='.exe'} ac_cv_func___setostype=${ac_cv_func___setostype='no'} ac_cv_func__doprnt=${ac_cv_func__doprnt='no'} ac_cv_func_alloca_works=${ac_cv_func_alloca_works='yes'} ac_cv_func_asprintf=${ac_cv_func_asprintf='no'} ac_cv_func_bcopy=${ac_cv_func_bcopy='yes'} ac_cv_func_bindtextdomain=${ac_cv_func_bindtextdomain='no'} ac_cv_func_bzero=${ac_cv_func_bzero='yes'} ac_cv_func_confstr=${ac_cv_func_confstr='no'} ac_cv_func_dlclose=${ac_cv_func_dlclose='yes'} ac_cv_func_dlopen=${ac_cv_func_dlopen='yes'} ac_cv_func_dlsym=${ac_cv_func_dlsym='yes'} ac_cv_func_dup2=${ac_cv_func_dup2='yes'} ac_cv_func_fnmatch=${ac_cv_func_fnmatch='no'} ac_cv_func_getaddrinfo=${ac_cv_func_getaddrinfo='no'} ac_cv_func_getcwd=${ac_cv_func_getcwd='yes'} ac_cv_func_getdtablesize=${ac_cv_func_getdtablesize='yes'} ac_cv_func_getgroups=${ac_cv_func_getgroups='yes'} ac_cv_func_gethostbyname=${ac_cv_func_gethostbyname='yes'} ac_cv_func_gethostname=${ac_cv_func_gethostname='yes'} ac_cv_func_getpagesize=${ac_cv_func_getpagesize='yes'} ac_cv_func_getpeername=${ac_cv_func_getpeername='yes'} ac_cv_func_getpgrp_void=${ac_cv_func_getpgrp_void='yes'} ac_cv_func_getrlimit=${ac_cv_func_getrlimit='yes'} ac_cv_func_getrusage=${ac_cv_func_getrusage='yes'} ac_cv_func_getservbyname=${ac_cv_func_getservbyname='yes'} ac_cv_func_gettext=${ac_cv_func_gettext='no'} ac_cv_func_gettimeofday=${ac_cv_func_gettimeofday='yes'} ac_cv_func_inet_aton=${ac_cv_func_inet_aton='yes'} ac_cv_func_isascii=${ac_cv_func_isascii='yes'} ac_cv_func_isblank=${ac_cv_func_isblank='no'} ac_cv_func_isgraph=${ac_cv_func_isgraph='yes'} ac_cv_func_isprint=${ac_cv_func_isprint='yes'} ac_cv_func_isspace=${ac_cv_func_isspace='yes'} ac_cv_func_isxdigit=${ac_cv_func_isxdigit='yes'} ac_cv_func_killpg=${ac_cv_func_killpg='yes'} ac_cv_func_lstat=${ac_cv_func_lstat='yes'} ac_cv_func_memmove=${ac_cv_func_memmove='yes'} ac_cv_func_mkfifo=${ac_cv_func_mkfifo='yes'} ac_cv_func_pathconf=${ac_cv_func_pathconf='yes'} ac_cv_func_putenv=${ac_cv_func_putenv='yes'} ac_cv_func_readlink=${ac_cv_func_readlink='yes'} ac_cv_func_rename=${ac_cv_func_rename='yes'} ac_cv_func_sbrk=${ac_cv_func_sbrk='yes'} ac_cv_func_select=${ac_cv_func_select='yes'} ac_cv_func_setdtablesize=${ac_cv_func_setdtablesize='yes'} ac_cv_func_setenv=${ac_cv_func_setenv='yes'} ac_cv_func_setlinebuf=${ac_cv_func_setlinebuf='no'} ac_cv_func_setlocale=${ac_cv_func_setlocale='yes'} ac_cv_func_setvbuf=${ac_cv_func_setvbuf='yes'} ac_cv_func_setvbuf_reversed=${ac_cv_func_setvbuf_reversed='no'} ac_cv_func_siginterrupt=${ac_cv_func_siginterrupt='no'} ac_cv_func_snprintf=${ac_cv_func_snprintf='yes'} ac_cv_func_strcasecmp=${ac_cv_func_strcasecmp='yes'} ac_cv_func_strchr=${ac_cv_func_strchr='yes'} ac_cv_func_strcoll_works=${ac_cv_func_strcoll_works='yes'} ac_cv_func_strerror=${ac_cv_func_strerror='yes'} ac_cv_func_strpbrk=${ac_cv_func_strpbrk='yes'} ac_cv_func_strtod=${ac_cv_func_strtod='yes'} ac_cv_func_strtoimax=${ac_cv_func_strtoimax='no'} ac_cv_func_strtol=${ac_cv_func_strtol='yes'} ac_cv_func_strtoll=${ac_cv_func_strtoll='no'} ac_cv_func_strtoul=${ac_cv_func_strtoul='yes'} ac_cv_func_strtoull=${ac_cv_func_strtoull='no'} ac_cv_func_strtoumax=${ac_cv_func_strtoumax='no'} ac_cv_func_sysconf=${ac_cv_func_sysconf='yes'} ac_cv_func_tcgetattr=${ac_cv_func_tcgetattr='yes'} ac_cv_func_tcgetpgrp=${ac_cv_func_tcgetpgrp='yes'} ac_cv_func_textdomain=${ac_cv_func_textdomain='no'} ac_cv_func_times=${ac_cv_func_times='yes'} ac_cv_func_ttyname=${ac_cv_func_ttyname='yes'} ac_cv_func_tzset=${ac_cv_func_tzset='yes'} ac_cv_func_ulimit=${ac_cv_func_ulimit='no'} ac_cv_func_uname=${ac_cv_func_uname='yes'} ac_cv_func_vasprintf=${ac_cv_func_vasprintf='no'} ac_cv_func_vprintf=${ac_cv_func_vprintf='yes'} ac_cv_func_vsnprintf=${ac_cv_func_vsnprintf='yes'} ac_cv_func_wait3=${ac_cv_func_wait3='yes'} ac_cv_func_waitpid=${ac_cv_func_waitpid='yes'} ac_cv_have_decl_confstr=${ac_cv_have_decl_confstr='no'} ac_cv_have_decl_printf=${ac_cv_have_decl_printf='yes'} ac_cv_have_decl_sbrk=${ac_cv_have_decl_sbrk='yes'} ac_cv_have_decl_strsignal=${ac_cv_have_decl_strsignal='yes'} ac_cv_have_decl_strtold=${ac_cv_have_decl_strtold='no'} ac_cv_header_arpa_inet_h=${ac_cv_header_arpa_inet_h='yes'} ac_cv_header_dirent_dirent_h=${ac_cv_header_dirent_dirent_h='yes'} ac_cv_header_dlfcn_h=${ac_cv_header_dlfcn_h='yes'} ac_cv_header_grp_h=${ac_cv_header_grp_h='yes'} ac_cv_header_inttypes_h=${ac_cv_header_inttypes_h='no'} ac_cv_header_libintl_h=${ac_cv_header_libintl_h='yes'} ac_cv_header_limits_h=${ac_cv_header_limits_h='yes'} ac_cv_header_locale_h=${ac_cv_header_locale_h='yes'} ac_cv_header_memory_h=${ac_cv_header_memory_h='yes'} ac_cv_header_minix_config_h=${ac_cv_header_minix_config_h='no'} ac_cv_header_netdb_h=${ac_cv_header_netdb_h='yes'} ac_cv_header_netinet_in_h=${ac_cv_header_netinet_in_h='yes'} ac_cv_header_stat_broken=${ac_cv_header_stat_broken='no'} ac_cv_header_stdarg_h=${ac_cv_header_stdarg_h='yes'} ac_cv_header_stdc=${ac_cv_header_stdc='yes'} ac_cv_header_stddef_h=${ac_cv_header_stddef_h='yes'} ac_cv_header_stdint_h=${ac_cv_header_stdint_h='no'} ac_cv_header_stdlib_h=${ac_cv_header_stdlib_h='yes'} ac_cv_header_string_h=${ac_cv_header_string_h='yes'} ac_cv_header_strings_h=${ac_cv_header_strings_h='yes'} ac_cv_header_sys_file_h=${ac_cv_header_sys_file_h='yes'} ac_cv_header_sys_param_h=${ac_cv_header_sys_param_h='yes'} ac_cv_header_sys_pte_h=${ac_cv_header_sys_pte_h='no'} ac_cv_header_sys_ptem_h=${ac_cv_header_sys_ptem_h='no'} ac_cv_header_sys_resource_h=${ac_cv_header_sys_resource_h='yes'} ac_cv_header_sys_select_h=${ac_cv_header_sys_select_h='yes'} ac_cv_header_sys_socket_h=${ac_cv_header_sys_socket_h='yes'} ac_cv_header_sys_stat_h=${ac_cv_header_sys_stat_h='yes'} ac_cv_header_sys_stream_h=${ac_cv_header_sys_stream_h='no'} ac_cv_header_sys_time_h=${ac_cv_header_sys_time_h='yes'} ac_cv_header_sys_times_h=${ac_cv_header_sys_times_h='yes'} ac_cv_header_sys_types_h=${ac_cv_header_sys_types_h='yes'} ac_cv_header_sys_wait_h=${ac_cv_header_sys_wait_h='yes'} ac_cv_header_termcap_h=${ac_cv_header_termcap_h='yes'} ac_cv_header_termio_h=${ac_cv_header_termio_h='yes'} ac_cv_header_termios_h=${ac_cv_header_termios_h='yes'} ac_cv_header_time=${ac_cv_header_time='yes'} ac_cv_header_unistd_h=${ac_cv_header_unistd_h='yes'} ac_cv_header_varargs_h=${ac_cv_header_varargs_h='yes'} ac_cv_host=${ac_cv_host='i686-pc-cygwin'} ac_cv_host_alias=${ac_cv_host_alias='i686-pc-cygwin'} ac_cv_lib_dir_opendir=${ac_cv_lib_dir_opendir='no'} ac_cv_lib_dl_dlopen=${ac_cv_lib_dl_dlopen='no'} ac_cv_lib_intl_bindtextdomain=${ac_cv_lib_intl_bindtextdomain='yes'} ac_cv_lib_termcap_tgetent=${ac_cv_lib_termcap_tgetent='yes'} ac_cv_member_struct_stat_st_blocks=${ac_cv_member_struct_stat_st_blocks='yes'} ac_cv_member_struct_termio_c_line=${ac_cv_member_struct_termio_c_line='yes'} ac_cv_member_struct_termios_c_line=${ac_cv_member_struct_termios_c_line='yes'} ac_cv_objext=${ac_cv_objext='o'} ac_cv_path_install=${ac_cv_path_install='/usr/bin/install -c'} ac_cv_prog_AR=${ac_cv_prog_AR='ar'} ac_cv_prog_CPP=${ac_cv_prog_CPP='gcc -E'} ac_cv_prog_YACC=${ac_cv_prog_YACC='bison -y'} ac_cv_prog_ac_ct_CC=${ac_cv_prog_ac_ct_CC='gcc'} ac_cv_prog_ac_ct_RANLIB=${ac_cv_prog_ac_ct_RANLIB='ranlib'} ac_cv_prog_cc_g=${ac_cv_prog_cc_g='yes'} ac_cv_prog_cc_stdc=${ac_cv_prog_cc_stdc=''} ac_cv_prog_gcc_traditional=${ac_cv_prog_gcc_traditional='no'} ac_cv_prog_make_make_set=${ac_cv_prog_make_make_set='yes'} ac_cv_sizeof_char=${ac_cv_sizeof_char='1'} ac_cv_sizeof_char_p=${ac_cv_sizeof_char_p='4'} ac_cv_sizeof_double=${ac_cv_sizeof_double='8'} ac_cv_sizeof_int=${ac_cv_sizeof_int='4'} ac_cv_sizeof_long=${ac_cv_sizeof_long='4'} ac_cv_sizeof_long_long=${ac_cv_sizeof_long_long='8'} ac_cv_sizeof_short=${ac_cv_sizeof_short='2'} ac_cv_sys_file_offset_bits=${ac_cv_sys_file_offset_bits='no'} ac_cv_sys_interpreter=${ac_cv_sys_interpreter='yes'} ac_cv_sys_large_files=${ac_cv_sys_large_files='no'} ac_cv_sys_largefile_CC=${ac_cv_sys_largefile_CC='no'} ac_cv_sys_posix_termios=${ac_cv_sys_posix_termios='yes'} ac_cv_sys_tiocgwinsz_in_termios_h=${ac_cv_sys_tiocgwinsz_in_termios_h='yes'} ac_cv_type_bits16_t=${ac_cv_type_bits16_t='no'} ac_cv_type_bits32_t=${ac_cv_type_bits32_t='no'} ac_cv_type_bits64_t=${ac_cv_type_bits64_t='no'} ac_cv_type_char=${ac_cv_type_char='yes'} ac_cv_type_char_p=${ac_cv_type_char_p='yes'} ac_cv_type_double=${ac_cv_type_double='yes'} ac_cv_type_getgroups=${ac_cv_type_getgroups='gid_t'} ac_cv_type_int=${ac_cv_type_int='yes'} ac_cv_type_long=${ac_cv_type_long='yes'} ac_cv_type_long_long=${ac_cv_type_long_long='yes'} ac_cv_type_mode_t=${ac_cv_type_mode_t='yes'} ac_cv_type_off_t=${ac_cv_type_off_t='yes'} ac_cv_type_pid_t=${ac_cv_type_pid_t='yes'} ac_cv_type_ptrdiff_t=${ac_cv_type_ptrdiff_t='yes'} ac_cv_type_short=${ac_cv_type_short='yes'} ac_cv_type_signal=${ac_cv_type_signal='void'} ac_cv_type_size_t=${ac_cv_type_size_t='yes'} ac_cv_type_ssize_t=${ac_cv_type_ssize_t='yes'} ac_cv_type_time_t=${ac_cv_type_time_t='yes'} ac_cv_type_u_bits16_t=${ac_cv_type_u_bits16_t='no'} ac_cv_type_u_bits32_t=${ac_cv_type_u_bits32_t='no'} ac_cv_type_u_int=${ac_cv_type_u_int='yes'} ac_cv_type_u_long=${ac_cv_type_u_long='yes'} ac_cv_type_uid_t=${ac_cv_type_uid_t='yes'} ac_cv_working_alloca_h=${ac_cv_working_alloca_h='no'} bash_cv_decl_strtoimax=${bash_cv_decl_strtoimax='no'} bash_cv_decl_strtol=${bash_cv_decl_strtol='yes'} bash_cv_decl_strtoll=${bash_cv_decl_strtoll='no'} bash_cv_decl_strtoul=${bash_cv_decl_strtoul='yes'} bash_cv_decl_strtoull=${bash_cv_decl_strtoull='no'} bash_cv_decl_strtoumax=${bash_cv_decl_strtoumax='no'} bash_cv_decl_under_sys_siglist=${bash_cv_decl_under_sys_siglist='no'} bash_cv_dev_fd=${bash_cv_dev_fd='absent'} bash_cv_dev_stdin=${bash_cv_dev_stdin='absent'} bash_cv_dirent_has_d_fileno=${bash_cv_dirent_has_d_fileno='no'} bash_cv_dirent_has_dino=${bash_cv_dirent_has_dino='yes'} bash_cv_dup2_broken=${bash_cv_dup2_broken='no'} bash_cv_fionread_in_ioctl=${bash_cv_fionread_in_ioctl='no'} bash_cv_func_sigsetjmp=${bash_cv_func_sigsetjmp='present'} bash_cv_func_strcoll_broken=${bash_cv_func_strcoll_broken='no'} bash_cv_getenv_redef=${bash_cv_getenv_redef='yes'} bash_cv_getpw_declared=${bash_cv_getpw_declared='yes'} bash_cv_have_strsignal=${bash_cv_have_strsignal='yes'} bash_cv_job_control_missing=${bash_cv_job_control_missing='present'} bash_cv_mail_dir=${bash_cv_mail_dir='unknown'} bash_cv_must_reinstall_sighandlers=${bash_cv_must_reinstall_sighandlers='no'} bash_cv_opendir_not_robust=${bash_cv_opendir_not_robust='no'} bash_cv_pgrp_pipe=${bash_cv_pgrp_pipe='no'} bash_cv_printf_a_format=${bash_cv_printf_a_format='no'} bash_cv_signal_vintage=${bash_cv_signal_vintage='posix'} bash_cv_speed_t_in_sys_types=${bash_cv_speed_t_in_sys_types='no'} bash_cv_struct_timeval=${bash_cv_struct_timeval='yes'} bash_cv_struct_winsize_header=${bash_cv_struct_winsize_header='termios_h'} bash_cv_sys_errlist=${bash_cv_sys_errlist='no'} bash_cv_sys_named_pipes=${bash_cv_sys_named_pipes='present'} bash_cv_sys_siglist=${bash_cv_sys_siglist='no'} bash_cv_termcap_lib=${bash_cv_termcap_lib='libtermcap'} bash_cv_tiocstat_in_ioctl=${bash_cv_tiocstat_in_ioctl='no'} bash_cv_type_clock_t=${bash_cv_type_clock_t='yes'} bash_cv_type_intmax_t=${bash_cv_type_intmax_t='no'} bash_cv_type_long_long=${bash_cv_type_long_long='long long'} bash_cv_type_quad_t=${bash_cv_type_quad_t='no'} bash_cv_type_rlimit=${bash_cv_type_rlimit='rlim_t'} bash_cv_type_sigset_t=${bash_cv_type_sigset_t='yes'} bash_cv_type_socklen_t=${bash_cv_type_socklen_t='no'} bash_cv_type_uintmax_t=${bash_cv_type_uintmax_t='no'} bash_cv_type_unsigned_long_long=${bash_cv_type_unsigned_long_long='unsigned long long'} bash_cv_ulimit_maxfds=${bash_cv_ulimit_maxfds='no'} bash_cv_under_sys_siglist=${bash_cv_under_sys_siglist='no'} bash_cv_unusable_rtsigs=${bash_cv_unusable_rtsigs='no'} bash_cv_void_sighandler=${bash_cv_void_sighandler='yes'} bash-2.05a/cross-build/win32sig.h100644 436 0 6312 7374236570 15016 0ustar chetwheel/* This file is used when cross-compiling for the CYGWIN32 environment on a Unix machine. It gets copied to signames.h in the build directory. */ #include #include #ifndef __GNUC__ # error cross compiling requires gcc #endif /* A translation list so we can be polite to our users. Use gcc labelled initializers to set up the array. Note that some entries might wind up being NULL. */ char *signal_names[NSIG + 3] = { [0] "EXIT", #ifdef SIGLOST [SIGLOST] "SIGLOST", #endif #ifdef SIGMSG [SIGMSG] "SIGMSG", #endif #ifdef SIGDANGER [SIGDANGER] "SIGDANGER", #endif #ifdef SIGMIGRATE [SIGMIGRATE] "SIGMIGRATE", #endif #ifdef SIGPRE [SIGPRE] "SIGPRE", #endif #ifdef SIGVIRT [SIGVIRT] "SIGVIRT", #endif #ifdef SIGALRM1 [SIGALRM1] "SIGALRM1", #endif #ifdef SIGWAITING [SIGWAITING] "SIGWAITING", #endif #ifdef SIGGRANT [SIGGRANT] "SIGGRANT", #endif #ifdef SIGKAP [SIGKAP] "SIGKAP", #endif #ifdef SIGRETRACT [SIGRETRACT] "SIGRETRACT", #endif #ifdef SIGSOUND [SIGSOUND] "SIGSOUND", #endif #ifdef SIGSAK [SIGSAK] "SIGSAK", #endif #ifdef SIGLWP [SIGLWP] "SIGLWP", #endif #ifdef SIGFREEZE [SIGFREEZE] "SIGFREEZE", #endif #ifdef SIGTHAW [SIGTHAW] "SIGTHAW", #endif #ifdef SIGCANCEL [SIGCANCEL] "SIGCANCEL", #endif #ifdef SIGDIL [SIGDIL] "SIGDIL", #endif #ifdef SIGCLD #ifndef SIGCHLD [SIGCLD] "SIGCLD", #else #if SIGCHLD != SIGCLD [SIGCLD] "SIGCLD", #endif #endif #endif #ifdef SIGPWR [SIGPWR] "SIGPWR", #endif #ifdef SIGPOLL #ifndef SIGIO [SIGPOLL] "SIGPOLL", #else #if SIGIO != SIGPOLL [SIGPOLL] "SIGPOLL", #endif #endif #endif #ifdef SIGWINDOW [SIGWINDOW] "SIGWINDOW", #endif #ifdef SIGHUP [SIGHUP] "SIGHUP", #endif #ifdef SIGINT [SIGINT] "SIGINT", #endif #ifdef SIGQUIT [SIGQUIT] "SIGQUIT", #endif #ifdef SIGILL [SIGILL] "SIGILL", #endif #ifdef SIGTRAP [SIGTRAP] "SIGTRAP", #endif #ifdef SIGIOT #ifndef SIGABRT [SIGIOT] "SIGIOT", #else #if SIGABRT != SIGIOT [SIGIOT] "SIGIOT", #endif #endif #endif #ifdef SIGABRT [SIGABRT] "SIGABRT", #endif #ifdef SIGEMT [SIGEMT] "SIGEMT", #endif #ifdef SIGFPE [SIGFPE] "SIGFPE", #endif #ifdef SIGKILL [SIGKILL] "SIGKILL", #endif #ifdef SIGBUS [SIGBUS] "SIGBUS", #endif #ifdef SIGSEGV [SIGSEGV] "SIGSEGV", #endif #ifdef SIGSYS [SIGSYS] "SIGSYS", #endif #ifdef SIGPIPE [SIGPIPE] "SIGPIPE", #endif #ifdef SIGALRM [SIGALRM] "SIGALRM", #endif #ifdef SIGTERM [SIGTERM] "SIGTERM", #endif #ifdef SIGURG [SIGURG] "SIGURG", #endif #ifdef SIGSTOP [SIGSTOP] "SIGSTOP", #endif #ifdef SIGTSTP [SIGTSTP] "SIGTSTP", #endif #ifdef SIGCONT [SIGCONT] "SIGCONT", #endif #ifdef SIGCHLD [SIGCHLD] "SIGCHLD", #endif #ifdef SIGTTIN [SIGTTIN] "SIGTTIN", #endif #ifdef SIGTTOU [SIGTTOU] "SIGTTOU", #endif #ifdef SIGIO [SIGIO] "SIGIO", #endif #ifdef SIGXCPU [SIGXCPU] "SIGXCPU", #endif #ifdef SIGXFSZ [SIGXFSZ] "SIGXFSZ", #endif #ifdef SIGVTALRM [SIGVTALRM] "SIGVTALRM", #endif #ifdef SIGPROF [SIGPROF] "SIGPROF", #endif #ifdef SIGWINCH [SIGWINCH] "SIGWINCH", #endif #ifdef SIGINFO [SIGINFO] "SIGINFO", #endif #ifdef SIGUSR1 [SIGUSR1] "SIGUSR1", #endif #ifdef SIGUSR2 [SIGUSR2] "SIGUSR2", #endif [NSIG] "DEBUG", [NSIG + 1] "ERR", [NSIG + 2] (char *)0x0 }; bash-2.05a/cross-build/x86-beos.cache100664 436 0 4034 6570552134 15533 0ustar chetwheel# This file is a shell script that caches the results of configure # tests for x86 BeOS so they don't need to be done when cross-compiling. # AC_FUNC_GETPGRP should also define GETPGRP_VOID ac_cv_func_getpgrp_void=${ac_cv_func_getpgrp_void='yes'} # AC_FUNC_SETVBUF_REVERSED should not define anything else ac_cv_func_setvbuf_reversed=${ac_cv_func_setvbuf_reversed='no'} # on BeOS, system calls do not restart ac_cv_sys_restartable_syscalls=${ac_cv_sys_restartable_syscalls='no'} bash_cv_sys_restartable_syscalls=${bash_cv_sys_restartable_syscalls='no'} ac_cv_func_tcgetattr=${ac_cv_func_tcgetattr='yes'} # x86 BeOS is little endian ac_cv_c_bigendian=${ac_cv_c_bigendian='no'} ac_cv_sizeof_char_p=${ac_cv_sizeof_char_p='4'} ac_cv_sizeof_int=${ac_cv_sizeof_int='4'} ac_cv_sizeof_long=${ac_cv_sizeof_long='4'} ac_cv_sizeof_double=${ac_cv_sizeof_double='8'} bash_cv_dev_fd=${bash_cv_dev_fd='absent'} bash_cv_dup2_broken=${bash_cv_dup2_broken='no'} bash_cv_pgrp_pipe=${bash_cv_pgrp_pipe='no'} bash_cv_type_rlimit=${bash_cv_type_rlimit='long'} bash_cv_decl_under_sys_siglist=${bash_cv_decl_under_sys_siglist='no'} bash_cv_under_sys_siglist=${bash_cv_under_sys_siglist='no'} bash_cv_sys_siglist=${bash_cv_sys_siglist='yes'} bash_cv_opendir_not_robust=${bash_cv_opendir_not_robust='no'} bash_cv_getenv_redef=${bash_cv_getenv_redef='yes'} bash_cv_printf_declared=${bash_cv_printf_declared='yes'} bash_cv_ulimit_maxfds=${bash_cv_ulimit_maxfds='no'} bash_cv_getcwd_calls_popen=${bash_cv_getcwd_calls_popen='no'} bash_cv_must_reinstall_sighandlers=${bash_cv_must_reinstall_sighandlers='no'} bash_cv_job_control_missing=${bash_cv_job_control_missing='present'} bash_cv_sys_named_pipes=${bash_cv_sys_named_pipes='present'} bash_cv_func_sigsetjmp=${bash_cv_func_sigsetjmp='missing'} bash_cv_mail_dir=${bash_cv_mail_dir='unknown'} bash_cv_func_strcoll_broken=${bash_cv_func_strcoll_broken='no'} bash_cv_type_int32_t=${bash_cv_type_int32_t='int'} bash_cv_type_u_int32_t=${bash_cv_type_u_int32_t='int'} ac_cv_type_bits64_t=${ac_cv_type_bits64_t='no'} # end of cross-build/x86-beos.cache bash-2.05a/cross-build/beos-sig.h100664 436 0 1705 7361126640 15054 0ustar chetwheel/* This file is used when cross compiling bash to run native on BeOS. */ #ifndef __GNUC__ # error cross compiling requires gcc #endif /* A translation list so we can be polite to our users. Use gcc labelled initializers to set up the array. Note that some entries might wind up being NULL. */ char *signal_names[NSIG + 3] = { [0] "EXIT", [SIGHUP] "SIGHUP", [SIGINT] "SIGINT", [SIGQUIT] "SIGQUIT", [SIGILL] "SIGILL", [SIGCHLD] "SIGCHLD", [SIGABRT] "SIGABRT", [SIGPIPE] "SIGPIPE", [SIGFPE] "SIGFPE", [SIGKILL] "SIGKILL", [SIGSTOP] "SIGSTOP", [SIGSEGV] "SIGSEGV", [SIGCONT] "SIGCONT", [SIGTSTP] "SIGTSTP", [SIGALRM] "SIGALRM", [SIGTERM] "SIGTERM", [SIGTTIN] "SIGTTIN", [SIGTTOU] "SIGTTOU", [SIGUSR1] "SIGUSR1", [SIGUSR2] "SIGUSR2", [SIGWINCH] "SIGWINCH", [SIGKILLTHR] "SIGKILLTHR", [NSIG] "DEBUG", [NSIG + 1] "ERR", [NSIG + 2] (char *)0x0, }; bash-2.05a/cross-build/opennt.cache100664 436 0 20610 7264620010 15467 0ustar chetwheel# This file is a shell script that caches the results of configure # tests run on this system so they can be shared between configure # scripts and configure runs. It is not useful on other systems. # If it contains results you don't want to keep, you may remove or edit it. # # By default, configure uses ./config.cache as the cache file, # creating it if it does not exist already. You can give configure # the --cache-file=FILE option to use a different cache file; that is # what configure does when it calls configure scripts in # subdirectories, so they share the cache. # Giving --cache-file=/dev/null disables caching, for debugging configure. # config.status only pays attention to the cache file if you give it the # --recheck option to rerun configure. # ac_cv_c_bigendian=${ac_cv_c_bigendian=no} ac_cv_decl_sys_siglist=${ac_cv_decl_sys_siglist=no} ac_cv_func___setostype=${ac_cv_func___setostype=no} ac_cv_func_alloca_works=${ac_cv_func_alloca_works=yes} ac_cv_func_bcopy=${ac_cv_func_bcopy=yes} ac_cv_func_bindtextdomain=${ac_cv_func_bindtextdomain=no} ac_cv_func_bzero=${ac_cv_func_bzero=yes} ac_cv_func_confstr=${ac_cv_func_confstr=yes} ac_cv_func_dlclose=${ac_cv_func_dlclose=no} ac_cv_func_dlopen=${ac_cv_func_dlopen=no} ac_cv_func_dlsym=${ac_cv_func_dlsym=no} ac_cv_func_dup2=${ac_cv_func_dup2=yes} ac_cv_func_getcwd=${ac_cv_func_getcwd=yes} ac_cv_func_getdtablesize=${ac_cv_func_getdtablesize=no} ac_cv_func_getgroups=${ac_cv_func_getgroups=yes} ac_cv_func_gethostname=${ac_cv_func_gethostname=yes} ac_cv_func_getpagesize=${ac_cv_func_getpagesize=yes} ac_cv_func_getpeername=${ac_cv_func_getpeername=yes} ac_cv_func_getpgrp_void=${ac_cv_func_getpgrp_void=yes} ac_cv_func_getrlimit=${ac_cv_func_getrlimit=no} ac_cv_func_getrusage=${ac_cv_func_getrusage=no} ac_cv_func_gettext=${ac_cv_func_gettext=no} ac_cv_func_gettimeofday=${ac_cv_func_gettimeofday=yes} ac_cv_func_killpg=${ac_cv_func_killpg=yes} ac_cv_func_lstat=${ac_cv_func_lstat=no} ac_cv_func_memmove=${ac_cv_func_memmove=yes} ac_cv_func_mkfifo=${ac_cv_func_mkfifo=yes} ac_cv_func_putenv=${ac_cv_func_putenv=yes} ac_cv_func_rename=${ac_cv_func_rename=yes} ac_cv_func_sbrk=${ac_cv_func_sbrk=no} ac_cv_func_select=${ac_cv_func_select=yes} ac_cv_func_setdtablesize=${ac_cv_func_setdtablesize=no} ac_cv_func_setenv=${ac_cv_func_setenv=yes} ac_cv_func_setlinebuf=${ac_cv_func_setlinebuf=yes} ac_cv_func_setlocale=${ac_cv_func_setlocale=yes} ac_cv_func_setvbuf_reversed=${ac_cv_func_setvbuf_reversed=no} ac_cv_func_siginterrupt=${ac_cv_func_siginterrupt=no} ac_cv_func_strcasecmp=${ac_cv_func_strcasecmp=yes} ac_cv_func_strchr=${ac_cv_func_strchr=yes} ac_cv_func_strcoll_works=${ac_cv_func_strcoll_works=yes} ac_cv_func_strerror=${ac_cv_func_strerror=yes} ac_cv_func_strtod=${ac_cv_func_strtod=yes} ac_cv_func_strtol=${ac_cv_func_strtol=yes} ac_cv_func_strtoul=${ac_cv_func_strtoul=yes} ac_cv_func_sysconf=${ac_cv_func_sysconf=yes} ac_cv_func_tcgetattr=${ac_cv_func_tcgetattr=yes} ac_cv_func_tcgetpgrp=${ac_cv_func_tcgetpgrp=yes} ac_cv_func_textdomain=${ac_cv_func_textdomain=no} ac_cv_func_times=${ac_cv_func_times=yes} ac_cv_func_tzset=${ac_cv_func_tzset=yes} ac_cv_func_ulimit=${ac_cv_func_ulimit=no} ac_cv_func_uname=${ac_cv_func_uname=yes} ac_cv_func_vprintf=${ac_cv_func_vprintf=yes} ac_cv_func_wait3=${ac_cv_func_wait3=no} ac_cv_func_wait3_rusage=${ac_cv_func_wait3_rusage=no} ac_cv_func_waitpid=${ac_cv_func_waitpid=yes} ac_cv_header_alloca_h=${ac_cv_header_alloca_h=no} ac_cv_header_dirent_dirent_h=${ac_cv_header_dirent_dirent_h=yes} ac_cv_header_dlfcn_h=${ac_cv_header_dlfcn_h=no} ac_cv_header_libintl_h=${ac_cv_header_libintl_h=no} ac_cv_header_limits_h=${ac_cv_header_limits_h=yes} ac_cv_header_locale_h=${ac_cv_header_locale_h=yes} ac_cv_header_memory_h=${ac_cv_header_memory_h=yes} ac_cv_header_minix_config_h=${ac_cv_header_minix_config_h=no} ac_cv_header_stat_broken=${ac_cv_header_stat_broken=no} ac_cv_header_stdarg_h=${ac_cv_header_stdarg_h=yes} ac_cv_header_stdc=${ac_cv_header_stdc=yes} ac_cv_header_stdlib_h=${ac_cv_header_stdlib_h=yes} ac_cv_header_string_h=${ac_cv_header_string_h=yes} ac_cv_header_sys_file_h=${ac_cv_header_sys_file_h=yes} ac_cv_header_sys_param_h=${ac_cv_header_sys_param_h=yes} ac_cv_header_sys_pte_h=${ac_cv_header_sys_pte_h=no} ac_cv_header_sys_ptem_h=${ac_cv_header_sys_ptem_h=no} ac_cv_header_sys_resource_h=${ac_cv_header_sys_resource_h=no} ac_cv_header_sys_select_h=${ac_cv_header_sys_select_h=no} ac_cv_header_sys_socket_h=${ac_cv_header_sys_socket_h=yes} ac_cv_header_sys_stream_h=${ac_cv_header_sys_stream_h=no} ac_cv_header_sys_time_h=${ac_cv_header_sys_time_h=yes} ac_cv_header_sys_times_h=${ac_cv_header_sys_times_h=yes} ac_cv_header_sys_wait_h=${ac_cv_header_sys_wait_h=yes} ac_cv_header_termcap_h=${ac_cv_header_termcap_h=no} ac_cv_header_termio_h=${ac_cv_header_termio_h=no} ac_cv_header_termios_h=${ac_cv_header_termios_h=yes} ac_cv_header_time=${ac_cv_header_time=yes} ac_cv_header_unistd_h=${ac_cv_header_unistd_h=yes} ac_cv_header_varargs_h=${ac_cv_header_varargs_h=no} ac_cv_lib_dir_opendir=${ac_cv_lib_dir_opendir=no} ac_cv_lib_dl_dlopen=${ac_cv_lib_dl_dlopen=no} ac_cv_lib_intl_bindtextdomain=${ac_cv_lib_intl_bindtextdomain=no} ac_cv_lib_termcap_tgetent=${ac_cv_lib_termcap_tgetent=yes} ac_cv_path_install=${ac_cv_path_install='$INTERIX_ROOT/bin/install -c'} ac_cv_prog_AR=${ac_cv_prog_AR=ar} ac_cv_prog_CC=${ac_cv_prog_CC=gcc} ac_cv_prog_CPP=${ac_cv_prog_CPP='cc -E'} ac_cv_prog_RANLIB=${ac_cv_prog_RANLIB=:} ac_cv_prog_cc_cross=${ac_cv_prog_cc_cross=no} ac_cv_prog_cc_g=${ac_cv_prog_cc_g=yes} ac_cv_prog_cc_works=${ac_cv_prog_cc_works=yes} ac_cv_prog_gcc=${ac_cv_prog_gcc=yes} ac_cv_prog_gcc_traditional=${ac_cv_prog_gcc_traditional=no} ac_cv_prog_make_make_set=${ac_cv_prog_make_make_set=yes} ac_cv_sizeof_char_p=${ac_cv_sizeof_char_p=4} ac_cv_sizeof_double=${ac_cv_sizeof_double=8} ac_cv_sizeof_int=${ac_cv_sizeof_int=4} ac_cv_sizeof_long=${ac_cv_sizeof_long=4} ac_cv_sys_interpreter=${ac_cv_sys_interpreter=yes} ac_cv_sys_restartable_syscalls=${ac_cv_sys_restartable_syscalls=no} ac_cv_type_getgroups=${ac_cv_type_getgroups=gid_t} ac_cv_type_mode_t=${ac_cv_type_mode_t=yes} ac_cv_type_off_t=${ac_cv_type_off_t=yes} ac_cv_type_pid_t=${ac_cv_type_pid_t=yes} ac_cv_type_signal=${ac_cv_type_signal=void} ac_cv_type_size_t=${ac_cv_type_size_t=yes} ac_cv_type_time_t=${ac_cv_type_time_t=yes} ac_cv_type_uid_t=${ac_cv_type_uid_t=yes} bash_cv_can_redecl_getpw=${bash_cv_can_redecl_getpw=yes} bash_cv_decl_under_sys_siglist=${bash_cv_decl_under_sys_siglist=no} bash_cv_dev_fd=${bash_cv_dev_fd=absent} bash_cv_dirent_has_d_fileno=${bash_cv_dirent_has_d_fileno=no} bash_cv_dirent_has_dino=${bash_cv_dirent_has_dino=yes} bash_cv_dup2_broken=${bash_cv_dup2_broken=no} bash_cv_fionread_in_ioctl=${bash_cv_fionread_in_ioctl=yes} bash_cv_func_lstat=${bash_cv_func_lstat=no} bash_cv_func_sigsetjmp=${bash_cv_func_sigsetjmp=present} bash_cv_func_strcoll_broken=${bash_cv_func_strcoll_broken=no} bash_cv_getcwd_calls_popen=${bash_cv_getcwd_calls_popen=no} bash_cv_getenv_redef=${bash_cv_getenv_redef=yes} bash_cv_have_strsignal=${bash_cv_have_strsignal=yes} bash_cv_job_control_missing=${bash_cv_job_control_missing=present} bash_cv_mail_dir=${bash_cv_mail_dir=/usr/spool/mail} bash_cv_must_reinstall_sighandlers=${bash_cv_must_reinstall_sighandlers=no} bash_cv_opendir_not_robust=${bash_cv_opendir_not_robust=no} bash_cv_pgrp_pipe=${bash_cv_pgrp_pipe=no} bash_cv_printf_declared=${bash_cv_printf_declared=yes} bash_cv_sbrk_declared=${bash_cv_sbrk_declared=no} bash_cv_signal_vintage=${bash_cv_signal_vintage=posix} bash_cv_speed_t_in_sys_types=${bash_cv_speed_t_in_sys_types=no} bash_cv_struct_timeval=${bash_cv_struct_timeval=yes} bash_cv_struct_winsize_header=${bash_cv_struct_winsize_header=ioctl_h} bash_cv_struct_winsize_in_ioctl=${bash_cv_struct_winsize_in_ioctl=yes} bash_cv_sys_errlist=${bash_cv_sys_errlist=yes} bash_cv_sys_named_pipes=${bash_cv_sys_named_pipes=present} bash_cv_sys_siglist=${bash_cv_sys_siglist=yes} bash_cv_termcap_lib=${bash_cv_termcap_lib=libtermcap} bash_cv_termio_ldisc=${bash_cv_termio_ldisc=no} bash_cv_termios_ldisc=${bash_cv_termios_ldisc=no} bash_cv_tiocgwinsz_in_ioctl=${bash_cv_tiocgwinsz_in_ioctl=yes} bash_cv_tiocstat_in_ioctl=${bash_cv_tiocstat_in_ioctl=no} bash_cv_type_clock_t=${bash_cv_type_clock_t=yes} bash_cv_type_quad_t=${bash_cv_type_quad_t=yes} bash_cv_type_rlimit=${bash_cv_type_rlimit=long} bash_cv_type_sigset_t=${bash_cv_type_sigset_t=yes} bash_cv_ulimit_maxfds=${bash_cv_ulimit_maxfds=no} bash_cv_under_sys_siglist=${bash_cv_under_sys_siglist=no} bash_cv_void_sighandler=${bash_cv_void_sighandler=yes} bash-2.05a/doc/ 40775 436 0 0 7373775244 11427 5ustar chetwheelbash-2.05a/doc/FAQ100644 436 0 176414 7374252765 12130 0ustar chetwheelThis is the Bash FAQ, version 3.17, for Bash version 2.05a. This document contains a set of frequently-asked questions concerning Bash, the GNU Bourne-Again Shell. Bash is a freely-available command interpreter with advanced features for both interactive use and shell programming. Another good source of basic information about shells is the collection of FAQ articles periodically posted to comp.unix.shell. Questions and comments concerning this document should be sent to chet@po.cwru.edu. This document is available for anonymous FTP with the URL ftp://ftp.cwru.edu/pub/bash/FAQ The Bash home page is http://cnswww.cns.cwru.edu/~chet/bash/bashtop.html ---------- Contents: Section A: The Basics A1) What is it? A2) What's the latest version? A3) Where can I get it? A4) On what machines will bash run? A5) Will bash run on operating systems other than Unix? A6) How can I build bash with gcc? A7) How can I make bash my login shell? A8) I just changed my login shell to bash, and now I can't FTP into my machine. Why not? A9) What's the `POSIX 1003.2 standard'? A10) What is the bash `posix mode'? Section B: The latest version B1) What's new in version 2.05a? B2) Are there any user-visible incompatibilities between bash-2.05a and bash-1.14.7? Section C: Differences from other Unix shells C1) How does bash differ from sh, the Bourne shell? C2) How does bash differ from the Korn shell, version ksh88? C3) Which new features in ksh-93 are not in bash, and which are? Section D: Why does bash do some things differently than other Unix shells? D1) Why does bash run a different version of `command' than `which command' says it will? D2) Why doesn't bash treat brace expansions exactly like csh? D3) Why doesn't bash have csh variable modifiers? D4) How can I make my csh aliases work when I convert to bash? D5) How can I pipe standard output and standard error from one command to another, like csh does with `|&'? D6) Now that I've converted from ksh to bash, are there equivalents to ksh features like autoloaded functions and the `whence' command? Section E: Why does bash do certain things the way it does? E1) Why is the bash builtin `test' slightly different from /bin/test? E2) Why does bash sometimes say `Broken pipe'? E3) When I have terminal escape sequences in my prompt, why does bash wrap lines at the wrong column? E4) If I pipe the output of a command into `read variable', why doesn't the output show up in $variable when the read command finishes? E5) I have a bunch of shell scripts that use backslash-escaped characters in arguments to `echo'. Bash doesn't interpret these characters. Why not, and how can I make it understand them? E6) Why doesn't a while or for loop get suspended when I type ^Z? E7) What about empty for loops in Makefiles? E8) Why does the arithmetic evaluation code complain about `08'? E9) Why does the pattern matching expression [A-Z]* match files beginning with every letter except `z'? Section F: Things to watch out for on certain Unix versions F1) Why can't I use command line editing in my `cmdtool'? F2) I built bash on Solaris 2. Why do globbing expansions and filename completion chop off the first few characters of each filename? F3) Why does bash dump core after I interrupt username completion or `~user' tilde expansion on a machine running NIS? F4) I'm running SVR4.2. Why is the line erased every time I type `@'? F5) Why does bash report syntax errors when my C News scripts use a redirection before a subshell command? F6) Why can't I use vi-mode editing on Red Hat Linux 6.1? Section G: How can I get bash to do certain common things? G1) How can I get bash to read and display eight-bit characters? G2) How do I write a function `x' to replace builtin command `x', but still invoke the command from within the function? G3) How can I find the value of a shell variable whose name is the value of another shell variable? G4) How can I make the bash `time' reserved word print timing output that looks like the output from my system's /usr/bin/time? G5) How do I get the current directory into my prompt? G6) How can I rename "*.foo" to "*.bar"? G7) How can I translate a filename from uppercase to lowercase? G8) How can I write a filename expansion (globbing) pattern that will match all files in the current directory except "." and ".."? Section H: Where do I go from here? H1) How do I report bugs in bash, and where should I look for fixes and advice? H2) What kind of bash documentation is there? H3) What's coming in future versions? H4) What's on the bash `wish list'? H5) When will the next release appear? ---------- Section A: The Basics A1) What is it? Bash is a Unix command interpreter (shell). It is an implementation of the Posix 1003.2 shell standard, and resembles the Korn and System V shells. Bash contains a number of enhancements over those shells, both for interactive use and shell programming. Features geared toward interactive use include command line editing, command history, job control, aliases, and prompt expansion. Programming features include additional variable expansions, shell arithmetic, and a number of variables and options to control shell behavior. Bash was originally written by Brian Fox of the Free Software Foundation. The current developer and maintainer is Chet Ramey of Case Western Reserve University. A2) What's the latest version? The latest version is 2.05a, first made available on Thursday, 15 November, 2001. A3) Where can I get it? Bash is the GNU project's shell, and so is available from the master GNU archive site, ftp.gnu.org, and its mirrors. The latest version is also available for FTP from ftp.cwru.edu. The following URLs tell how to get version 2.05a: ftp://ftp.gnu.org/pub/gnu/bash/bash-2.05a.tar.gz ftp://ftp.cwru.edu/pub/bash/bash-2.05a.tar.gz Formatted versions of the documentation are available with the URLs: ftp://ftp.gnu.org/pub/gnu/bash/bash-doc-2.05a.tar.gz ftp://ftp.cwru.edu/pub/bash/bash-doc-2.05a.tar.gz A4) On what machines will bash run? Bash has been ported to nearly every version of UNIX. All you should have to do to build it on a machine for which a port exists is to type `configure' and then `make'. The build process will attempt to discover the version of UNIX you have and tailor itself accordingly, using a script created by GNU autoconf. More information appears in the file `INSTALL' in the distribution. The Bash web page (http://cnswww.cns.cwru.edu/~chet/bash/bashtop.html) explains how to obtain binary versions of bash for most of the major commercial Unix systems. A5) Will bash run on operating systems other than Unix? Configuration specifics for Unix-like systems such as QNX and LynxOS are included in the distribution. Bash-2.05 and later versions should compile and run on Minix 2.0 (patches were contributed), but I don't believe anyone has built bash-2.x on earlier Minix versions yet. Bash has been ported to versions of Windows implementing the Win32 programming interface. This includes Windows 95 and Windows NT. The port was done by Cygnus Solutions as part of their CYGWIN project. For more information about the project, look at the URLs http://www.cygwin.com/ http://sourceware.cygnus.com/cygwin Cygnus originally ported bash-1.14.7, and that port was part of their early GNU-Win32 (the original name) releases. Cygnus has also done a port of bash-2.05 to the CYGWIN environment, and it is available as part of their current release. Bash-2.05a should require no local Cygnus changes to build and run under CYGWIN. The Cygnus port works only on Intel machines. There is a port of bash (I don't know which version) to the alpha/NT environment available from ftp://ftp.gnustep.org//pub/win32/bash-alpha-nt-1.01.tar.gz DJ Delorie has a port of bash-2.x which runs under MS-DOS, as part of the DJGPP project. For more information on the project, see http://www.delorie.com/djgpp/ I have been told that the original DJGPP port was done by Daisuke Aoyama. Mark Elbrecht has sent me notice that bash-2.04 is available for DJGPP V2. The files are available as: ftp://ftp.simtel.net/pub/simtelnet/gnu/djgpp/v2gnu/bsh204b.zip binary ftp://ftp.simtel.net/pub/simtelnet/gnu/djgpp/v2gnu/bsh204d.zip documentation ftp://ftp.simtel.net/pub/simtelnet/gnu/djgpp/v2gnu/bsh204s.zip source Mark has begun to work with bash-2.05, but I don't know the status. Ports of bash-1.12 and bash-2.0 are available for OS/2 from ftp://hobbes.nmsu.edu/pub/os2/util/shell/bash_112.zip ftp://hobbes.nmsu.edu/pub/os2/util/shell/bash-2.0(253).zip I haven't looked at either, but the second appears to be a binary-only distribution. Beware. I have received word that Bash (I'm not sure which version, but I believe that it's at least bash-2.02.1) is the standard shell on BeOS. A6) How can I build bash with gcc? Bash configures to use gcc by default if it is available. Read the file INSTALL in the distribution for more information. A7) How can I make bash my login shell? Some machines let you use `chsh' to change your login shell. Other systems use `passwd -s' or `passwd -e'. If one of these works for you, that's all you need. Note that many systems require the full pathname to a shell to appear in /etc/shells before you can make it your login shell. For this, you may need the assistance of your friendly local system administrator. If you cannot do this, you can still use bash as your login shell, but you need to perform some tricks. The basic idea is to add a command to your login shell's startup file to replace your login shell with bash. For example, if your login shell is csh or tcsh, and you have installed bash in /usr/gnu/bin/bash, add the following line to ~/.login: if ( -f /usr/gnu/bin/bash ) exec /usr/gnu/bin/bash --login (the `--login' tells bash that it is a login shell). It's not a good idea to put this command into ~/.cshrc, because every csh you run without the `-f' option, even ones started to run csh scripts, reads that file. If you must put the command in ~/.cshrc, use something like if ( $?prompt ) exec /usr/gnu/bin/bash --login to ensure that bash is exec'd only when the csh is interactive. If your login shell is sh or ksh, you have to do two things. First, create an empty file in your home directory named `.bash_profile'. The existence of this file will prevent the exec'd bash from trying to read ~/.profile, and re-execing itself over and over again. ~/.bash_profile is the first file bash tries to read initialization commands from when it is invoked as a login shell. Next, add a line similar to the above to ~/.profile: [ -f /usr/gnu/bin/bash ] && exec /usr/gnu/bin/bash --login This will cause login shells to replace themselves with bash running as a login shell. Once you have this working, you can copy your initialization code from ~/.profile to ~/.bash_profile. I have received word that the recipe supplied above is insufficient for machines running CDE. CDE has a maze of twisty little startup files, all slightly different. If you cannot change your login shell in the password file to bash, you will have to (apparently) live with CDE using the shell in the password file to run its startup scripts. If you have changed your shell to bash, there is code in the CDE startup files (on Solaris, at least) that attempts to do the right thing. It is, however, often broken, and may require that you use the $BASH_ENV trick described below. `dtterm' claims to use $SHELL as the default program to start, so if you can change $SHELL in the CDE startup files, you should be able to use bash in your terminal windows. Setting DTSOURCEPROFILE in ~/.dtprofile will cause the `Xsession' program to read your login shell's startup files. You may be able to use bash for the rest of the CDE programs by setting SHELL to bash in ~/.dtprofile as well, but I have not tried this. You can use the above `exec' recipe to start bash when not logging in with CDE by testing the value of the DT variable: if [ -n "$DT" ]; then [ -f /usr/gnu/bin/bash ] && exec /usr/gnu/bin/bash --login fi If CDE starts its shells non-interactively during login, the login shell startup files (~/.profile, ~/.bash_profile) will not be sourced at login. To get around this problem, append a line similar to the following to your ~/.dtprofile: BASH_ENV=${HOME}/.bash_profile ; export BASH_ENV and add the following line to the beginning of ~/.bash_profile: unset BASH_ENV A8) I just changed my login shell to bash, and now I can't FTP into my machine. Why not? You must add the full pathname to bash to the file /etc/shells. As noted in the answer to the previous question, many systems require this before you can make bash your login shell. Most versions of ftpd use this file to prohibit `special' users such as `uucp' and `news' from using FTP. A9) What's the `POSIX 1003.2 standard'? POSIX is a name originally coined by Richard Stallman for a family of open system standards based on UNIX. There are a number of aspects of UNIX under consideration for standardization, from the basic system services at the system call and C library level to applications and tools to system administration and management. Each area of standardization is assigned to a working group in the 1003 series. The POSIX Shell and Utilities standard has been developed by IEEE Working Group 1003.2 (POSIX.2). It concentrates on the command interpreter interface and utility programs commonly executed from the command line or by other programs. An initial version of the standard has been approved and published by the IEEE, and work is currently underway to update it. Bash is concerned with the aspects of the shell's behavior defined by POSIX.2. The shell command language has of course been standardized, including the basic flow control and program execution constructs, I/O redirection and pipelining, argument handling, variable expansion, and quoting. The `special' builtins, which must be implemented as part of the shell to provide the desired functionality, are specified as being part of the shell; examples of these are `eval' and `export'. Other utilities appear in the sections of POSIX.2 not devoted to the shell which are commonly (and in some cases must be) implemented as builtin commands, such as `read' and `test'. POSIX.2 also specifies aspects of the shell's interactive behavior as part of the UPE, including job control and command line editing. Only vi-style line editing commands have been standardized; emacs editing commands were left out due to objections. The Open Group has made an older version of its Single Unix Specification (version 2), which is very similar to POSIX.2, available on the web at http://www.opengroup.org/onlinepubs/007908799/ A10) What is the bash `posix mode'? Although bash is an implementation of the POSIX.2 shell specification, there are areas where the bash default behavior differs from that spec. The bash `posix mode' changes the bash behavior in these areas so that it obeys the spec more closely. Posix mode is entered by starting bash with the --posix option or executing `set -o posix' after bash is running. The specific aspects of bash which change when posix mode is active are listed in the file CWRU/POSIX.NOTES in the bash distribution. They are also listed in a section in the Bash Reference Manual. Section B: The latest version B1) What's new in version 2.05a? The raison d'etre for bash-2.05a is to make an intermediate release containing principally bug fixes (some very good work was done and contributed after bash-2.05 was released) available before I start to work on the major new features to be available in the next release (bash-2.06 or bash-3.0 or whatever I tag it). As such, there are only a few relatively minor new features. Bash-2.05a contains the following new features (see the manual page for complete descriptions and the CHANGES and NEWS files in the bash-2.05a distribution): o The `printf' builtin has undergone major work o There is a new read-only `shopt' option: login_shell, which is set by login shells and unset otherwise o New `\A' prompt string escape sequence; expanding to time in 24-hour HH:MM format o New `-A group/-g' option to complete and compgen; goes group name completion o New [+-]O invocation option to set and unset `shopt' options at startup o ksh-like `ERR' trap o `for' loops now allow empty word lists after the `in' reserved word o new `hard' and `soft' arguments for the `ulimit' builtin o Readline can be configured to place the user at the same point on the line when retrieving commands from the history list o Readline can be configured to skip `hidden' files (filenames with a leading `.' on Unix) when performing completion A short feature history dating from bash-2.0: Bash-2.05 introduced the following new features: o This version has once again reverted to using locales and strcoll(3) when processing pattern matching bracket expressions, as POSIX requires. o Added a new `--init-file' invocation argument as a synonym for `--rcfile', per the new GNU coding standards. o The /dev/tcp and /dev/udp redirections now accept service names as well as port numbers. o `complete' and `compgen' now take a `-o value' option, which controls some of the aspects of that compspec. Valid values are: default - perform bash default completion if programmable completion produces no matches dirnames - perform directory name completion if programmable completion produces no matches filenames - tell readline that the compspec produces filenames, so it can do things like append slashes to directory names and suppress trailing spaces o A new loadable builtin, realpath, which canonicalizes and expands symlinks in pathname arguments. o When `set' is called without options, it prints function defintions in a way that allows them to be reused as input. This affects `declare' and `declare -p' as well. This only happens when the shell is not in POSIX mode, since POSIX.2 forbids this behavior. Bash-2.04 introduced the following new features: o Programmable word completion with the new `complete' and `compgen' builtins; examples are provided in examples/complete/complete-examples o `history' has a new `-d' option to delete a history entry o `bind' has a new `-x' option to bind key sequences to shell commands o The prompt expansion code has new `\j' and `\l' escape sequences o The `no_empty_cmd_completion' shell option, if enabled, inhibits command completion when TAB is typed on an empty line o `help' has a new `-s' option to print a usage synopsis o New arithmetic operators: var++, var--, ++var, --var, expr1,expr2 (comma) o New ksh93-style arithmetic for command: for ((expr1 ; expr2; expr3 )); do list; done o `read' has new options: `-t', `-n', `-d', `-s' o The redirection code handles several filenames specially: /dev/fd/N, /dev/stdin, /dev/stdout, /dev/stderr o The redirection code now recognizes /dev/tcp/HOST/PORT and /dev/udp/HOST/PORT and tries to open a TCP or UDP socket, respectively, to the specified port on the specified host o The ${!prefix*} expansion has been implemented o A new FUNCNAME variable, which expands to the name of a currently-executing function o The GROUPS variable is no longer readonly o A new shopt `xpg_echo' variable, to control the behavior of echo with respect to backslash-escape sequences at runtime o The NON_INTERACTIVE_LOGIN_SHELLS #define has returned The version of Readline released with Bash-2.04, Readline-4.1, had several new features as well: o Parentheses matching is always compiled into readline, and controllable with the new `blink-matching-paren' variable o The history-search-forward and history-search-backward functions now leave point at the end of the line when the search string is empty, like reverse-search-history, and forward-search-history o A new function for applications: rl_on_new_line_with_prompt() o New variables for applications: rl_already_prompted, and rl_gnu_readline_p Bash-2.03 had very few new features, in keeping with the convention that odd-numbered releases provide mainly bug fixes. A number of new features were added to Readline, mostly at the request of the Cygnus folks. A new shopt option, `restricted_shell', so that startup files can test whether or not the shell was started in restricted mode Filename generation is now performed on the words between ( and ) in compound array assignments (this is really a bug fix) OLDPWD is now auto-exported, as POSIX.2 requires ENV and BASH_ENV are read-only variables in a restricted shell Bash may now be linked against an already-installed Readline library, as long as the Readline library is version 4 or newer All shells begun with the `--login' option will source the login shell startup files, even if the shell is not interactive There were lots of changes to the version of the Readline library released along with Bash-2.03. For a complete list of the changes, read the file CHANGES in the Bash-2.03 distribution. Bash-2.02 contained the following new features: a new version of malloc (based on the old GNU malloc code in previous bash versions) that is more page-oriented, more conservative with memory usage, does not `orphan' large blocks when they are freed, is usable on 64-bit machines, and has allocation checking turned on unconditionally POSIX.2-style globbing character classes ([:alpha:], [:alnum:], etc.) POSIX.2-style globbing equivalence classes POSIX.2-style globbing collating symbols the ksh [[...]] extended conditional command the ksh egrep-style extended pattern matching operators a new `printf' builtin the ksh-like $(, &>, >| prompt string special char translation and variable expansion auto-export of variables in initial environment command search finds functions before builtins bash return builtin will exit a file sourced with `.' builtins: cd -/-L/-P, exec -l/-c/-a, echo -e/-E, hash -p/-t. export -n/-f/-p/name=value, pwd -L/-P, read -e/-p/-a/-t/-n/-d/-s, readonly -a/-f/name=value, trap -l, set +o, set -b/-m/-o option/-h/-p/-B/-C/-H/-P, unset -f/-v, ulimit -m/-p/-u, type -a/-p/-t, suspend -f, kill -n, test -o optname/s1 == s2/s1 < s2/s1 > s2/-nt/-ot/-ef/-O/-G/-S bash reads ~/.bashrc for interactive shells, $ENV for non-interactive bash restricted shell mode is more extensive bash allows functions and variables with the same name brace expansion tilde expansion arithmetic expansion with $((...)) and `let' builtin the `[[...]]' extended conditional command process substitution aliases and alias/unalias builtins local variables in functions and `local' builtin readline and command-line editing with programmable completion command history and history/fc builtins csh-like history expansion other new bash builtins: bind, command, compgen, complete, builtin, declare/typeset, dirs, enable, fc, help, history, logout, popd, pushd, disown, shopt, printf exported functions filename generation when using output redirection (command >a*) POSIX.2-style globbing character classes POSIX.2-style globbing equivalence classes POSIX.2-style globbing collating symbols egrep-like extended pattern matching operators case-insensitive pattern matching and globbing variable assignments preceding commands affect only that command, even for builtins and functions posix mode redirection to /dev/fd/N, /dev/stdin, /dev/stdout, /dev/stderr, /dev/tcp/host/port, /dev/udp/host/port Things sh has that bash does not: uses variable SHACCT to do shell accounting includes `stop' builtin (bash can use alias stop='kill -s STOP') `newgrp' builtin turns on job control if called as `jsh' $TIMEOUT (like bash $TMOUT) `^' is a synonym for `|' new SVR4.2 sh builtins: mldmode, priv Implementation differences: redirection to/from compound commands causes sh to create a subshell bash does not allow unbalanced quotes; sh silently inserts them at EOF bash does not mess with signal 11 sh sets (euid, egid) to (uid, gid) if -p not supplied and uid < 100 bash splits only the results of expansions on IFS, using POSIX.2 field splitting rules; sh splits all words on IFS sh does not allow MAILCHECK to be unset (?) sh does not allow traps on SIGALRM or SIGCHLD bash allows multiple option arguments when invoked (e.g. -x -v); sh allows only a single option argument (`sh -x -v' attempts to open a file named `-v', and, on SunOS 4.1.4, dumps core. On Solaris 2.4 and earlier versions, sh goes into an infinite loop.) sh exits a script if any builtin fails; bash exits only if one of the POSIX.2 `special' builtins fails C2) How does bash differ from the Korn shell, version ksh88? Things bash has or uses that ksh88 does not: long invocation options [-+]O invocation option `!' reserved word arithmetic for command: for ((expr1 ; expr2; expr3 )); do list; done posix mode and posix conformance command hashing tilde expansion for assignment statements that look like $PATH process substitution with named pipes if /dev/fd is not available the ${!param} indirect parameter expansion operator the ${!param*} prefix expansion operator the ${param:length[:offset]} parameter substring operator the ${param/pat[/string]} parameter pattern substitution operator variables: BASH, BASH_VERSION, BASH_VERSINFO, UID, EUID, SHLVL, TIMEFORMAT, HISTCMD, HOSTTYPE, OSTYPE, MACHTYPE, HISTFILESIZE, HISTIGNORE, HISTCONTROL, PROMPT_COMMAND, IGNOREEOF, FIGNORE, INPUTRC, HOSTFILE, DIRSTACK, PIPESTATUS, HOSTNAME, OPTERR, SHELLOPTS, GLOBIGNORE, GROUPS, FUNCNAME, histchars, auto_resume prompt expansion with backslash escapes and command substitution redirection: &> (stdout and stderr) more extensive and extensible editing and programmable completion builtins: bind, builtin, command, declare, dirs, echo -e/-E, enable, exec -l/-c/-a, fc -s, export -n/-f/-p, hash, help, history, jobs -x/-r/-s, kill -s/-n/-l, local, logout, popd, pushd, read -e/-p/-a/-t/-n/-d/-s, readonly -a/-n/-f/-p, set -o braceexpand/-o histexpand/-o interactive-comments/ -o notify/-o physical/-o posix/-o hashall/-o onecmd/ -h/-B/-C/-b/-H/-P, set +o, suspend, trap -l, type, typeset -a/-F/-p, ulimit -u, umask -S, alias -p, shopt, disown, printf, complete, compgen `!' csh-style history expansion POSIX.2-style globbing character classes POSIX.2-style globbing equivalence classes POSIX.2-style globbing collating symbols egrep-like extended pattern matching operators case-insensitive pattern matching and globbing `**' arithmetic operator to do exponentiation redirection to /dev/fd/N, /dev/stdin, /dev/stdout, /dev/stderr arrays of unlimited size Things ksh88 has or uses that bash does not: tracked aliases (alias -t) variables: ERRNO, FPATH, EDITOR, VISUAL co-processes (|&, >&p, <&p) weirdly-scoped functions typeset +f to list all function names without definitions text of command history kept in a file, not memory builtins: alias -x, cd old new, fc -e -, newgrp, print, read -p/-s/-u/var?prompt, set -A/-o gmacs/ -o bgnice/-o markdirs/-o nolog/-o trackall/-o viraw/-s, typeset -H/-L/-R/-Z/-A/-ft/-fu/-fx/-l/-u/-t, whence using environment to pass attributes of exported variables arithmetic evaluation done on arguments to some builtins reads .profile from $PWD when invoked as login shell Implementation differences: ksh runs last command of a pipeline in parent shell context bash has brace expansion by default (ksh88 compile-time option) bash has fixed startup file for all interactive shells; ksh reads $ENV bash has exported functions bash command search finds functions before builtins bash waits for all commands in pipeline to exit before returning status emacs-mode editing has some slightly different key bindings C3) Which new features in ksh-93 are not in bash, and which are? New things in ksh-93 not in bash-2.05a: associative arrays floating point arithmetic and variables math library functions ${!name[sub]} name of subscript for associative array `.' is allowed in variable names to create a hierarchical namespace more extensive compound assignment syntax discipline functions `sleep' and `getconf' builtins (bash has loadable versions) typeset -n and `nameref' variables KEYBD trap variables: .sh.edchar, .sh.edmode, .sh.edcol, .sh.edtext, .sh.version, .sh.name, .sh.subscript, .sh.value, .sh.match, HISTEDIT backreferences in pattern matching (\N) `&' operator in pattern lists for matching print -f (bash uses printf) `fc' has been renamed to `hist' `.' can execute shell functions exit statuses between 0 and 255 set -o pipefail `+=' variable assignment operator TMOUT is default timeout for `read' and `select' <&N- and >&N- redirections (combination dup and close) FPATH and PATH mixing getopts -a -I invocation option DEBUG trap now executed before each simple command, instead of after printf %H, %P, %T, %Z modifiers, output base for %d New things in ksh-93 present in bash-2.05a: for (( expr1; expr2; expr3 )) ; do list; done - arithmetic for command ?:, ++, --, `expr1 , expr2' arithmetic operators expansions: ${!param}, ${param:offset[:len]}, ${param/pat[/str]}, ${!param*} compound array assignment the `!' reserved word loadable builtins -- but ksh uses `builtin' while bash uses `enable' `command', `builtin', `disown' builtins new $'...' and $"..." quoting FIGNORE (but bash uses GLOBIGNORE), HISTCMD set -o notify/-C changes to kill builtin read -A (bash uses read -a) read -t/-d trap -p exec -c/-a `.' restores the positional parameters when it completes POSIX.2 `test' umask -S unalias -a command and arithmetic substitution performed on PS1, PS4, and ENV command name completion ENV processed only for interactive shells Section D: Why does bash do some things differently than other Unix shells? D1) Why does bash run a different version of `command' than `which command' says it will? On many systems, `which' is actually a csh script that assumes you're running csh. In tcsh, `which' and its cousin `where' are builtins. On other Unix systems, `which' is a perl script that uses the PATH environment variable. The csh script version reads the csh startup files from your home directory and uses those to determine which `command' will be invoked. Since bash doesn't use any of those startup files, there's a good chance that your bash environment differs from your csh environment. The bash `type' builtin does everything `which' does, and will report correct results for the running shell. If you're really wedded to the name `which', try adding the following function definition to your .bashrc: which() { builtin type "$@" } If you're moving from tcsh and would like to bring `where' along as well, use this function: where() { builtin type -a "$@" } D2) Why doesn't bash treat brace expansions exactly like csh? The only difference between bash and csh brace expansion is that bash requires a brace expression to contain at least one unquoted comma if it is to be expanded. Any brace-surrounded word not containing an unquoted comma is left unchanged by the brace expansion code. This affords the greatest degree of sh compatibility. Bash, ksh, zsh, and pd-ksh all implement brace expansion this way. D3) Why doesn't bash have csh variable modifiers? Posix has specified a more powerful, albeit somewhat more cryptic, mechanism cribbed from ksh, and bash implements it. ${parameter%word} Remove smallest suffix pattern. The WORD is expanded to produce a pattern. It then expands to the value of PARAMETER, with the smallest portion of the suffix matched by the pattern deleted. x=file.c echo ${x%.c}.o -->file.o ${parameter%%word} Remove largest suffix pattern. The WORD is expanded to produce a pattern. It then expands to the value of PARAMETER, with the largest portion of the suffix matched by the pattern deleted. x=posix/src/std echo ${x%%/*} -->posix ${parameter#word} Remove smallest prefix pattern. The WORD is expanded to produce a pattern. It then expands to the value of PARAMETER, with the smallest portion of the prefix matched by the pattern deleted. x=$HOME/src/cmd echo ${x#$HOME} -->/src/cmd ${parameter##word} Remove largest prefix pattern. The WORD is expanded to produce a pattern. It then expands to the value of PARAMETER, with the largest portion of the prefix matched by the pattern deleted. x=/one/two/three echo ${x##*/} -->three Given a=/a/b/c/d b=b.xxx csh bash result --- ---- ------ $a:h ${a%/*} /a/b/c $a:t ${a##*/} d $b:r ${b%.*} b $b:e ${b##*.} xxx D4) How can I make my csh aliases work when I convert to bash? Bash uses a different syntax to support aliases than csh does. The details can be found in the documentation. We have provided a shell script which does most of the work of conversion for you; this script can be found in ./examples/misc/aliasconv.sh. Here is how you use it: Start csh in the normal way for you. (e.g., `csh') Pipe the output of `alias' through `aliasconv.sh', saving the results into `bash_aliases': alias | bash aliasconv.sh >bash_aliases Edit `bash_aliases', carefully reading through any created functions. You will need to change the names of some csh specific variables to the bash equivalents. The script converts $cwd to $PWD, $term to $TERM, $home to $HOME, $user to $USER, and $prompt to $PS1. You may also have to add quotes to avoid unwanted expansion. For example, the csh alias: alias cd 'cd \!*; echo $cwd' is converted to the bash function: cd () { command cd "$@"; echo $PWD ; } The only thing that needs to be done is to quote $PWD: cd () { command cd "$@"; echo "$PWD" ; } Merge the edited file into your ~/.bashrc. There is an additional, more ambitious, script in examples/misc/cshtobash that attempts to convert your entire csh environment to its bash equivalent. This script can be run as simply `cshtobash' to convert your normal interactive environment, or as `cshtobash ~/.login' to convert your login environment. D5) How can I pipe standard output and standard error from one command to another, like csh does with `|&'? Use command 2>&1 | command2 The key is to remember that piping is performed before redirection, so file descriptor 1 points to the pipe when it is duplicated onto file descriptor 2. D6) Now that I've converted from ksh to bash, are there equivalents to ksh features like autoloaded functions and the `whence' command? There are features in ksh-88 and ksh-93 that do not have direct bash equivalents. Most, however, can be emulated with very little trouble. ksh-88 feature Bash equivalent -------------- --------------- compiled-in aliases set up aliases in .bashrc; some ksh aliases are bash builtins (hash, history, type) coprocesses named pipe pairs (one for read, one for write) typeset +f declare -F cd, print, whence function substitutes in examples/functions/kshenv autoloaded functions examples/functions/autoload is the same as typeset -fu read var?prompt read -p prompt var ksh-93 feature Bash equivalent -------------- --------------- sleep, getconf Bash has loadable versions in examples/loadables ${.sh.version} $BASH_VERSION print -f printf hist alias fc=hist $HISTEDIT $FCEDIT Section E: How can I get bash to do certain things, and why does bash do things the way it does? E1) Why is the bash builtin `test' slightly different from /bin/test? The specific example used here is [ ! x -o x ], which is false. Bash's builtin `test' implements the Posix.2 spec, which can be summarized as follows (the wording is due to David Korn): Here is the set of rules for processing test arguments. 0 Args: False 1 Arg: True iff argument is not null. 2 Args: If first arg is !, True iff second argument is null. If first argument is unary, then true if unary test is true Otherwise error. 3 Args: If second argument is a binary operator, do binary test of $1 $3 If first argument is !, negate two argument test of $2 $3 If first argument is `(' and third argument is `)', do the one-argument test of the second argument. Otherwise error. 4 Args: If first argument is !, negate three argument test of $2 $3 $4. Otherwise unspecified 5 or more Args: unspecified. (Historical shells would use their current algorithm). The operators -a and -o are considered binary operators for the purpose of the 3 Arg case. As you can see, the test becomes (not (x or x)), which is false. E2) Why does bash sometimes say `Broken pipe'? If a sequence of commands appears in a pipeline, and one of the reading commands finishes before the writer has finished, the writer receives a SIGPIPE signal. Many other shells special-case SIGPIPE as an exit status in the pipeline and do not report it. For example, in: ps -aux | head `head' can finish before `ps' writes all of its output, and ps will try to write on a pipe without a reader. In that case, bash will print `Broken pipe' to stderr when ps is killed by a SIGPIPE. You can build a version of bash that will not report SIGPIPE errors by uncommenting the definition of DONT_REPORT_SIGPIPE in the file config-top.h. E3) When I have terminal escape sequences in my prompt, why does bash wrap lines at the wrong column? Readline, the line editing library that bash uses, does not know that the terminal escape sequences do not take up space on the screen. The redisplay code assumes, unless told otherwise, that each character in the prompt is a `printable' character that takes up one character position on the screen. You can use the bash prompt expansion facility (see the PROMPTING section in the manual page) to tell readline that sequences of characters in the prompt strings take up no screen space. Use the \[ escape to begin a sequence of non-printing characters, and the \] escape to signal the end of such a sequence. E4) If I pipe the output of a command into `read variable', why doesn't the output show up in $variable when the read command finishes? This has to do with the parent-child relationship between Unix processes. It affects all commands run in pipelines, not just simple calls to `read'. For example, piping a command's output into a `while' loop that repeatedly calls `read' will result in the same behavior. Each element of a pipeline runs in a separate process, a child of the shell running the pipeline. A subprocess cannot affect its parent's environment. When the `read' command sets the variable to the input, that variable is set only in the subshell, not the parent shell. When the subshell exits, the value of the variable is lost. Many pipelines that end with `read variable' can be converted into command substitutions, which will capture the output of a specified command. The output can then be assigned to a variable: grep ^gnu /usr/lib/news/active | wc -l | read ngroup can be converted into ngroup=$(grep ^gnu /usr/lib/news/active | wc -l) This does not, unfortunately, work to split the text among multiple variables, as read does when given multiple variable arguments. If you need to do this, you can either use the command substitution above to read the output into a variable and chop up the variable using the bash pattern removal expansion operators or use some variant of the following approach. Say /usr/local/bin/ipaddr is the following shell script: #! /bin/sh host `hostname` | awk '/address/ {print $NF}' Instead of using /usr/local/bin/ipaddr | read A B C D to break the local machine's IP address into separate octets, use OIFS="$IFS" IFS=. set -- $(/usr/local/bin/ipaddr) IFS="$OIFS" A="$1" B="$2" C="$3" D="$4" Beware, however, that this will change the shell's positional parameters. If you need them, you should save them before doing this. This is the general approach -- in most cases you will not need to set $IFS to a different value. Some other user-supplied alternatives include: read A B C D << HERE $(IFS=.; echo $(/usr/local/bin/ipaddr)) HERE and, where process substitution is available, read A B C D < <(IFS=.; echo $(/usr/local/bin/ipaddr)) E5) I have a bunch of shell scripts that use backslash-escaped characters in arguments to `echo'. Bash doesn't interpret these characters. Why not, and how can I make it understand them? This is the behavior of echo on most Unix System V machines. The bash builtin `echo' is modeled after the 9th Edition Research Unix version of `echo'. It does not interpret backslash-escaped characters in its argument strings by default; it requires the use of the -e option to enable the interpretation. The System V echo provides no way to disable the special characters; the bash echo has a -E option to disable them. There is a configuration option that will make bash behave like the System V echo and interpret things like `\t' by default. Run configure with the --enable-xpg-echo-default option to turn this on. Be aware that this will cause some of the tests run when you type `make tests' to fail. There is a shell option, `xpg_echo', settable with `shopt' that will change the behavior of echo at runtime. Enabling this option turns on expansion of backslash-escape sequences. E6) Why doesn't a while or for loop get suspended when I type ^Z? This is a consequence of how job control works on Unix. The only thing that can be suspended is the process group. This is a single command or pipeline of commands that the shell forks and executes. When you run a while or for loop, the only thing that the shell forks and executes are any commands in the while loop test and commands in the loop bodies. These, therefore, are the only things that can be suspended when you type ^Z. If you want to be able to stop the entire loop, you need to put it within parentheses, which will force the loop into a subshell that may be stopped (and subsequently restarted) as a single unit. E7) What about empty for loops in Makefiles? It's fairly common to see constructs like this in automatically-generated Makefiles: SUBDIRS = @SUBDIRS@ ... subdirs-clean: for d in ${SUBDIRS}; do \ ( cd $$d && ${MAKE} ${MFLAGS} clean ) \ done When SUBDIRS is empty, this results in a command like this being passed to bash: for d in ; do ( cd $d && ${MAKE} ${MFLAGS} clean ) done In versions of bash before bash-2.05a, this was a syntax error. If the reserved word `in' was present, a word must follow it before the semicolon or newline. The language in the manual page referring to the list of words being empty referred to the list after it is expanded. These versions of bash required that there be at least one word following the `in' when the construct was parsed. The idiomatic Makefile solution is something like: SUBDIRS = @SUBDIRS@ subdirs-clean: subdirs=$SUBDIRS ; for d in $$subdirs; do \ ( cd $$d && ${MAKE} ${MFLAGS} clean ) \ done The latest drafts of the updated POSIX standard have changed this: the word list is no longer required. Bash versions 2.05a and later accept the new syntax. E8) Why does the arithmetic evaluation code complain about `08'? The bash arithmetic evaluation code (used for `let', $(()), (()), and in other places), interprets a leading `0' in numeric constants as denoting an octal number, and a leading `0x' as denoting hexadecimal. This is in accordance with the POSIX.2 spec, section 2.9.2.1, which states that arithmetic constants should be handled as signed long integers as defined by the ANSI/ISO C standard. The POSIX.2 interpretation committee has confirmed this: http://www.pasc.org/interps/unofficial/db/p1003.2/pasc-1003.2-173.html E9) Why does the pattern matching expression [A-Z]* match files beginning with every letter except `z'? Bash-2.05 and later versions have reverted to the bash-2.03 behavior of honoring the current locale setting when processing ranges within pattern matching bracket expressions ([A-Z]). This is what POSIX.2 and SUSv2/XPG5 specify. The behavior of the matcher in bash-2.05 and later versions depends on the current LC_COLLATE setting. Setting this variable to `C' or `POSIX' will result in the traditional behavior ([A-Z] matches all uppercase ASCII characters). Many other locales, including the en_US locale (the default on many US versions of Linux) collate the upper and lower case letters like this: AaBb...Zz which means that [A-Z] matches every letter except `z'. The portable way to specify upper case letters is [:upper:] instead of A-Z; lower case may be specified as [:lower:] instead of a-z. Look at the manual pages for setlocale(3), strcoll(3), and, if it is present, locale(1). If you have locale(1), you can use it to find your current locale information even if you do not have any of the LC_ variables set. My advice is to put export LC_COLLATE=C into /etc/profile and inspect any shell scripts run from cron for constructs like [A-Z]. This will prevent things like rm [A-Z]* from removing every file in the current directory except those beginning with `z' and still allow individual users to change the collation order. Users may put the above command into their own profiles as well, of course. Section F: Things to watch out for on certain Unix versions F1) Why can't I use command line editing in my `cmdtool'? The problem is `cmdtool' and bash fighting over the input. When scrolling is enabled in a cmdtool window, cmdtool puts the tty in `raw mode' to permit command-line editing using the mouse for applications that cannot do it themselves. As a result, bash and cmdtool each try to read keyboard input immediately, with neither getting enough of it to be useful. This mode also causes cmdtool to not implement many of the terminal functions and control sequences appearing in the `sun-cmd' termcap entry. For a more complete explanation, see that file examples/suncmd.termcap in the bash distribution. `xterm' is a better choice, and gets along with bash much more smoothly. If you must use cmdtool, you can use the termcap description in examples/suncmd.termcap. Set the TERMCAP variable to the terminal description contained in that file, i.e. TERMCAP='Mu|sun-cmd:am:bs:km:pt:li#34:co#80:cl=^L:ce=\E[K:cd=\E[J:rs=\E[s:' Then export TERMCAP and start a new cmdtool window from that shell. The bash command-line editing should behave better in the new cmdtool. If this works, you can put the assignment to TERMCAP in your bashrc file. F2) I built bash on Solaris 2. Why do globbing expansions and filename completion chop off the first few characters of each filename? This is the consequence of building bash on SunOS 5 and linking with the libraries in /usr/ucblib, but using the definitions and structures from files in /usr/include. The actual conflict is between the dirent structure in /usr/include/dirent.h and the struct returned by the version of `readdir' in libucb.a (a 4.3-BSD style `struct direct'). Make sure you've got /usr/ccs/bin ahead of /usr/ucb in your $PATH when configuring and building bash. This will ensure that you use /usr/ccs/bin/cc or acc instead of /usr/ucb/cc and that you link with libc before libucb. If you have installed the Sun C compiler, you may also need to put /usr/ccs/bin and /opt/SUNWspro/bin into your $PATH before /usr/ucb. F3) Why does bash dump core after I interrupt username completion or `~user' tilde expansion on a machine running NIS? This is a famous and long-standing bug in the SunOS YP (sorry, NIS) client library, which is part of libc. The YP library code keeps static state -- a pointer into the data returned from the server. When YP initializes itself (setpwent), it looks at this pointer and calls free on it if it's non-null. So far, so good. If one of the YP functions is interrupted during getpwent (the exact function is interpretwithsave()), and returns NULL, the pointer is freed without being reset to NULL, and the function returns. The next time getpwent is called, it sees that this pointer is non-null, calls free, and the bash free() blows up because it's being asked to free freed memory. The traditional Unix mallocs allow memory to be freed multiple times; that's probably why this has never been fixed. You can run configure with the `--without-gnu-malloc' option to use the C library malloc and avoid the problem. F4) I'm running SVR4.2. Why is the line erased every time I type `@'? The `@' character is the default `line kill' character in most versions of System V, including SVR4.2. You can change this character to whatever you want using `stty'. For example, to change the line kill character to control-u, type stty kill ^U where the `^' and `U' can be two separate characters. F5) Why does bash report syntax errors when my C News scripts use a redirection before a subshell command? The actual command in question is something like < file ( command ) According to the grammar given in the POSIX.2 standard, this construct is, in fact, a syntax error. Redirections may only precede `simple commands'. A subshell construct such as the above is one of the shell's `compound commands'. A redirection may only follow a compound command. This affects the mechanical transformation of commands that use `cat' to pipe a file into a command (a favorite Useless-Use-Of-Cat topic on comp.unix.shell). While most commands of the form cat file | command can be converted to `< file command', shell control structures such as loops and subshells require `command < file'. The file CWRU/sh-redir-hack in the bash-2.05a distribution is an (unofficial) patch to parse.y that will modify the grammar to support this construct. It will not apply with `patch'; you must modify parse.y by hand. Note that if you apply this, you must recompile with -DREDIRECTION_HACK. This introduces a large number of reduce/reduce conflicts into the shell grammar. F6) Why can't I use vi-mode editing on Red Hat Linux 6.1? The short answer is that Red Hat screwed up. The long answer is that they shipped an /etc/inputrc that only works for emacs mode editing, and then screwed all the vi users by setting INPUTRC to /etc/inputrc in /etc/profile. The short fix is to do one of the following: remove or rename /etc/inputrc, set INPUTRC=~/.inputrc in ~/.bashrc (or .bash_profile, but make sure you export it if you do), remove the assignment to INPUTRC from /etc/profile, add set keymap emacs to the beginning of /etc/inputrc, or bracket the key bindings in /etc/inputrc with these lines $if mode=emacs [...] $endif Section G: How can I get bash to do certain common things? G1) How can I get bash to read and display eight-bit characters? This is a process requiring several steps. First, you must ensure that the `physical' data path is a full eight bits. For xterms, for example, the `vt100' resources `eightBitInput' and `eightBitOutput' should be set to `true'. Once you have set up an eight-bit path, you must tell the kernel and tty driver to leave the eighth bit of characters alone when processing keyboard input. Use `stty' to do this: stty cs8 -istrip -parenb For old BSD-style systems, you can use stty pass8 You may also need stty even odd Finally, you need to tell readline that you will be inputting and displaying eight-bit characters. You use readline variables to do this. These variables can be set in your .inputrc or using the bash `bind' builtin. Here's an example using `bind': bash$ bind 'set convert-meta off' bash$ bind 'set meta-flag on' bash$ bind 'set output-meta on' The `set' commands between the single quotes may also be placed in ~/.inputrc. G2) How do I write a function `x' to replace builtin command `x', but still invoke the command from within the function? This is why the `command' and `builtin' builtins exist. The `command' builtin executes the command supplied as its first argument, skipping over any function defined with that name. The `builtin' builtin executes the builtin command given as its first argument directly. For example, to write a function to replace `cd' that writes the hostname and current directory to an xterm title bar, use something like the following: cd() { builtin cd "$@" && xtitle "$HOST: $PWD" } This could also be written using `command' instead of `builtin'; the version above is marginally more efficient. G3) How can I find the value of a shell variable whose name is the value of another shell variable? Versions of Bash newer than Bash-2.0 support this directly. You can use ${!var} For example, the following sequence of commands will echo `z': var1=var2 var2=z echo ${!var1} For sh compatibility, use the `eval' builtin. The important thing to remember is that `eval' expands the arguments you give it again, so you need to quote the parts of the arguments that you want `eval' to act on. For example, this expression prints the value of the last positional parameter: eval echo \"\$\{$#\}\" The expansion of the quoted portions of this expression will be deferred until `eval' runs, while the `$#' will be expanded before `eval' is executed. In versions of bash later than bash-2.0, echo ${!#} does the same thing. This is not the same thing as ksh93 `nameref' variables, though the syntax is similar. I may add namerefs in a future bash version. G4) How can I make the bash `time' reserved word print timing output that looks like the output from my system's /usr/bin/time? The bash command timing code looks for a variable `TIMEFORMAT' and uses its value as a format string to decide how to display the timing statistics. The value of TIMEFORMAT is a string with `%' escapes expanded in a fashion similar in spirit to printf(3). The manual page explains the meanings of the escape sequences in the format string. If TIMEFORMAT is not set, bash acts as if the following assignment had been performed: TIMEFORMAT=$'\nreal\t%3lR\nuser\t%3lU\nsys\t%3lS' The POSIX.2 default time format (used by `time -p command') is TIMEFORMAT=$'real %2R\nuser %2U\nsys %2S' The BSD /usr/bin/time format can be emulated with: TIMEFORMAT=$'\t%1R real\t%1U user\t%1S sys' The System V /usr/bin/time format can be emulated with: TIMEFORMAT=$'\nreal\t%1R\nuser\t%1U\nsys\t%1S' The ksh format can be emulated with: TIMEFORMAT=$'\nreal\t%2lR\nuser\t%2lU\nsys\t%2lS' G5) How do I get the current directory into my prompt? Bash provides a number of backslash-escape sequences which are expanded when the prompt string (PS1 or PS2) is displayed. The full list is in the manual page. The \w expansion gives the full pathname of the current directory, with a tilde (`~') substituted for the current value of $HOME. The \W expansion gives the basename of the current directory. To put the full pathname of the current directory into the path without any tilde subsitution, use $PWD. Here are some examples: PS1='\w$ ' # current directory with tilde PS1='\W$ ' # basename of current directory PS1='$PWD$ ' # full pathname of current directory The single quotes are important in the final example to prevent $PWD from being expanded when the assignment to PS1 is performed. G6) How can I rename "*.foo" to "*.bar"? Use the pattern removal functionality described in D3. The following `for' loop will do the trick: for f in *.foo; do mv $f ${f%foo}bar done G7) How can I translate a filename from uppercase to lowercase? The script examples/functions/lowercase, originally written by John DuBois, will do the trick. The converse is left as an exercise. G8) How can I write a filename expansion (globbing) pattern that will match all files in the current directory except "." and ".."? You must have set the `extglob' shell option using `shopt -s extglob' to use this: echo .!(.|) * A solution that works without extended globbing is given in the Unix Shell FAQ, posted periodically to comp.unix.shell. Section H: Where do I go from here? H1) How do I report bugs in bash, and where should I look for fixes and advice? Use the `bashbug' script to report bugs. It is built and installed at the same time as bash. It provides a standard template for reporting a problem and automatically includes information about your configuration and build environment. `bashbug' sends its reports to bug-bash@gnu.org, which is a large mailing list gatewayed to the usenet newsgroup gnu.bash.bug. Bug fixes, answers to questions, and announcements of new releases are all posted to gnu.bash.bug. Discussions concerning bash features and problems also take place there. To reach the bash maintainers directly, send mail to bash-maintainers@gnu.org. H2) What kind of bash documentation is there? First, look in the doc directory in the bash distribution. It should contain at least the following files: bash.1 an extensive, thorough Unix-style manual page builtins.1 a manual page covering just bash builtin commands bashref.texi a reference manual in GNU tex`info format bashref.info an info version of the reference manual FAQ this file article.ms text of an article written for The Linux Journal readline.3 a man page describing readline Postscript, HTML, and ASCII files created from the above source are available in the documentation distribution. There is additional documentation available for anonymous FTP from host ftp.cwru.edu in the `pub/bash' directory. Cameron Newham and Bill Rosenblatt have written a book on bash, published by O'Reilly and Associates. The book is based on Bill Rosenblatt's Korn Shell book. The title is ``Learning the Bash Shell'', and the ISBN number is 1-56592-147-X. Look for it in fine bookstores near you. This book covers bash-1.14, but has an appendix describing some of the new features in bash-2.0. A second edition of this book is available, published in January, 1998. The ISBN number is 1-56592-347-2. Look for it in the same fine bookstores or on the web. H3) What's coming in future versions? These are features I hope to include in a future version of bash. a better bash debugger (a minimally-tested version is included with bash-2.05a) associative arrays changes to the DEBUG trap to be compatible with ksh93 (which runs the trap before each simple command, instead of after each one like previous versions) co-processes, but with a new-style syntax that looks like function declaration H4) What's on the bash `wish list' for future versions? These are features that may or may not appear in a future version of bash. breaking some of the shell functionality into embeddable libraries a module system like zsh's, using dynamic loading like builtins better internationalization using GNU `gettext' an option to use external files for the long `help' text date-stamped command history a bash programmer's guide with a chapter on creating loadable builtins a better loadable interface to perl with access to the shell builtins and variables (contributions gratefully accepted) ksh93-like `nameref' variables ksh93-like `+=' variable assignment operator ksh93-like `xx.yy' variables (including some of the .sh.* variables) and associated disipline functions Some of the new ksh93 pattern matching operators, like backreferencing H5) When will the next release appear? The next version will appear sometime in 2002. Never make predictions. This document is Copyright 1995-2001 by Chester Ramey. Permission is hereby granted, without written agreement and without license or royalty fees, to use, copy, and distribute this document for any purpose, provided that the above copyright notice appears in all copies of this document and that the contents of this document remain unaltered. bash-2.05a/doc/Makefile.in100664 436 0 15315 7274025445 13605 0ustar chetwheel# This Makefile is for the Bash/documentation directory -*- text -*-. # # Copyright (C) 1996 Free Software Foundation, Inc. # This program is free software; you can redistribute it and/or modify # it under the terms of the GNU General Public License as published by # the Free Software Foundation; either version 2, or (at your option) # any later version. # This program is distributed in the hope that it will be useful, # but WITHOUT ANY WARRANTY; without even the implied warranty of # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the # GNU General Public License for more details. # You should have received a copy of the GNU General Public License # along with this program; if not, write to the Free Software # Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111 USA. # SHELL = @MAKE_SHELL@ RM = rm -f topdir = @top_srcdir@ srcdir = @srcdir@ VPATH = .:@srcdir@ prefix = @prefix@ exec_prefix = @exec_prefix@ infodir = @infodir@ # set this to a directory name to have the HTML files installed htmldir = @htmldir@ # Support an alternate destination root directory for package building DESTDIR = mandir = @mandir@ manpfx = man man1ext = .1 man1dir = $(mandir)/$(manpfx)1 man3ext = .3 man3dir = $(mandir)/$(manpfx)3 INSTALL = @INSTALL@ INSTALL_DATA = @INSTALL_DATA@ BUILD_DIR = @BUILD_DIR@ # bad style RL_LIBDIR = $(topdir)/lib/readline # unused TEXINDEX = texindex TEX = tex MAKEINFO = makeinfo TEXI2DVI = ${topdir}/support/texi2dvi TEXI2HTML = ${topdir}/support/texi2html MAN2HTML = ${BUILD_DIR}/support/man2html HTMLPOST = ${srcdir}/htmlpost.sh QUIETPS = #set this to -q to shut up dvips PAPERSIZE = letter # change to a4 for A4-size paper PSDPI = 300 # could be 600 if you like DVIPS = dvips -D ${PSDPI} $(QUIETPS) -t ${PAPERSIZE} -o $@ # tricky TEXINPUTDIR = $(RL_LIBDIR)/doc MKDIRS = ${topdir}/support/mkdirs # 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 HSUSER = $(RL_LIBDIR)/doc/hsuser.texinfo RLUSER = $(RL_LIBDIR)/doc/rluser.texinfo .SUFFIXES: .0 .1 .3 .ms .ps .txt .dvi .html .1.ps: $(RM) $@ -${GROFF} -man $< > $@ .1.0: $(RM) $@ -${NROFF} -man $< > $@ .1.html: $(RM) $@ -${MAN2HTML} $< | ${HTMLPOST} > $@ .ms.ps: $(RM) $@ -${GROFF} -ms $< > $@ .ms.txt: $(RM) $@ -${NROFF} -ms $< > $@ .3.ps: $(RM) $@ -${GROFF} -man $< > $@ .3.0: $(RM) $@ -${NROFF} -man $< > $@ .3.html: $(RM) $@ -${MAN2HTML} $< > $@ all: ps info dvi text html nodvi: ps info text html PSFILES = bash.ps bashbug.ps article.ps builtins.ps rbash.ps DVIFILES = bashref.dvi bashref.ps INFOFILES = bashref.info MAN0FILES = bash.0 bashbug.0 builtins.0 rbash.0 HTMLFILES = bashref.html bash.html ps: ${PSFILES} dvi: ${DVIFILES} info: ${INFOFILES} text: ${MAN0FILES} html: ${HTMLFILES} bashref.dvi: $(srcdir)/bashref.texi $(HSUSER) $(RLUSER) TEXINPUTS=.:$(TEXINPUTDIR):$$TEXINPUTS $(TEXI2DVI) $(srcdir)/bashref.texi bashref.ps: bashref.dvi $(RM) $@ $(DVIPS) bashref.dvi bashref.info: $(srcdir)/bashref.texi $(HSUSER) $(RLUSER) $(MAKEINFO) --no-split -I$(TEXINPUTDIR) $(srcdir)/bashref.texi bashref.html: bashref.texi $(HSUSER) $(RLUSER) $(TEXI2HTML) -menu -monolithic -I $(TEXINPUTDIR) $(srcdir)/bashref.texi new-bashref.dvi: $(srcdir)/new-bashref.texi $(HSUSER) $(RLUSER) TEXINPUTS=.:$(TEXINPUTDIR):$$TEXINPUTS $(TEXI2DVI) $(srcdir)/new-bashref.texi new-bashref.ps: new-bashref.dvi $(RM) $@ $(DVIPS) new-bashref.dvi new-bashref.info: $(srcdir)/new-bashref.texi $(HSUSER) $(RLUSER) $(MAKEINFO) --no-split -I$(TEXINPUTDIR) $(srcdir)/new-bashref.texi bash.dvi: bash.texinfo $(HSUSER) $(RLUSER) TEXINPUTS=.:$(TEXINPUTDIR):$$TEXINPUTS $(TEXI2DVI) bash.texinfo bashman.ps: bash.dvi $(RM) $@ $(DVIPS) bash.dvi bash.txt: bash.1 bash.ps: bash.1 bash.html: bash.1 $(MAN2HTML) bashbug.ps: bashbug.1 builtins.ps: builtins.1 bash.1 rbash.ps: rbash.1 bash.1 bash.0: bash.1 bashbug.0: bashbug.1 builtins.0: builtins.1 bash.1 rbash.0: rbash.1 bash.1 article.ps: article.ms $(MAN2HTML): ${topdir}/support/man2html.c -( cd ${BUILD_DIR}/support ; ${MAKE} ${MFLAGS} man2html) clean: $(RM) *.aux *.bak *.cp *.fn *.ky *.log *.pg *.toc *.tp *.vr *.cps \ *.pgs *.bt *.bts *.rw *.rws *.fns *.kys *.tps *.vrs *.o ${RM} core *.core distclean mostlyclean: clean $(RM) Makefile maintainer-clean: clean ${RM} ${PSFILES} ${DVIFILES} ${INFOFILES} ${MAN0FILES} ${HTMLFILES} ${RM} ${CREATED_FAQ} $(RM) Makefile installdirs: -test -d $(man1dir) || $(SHELL) ${MKDIRS} $(DESTDIR)$(man1dir) -test -d $(infodir) || $(SHELL) ${MKDIRS} $(DESTDIR)$(infodir) -if test -n "$(htmldir)" ; then \ test -d $(htmldir) || $(SHELL) ${MKDIRS} $(DESTDIR)$(htmldir) ; \ fi install: info installdirs -$(INSTALL_DATA) $(srcdir)/bash.1 $(DESTDIR)$(man1dir)/bash${man1ext} -$(INSTALL_DATA) $(srcdir)/bashbug.1 $(DESTDIR)$(man1dir)/bashbug${man1ext} # uncomment the next line to install the builtins man page # -$(INSTALL_DATA) $(srcdir)/builtins.1 $(DESTDIR)$(man1dir)/bash_builtins${man1ext} -$(INSTALL_DATA) $(srcdir)/bashref.info $(DESTDIR)$(infodir)/bash.info # run install-info if it is present to update the info directory if $(SHELL) -c 'install-info --version' >/dev/null 2>&1; then \ install-info --dir-file=$(DESTDIR)$(infodir)/dir $(DESTDIR)$(infodir)/bash.info; \ else true; fi # if htmldir is set, install the html files into that directory -if test -n "${htmldir}" ; then \ $(INSTALL_DATA) $(srcdir)/bash.html $(DESTDIR)$(htmldir) ; \ $(INSTALL_DATA) $(srcdir)/bashref.html $(DESTDIR)$(htmldir) ; \ fi uninstall: -$(RM) $(DESTDIR)$(man1dir)/bash${man1ext} $(DESTDIR)$(man1dir)/bashbug${man1ext} $(RM) $(DESTDIR)$(infodir)/bash.info -if test -n "$(htmldir)" ; then \ $(RM) $(DESTDIR)$(htmldir)/bash.html ; \ $(RM) $(DESTDIR)$(htmldir)/bashref.html ; \ fi # for use by chet CREATED_FAQ = faq.news faq.news2 faq.mail faq.version faq: ${CREATED_FAQ} faq.version: FAQ.version FAQ sh mkfaqvers FAQ.version > $@ faq.headers.mail: FAQ.headers.mail FAQ sh mkfaqvers FAQ.headers.mail > $@ faq.headers.news: FAQ.headers.news FAQ sh mkfaqvers FAQ.headers.news > $@ faq.headers.news2: FAQ.headers.news2 FAQ sh mkfaqvers FAQ.headers.news2 > $@ faq.news: FAQ faq.headers.news faq.version $(RM) $@ cat faq.headers.news faq.version FAQ > $@ faq.news2: FAQ faq.headers.news2 faq.version $(RM) $@ cat faq.headers.news2 faq.version FAQ > $@ faq.mail: FAQ faq.headers.mail faq.version $(RM) $@ cat faq.headers.mail faq.version FAQ > $@ inst: bashref.texi $(SHELL) ./mkinstall cmp -s INSTALL ../INSTALL || mv INSTALL ../INSTALL $(RM) INSTALL posix: bashref.texi $(SHELL) ./mkposix cmp -s POSIX.NOTES ../CWRU/POSIX.NOTES || mv POSIX.NOTES ../CWRU/POSIX.NOTES $(RM) POSIX.NOTES xdist: inst posix bash-2.05a/doc/bash.1100644 436 0 662770 7374257257 12603 0ustar chetwheel.\" .\" MAN PAGE COMMENTS to .\" .\" Chet Ramey .\" Information Network Services .\" Case Western Reserve University .\" chet@ins.CWRU.Edu .\" .\" Last Change: Tue Nov 13 12:55:51 EST 2001 .\" .\" bash_builtins, strip all but Built-Ins section .if \n(zZ=1 .ig zZ .if \n(zY=1 .ig zY .TH BASH 1 "2001 November 13" "GNU Bash-2.05a" .\" .\" There's some problem with having a `@' .\" in a tagged paragraph with the BSD man macros. .\" It has to do with `@' appearing in the }1 macro. .\" This is a problem on 4.3 BSD and Ultrix, but Sun .\" appears to have fixed it. .\" If you're seeing the characters .\" `@u-3p' appearing before the lines reading .\" `possible-hostname-completions .\" and `complete-hostname' down in READLINE, .\" then uncomment this redefinition. .\" .de }1 .ds ]X \&\\*(]B\\ .nr )E 0 .if !"\\$1"" .nr )I \\$1n .}f .ll \\n(LLu .in \\n()Ru+\\n(INu+\\n()Iu .ti \\n(INu .ie !\\n()Iu+\\n()Ru-\w\\*(]Xu-3p \{\\*(]X .br\} .el \\*(]X\h|\\n()Iu+\\n()Ru\c .}f .. .\" .\" File Name macro. This used to be `.PN', for Path Name, .\" but Sun doesn't seem to like that very much. .\" .de FN \fI\|\\$1\|\fP .. .SH NAME bash \- GNU Bourne-Again SHell .SH SYNOPSIS .B bash [options] [file] .SH COPYRIGHT .if n Bash is Copyright (C) 1989-2001 by the Free Software Foundation, Inc. .if t Bash is Copyright \(co 1989-2001 by the Free Software Foundation, Inc. .SH DESCRIPTION .B Bash is an \fBsh\fR-compatible command language interpreter that executes commands read from the standard input or from a file. .B Bash also incorporates useful features from the \fIKorn\fP and \fIC\fP shells (\fBksh\fP and \fBcsh\fP). .PP .B Bash is intended to be a conformant implementation of the IEEE POSIX Shell and Tools specification (IEEE Working Group 1003\.2). .SH OPTIONS In addition to the single-character shell options documented in the description of the \fBset\fR builtin command, \fBbash\fR interprets the following options when it is invoked: .PP .PD 0 .TP 10 .BI \-c "\| string\^" If the .B \-c option is present, then commands are read from .IR string . If there are arguments after the .IR string , they are assigned to the positional parameters, starting with .BR $0 . .TP .B \-r If the .B \-r option is present, the shell becomes .I restricted (see .SM .B "RESTRICTED SHELL" below). .TP .B \-i If the .B \-i option is present, the shell is .IR interactive . .TP .B \-s If the .B \-s option is present, or if no arguments remain after option processing, then commands are read from the standard input. This option allows the positional parameters to be set when invoking an interactive shell. .TP .B \-D A list of all double-quoted strings preceded by \fB$\fP is printed on the standard ouput. These are the strings that are subject to language translation when the current locale is not \fBC\fP or \fBPOSIX\fP. This implies the \fB\-n\fP option; no commands will be executed. .TP .B [\-+]O [\fIshopt_option\fP] \fIshopt_option\fP is one of the shell options accepted by the \fBshopt\fP builtin (see .SM .B SHELL BUILTIN COMMANDS below). If \fIshopt_option\fP is present, \fB\-O\fP sets the value of that option; \fB+O\fP unsets it. If \fIshopt_option\fP is not supplied, the names and values of the shell options accepted by \fBshopt\fP are printed on the standard output. If the invocation option is \fB+O\fP, the output is displayed in a format that may be reused as input. .TP .B \-\- A .B \-\- signals the end of options and disables further option processing. Any arguments after the .B \-\- are treated as filenames and arguments. An argument of .B \- is equivalent to \fB\-\-\fP. .PD .PP .B Bash also interprets a number of multi-character options. These options must appear on the command line before the single-character options in order for them to be recognized. .PP .PD 0 .TP .B \-\-dump\-po\-strings Equivalent to \fB\-D\fP, but the output is in the GNU \fIgettext\fP \fBpo\fP (portable object) file format. .TP .B \-\-dump\-strings Equivalent to \fB\-D\fP. .TP .B \-\-help Display a usage message on standard output and exit successfully. .TP .PD 0 \fB\-\-init\-file\fP \fIfile\fP .TP \fB\-\-rcfile\fP \fIfile\fP .PD Execute commands from .I file instead of the standard personal initialization file .I ~/.bashrc if the shell is interactive (see .SM .B INVOCATION below). .TP .B \-\-login Make .B bash act as if it had been invoked as a login shell (see .SM .B INVOCATION below). .TP .B \-\-noediting Do not use the GNU .B readline library to read command lines when the shell is interactive. .TP .B \-\-noprofile Do not read either the system-wide startup file .FN /etc/profile or any of the personal initialization files .IR ~/.bash_profile , .IR ~/.bash_login , or .IR ~/.profile . By default, .B bash reads these files when it is invoked as a login shell (see .SM .B INVOCATION below). .TP .B \-\-norc Do not read and execute the personal initialization file .I ~/.bashrc if the shell is interactive. This option is on by default if the shell is invoked as .BR sh . .TP .B \-\-posix Change the behavior of \fBbash\fP where the default operation differs from the POSIX 1003.2 standard to match the standard (\fIposix mode\fP). .TP .B \-\-restricted The shell becomes restricted (see .SM .B "RESTRICTED SHELL" below). .TP .B \-\-verbose Equivalent to \fB\-v\fP. .TP .B \-\-version Show version information for this instance of .B bash on the standard output and exit successfully. .PD .SH ARGUMENTS If arguments remain after option processing, and neither the .B \-c nor the .B \-s option has been supplied, the first argument is assumed to be the name of a file containing shell commands. If .B bash is invoked in this fashion, .B $0 is set to the name of the file, and the positional parameters are set to the remaining arguments. .B Bash reads and executes commands from this file, then exits. \fBBash\fP's exit status is the exit status of the last command executed in the script. If no commands are executed, the exit status is 0. An attempt is first made to open the file in the current directory, and, if no file is found, then the shell searches the directories in .SM .B PATH for the script. .SH INVOCATION A \fIlogin shell\fP is one whose first character of argument zero is a .BR \- , or one started with the .B \-\-login option. .PP An \fIinteractive\fP shell is one started without non-option arguments and without the .B \-c option whose standard input and output are both connected to terminals (as determined by .IR isatty (3)), or one started with the .B \-i option. .SM .B PS1 is set and .B $\- includes .B i if .B bash is interactive, allowing a shell script or a startup file to test this state. .PP The following paragraphs describe how .B bash executes its startup files. If any of the files exist but cannot be read, .B bash reports an error. Tildes are expanded in file names as described below under .B "Tilde Expansion" in the .SM .B EXPANSION section. .PP When .B bash is invoked as an interactive login shell, or as a non-interactive shell with the \fB\-\-login\fP option, it first reads and executes commands from the file \fI/etc/profile\fP, if that file exists. After reading that file, it looks for \fI~/.bash_profile\fP, \fI~/.bash_login\fP, and \fI~/.profile\fP, in that order, and reads and executes commands from the first one that exists and is readable. The .B \-\-noprofile option may be used when the shell is started to inhibit this behavior. .PP When a login shell exits, .B bash reads and executes commands from the file \fI~/.bash_logout\fP, if it exists. .PP When an interactive shell that is not a login shell is started, .B bash reads and executes commands from \fI~/.bashrc\fP, if that file exists. This may be inhibited by using the .B \-\-norc option. The \fB\-\-rcfile\fP \fIfile\fP option will force .B bash to read and execute commands from \fIfile\fP instead of \fI~/.bashrc\fP. .PP When .B bash is started non-interactively, to run a shell script, for example, it looks for the variable .SM .B BASH_ENV in the environment, expands its value if it appears there, and uses the expanded value as the name of a file to read and execute. .B Bash behaves as if the following command were executed: .sp .5 .RS .if t \f(CWif [ \-n "$BASH_ENV" ]; then . "$BASH_ENV"; fi\fP .if n if [ \-n "$BASH_ENV" ]; then . "$BASH_ENV"; fi .RE .sp .5 but the value of the .SM .B PATH variable is not used to search for the file name. .PP If .B bash is invoked with the name .BR sh , it tries to mimic the startup behavior of historical versions of .B sh as closely as possible, while conforming to the POSIX standard as well. When invoked as an interactive login shell, or a non-interactive shell with the \fB\-\-login\fP option, it first attempts to read and execute commands from .I /etc/profile and .IR ~/.profile , in that order. The .B \-\-noprofile option may be used to inhibit this behavior. When invoked as an interactive shell with the name .BR sh , .B bash looks for the variable .SM .BR ENV , expands its value if it is defined, and uses the expanded value as the name of a file to read and execute. Since a shell invoked as .B sh does not attempt to read and execute commands from any other startup files, the .B \-\-rcfile option has no effect. A non-interactive shell invoked with the name .B sh does not attempt to read any other startup files. When invoked as .BR sh , .B bash enters .I posix mode after the startup files are read. .PP When .B bash is started in .I posix mode, as with the .B \-\-posix command line option, it follows the POSIX standard for startup files. In this mode, interactive shells expand the .SM .B ENV variable and commands are read and executed from the file whose name is the expanded value. No other startup files are read. .PP .B Bash attempts to determine when it is being run by the remote shell daemon, usually \fIrshd\fP. If .B bash determines it is being run by \fIrshd\fP, it reads and executes commands from \fI~/.bashrc\fP, if that file exists and is readable. It will not do this if invoked as \fBsh\fP. The .B \-\-norc option may be used to inhibit this behavior, and the .B \-\-rcfile option may be used to force another file to be read, but \fIrshd\fP does not generally invoke the shell with those options or allow them to be specified. .PP If the shell is started with the effective user (group) id not equal to the real user (group) id, and the \fB\-p\fP option is not supplied, no startup files are read, shell functions are not inherited from the environment, the .SM .B SHELLOPTS variable, if it appears in the environment, is ignored, and the effective user id is set to the real user id. If the \fB\-p\fP option is supplied at invocation, the startup behavior is the same, but the effective user id is not reset. .SH DEFINITIONS .PP The following definitions are used throughout the rest of this document. .PD 0 .TP .B blank A space or tab. .TP .B word A sequence of characters considered as a single unit by the shell. Also known as a .BR token . .TP .B name A .I word consisting only of alphanumeric characters and underscores, and beginning with an alphabetic character or an underscore. Also referred to as an .BR identifier . .TP .B metacharacter A character that, when unquoted, separates words. One of the following: .br .RS .PP .if t \fB| & ; ( ) < > space tab\fP .if n \fB| & ; ( ) < > space tab\fP .RE .PP .TP .B control operator A \fItoken\fP that performs a control function. It is one of the following symbols: .RS .PP .if t \fB\(bv\(bv & && ; ;; ( ) | \fP .if n \fB|| & && ; ;; ( ) | \fP .RE .PD .SH "RESERVED WORDS" \fIReserved words\fP are words that have a special meaning to the shell. The following words are recognized as reserved when unquoted and either the first word of a simple command (see .SM .B SHELL GRAMMAR below) or the third word of a .B case or .B for command: .if t .RS .PP .B .if n ! case do done elif else esac fi for function if in select then until while { } time [[ ]] .if t ! case do done elif else esac fi for function if in select then until while { } time [[ ]] .if t .RE .RE .SH "SHELL GRAMMAR" .SS Simple Commands .PP A \fIsimple command\fP is a sequence of optional variable assignments followed by \fBblank\fP-separated words and redirections, and terminated by a \fIcontrol operator\fP. The first word specifies the command to be executed, and is passed as argument zero. The remaining words are passed as arguments to the invoked command. .PP The return value of a \fIsimple command\fP is its exit status, or 128+\fIn\^\fP if the command is terminated by signal .IR n . .SS Pipelines .PP A \fIpipeline\fP is a sequence of one or more commands separated by the character .BR | . The format for a pipeline is: .RS .PP [\fBtime\fP [\fB\-p\fP]] [ ! ] \fIcommand\fP [ \fB|\fP \fIcommand2\fP ... ] .RE .PP The standard output of .I command is connected via a pipe to the standard input of .IR command2 . This connection is performed before any redirections specified by the command (see .SM .B REDIRECTION below). .PP If the reserved word .B ! precedes a pipeline, the exit status of that pipeline is the logical NOT of the exit status of the last command. Otherwise, the status of the pipeline is the exit status of the last command. The shell waits for all commands in the pipeline to terminate before returning a value. .PP If the .B time reserved word precedes a pipeline, the elapsed as well as user and system time consumed by its execution are reported when the pipeline terminates. The \fB\-p\fP option changes the output format to that specified by POSIX. The .SM .B TIMEFORMAT variable may be set to a format string that specifies how the timing information should be displayed; see the description of .SM .B TIMEFORMAT under .B "Shell Variables" below. .PP Each command in a pipeline is executed as a separate process (i.e., in a subshell). .SS Lists .PP A \fIlist\fP is a sequence of one or more pipelines separated by one of the operators .BR ; , .BR & , .BR && , or .BR \(bv\(bv , and optionally terminated by one of .BR ; , .BR & , or .BR . .PP Of these list operators, .B && and .B \(bv\(bv have equal precedence, followed by .B ; and .BR &, which have equal precedence. .PP If a command is terminated by the control operator .BR & , the shell executes the command in the \fIbackground\fP in a subshell. The shell does not wait for the command to finish, and the return status is 0. Commands separated by a .B ; are executed sequentially; the shell waits for each command to terminate in turn. The return status is the exit status of the last command executed. .PP The control operators .B && and .B \(bv\(bv denote AND lists and OR lists, respectively. An AND list has the form .RS .PP \fIcommand1\fP \fB&&\fP \fIcommand2\fP .RE .PP .I command2 is executed if, and only if, .I command1 returns an exit status of zero. .PP An OR list has the form .RS .PP \fIcommand1\fP \fB\(bv\(bv\fP \fIcommand2\fP .PP .RE .PP .I command2 is executed if and only if .I command1 returns a non-zero exit status. The return status of AND and OR lists is the exit status of the last command executed in the list. .SS Compound Commands .PP A \fIcompound command\fP is one of the following: .TP (\fIlist\fP) \fIlist\fP is executed in a subshell. Variable assignments and builtin commands that affect the shell's environment do not remain in effect after the command completes. The return status is the exit status of \fIlist\fP. .TP { \fIlist\fP; } \fIlist\fP is simply executed in the current shell environment. \fIlist\fP must be terminated with a newline or semicolon. This is known as a \fIgroup command\fP. The return status is the exit status of \fIlist\fP. Note that unlike the metacharacters \fB(\fP and \fB\)\fP, \fB{\fP and \fB}\fP are \fIreserved words\fP and must occur where a reserved word is permitted to be recognized. Since they do not cause a word break, they must be separated from \fIlist\fP by whitespace. .TP ((\fIexpression\fP)) The \fIexpression\fP is evaluated according to the rules described below under .SM .BR "ARITHMETIC EVALUATION" . If the value of the expression is non-zero, the return status is 0; otherwise the return status is 1. This is exactly equivalent to \fBlet "\fIexpression\fP"\fR. .TP \fB[[\fP \fIexpression\fP \fB]]\fP Return a status of 0 or 1 depending on the evaluation of the conditional expression \fIexpression\fP. Expressions are composed of the primaries described below under .SM .BR "CONDITIONAL EXPRESSIONS" . Word splitting and pathname expansion are not performed on the words between the \fB[[\fP and \fB]]\fP; tilde expansion, parameter and variable expansion, arithmetic expansion, command substitution, process substitution, and quote removal are performed. .if t .sp 0.5 .if n .sp 1 When the \fB==\fP and \fB!=\fP operators are used, the string to the right of the operator is considered a pattern and matched according to the rules described below under \fBPattern Matching\fP. The return value is 0 if the string matches or does not match the pattern, respectively, and 1 otherwise. Any part of the pattern may be quoted to force it to be matched as a string. .if t .sp 0.5 .if n .sp 1 Expressions may be combined using the following operators, listed in decreasing order of precedence: .if t .sp 0.5 .if n .sp 1 .RS .PD 0 .TP .B ( \fIexpression\fP ) Returns the value of \fIexpression\fP. This may be used to override the normal precedence of operators. .TP .B ! \fIexpression\fP True if .I expression is false. .TP \fIexpression1\fP \fB&&\fP \fIexpression2\fP True if both .I expression1 and .I expression2 are true. .TP .if t \fIexpression1\fP \fB\(bv\(bv\fP \fIexpression2\fP .if n \fIexpression1\fP \fB||\fP \fIexpression2\fP True if either .I expression1 or .I expression2 is true. .PD .LP The \fB&&\fP and .if t \fB\(bv\(bv\fP .if n \fB||\fP operators do not execute \fIexpression2\fP if the value of \fIexpression1\fP is sufficient to determine the return value of the entire conditional expression. .RE .TP \fBfor\fP \fIname\fP [ \fBin\fP \fIword\fP ] ; \fBdo\fP \fIlist\fP ; \fBdone\fP The list of words following \fBin\fP is expanded, generating a list of items. The variable \fIname\fP is set to each element of this list in turn, and \fIlist\fP is executed each time. If the \fBin\fP \fIword\fP is omitted, the \fBfor\fP command executes \fIlist\fP once for each positional parameter that is set (see .SM .B PARAMETERS below). The return status is the exit status of the last command that executes. If the expansion of the items following \fBin\fP results in an empty list, no commands are executed, and the return status is 0. .TP \fBfor\fP (( \fIexpr1\fP ; \fIexpr2\fP ; \fIexpr3\fP )) ; \fBdo\fP \fIlist\fP ; \fBdone\fP First, the arithmetic expression \fIexpr1\fP is evaluated according to the rules described below under .SM .BR "ARITHMETIC EVALUATION" . The arithmetic expression \fIexpr2\fP is then evaluated repeatedly until it evaluates to zero. Each time \fIexpr2\fP evaluates to a non-zero value, \fIlist\fP is executed and the arithmetic expression \fIexpr3\fP is evaluated. If any expression is omitted, it behaves as if it evaluates to 1. The return value is the exit status of the last command in \fIlist\fP that is executed, or false if any of the expressions is invalid. .TP \fBselect\fP \fIname\fP [ \fBin\fP \fIword\fP ] ; \fBdo\fP \fIlist\fP ; \fBdone\fP The list of words following \fBin\fP is expanded, generating a list of items. The set of expanded words is printed on the standard error, each preceded by a number. If the \fBin\fP \fIword\fP is omitted, the positional parameters are printed (see .SM .B PARAMETERS below). The .B PS3 prompt is then displayed and a line read from the standard input. If the line consists of a number corresponding to one of the displayed words, then the value of .I name is set to that word. If the line is empty, the words and prompt are displayed again. If EOF is read, the command completes. Any other value read causes .I name to be set to null. The line read is saved in the variable .BR REPLY . The .I list is executed after each selection until a .B break command is executed. The exit status of .B select is the exit status of the last command executed in .IR list , or zero if no commands were executed. .TP \fBcase\fP \fIword\fP \fBin\fP [ [(] \fIpattern\fP [ \fB|\fP \fIpattern\fP ] \ ... ) \fIlist\fP ;; ] ... \fBesac\fP A \fBcase\fP command first expands \fIword\fP, and tries to match it against each \fIpattern\fP in turn, using the same matching rules as for pathname expansion (see .B Pathname Expansion below). When a match is found, the corresponding \fIlist\fP is executed. After the first match, no subsequent matches are attempted. The exit status is zero if no pattern matches. Otherwise, it is the exit status of the last command executed in \fIlist\fP. .TP \fBif\fP \fIlist\fP; \fBthen\fP \fIlist;\fP \ [ \fBelif\fP \fIlist\fP; \fBthen\fP \fIlist\fP; ] ... \ [ \fBelse\fP \fIlist\fP; ] \fBfi\fP The .B if .I list is executed. If its exit status is zero, the \fBthen\fP \fIlist\fP is executed. Otherwise, each \fBelif\fP \fIlist\fP is executed in turn, and if its exit status is zero, the corresponding \fBthen\fP \fIlist\fP is executed and the command completes. Otherwise, the \fBelse\fP \fIlist\fP is executed, if present. The exit status is the exit status of the last command executed, or zero if no condition tested true. .TP .PD 0 \fBwhile\fP \fIlist\fP; \fBdo\fP \fIlist\fP; \fBdone\fP .TP \fBuntil\fP \fIlist\fP; \fBdo\fP \fIlist\fP; \fBdone\fP .PD The \fBwhile\fP command continuously executes the \fBdo\fP \fIlist\fP as long as the last command in \fIlist\fP returns an exit status of zero. The \fBuntil\fP command is identical to the \fBwhile\fP command, except that the test is negated; the .B do .I list is executed as long as the last command in .I list returns a non-zero exit status. The exit status of the \fBwhile\fP and \fBuntil\fP commands is the exit status of the last \fBdo\fP \fIlist\fP command executed, or zero if none was executed. .TP [ \fBfunction\fP ] \fIname\fP () { \fIlist\fP; } This defines a function named \fIname\fP. The \fIbody\fP of the function is the .I list of commands between { and }. This list is executed whenever \fIname\fP is specified as the name of a simple command. The exit status of a function is the exit status of the last command executed in the body. (See .SM .B FUNCTIONS below.) .SH COMMENTS In a non-interactive shell, or an interactive shell in which the .B interactive_comments option to the .B shopt builtin is enabled (see .SM .B "SHELL BUILTIN COMMANDS" below), a word beginning with .B # causes that word and all remaining characters on that line to be ignored. An interactive shell without the .B interactive_comments option enabled does not allow comments. The .B interactive_comments option is on by default in interactive shells. .SH QUOTING \fIQuoting\fP is used to remove the special meaning of certain characters or words to the shell. Quoting can be used to disable special treatment for special characters, to prevent reserved words from being recognized as such, and to prevent parameter expansion. .PP Each of the \fImetacharacters\fP listed above under .SM .B DEFINITIONS has special meaning to the shell and must be quoted if it is to represent itself. .PP When the command history expansion facilities are being used, the \fIhistory expansion\fP character, usually \fB!\fP, must be quoted to prevent history expansion. .PP There are three quoting mechanisms: the .IR "escape character" , single quotes, and double quotes. .PP A non-quoted backslash (\fB\e\fP) is the .IR "escape character" . It preserves the literal value of the next character that follows, with the exception of . If a \fB\e\fP pair appears, and the backslash is not itself quoted, the \fB\e\fP is treated as a line continuation (that is, it is removed from the input stream and effectively ignored). .PP Enclosing characters in single quotes preserves the literal value of each character within the quotes. A single quote may not occur between single quotes, even when preceded by a backslash. .PP Enclosing characters in double quotes preserves the literal value of all characters within the quotes, with the exception of .BR $ , .BR ` , and .BR \e . The characters .B $ and .B ` retain their special meaning within double quotes. The backslash retains its special meaning only when followed by one of the following characters: .BR $ , .BR ` , \^\fB"\fP\^, .BR \e , or .BR . A double quote may be quoted within double quotes by preceding it with a backslash. .PP The special parameters .B * and .B @ have special meaning when in double quotes (see .SM .B PARAMETERS below). .PP Words of the form \fB$\fP'\fIstring\fP' are treated specially. The word expands to \fIstring\fP, with backslash-escaped characters replaced as specifed by the ANSI C standard. Backslash escape sequences, if present, are decoded as follows: .RS .PD 0 .TP .B \ea alert (bell) .TP .B \eb backspace .TP .B \ee an escape character .TP .B \ef form feed .TP .B \en new line .TP .B \er carriage return .TP .B \et horizontal tab .TP .B \ev vertical tab .TP .B \e\e backslash .TP .B \e' single quote .TP .B \e\fInnn\fP the eight-bit character whose value is the octal value \fInnn\fP (one to three digits) .TP .B \ex\fIHH\fP the eight-bit character whose value is the hexadecimal value \fIHH\fP (one or two hex digits) .PD .RE .LP The expanded result is single-quoted, as if the dollar sign had not been present. .PP A double-quoted string preceded by a dollar sign (\fB$\fP) will cause the string to be translated according to the current locale. If the current locale is \fBC\fP or \fBPOSIX\fP, the dollar sign is ignored. If the string is translated and replaced, the replacement is double-quoted. .SH PARAMETERS A .I parameter is an entity that stores values. It can be a .IR name , a number, or one of the special characters listed below under .BR "Special Parameters" . For the shell's purposes, a .I variable is a parameter denoted by a .IR name . A variable has a \fIvalue\fP and zero or more \fIattributes\fP. Attributes are assigned using the .B declare builtin command (see .B declare below in .SM .BR "SHELL BUILTIN COMMANDS" ). .PP A parameter is set if it has been assigned a value. The null string is a valid value. Once a variable is set, it may be unset only by using the .B unset builtin command (see .SM .B SHELL BUILTIN COMMANDS below). .PP A .I variable may be assigned to by a statement of the form .RS .PP \fIname\fP=[\fIvalue\fP] .RE .PP If .I value is not given, the variable is assigned the null string. All .I values undergo tilde expansion, parameter and variable expansion, command substitution, arithmetic expansion, and quote removal (see .SM .B EXPANSION below). If the variable has its .B integer attribute set, then .I value is subject to arithmetic expansion even if the $((...)) expansion is not used (see .B "Arithmetic Expansion" below). Word splitting is not performed, with the exception of \fB"$@"\fP as explained below under .BR "Special Parameters" . Pathname expansion is not performed. Assignment statements may also appear as arguments to the .BR declare , .BR typeset , .BR export , .BR readonly , and .B local builtin commands. .SS Positional Parameters .PP A .I positional parameter is a parameter denoted by one or more digits, other than the single digit 0. Positional parameters are assigned from the shell's arguments when it is invoked, and may be reassigned using the .B set builtin command. Positional parameters may not be assigned to with assignment statements. The positional parameters are temporarily replaced when a shell function is executed (see .SM .B FUNCTIONS below). .PP When a positional parameter consisting of more than a single digit is expanded, it must be enclosed in braces (see .SM .B EXPANSION below). .SS Special Parameters .PP The shell treats several parameters specially. These parameters may only be referenced; assignment to them is not allowed. .PD 0 .TP .B * Expands to the positional parameters, starting from one. When the expansion occurs within double quotes, it expands to a single word with the value of each parameter separated by the first character of the .SM .B IFS special variable. That is, "\fB$*\fP" is equivalent to "\fB$1\fP\fIc\fP\fB$2\fP\fIc\fP\fB...\fP", where .I c is the first character of the value of the .SM .B IFS variable. If .SM .B IFS is unset, the parameters are separated by spaces. If .SM .B IFS is null, the parameters are joined without intervening separators. .TP .B @ Expands to the positional parameters, starting from one. When the expansion occurs within double quotes, each parameter expands to a separate word. That is, "\fB$@\fP" is equivalent to "\fB$1\fP" "\fB$2\fP" ... When there are no positional parameters, "\fB$@\fP" and .B $@ expand to nothing (i.e., they are removed). .TP .B # Expands to the number of positional parameters in decimal. .TP .B ? Expands to the status of the most recently executed foreground pipeline. .TP .B \- Expands to the current option flags as specified upon invocation, by the .B set builtin command, or those set by the shell itself (such as the .B \-i option). .TP .B $ Expands to the process ID of the shell. In a () subshell, it expands to the process ID of the current shell, not the subshell. .TP .B ! Expands to the process ID of the most recently executed background (asynchronous) command. .TP .B 0 Expands to the name of the shell or shell script. This is set at shell initialization. If .B bash is invoked with a file of commands, .B $0 is set to the name of that file. If .B bash is started with the .B \-c option, then .B $0 is set to the first argument after the string to be executed, if one is present. Otherwise, it is set to the file name used to invoke .BR bash , as given by argument zero. .TP .B _ At shell startup, set to the absolute file name of the shell or shell script being executed as passed in the argument list. Subsequently, expands to the last argument to the previous command, after expansion. Also set to the full file name of each command executed and placed in the environment exported to that command. When checking mail, this parameter holds the name of the mail file currently being checked. .PD .SS Shell Variables .PP The following variables are set by the shell: .PP .PD 0 .TP .B BASH Expands to the full file name used to invoke this instance of .BR bash . .TP .B BASH_VERSINFO A readonly array variable whose members hold version information for this instance of .BR bash . The values assigned to the array members are as follows: .sp .5 .RS .PD 0 .TP 24 .B BASH_VERSINFO[\fR0\fP] The major version number (the \fIrelease\fP). .TP .B BASH_VERSINFO[\fR1\fP] The minor version number (the \fIversion\fP). .TP .B BASH_VERSINFO[\fR2\fP] The patch level. .TP .B BASH_VERSINFO[\fR3\fP] The build version. .TP .B BASH_VERSINFO[\fR4\fP] The release status (e.g., \fIbeta1\fP). .TP .B BASH_VERSINFO[\fR5\fP] The value of \fBMACHTYPE\fP. .PD .RE .TP .B BASH_VERSION Expands to a string describing the version of this instance of .BR bash . .TP .B COMP_CWORD An index into \fB${COMP_WORDS}\fP of the word containing the current cursor position. This variable is available only in shell functions invoked by the programmable completion facilities (see \fBProgrammable Completion\fP below). .TP .B COMP_LINE The current command line. This variable is available only in shell functions and external commands invoked by the programmable completion facilities (see \fBProgrammable Completion\fP below). .TP .B COMP_POINT The index of the current cursor position relative to the beginning of the current command. If the current cursor position is at the end of the current command, the value of this variable is equal to \fB${#COMP_LINE}\fP. This variable is available only in shell functions and external commands invoked by the programmable completion facilities (see \fBProgrammable Completion\fP below). .TP .B COMP_WORDS An array variable (see \fBArrays\fP below) consisting of the individual words in the current command line. This variable is available only in shell functions invoked by the programmable completion facilities (see \fBProgrammable Completion\fP below). .TP .B DIRSTACK An array variable (see .B Arrays below) containing the current contents of the directory stack. Directories appear in the stack in the order they are displayed by the .B dirs builtin. Assigning to members of this array variable may be used to modify directories already in the stack, but the .B pushd and .B popd builtins must be used to add and remove directories. Assignment to this variable will not change the current directory. If .SM .B DIRSTACK is unset, it loses its special properties, even if it is subsequently reset. .TP .B EUID Expands to the effective user ID of the current user, initialized at shell startup. This variable is readonly. .TP .B FUNCNAME The name of any currently-executing shell function. This variable exists only when a shell function is executing. Assignments to .SM .B FUNCNAME have no effect and return an error status. If .SM .B FUNCNAME is unset, it loses its special properties, even if it is subsequently reset. .TP .B GROUPS An array variable containing the list of groups of which the current user is a member. Assignments to .SM .B GROUPS have no effect and return an error status. If .SM .B GROUPS is unset, it loses its special properties, even if it is subsequently reset. .TP .B HISTCMD The history number, or index in the history list, of the current command. If .SM .B HISTCMD is unset, it loses its special properties, even if it is subsequently reset. .TP .B HOSTNAME Automatically set to the name of the current host. .TP .B HOSTTYPE Automatically set to a string that uniquely describes the type of machine on which .B bash is executing. The default is system-dependent. .TP .B LINENO Each time this parameter is referenced, the shell substitutes a decimal number representing the current sequential line number (starting with 1) within a script or function. When not in a script or function, the value substituted is not guaranteed to be meaningful. If .SM .B LINENO is unset, it loses its special properties, even if it is subsequently reset. .TP .B MACHTYPE Automatically set to a string that fully describes the system type on which .B bash is executing, in the standard GNU \fIcpu-company-system\fP format. The default is system-dependent. .TP .B OLDPWD The previous working directory as set by the .B cd command. .TP .B OPTARG The value of the last option argument processed by the .B getopts builtin command (see .SM .B SHELL BUILTIN COMMANDS below). .TP .B OPTIND The index of the next argument to be processed by the .B getopts builtin command (see .SM .B SHELL BUILTIN COMMANDS below). .TP .B OSTYPE Automatically set to a string that describes the operating system on which .B bash is executing. The default is system-dependent. .TP .B PIPESTATUS An array variable (see .B Arrays below) containing a list of exit status values from the processes in the most-recently-executed foreground pipeline (which may contain only a single command). .TP .B PPID The process ID of the shell's parent. This variable is readonly. .TP .B PWD The current working directory as set by the .B cd command. .TP .B RANDOM Each time this parameter is referenced, a random integer between 0 and 32767 is generated. The sequence of random numbers may be initialized by assigning a value to .SM .BR RANDOM . If .SM .B RANDOM is unset, it loses its special properties, even if it is subsequently reset. .TP .B REPLY Set to the line of input read by the .B read builtin command when no arguments are supplied. .TP .B SECONDS Each time this parameter is referenced, the number of seconds since shell invocation is returned. If a value is assigned to .SM .BR SECONDS , the value returned upon subsequent references is the number of seconds since the assignment plus the value assigned. If .SM .B SECONDS is unset, it loses its special properties, even if it is subsequently reset. .TP .B SHELLOPTS A colon-separated list of enabled shell options. Each word in the list is a valid argument for the .B \-o option to the .B set builtin command (see .SM .B "SHELL BUILTIN COMMANDS" below). The options appearing in .SM .B SHELLOPTS are those reported as .I on by \fBset \-o\fP. If this variable is in the environment when .B bash starts up, each shell option in the list will be enabled before reading any startup files. This variable is read-only. .TP .B SHLVL Incremented by one each time an instance of .B bash is started. .TP .B UID Expands to the user ID of the current user, initialized at shell startup. This variable is readonly. .PD .PP The following variables are used by the shell. In some cases, .B bash assigns a default value to a variable; these cases are noted below. .PP .PD 0 .TP .B BASH_ENV If this parameter is set when \fBbash\fP is executing a shell script, its value is interpreted as a filename containing commands to initialize the shell, as in .IR ~/.bashrc . The value of .SM .B BASH_ENV is subjected to parameter expansion, command substitution, and arithmetic expansion before being interpreted as a file name. .SM .B PATH is not used to search for the resultant file name. .TP .B CDPATH The search path for the .B cd command. This is a colon-separated list of directories in which the shell looks for destination directories specified by the .B cd command. A sample value is ``.:~:/usr''. .TP .B COLUMNS Used by the \fBselect\fP builtin command to determine the terminal width when printing selection lists. Automatically set upon receipt of a SIGWINCH. .TP .B COMPREPLY An array variable from which \fBbash\fP reads the possible completions generated by a shell function invoked by the programmable completion facility (see \fBProgrammable Completion\fP below). .TP .B FCEDIT The default editor for the .B fc builtin command. .TP .B FIGNORE A colon-separated list of suffixes to ignore when performing filename completion (see .SM .B READLINE below). A filename whose suffix matches one of the entries in .SM .B FIGNORE is excluded from the list of matched filenames. A sample value is ``.o:~''. .TP .B GLOBIGNORE A colon-separated list of patterns defining the set of filenames to be ignored by pathname expansion. If a filename matched by a pathname expansion pattern also matches one of the patterns in .SM .BR GLOBIGNORE , it is removed from the list of matches. .TP .B HISTCONTROL If set to a value of .IR ignorespace , lines which begin with a .B space character are not entered on the history list. If set to a value of .IR ignoredups , lines matching the last history line are not entered. A value of .I ignoreboth combines the two options. If unset, or if set to any other value than those above, all lines read by the parser are saved on the history list, subject to the value of .BR HISTIGNORE . This variable's function is superseded by .BR HISTIGNORE . The second and subsequent lines of a multi-line compound command are not tested, and are added to the history regardless of the value of .BR HISTCONTROL . .TP .B HISTFILE The name of the file in which command history is saved (see .SM .B HISTORY below). The default value is \fI~/.bash_history\fP. If unset, the command history is not saved when an interactive shell exits. .TP .B HISTFILESIZE The maximum number of lines contained in the history file. When this variable is assigned a value, the history file is truncated, if necessary, to contain no more than that number of lines. The default value is 500. The history file is also truncated to this size after writing it when an interactive shell exits. .TP .B HISTIGNORE A colon-separated list of patterns used to decide which command lines should be saved on the history list. Each pattern is anchored at the beginning of the line and must match the complete line (no implicit `\fB*\fP' is appended). Each pattern is tested against the line after the checks specified by .B HISTCONTROL are applied. In addition to the normal shell pattern matching characters, `\fB&\fP' matches the previous history line. `\fB&\fP' may be escaped using a backslash; the backslash is removed before attempting a match. The second and subsequent lines of a multi-line compound command are not tested, and are added to the history regardless of the value of .BR HISTIGNORE . .TP .B HISTSIZE The number of commands to remember in the command history (see .SM .B HISTORY below). The default value is 500. .TP .B HOME The home directory of the current user; the default argument for the \fBcd\fP builtin command. The value of this variable is also used when performing tilde expansion. .TP .B HOSTFILE Contains the name of a file in the same format as .FN /etc/hosts that should be read when the shell needs to complete a hostname. The list of possible hostname completions may be changed while the shell is running; the next time hostname completion is attempted after the value is changed, .B bash adds the contents of the new file to the existing list. If .SM .B HOSTFILE is set, but has no value, \fBbash\fP attempts to read .FN /etc/hosts to obtain the list of possible hostname completions. When .SM .B HOSTFILE is unset, the hostname list is cleared. .TP .B IFS The .I Internal Field Separator that is used for word splitting after expansion and to split lines into words with the .B read builtin command. The default value is ``''. .TP .B IGNOREEOF Controls the action of an interactive shell on receipt of an .SM .B EOF character as the sole input. If set, the value is the number of consecutive .SM .B EOF characters which must be typed as the first characters on an input line before .B bash exits. If the variable exists but does not have a numeric value, or has no value, the default value is 10. If it does not exist, .SM .B EOF signifies the end of input to the shell. .TP .B INPUTRC The filename for the .B readline startup file, overriding the default of .FN ~/.inputrc (see .SM .B READLINE below). .TP .B LANG Used to determine the locale category for any category not specifically selected with a variable starting with \fBLC_\fP. .TP .B LC_ALL This variable overrides the value of \fBLANG\fP and any other \fBLC_\fP variable specifying a locale category. .TP .B LC_COLLATE This variable determines the collation order used when sorting the results of pathname expansion, and determines the behavior of range expressions, equivalence classes, and collating sequences within pathname expansion and pattern matching. .TP .B LC_CTYPE This variable determines the interpretation of characters and the behavior of character classes within pathname expansion and pattern matching. .TP .B LC_MESSAGES This variable determines the locale used to translate double-quoted strings preceded by a \fB$\fP. .TP .B LC_NUMERIC This variable determines the locale category used for number formatting. .TP .B LINES Used by the \fBselect\fP builtin command to determine the column length for printing selection lists. Automatically set upon receipt of a SIGWINCH. .TP .B MAIL If this parameter is set to a file name and the .SM .B MAILPATH variable is not set, .B bash informs the user of the arrival of mail in the specified file. .TP .B MAILCHECK Specifies how often (in seconds) .B bash checks for mail. The default is 60 seconds. When it is time to check for mail, the shell does so before displaying the primary prompt. If this variable is unset, or set to a value that is not a number greater than or equal to zero, the shell disables mail checking. .TP .B MAILPATH A colon-separated list of file names to be checked for mail. The message to be printed when mail arrives in a particular file may be specified by separating the file name from the message with a `?'. When used in the text of the message, \fB$_\fP expands to the name of the current mailfile. Example: .RS .PP \fBMAILPATH\fP='/var/mail/bfox?"You have mail":~/shell\-mail?"$_ has mail!"' .PP .B Bash supplies a default value for this variable, but the location of the user mail files that it uses is system dependent (e.g., /var/mail/\fB$USER\fP). .RE .TP .B OPTERR If set to the value 1, .B bash displays error messages generated by the .B getopts builtin command (see .SM .B SHELL BUILTIN COMMANDS below). .SM .B OPTERR is initialized to 1 each time the shell is invoked or a shell script is executed. .TP .B PATH The search path for commands. It is a colon-separated list of directories in which the shell looks for commands (see .SM .B COMMAND EXECUTION below). The default path is system-dependent, and is set by the administrator who installs .BR bash . A common value is .if t \f(CW/usr/gnu/bin:/usr/local/bin:/usr/ucb:/bin:/usr/bin:.\fP. .if n ``/usr/gnu/bin:/usr/local/bin:/usr/ucb:/bin:/usr/bin:.''. .TP .B POSIXLY_CORRECT If this variable is in the environment when \fBbash\fP starts, the shell enters \fIposix mode\fP before reading the startup files, as if the .B \-\-posix invocation option had been supplied. If it is set while the shell is running, \fBbash\fP enables \fIposix mode\fP, as if the command .if t \f(CWset -o posix\fP .if n \fIset -o posix\fP had been executed. .TP .B PROMPT_COMMAND If set, the value is executed as a command prior to issuing each primary prompt. .TP .B PS1 The value of this parameter is expanded (see .SM .B PROMPTING below) and used as the primary prompt string. The default value is ``\fB\es\-\ev\e$ \fP''. .TP .B PS2 The value of this parameter is expanded as with .B PS1 and used as the secondary prompt string. The default is ``\fB> \fP''. .TP .B PS3 The value of this parameter is used as the prompt for the .B select command (see .SM .B SHELL GRAMMAR above). .TP .B PS4 The value of this parameter is expanded as with .B PS1 and the value is printed before each command .B bash displays during an execution trace. The first character of .SM .B PS4 is replicated multiple times, as necessary, to indicate multiple levels of indirection. The default is ``\fB+ \fP''. .TP .B TIMEFORMAT The value of this parameter is used as a format string specifying how the timing information for pipelines prefixed with the .B time reserved word should be displayed. The \fB%\fP character introduces an escape sequence that is expanded to a time value or other information. The escape sequences and their meanings are as follows; the braces denote optional portions. .sp .5 .RS .PD 0 .TP 10 .B %% A literal \fB%\fP. .TP .B %[\fIp\fP][l]R The elapsed time in seconds. .TP .B %[\fIp\fP][l]U The number of CPU seconds spent in user mode. .TP .B %[\fIp\fP][l]S The number of CPU seconds spent in system mode. .TP .B %P The CPU percentage, computed as (%U + %S) / %R. .PD .RE .IP The optional \fIp\fP is a digit specifying the \fIprecision\fP, the number of fractional digits after a decimal point. A value of 0 causes no decimal point or fraction to be output. At most three places after the decimal point may be specified; values of \fIp\fP greater than 3 are changed to 3. If \fIp\fP is not specified, the value 3 is used. .IP The optional \fBl\fP specifies a longer format, including minutes, of the form \fIMM\fPm\fISS\fP.\fIFF\fPs. The value of \fIp\fP determines whether or not the fraction is included. .IP If this variable is not set, \fBbash\fP acts as if it had the value \fB$'\enreal\et%3lR\enuser\et%3lU\ensys\t%3lS'\fP. If the value is null, no timing information is displayed. A trailing newline is added when the format string is displayed. .TP .B TMOUT If set to a value greater than zero, the value is interpreted as the number of seconds to wait for input after issuing the primary prompt. .B Bash terminates after waiting for that number of seconds if input does not arrive. .TP .B auto_resume This variable controls how the shell interacts with the user and job control. If this variable is set, single word simple commands without redirections are treated as candidates for resumption of an existing stopped job. There is no ambiguity allowed; if there is more than one job beginning with the string typed, the job most recently accessed is selected. The .I name of a stopped job, in this context, is the command line used to start it. If set to the value .IR exact , the string supplied must match the name of a stopped job exactly; if set to .IR substring , the string supplied needs to match a substring of the name of a stopped job. The .I substring value provides functionality analogous to the .B %? job identifier (see .SM .B JOB CONTROL below). If set to any other value, the supplied string must be a prefix of a stopped job's name; this provides functionality analogous to the .B % job identifier. .TP .B histchars The two or three characters which control history expansion and tokenization (see .SM .B HISTORY EXPANSION below). The first character is the \fIhistory expansion\fP character, the character which signals the start of a history expansion, normally `\fB!\fP'. The second character is the \fIquick substitution\fP character, which is used as shorthand for re-running the previous command entered, substituting one string for another in the command. The default is `\fB^\fP'. The optional third character is the character which indicates that the remainder of the line is a comment when found as the first character of a word, normally `\fB#\fP'. The history comment character causes history substitution to be skipped for the remaining words on the line. It does not necessarily cause the shell parser to treat the rest of the line as a comment. .PD .SS Arrays .B Bash provides one-dimensional array variables. Any variable may be used as an array; the .B declare builtin will explicitly declare an array. There is no maximum limit on the size of an array, nor any requirement that members be indexed or assigned contiguously. Arrays are indexed using integers and are zero-based. .PP An array is created automatically if any variable is assigned to using the syntax \fIname\fP[\fIsubscript\fP]=\fIvalue\fP. The .I subscript is treated as an arithmetic expression that must evaluate to a number greater than or equal to zero. To explicitly declare an array, use .B declare \-a \fIname\fP (see .SM .B SHELL BUILTIN COMMANDS below). .B declare \-a \fIname\fP[\fIsubscript\fP] is also accepted; the \fIsubscript\fP is ignored. Attributes may be specified for an array variable using the .B declare and .B readonly builtins. Each attribute applies to all members of an array. .PP Arrays are assigned to using compound assignments of the form \fIname\fP=\fB(\fPvalue\fI1\fP ... value\fIn\fP\fB)\fP, where each \fIvalue\fP is of the form [\fIsubscript\fP]=\fIstring\fP. Only \fIstring\fP is required. If the optional brackets and subscript are supplied, that index is assigned to; otherwise the index of the element assigned is the last index assigned to by the statement plus one. Indexing starts at zero. This syntax is also accepted by the .B declare builtin. Individual array elements may be assigned to using the \fIname\fP[\fIsubscript\fP]=\fIvalue\fP syntax introduced above. .PP Any element of an array may be referenced using ${\fIname\fP[\fIsubscript\fP]}. The braces are required to avoid conflicts with pathname expansion. If \fIsubscript\fP is \fB@\fP or \fB*\fP, the word expands to all members of \fIname\fP. These subscripts differ only when the word appears within double quotes. If the word is double-quoted, ${\fIname\fP[*]} expands to a single word with the value of each array member separated by the first character of the .SM .B IFS special variable, and ${\fIname\fP[@]} expands each element of \fIname\fP to a separate word. When there are no array members, ${\fIname\fP[@]} expands to nothing. This is analogous to the expansion of the special parameters \fB*\fP and \fB@\fP (see .B Special Parameters above). ${#\fIname\fP[\fIsubscript\fP]} expands to the length of ${\fIname\fP[\fIsubscript\fP]}. If \fIsubscript\fP is \fB*\fP or \fB@\fP, the expansion is the number of elements in the array. Referencing an array variable without a subscript is equivalent to referencing element zero. .PP The .B unset builtin is used to destroy arrays. \fBunset\fP \fIname\fP[\fIsubscript\fP] destroys the array element at index \fIsubscript\fP. \fBunset\fP \fIname\fP, where \fIname\fP is an array, or \fBunset\fP \fIname\fP[\fIsubscript\fP], where \fIsubscript\fP is \fB*\fP or \fB@\fP, removes the entire array. .PP The .BR declare , .BR local , and .B readonly builtins each accept a .B \-a option to specify an array. The .B read builtin accepts a .B \-a option to assign a list of words read from the standard input to an array. The .B set and .B declare builtins display array values in a way that allows them to be reused as assignments. .SH EXPANSION Expansion is performed on the command line after it has been split into words. There are seven kinds of expansion performed: .IR "brace expansion" , .IR "tilde expansion" , .IR "parameter and variable expansion" , .IR "command substitution" , .IR "arithmetic expansion" , .IR "word splitting" , and .IR "pathname expansion" . .PP The order of expansions is: brace expansion, tilde expansion, parameter, variable and arithmetic expansion and command substitution (done in a left-to-right fashion), word splitting, and pathname expansion. .PP On systems that can support it, there is an additional expansion available: \fIprocess substitution\fP. .PP Only brace expansion, word splitting, and pathname expansion can change the number of words of the expansion; other expansions expand a single word to a single word. The only exceptions to this are the expansions of "\fB$@\fP" and "\fB${\fP\fIname\fP\fB[@]}\fP" as explained above (see .SM .BR PARAMETERS ). .SS Brace Expansion .PP .I "Brace expansion" is a mechanism by which arbitrary strings may be generated. This mechanism is similar to \fIpathname expansion\fP, but the filenames generated need not exist. Patterns to be brace expanded take the form of an optional .IR preamble , followed by a series of comma-separated strings between a pair of braces, followed by an optional .IR postscript . The preamble is prefixed to each string contained within the braces, and the postscript is then appended to each resulting string, expanding left to right. .PP Brace expansions may be nested. The results of each expanded string are not sorted; left to right order is preserved. For example, a\fB{\fPd,c,b\fB}\fPe expands into `ade ace abe'. .PP Brace expansion is performed before any other expansions, and any characters special to other expansions are preserved in the result. It is strictly textual. .B Bash does not apply any syntactic interpretation to the context of the expansion or the text between the braces. .PP A correctly-formed brace expansion must contain unquoted opening and closing braces, and at least one unquoted comma. Any incorrectly formed brace expansion is left unchanged. A \fB{\fP or \fB,\fP may be quoted with a backslash to prevent its being considered part of a brace expression. To avoid conflicts with parameter expansion, the string \fB${\fP is not considered eligible for brace expansion. .PP This construct is typically used as shorthand when the common prefix of the strings to be generated is longer than in the above example: .RS .PP mkdir /usr/local/src/bash/{old,new,dist,bugs} .RE or .RS chown root /usr/{ucb/{ex,edit},lib/{ex?.?*,how_ex}} .RE .PP Brace expansion introduces a slight incompatibility with historical versions of .BR sh . .B sh does not treat opening or closing braces specially when they appear as part of a word, and preserves them in the output. .B Bash removes braces from words as a consequence of brace expansion. For example, a word entered to .B sh as \fIfile{1,2}\fP appears identically in the output. The same word is output as .I file1 file2 after expansion by .BR bash . If strict compatibility with .B sh is desired, start .B bash with the .B +B option or disable brace expansion with the .B +B option to the .B set command (see .SM .B SHELL BUILTIN COMMANDS below). .SS Tilde Expansion .PP If a word begins with an unquoted tilde character (`\fB~\fP'), all of the characters preceding the first unquoted slash (or all characters, if there is no unquoted slash) are considered a \fItilde-prefix\fP. If none of the characters in the tilde-prefix are quoted, the characters in the tilde-prefix following the tilde are treated as a possible \fIlogin name\fP. If this login name is the null string, the tilde is replaced with the value of the shell parameter .SM .BR HOME . If .SM .B HOME is unset, the home directory of the user executing the shell is substituted instead. Otherwise, the tilde-prefix is replaced with the home directory associated with the specified login name. .PP If the tilde-prefix is a `~+', the value of the shell variable .SM .B PWD replaces the tilde-prefix. If the tilde-prefix is a `~\-', the value of the shell variable .SM .BR OLDPWD , if it is set, is substituted. If the characters following the tilde in the tilde-prefix consist of a number \fIN\fP, optionally prefixed by a `+' or a `\-', the tilde-prefix is replaced with the corresponding element from the directory stack, as it would be displayed by the .B dirs builtin invoked with the tilde-prefix as an argument. If the characters following the tilde in the tilde-prefix consist of a number without a leading `+' or `\-', `+' is assumed. .PP If the login name is invalid, or the tilde expansion fails, the word is unchanged. .PP Each variable assignment is checked for unquoted tilde-prefixes immediately following a .B : or .BR = . In these cases, tilde expansion is also performed. Consequently, one may use file names with tildes in assignments to .SM .BR PATH , .SM .BR MAILPATH , and .SM .BR CDPATH , and the shell assigns the expanded value. .SS Parameter Expansion .PP The `\fB$\fP' character introduces parameter expansion, command substitution, or arithmetic expansion. The parameter name or symbol to be expanded may be enclosed in braces, which are optional but serve to protect the variable to be expanded from characters immediately following it which could be interpreted as part of the name. .PP When braces are used, the matching ending brace is the first `\fB}\fP' not escaped by a backslash or within a quoted string, and not within an embedded arithmetic expansion, command substitution, or paramter expansion. .PP .PD 0 .TP ${\fIparameter\fP} The value of \fIparameter\fP is substituted. The braces are required when .I parameter is a positional parameter with more than one digit, or when .I parameter is followed by a character which is not to be interpreted as part of its name. .PD .PP If the first character of \fIparameter\fP is an exclamation point, a level of variable indirection is introduced. \fBBash\fP uses the value of the variable formed from the rest of \fIparameter\fP as the name of the variable; this variable is then expanded and that value is used in the rest of the substitution, rather than the value of \fIparameter\fP itself. This is known as \fIindirect expansion\fP. The exception to this is the expansion of ${!\fIprefix\fP*} described below. .PP In each of the cases below, \fIword\fP is subject to tilde expansion, parameter expansion, command substitution, and arithmetic expansion. When not performing substring expansion, \fBbash\fP tests for a parameter that is unset or null; omitting the colon results in a test only for a parameter that is unset. .PP .PD 0 .TP ${\fIparameter\fP\fB:\-\fP\fIword\fP} \fBUse Default Values\fP. If .I parameter is unset or null, the expansion of .I word is substituted. Otherwise, the value of .I parameter is substituted. .TP ${\fIparameter\fP\fB:=\fP\fIword\fP} \fBAssign Default Values\fP. If .I parameter is unset or null, the expansion of .I word is assigned to .IR parameter . The value of .I parameter is then substituted. Positional parameters and special parameters may not be assigned to in this way. .TP ${\fIparameter\fP\fB:?\fP\fIword\fP} \fBDisplay Error if Null or Unset\fP. If .I parameter is null or unset, the expansion of \fIword\fP (or a message to that effect if .I word is not present) is written to the standard error and the shell, if it is not interactive, exits. Otherwise, the value of \fIparameter\fP is substituted. .TP ${\fIparameter\fP\fB:+\fP\fIword\fP} \fBUse Alternate Value\fP. If .I parameter is null or unset, nothing is substituted, otherwise the expansion of .I word is substituted. .TP .PD 0 ${\fIparameter\fP\fB:\fP\fIoffset\fP} .TP ${\fIparameter\fP\fB:\fP\fIoffset\fP\fB:\fP\fIlength\fP} .PD \fBSubstring Expansion.\fP Expands to up to \fIlength\fP characters of \fIparameter\fP starting at the character specified by \fIoffset\fP. If \fIlength\fP is omitted, expands to the substring of \fIparameter\fP starting at the character specified by \fIoffset\fP. \fIlength\fP and \fIoffset\fP are arithmetic expressions (see .SM .B ARITHMETIC EVALUATION below). \fIlength\fP must evaluate to a number greater than or equal to zero. If \fIoffset\fP evaluates to a number less than zero, the value is used as an offset from the end of the value of \fIparameter\fP. If \fIparameter\fP is \fB@\fP, the result is \fIlength\fP positional parameters beginning at \fIoffset\fP. If \fIparameter\fP is an array name indexed by @ or *, the result is the \fIlength\fP members of the array beginning with ${\fIparameter\fP[\fIoffset\fP]}. Substring indexing is zero-based unless the positional parameters are used, in which case the indexing starts at 1. .TP ${\fB!\fP\fIprefix\fP\fB*\fP} Expands to the names of variables whose names begin with \fIprefix\fP, separated by the first character of the .SM .B IFS special variable. .TP ${\fB#\fP\fIparameter\fP} The length in characters of the value of \fIparameter\fP is substituted. If .I parameter is .B * or .BR @ , the value substituted is the number of positional parameters. If .I parameter is an array name subscripted by .B * or .BR @ , the value substituted is the number of elements in the array. .TP .PD 0 ${\fIparameter\fP\fB#\fP\fIword\fP} .TP ${\fIparameter\fP\fB##\fP\fIword\fP} .PD The .I word is expanded to produce a pattern just as in pathname expansion. If the pattern matches the beginning of the value of .IR parameter , then the result of the expansion is the expanded value of .I parameter with the shortest matching pattern (the ``\fB#\fP'' case) or the longest matching pattern (the ``\fB##\fP'' case) deleted. If .I parameter is .B @ or .BR * , the pattern removal operation is applied to each positional parameter in turn, and the expansion is the resultant list. If .I parameter is an array variable subscripted with .B @ or .BR * , the pattern removal operation is applied to each member of the array in turn, and the expansion is the resultant list. .TP .PD 0 ${\fIparameter\fP\fB%\fP\fIword\fP} .TP ${\fIparameter\fP\fB%%\fP\fIword\fP} .PD The \fIword\fP is expanded to produce a pattern just as in pathname expansion. If the pattern matches a trailing portion of the expanded value of .IR parameter , then the result of the expansion is the expanded value of .I parameter with the shortest matching pattern (the ``\fB%\fP'' case) or the longest matching pattern (the ``\fB%%\fP'' case) deleted. If .I parameter is .B @ or .BR * , the pattern removal operation is applied to each positional parameter in turn, and the expansion is the resultant list. If .I parameter is an array variable subscripted with .B @ or .BR * , the pattern removal operation is applied to each member of the array in turn, and the expansion is the resultant list. .TP .PD 0 ${\fIparameter\fP\fB/\fP\fIpattern\fP\fB/\fP\fIstring\fP} .TP ${\fIparameter\fP\fB//\fP\fIpattern\fP\fB/\fP\fIstring\fP} .PD The \fIpattern\fP is expanded to produce a pattern just as in pathname expansion. \fIParameter\fP is expanded and the longest match of \fIpattern\fP against its value is replaced with \fIstring\fP. In the first form, only the first match is replaced. The second form causes all matches of \fIpattern\fP to be replaced with \fIstring\fP. If \fIpattern\fP begins with \fB#\fP, it must match at the beginning of the expanded value of \fIparameter\fP. If \fIpattern\fP begins with \fB%\fP, it must match at the end of the expanded value of \fIparameter\fP. If \fIstring\fP is null, matches of \fIpattern\fP are deleted and the \fB/\fP following \fIpattern\fP may be omitted. If .I parameter is .B @ or .BR * , the substitution operation is applied to each positional parameter in turn, and the expansion is the resultant list. If .I parameter is an array variable subscripted with .B @ or .BR * , the substitution operation is applied to each member of the array in turn, and the expansion is the resultant list. .SS Command Substitution .PP \fICommand substitution\fP allows the output of a command to replace the command name. There are two forms: .PP .RS .PP \fB$(\fP\fIcommand\fP\|\fB)\fP .RE or .RS \fB`\fP\fIcommand\fP\fB`\fP .RE .PP .B Bash performs the expansion by executing \fIcommand\fP and replacing the command substitution with the standard output of the command, with any trailing newlines deleted. Embedded newlines are not deleted, but they may be removed during word splitting. The command substitution \fB$(cat \fIfile\fP)\fR can be replaced by the equivalent but faster \fB$(< \fIfile\fP)\fR. .PP When the old-style backquote form of substitution is used, backslash retains its literal meaning except when followed by .BR $ , .BR ` , or .BR \e . The first backquote not preceded by a backslash terminates the command substitution. When using the $(\^\fIcommand\fP\|) form, all characters between the parentheses make up the command; none are treated specially. .PP Command substitutions may be nested. To nest when using the backquoted form, escape the inner backquotes with backslashes. .PP If the substitution appears within double quotes, word splitting and pathname expansion are not performed on the results. .SS Arithmetic Expansion .PP Arithmetic expansion allows the evaluation of an arithmetic expression and the substitution of the result. The format for arithmetic expansion is: .RS .PP \fB$((\fP\fIexpression\fP\fB))\fP .RE .PP The .I expression is treated as if it were within double quotes, but a double quote inside the parentheses is not treated specially. All tokens in the expression undergo parameter expansion, string expansion, command substitution, and quote removal. Arithmetic substitutions may be nested. .PP The evaluation is performed according to the rules listed below under .SM .BR "ARITHMETIC EVALUATION" . If .I expression is invalid, .B bash prints a message indicating failure and no substitution occurs. .SS Process Substitution .PP \fIProcess substitution\fP is supported on systems that support named pipes (\fIFIFOs\fP) or the \fB/dev/fd\fP method of naming open files. It takes the form of \fB<(\fP\fIlist\^\fP\fB)\fP or \fB>(\fP\fIlist\^\fP\fB)\fP. The process \fIlist\fP is run with its input or output connected to a \fIFIFO\fP or some file in \fB/dev/fd\fP. The name of this file is passed as an argument to the current command as the result of the expansion. If the \fB>(\fP\fIlist\^\fP\fB)\fP form is used, writing to the file will provide input for \fIlist\fP. If the \fB<(\fP\fIlist\^\fP\fB)\fP form is used, the file passed as an argument should be read to obtain the output of \fIlist\fP. .PP When available, process substitution is performed simultaneously with parameter and variable expansion, command substitution, and arithmetic expansion. .SS Word Splitting .PP The shell scans the results of parameter expansion, command substitution, and arithmetic expansion that did not occur within double quotes for .IR "word splitting" . .PP The shell treats each character of .SM .B IFS as a delimiter, and splits the results of the other expansions into words on these characters. If .SM .B IFS is unset, or its value is exactly .BR , the default, then any sequence of .SM .B IFS characters serves to delimit words. If .SM .B IFS has a value other than the default, then sequences of the whitespace characters .B space and .B tab are ignored at the beginning and end of the word, as long as the whitespace character is in the value of .SM .BR IFS (an .SM .B IFS whitespace character). Any character in .SM .B IFS that is not .SM .B IFS whitespace, along with any adjacent .SM .B IFS whitespace characters, delimits a field. A sequence of .SM .B IFS whitespace characters is also treated as a delimiter. If the value of .SM .B IFS is null, no word splitting occurs. .PP Explicit null arguments (\^\f3"\^"\fP or \^\f3'\^'\fP\^) are retained. Unquoted implicit null arguments, resulting from the expansion of parameters that have no values, are removed. If a parameter with no value is expanded within double quotes, a null argument results and is retained. .PP Note that if no expansion occurs, no splitting is performed. .SS Pathname Expansion .PP After word splitting, unless the .B \-f option has been set, .B bash scans each word for the characters .BR * , .BR ? , and .BR [ . If one of these characters appears, then the word is regarded as a .IR pattern , and replaced with an alphabetically sorted list of file names matching the pattern. If no matching file names are found, and the shell option .B nullglob is disabled, the word is left unchanged. If the .B nullglob option is set, and no matches are found, the word is removed. If the shell option .B nocaseglob is enabled, the match is performed without regard to the case of alphabetic characters. When a pattern is used for pathname expansion, the character .B ``.'' at the start of a name or immediately following a slash must be matched explicitly, unless the shell option .B dotglob is set. When matching a pathname, the slash character must always be matched explicitly. In other cases, the .B ``.'' character is not treated specially. See the description of .B shopt below under .SM .B SHELL BUILTIN COMMANDS for a description of the .BR nocaseglob , .BR nullglob , and .B dotglob shell options. .PP The .SM .B GLOBIGNORE shell variable may be used to restrict the set of file names matching a .IR pattern . If .SM .B GLOBIGNORE is set, each matching file name that also matches one of the patterns in .SM .B GLOBIGNORE is removed from the list of matches. The file names .B ``.'' and .B ``..'' are always ignored, even when .SM .B GLOBIGNORE is set. However, setting .SM .B GLOBIGNORE has the effect of enabling the .B dotglob shell option, so all other file names beginning with a .B ``.'' will match. To get the old behavior of ignoring file names beginning with a .BR ``.'' , make .B ``.*'' one of the patterns in .SM .BR GLOBIGNORE . The .B dotglob option is disabled when .SM .B GLOBIGNORE is unset. .PP \fBPattern Matching\fP .PP Any character that appears in a pattern, other than the special pattern characters described below, matches itself. The NUL character may not occur in a pattern. The special pattern characters must be quoted if they are to be matched literally. .PP The special pattern characters have the following meanings: .PP .PD 0 .TP .B * Matches any string, including the null string. .TP .B ? Matches any single character. .TP .B [...] Matches any one of the enclosed characters. A pair of characters separated by a hyphen denotes a \fIrange expression\fP; any character that sorts between those two characters, inclusive, using the current locale's collating sequence and character set, is matched. If the first character following the .B [ is a .B ! or a .B ^ then any character not enclosed is matched. The sorting order of characters in range expressions is determined by the current locale and the value of the \fBLC_COLLATE\fP shell variable, if set. A .B \- may be matched by including it as the first or last character in the set. A .B ] may be matched by including it as the first character in the set. .br .if t .sp 0.5 .if n .sp 1 Within .B [ and .BR ] , \fIcharacter classes\fP can be specified using the syntax \fB[:\fP\fIclass\fP\fB:]\fP, where \fIclass\fP is one of the following classes defined in the POSIX.2 standard: .PP .RS .B .if n alnum alpha ascii blank cntrl digit graph lower print punct space upper xdigit .if t alnum alpha ascii blank cntrl digit graph lower print punct space upper xdigit .br A character class matches any character belonging to that class. .br .if t .sp 0.5 .if n .sp 1 Within .B [ and .BR ] , an \fIequivalence class\fP can be specified using the syntax \fB[=\fP\fIc\fP\fB=]\fP, which matches all characters with the same collation weight (as defined by the current locale) as the character \fIc\fP. .br .if t .sp 0.5 .if n .sp 1 Within .B [ and .BR ] , the syntax \fB[.\fP\fIsymbol\fP\fB.]\fP matches the collating symbol \fIsymbol\fP. .RE .PD .PP If the \fBextglob\fP shell option is enabled using the \fBshopt\fP builtin, several extended pattern matching operators are recognized. In the following description, a \fIpattern-list\fP is a list of one or more patterns separated by a \fB|\fP. Composite patterns may be formed using one or more of the following sub-patterns: .sp 1 .PD 0 .RS .TP \fB?(\fP\^\fIpattern-list\^\fP\fB)\fP Matches zero or one occurrence of the given patterns .TP \fB*(\fP\^\fIpattern-list\^\fP\fB)\fP Matches zero or more occurrences of the given patterns .TP \fB+(\fP\^\fIpattern-list\^\fP\fB)\fP Matches one or more occurrences of the given patterns .TP \fB@(\fP\^\fIpattern-list\^\fP\fB)\fP Matches exactly one of the given patterns .TP \fB!(\fP\^\fIpattern-list\^\fP\fB)\fP Matches anything except one of the given patterns .RE .PD .SS Quote Removal .PP After the preceding expansions, all unquoted occurrences of the characters .BR \e , .BR ' , and \^\f3"\fP\^ that did not result from one of the above expansions are removed. .SH REDIRECTION Before a command is executed, its input and output may be .I redirected using a special notation interpreted by the shell. Redirection may also be used to open and close files for the current shell execution environment. The following redirection operators may precede or appear anywhere within a .I simple command or may follow a .IR command . Redirections are processed in the order they appear, from left to right. .PP In the following descriptions, if the file descriptor number is omitted, and the first character of the redirection operator is .BR < , the redirection refers to the standard input (file descriptor 0). If the first character of the redirection operator is .BR > , the redirection refers to the standard output (file descriptor 1). .PP The word following the redirection operator in the following descriptions, unless otherwise noted, is subjected to brace expansion, tilde expansion, parameter expansion, command substitution, arithmetic expansion, quote removal, pathname expansion, and word splitting. If it expands to more than one word, .B bash reports an error. .PP Note that the order of redirections is significant. For example, the command .RS .PP ls \fB>\fP dirlist 2\fB>&\fP1 .RE .PP directs both standard output and standard error to the file .IR dirlist , while the command .RS .PP ls 2\fB>&\fP1 \fB>\fP dirlist .RE .PP directs only the standard output to file .IR dirlist , because the standard error was duplicated as standard output before the standard output was redirected to .IR dirlist . .PP \fBBash\fP handles several filenames specially when they are used in redirections, as described in the following table: .RS .PP .PD 0 .TP .B /dev/fd/\fIfd\fP If \fIfd\fP is a valid integer, file descriptor \fIfd\fP is duplicated. .TP .B /dev/stdin File descriptor 0 is duplicated. .TP .B /dev/stdout File descriptor 1 is duplicated. .TP .B /dev/stderr File descriptor 2 is duplicated. .TP .B /dev/tcp/\fIhost\fP/\fIport\fP If \fIhost\fP is a valid hostname or Internet address, and \fIport\fP is an integer port number or service name, \fBbash\fP attempts to open a TCP connection to the corresponding socket. .TP .B /dev/udp/\fIhost\fP/\fIport\fP If \fIhost\fP is a valid hostname or Internet address, and \fIport\fP is an integer port number or service name, \fBbash\fP attempts to open a UDP connection to the corresponding socket. .PD .RE .PP A failure to open or create a file causes the redirection to fail. .SS Redirecting Input .PP Redirection of input causes the file whose name results from the expansion of .I word to be opened for reading on file descriptor .IR n , or the standard input (file descriptor 0) if .I n is not specified. .PP The general format for redirecting input is: .RS .PP [\fIn\fP]\fB<\fP\fIword\fP .RE .SS Redirecting Output .PP Redirection of output causes the file whose name results from the expansion of .I word to be opened for writing on file descriptor .IR n , or the standard output (file descriptor 1) if .I n is not specified. If the file does not exist it is created; if it does exist it is truncated to zero size. .PP The general format for redirecting output is: .RS .PP [\fIn\fP]\fB>\fP\fIword\fP .RE .PP If the redirection operator is .BR > , and the .B noclobber option to the .B set builtin has been enabled, the redirection will fail if the file whose name results from the expansion of \fIword\fP exists and is a regular file. If the redirection operator is .BR >| , or the redirection operator is .B > and the .B noclobber option to the .B set builtin command is not enabled, the redirection is attempted even if the file named by \fIword\fP exists. .SS Appending Redirected Output .PP Redirection of output in this fashion causes the file whose name results from the expansion of .I word to be opened for appending on file descriptor .IR n , or the standard output (file descriptor 1) if .I n is not specified. If the file does not exist it is created. .PP The general format for appending output is: .RS .PP [\fIn\fP]\fB>>\fP\fIword\fP .RE .PP .SS Redirecting Standard Output and Standard Error .PP .B Bash allows both the standard output (file descriptor 1) and the standard error output (file descriptor 2) to be redirected to the file whose name is the expansion of .I word with this construct. .PP There are two formats for redirecting standard output and standard error: .RS .PP \fB&>\fP\fIword\fP .RE and .RS \fB>&\fP\fIword\fP .RE .PP Of the two forms, the first is preferred. This is semantically equivalent to .RS .PP \fB>\fP\fIword\fP 2\fB>&\fP1 .RE .SS Here Documents .PP This type of redirection instructs the shell to read input from the current source until a line containing only .I word (with no trailing blanks) is seen. All of the lines read up to that point are then used as the standard input for a command. .PP The format of here-documents is as follows: .RS .PP .nf \fB<<\fP[\fB\-\fP]\fIword\fP \fIhere-document\fP \fIdelimiter\fP .fi .RE .PP No parameter expansion, command substitution, arithmetic expansion, or pathname expansion is performed on .IR word . If any characters in .I word are quoted, the .I delimiter is the result of quote removal on .IR word , and the lines in the here-document are not expanded. If \fIword\fP is unquoted, all lines of the here-document are subjected to parameter expansion, command substitution, and arithmetic expansion. In the latter case, the character sequence .B \e is ignored, and .B \e must be used to quote the characters .BR \e , .BR $ , and .BR ` . .PP If the redirection operator is .BR <<\- , then all leading tab characters are stripped from input lines and the line containing .IR delimiter . This allows here-documents within shell scripts to be indented in a natural fashion. .SS "Duplicating File Descriptors" .PP The redirection operator .RS .PP [\fIn\fP]\fB<&\fP\fIword\fP .RE .PP is used to duplicate input file descriptors. If .I word expands to one or more digits, the file descriptor denoted by .I n is made to be a copy of that file descriptor. If the digits in .I word do not specify a file descriptor open for input, a redirection error occurs. If .I word evaluates to .BR \- , file descriptor .I n is closed. If .I n is not specified, the standard input (file descriptor 0) is used. .PP The operator .RS .PP [\fIn\fP]\fB>&\fP\fIword\fP .RE .PP is used similarly to duplicate output file descriptors. If .I n is not specified, the standard output (file descriptor 1) is used. If the digits in .I word do not specify a file descriptor open for output, a redirection error occurs. As a special case, if \fIn\fP is omitted, and \fIword\fP does not expand to one or more digits, the standard output and standard error are redirected as described previously. .SS "Opening File Descriptors for Reading and Writing" .PP The redirection operator .RS .PP [\fIn\fP]\fB<>\fP\fIword\fP .RE .PP causes the file whose name is the expansion of .I word to be opened for both reading and writing on file descriptor .IR n , or on file descriptor 0 if .I n is not specified. If the file does not exist, it is created. .SH ALIASES \fIAliases\fP allow a string to be substituted for a word when it is used as the first word of a simple command. The shell maintains a list of aliases that may be set and unset with the .B alias and .B unalias builtin commands (see .SM .B SHELL BUILTIN COMMANDS below). The first word of each command, if unquoted, is checked to see if it has an alias. If so, that word is replaced by the text of the alias. The alias name and the replacement text may contain any valid shell input, including the .I metacharacters listed above, with the exception that the alias name may not contain \fI=\fP. The first word of the replacement text is tested for aliases, but a word that is identical to an alias being expanded is not expanded a second time. This means that one may alias .B ls to .BR "ls \-F" , for instance, and .B bash does not try to recursively expand the replacement text. If the last character of the alias value is a .IR blank , then the next command word following the alias is also checked for alias expansion. .PP Aliases are created and listed with the .B alias command, and removed with the .B unalias command. .PP There is no mechanism for using arguments in the replacement text. If arguments are needed, a shell function should be used (see .SM .B FUNCTIONS below). .PP Aliases are not expanded when the shell is not interactive, unless the .B expand_aliases shell option is set using .B shopt (see the description of .B shopt under .SM \fBSHELL BUILTIN COMMANDS\fP below). .PP The rules concerning the definition and use of aliases are somewhat confusing. .B Bash always reads at least one complete line of input before executing any of the commands on that line. Aliases are expanded when a command is read, not when it is executed. Therefore, an alias definition appearing on the same line as another command does not take effect until the next line of input is read. The commands following the alias definition on that line are not affected by the new alias. This behavior is also an issue when functions are executed. Aliases are expanded when a function definition is read, not when the function is executed, because a function definition is itself a compound command. As a consequence, aliases defined in a function are not available until after that function is executed. To be safe, always put alias definitions on a separate line, and do not use .B alias in compound commands. .PP For almost every purpose, aliases are superseded by shell functions. .SH FUNCTIONS A shell function, defined as described above under .SM .BR "SHELL GRAMMAR" , stores a series of commands for later execution. When the name of a shell function is used as a simple command name, the list of commands associated with that function name is executed. Functions are executed in the context of the current shell; no new process is created to interpret them (contrast this with the execution of a shell script). When a function is executed, the arguments to the function become the positional parameters during its execution. The special parameter .B # is updated to reflect the change. Positional parameter 0 is unchanged. The .SM .B FUNCNAME variable is set to the name of the function while the function is executing. All other aspects of the shell execution environment are identical between a function and its caller with the exception that the .SM .B DEBUG trap (see the description of the .B trap builtin under .SM .B SHELL BUILTIN COMMANDS below) is not inherited. .PP Variables local to the function may be declared with the .B local builtin command. Ordinarily, variables and their values are shared between the function and its caller. .PP If the builtin command .B return is executed in a function, the function completes and execution resumes with the next command after the function call. When a function completes, the values of the positional parameters and the special parameter .B # are restored to the values they had prior to the function's execution. .PP Function names and definitions may be listed with the .B \-f option to the .B declare or .B typeset builtin commands. The .B \-F option to .B declare or .B typeset will list the function names only. Functions may be exported so that subshells automatically have them defined with the .B \-f option to the .B export builtin. .PP Functions may be recursive. No limit is imposed on the number of recursive calls. .SH "ARITHMETIC EVALUATION" The shell allows arithmetic expressions to be evaluated, under certain circumstances (see the \fBlet\fP builtin command and \fBArithmetic Expansion\fP). Evaluation is done in long integers with no check for overflow, though division by 0 is trapped and flagged as an error. The operators and their precedence and associativity are the same as in the C language. The following list of operators is grouped into levels of equal-precedence operators. The levels are listed in order of decreasing precedence. .PP .PD 0 .TP .B \fIid\fP++ \fIid\fP\-\- variable post-increment and post-decrement .TP .B ++\fIid\fP \-\-\fIid\fP variable pre-increment and pre-decrement .TP .B \- + unary minus and plus .TP .B ! ~ logical and bitwise negation .TP .B ** exponentiation .TP .B * / % multiplication, division, remainder .TP .B + \- addition, subtraction .TP .B << >> left and right bitwise shifts .TP .B <= >= < > comparison .TP .B == != equality and inequality .TP .B & bitwise AND .TP .B ^ bitwise exclusive OR .TP .B | bitwise OR .TP .B && logical AND .TP .B || logical OR .TP .B \fIexpr\fP?\fIexpr\fP:\fIexpr\fP conditional evaluation .TP .B = *= /= %= += \-= <<= >>= &= ^= |= assignment .TP .B \fIexpr1\fP , \fIexpr2\fP comma .PD .PP Shell variables are allowed as operands; parameter expansion is performed before the expression is evaluated. Within an expression, shell variables may also be referenced by name without using the parameter expansion syntax. The value of a variable is evaluated as an arithmetic expression when it is referenced. A shell variable need not have its integer attribute turned on to be used in an expression. .PP Constants with a leading 0 are interpreted as octal numbers. A leading 0x or 0X denotes hexadecimal. Otherwise, numbers take the form [\fIbase#\fP]n, where \fIbase\fP is a decimal number between 2 and 64 representing the arithmetic base, and \fIn\fP is a number in that base. If \fIbase#\fP is omitted, then base 10 is used. The digits greater than 9 are represented by the lowercase letters, the uppercase letters, @, and _, in that order. If \fIbase\fP is less than or equal to 36, lowercase and uppercase letters may be used interchangably to represent numbers between 10 and 35. .PP Operators are evaluated in order of precedence. Sub-expressions in parentheses are evaluated first and may override the precedence rules above. .SH "CONDITIONAL EXPRESSIONS" Conditional expressions are used by the \fB[[\fP compound command and the \fBtest\fP and \fB[\fP builtin commands to test file attributes and perform string and arithmetic comparisons. Expressions are formed from the following unary or binary primaries. If any \fIfile\fP argument to one of the primaries is of the form \fI/dev/fd/n\fP, then file descriptor \fIn\fP is checked. If the \fIfile\fP argument to one of the primaries is one of \fI/dev/stdin\fP, \fI/dev/stdout\fP, or \fI/dev/stderr\fP, file descriptor 0, 1, or 2, respectively, is checked. .sp 1 .PD 0 .TP .B \-a \fIfile\fP True if \fIfile\fP exists. .TP .B \-b \fIfile\fP True if \fIfile\fP exists and is a block special file. .TP .B \-c \fIfile\fP True if \fIfile\fP exists and is a character special file. .TP .B \-d \fIfile\fP True if \fIfile\fP exists and is a directory. .TP .B \-e \fIfile\fP True if \fIfile\fP exists. .TP .B \-f \fIfile\fP True if \fIfile\fP exists and is a regular file. .TP .B \-g \fIfile\fP True if \fIfile\fP exists and is set-group-id. .TP .B \-h \fIfile\fP True if \fIfile\fP exists and is a symbolic link. .TP .B \-k \fIfile\fP True if \fIfile\fP exists and its ``sticky'' bit is set. .TP .B \-p \fIfile\fP True if \fIfile\fP exists and is a named pipe (FIFO). .TP .B \-r \fIfile\fP True if \fIfile\fP exists and is readable. .TP .B \-s \fIfile\fP True if \fIfile\fP exists and has a size greater than zero. .TP .B \-t \fIfd\fP True if file descriptor .I fd is open and refers to a terminal. .TP .B \-u \fIfile\fP True if \fIfile\fP exists and its set-user-id bit is set. .TP .B \-w \fIfile\fP True if \fIfile\fP exists and is writable. .TP .B \-x \fIfile\fP True if \fIfile\fP exists and is executable. .TP .B \-O \fIfile\fP True if \fIfile\fP exists and is owned by the effective user id. .TP .B \-G \fIfile\fP True if \fIfile\fP exists and is owned by the effective group id. .TP .B \-L \fIfile\fP True if \fIfile\fP exists and is a symbolic link. .TP .B \-S \fIfile\fP True if \fIfile\fP exists and is a socket. .TP .B \-N \fIfile\fP True if \fIfile\fP exists and has been modified since it was last read. .TP \fIfile1\fP \-\fBnt\fP \fIfile2\fP True if \fIfile1\fP is newer (according to modification date) than \fIfile2\fP. .TP \fIfile1\fP \-\fBot\fP \fIfile2\fP True if \fIfile1\fP is older than \fIfile2\fP. .TP \fIfile1\fP \fB\-ef\fP \fIfile2\fP True if \fIfile1\fP and \fIfile2\fP have the same device and inode numbers. .TP .B \-o \fIoptname\fP True if shell option .I optname is enabled. See the list of options under the description of the .B \-o option to the .B set builtin below. .TP .B \-z \fIstring\fP True if the length of \fIstring\fP is zero. .TP .B \-n \fIstring\fP .TP \fIstring\fP True if the length of .I string is non-zero. .TP \fIstring1\fP \fB==\fP \fIstring2\fP True if the strings are equal. \fB=\fP may be used in place of \fB==\fP. .TP \fIstring1\fP \fB!=\fP \fIstring2\fP True if the strings are not equal. .TP \fIstring1\fP \fB<\fP \fIstring2\fP True if \fIstring1\fP sorts before \fIstring2\fP lexicographically in the current locale. .TP \fIstring1\fP \fB>\fP \fIstring2\fP True if \fIstring1\fP sorts after \fIstring2\fP lexicographically in the current locale. .TP .I \fIarg1\fP \fBOP\fP \fIarg2\fP .SM .B OP is one of .BR \-eq , .BR \-ne , .BR \-lt , .BR \-le , .BR \-gt , or .BR \-ge . These arithmetic binary operators return true if \fIarg1\fP is equal to, not equal to, less than, less than or equal to, greater than, or greater than or equal to \fIarg2\fP, respectively. .I Arg1 and .I arg2 may be positive or negative integers. .PD .SH "SIMPLE COMMAND EXPANSION" When a simple command is executed, the shell performs the following expansions, assignments, and redirections, from left to right. .IP 1. The words that the parser has marked as variable assignments (those preceding the command name) and redirections are saved for later processing. .IP 2. The words that are not variable assignments or redirections are expanded. If any words remain after expansion, the first word is taken to be the name of the command and the remaining words are the arguments. .IP 3. Redirections are performed as described above under .SM .BR REDIRECTION . .IP 4. The text after the \fB=\fP in each variable assignment undergoes tilde expansion, parameter expansion, command substitution, arithmetic expansion, and quote removal before being assigned to the variable. .PP If no command name results, the variable assignments affect the current shell environment. Otherwise, the variables are added to the environment of the executed command and do not affect the current shell environment. If any of the assignments attempts to assign a value to a readonly variable, an error occurs, and the command exits with a non-zero status. .PP If no command name results, redirections are performed, but do not affect the current shell environment. A redirection error causes the command to exit with a non-zero status. .PP If there is a command name left after expansion, execution proceeds as described below. Otherwise, the command exits. If one of the expansions contained a command substitution, the exit status of the command is the exit status of the last command substitution performed. If there were no command substitutions, the command exits with a status of zero. .SH "COMMAND EXECUTION" After a command has been split into words, if it results in a simple command and an optional list of arguments, the following actions are taken. .PP If the command name contains no slashes, the shell attempts to locate it. If there exists a shell function by that name, that function is invoked as described above in .SM .BR FUNCTIONS . If the name does not match a function, the shell searches for it in the list of shell builtins. If a match is found, that builtin is invoked. .PP If the name is neither a shell function nor a builtin, and contains no slashes, .B bash searches each element of the .SM .B PATH for a directory containing an executable file by that name. .B Bash uses a hash table to remember the full pathnames of executable files (see .B hash under .SM .B "SHELL BUILTIN COMMANDS" below). A full search of the directories in .SM .B PATH is performed only if the command is not found in the hash table. If the search is unsuccessful, the shell prints an error message and returns an exit status of 127. .PP If the search is successful, or if the command name contains one or more slashes, the shell executes the named program in a separate execution environment. Argument 0 is set to the name given, and the remaining arguments to the command are set to the arguments given, if any. .PP If this execution fails because the file is not in executable format, and the file is not a directory, it is assumed to be a \fIshell script\fP, a file containing shell commands. A subshell is spawned to execute it. This subshell reinitializes itself, so that the effect is as if a new shell had been invoked to handle the script, with the exception that the locations of commands remembered by the parent (see .B hash below under .SM \fBSHELL BUILTIN COMMANDS\fP) are retained by the child. .PP If the program is a file beginning with .BR #! , the remainder of the first line specifies an interpreter for the program. The shell executes the specified interpreter on operating systems that do not handle this executable format themselves. The arguments to the interpreter consist of a single optional argument following the interpreter name on the first line of the program, followed by the name of the program, followed by the command arguments, if any. .SH COMMAND EXECUTION ENVIRONMENT The shell has an \fIexecution environment\fP, which consists of the following: .sp 1 .IP \(bu open files inherited by the shell at invocation, as modified by redirections supplied to the \fBexec\fP builtin .IP \(bu the current working directory as set by \fBcd\fP, \fBpushd\fP, or \fBpopd\fP, or inherited by the shell at invocation .IP \(bu the file creation mode mask as set by \fBumask\fP or inherited from the shell's parent .IP \(bu current traps set by \fBtrap\fP .IP \(bu shell parameters that are set by variable assignment or with \fBset\fP or inherited from the shell's parent in the environment .IP \(bu shell functions defined during execution or inherited from the shell's parent in the environment .IP \(bu options enabled at invocation (either by default or with command-line arguments) or by \fBset\fP .IP \(bu options enabled by \fBshopt\fP .IP \(bu shell aliases defined with \fBalias\fP .IP \(bu various process IDs, including those of background jobs, the value of \fB$$\fP, and the value of \fB$PPID\fP .PP When a simple command other than a builtin or shell function is to be executed, it is invoked in a separate execution environment that consists of the following. Unless otherwise noted, the values are inherited from the shell. .sp 1 .IP \(bu the shell's open files, plus any modifications and additions specified by redirections to the command .IP \(bu the current working directory .IP \(bu the file creation mode mask .IP \(bu shell variables marked for export, along with variables exported for the command, passed in the environment .IP \(bu traps caught by the shell are reset to the values the inherited from the shell's parent, and traps ignored by the shell are ignored .PP A command invoked in this separate environment cannot affect the shell's execution environment. .PP Command substitution and asynchronous commands are invoked in a subshell environment that is a duplicate of the shell environment, except that traps caught by the shell are reset to the values that the shell inherited from its parent at invocation. Builtin commands that are invoked as part of a pipeline are also executed in a subshell environment. Changes made to the subshell environment cannot affect the shell's execution environment. .PP If a command is followed by a \fB&\fP and job control is not active, the default standard input for the command is the empty file \fI/dev/null\fP. Otherwise, the invoked command inherits the file descriptors of the calling shell as modified by redirections. .SH ENVIRONMENT When a program is invoked it is given an array of strings called the .IR environment . This is a list of \fIname\fP\-\fIvalue\fP pairs, of the form .IR "name\fR=\fPvalue" . .PP The shell provides several ways to manipulate the environment. On invocation, the shell scans its own environment and creates a parameter for each name found, automatically marking it for .I export to child processes. Executed commands inherit the environment. The .B export and .B declare \-x commands allow parameters and functions to be added to and deleted from the environment. If the value of a parameter in the environment is modified, the new value becomes part of the environment, replacing the old. The environment inherited by any executed command consists of the shell's initial environment, whose values may be modified in the shell, less any pairs removed by the .B unset command, plus any additions via the .B export and .B declare \-x commands. .PP The environment for any .I simple command or function may be augmented temporarily by prefixing it with parameter assignments, as described above in .SM .BR PARAMETERS . These assignment statements affect only the environment seen by that command. .PP If the .B \-k option is set (see the .B set builtin command below), then .I all parameter assignments are placed in the environment for a command, not just those that precede the command name. .PP When .B bash invokes an external command, the variable .B _ is set to the full file name of the command and passed to that command in its environment. .SH "EXIT STATUS" For the shell's purposes, a command which exits with a zero exit status has succeeded. An exit status of zero indicates success. A non-zero exit status indicates failure. When a command terminates on a fatal signal \fIN\fP, \fBbash\fP uses the value of 128+\fIN\fP as the exit status. .PP If a command is not found, the child process created to execute it returns a status of 127. If a command is found but is not executable, the return status is 126. .PP If a command fails because of an error during expansion or redirection, the exit status is greater than zero. .PP Shell builtin commands return a status of 0 (\fItrue\fP) if successful, and non-zero (\fIfalse\fP) if an error occurs while they execute. All builtins return an exit status of 2 to indicate incorrect usage. .PP \fBBash\fP itself returns the exit status of the last command executed, unless a syntax error occurs, in which case it exits with a non-zero value. See also the \fBexit\fP builtin command below. .SH SIGNALS When \fBbash\fP is interactive, in the absence of any traps, it ignores .SM .B SIGTERM (so that \fBkill 0\fP does not kill an interactive shell), and .SM .B SIGINT is caught and handled (so that the \fBwait\fP builtin is interruptible). In all cases, \fBbash\fP ignores .SM .BR SIGQUIT . If job control is in effect, .B bash ignores .SM .BR SIGTTIN , .SM .BR SIGTTOU , and .SM .BR SIGTSTP . .PP Synchronous jobs started by \fBbash\fP have signal handlers set to the values inherited by the shell from its parent. When job control is not in effect, asynchronous commands ignore .SM .B SIGINT and .SM .B SIGQUIT as well. Commands run as a result of command substitution ignore the keyboard-generated job control signals .SM .BR SIGTTIN , .SM .BR SIGTTOU , and .SM .BR SIGTSTP . .PP The shell exits by default upon receipt of a .SM .BR SIGHUP . Before exiting, an interactive shell resends the .SM .B SIGHUP to all jobs, running or stopped. Stopped jobs are sent .SM .B SIGCONT to ensure that they receive the .SM .BR SIGHUP . To prevent the shell from sending the signal to a particular job, it should be removed from the jobs table with the .B disown builtin (see .SM .B "SHELL BUILTIN COMMANDS" below) or marked to not receive .SM .B SIGHUP using .BR "disown \-h" . .PP If the .B huponexit shell option has been set with .BR shopt , .B bash sends a .SM .B SIGHUP to all jobs when an interactive login shell exits. .PP When \fBbash\fP receives a signal for which a trap has been set while waiting for a command to complete, the trap will not be executed until the command completes. When \fBbash\fP is waiting for an asynchronous command via the \fBwait\fP builtin, the reception of a signal for which a trap has been set will cause the \fBwait\fP builtin to return immediately with an exit status greater than 128, immediately after which the trap is executed. .SH "JOB CONTROL" .I Job control refers to the ability to selectively stop (\fIsuspend\fP) the execution of processes and continue (\fIresume\fP) their execution at a later point. A user typically employs this facility via an interactive interface supplied jointly by the system's terminal driver and .BR bash . .PP The shell associates a .I job with each pipeline. It keeps a table of currently executing jobs, which may be listed with the .B jobs command. When .B bash starts a job asynchronously (in the .IR background ), it prints a line that looks like: .RS .PP [1] 25647 .RE .PP indicating that this job is job number 1 and that the process ID of the last process in the pipeline associated with this job is 25647. All of the processes in a single pipeline are members of the same job. .B Bash uses the .I job abstraction as the basis for job control. .PP To facilitate the implementation of the user interface to job control, the operating system maintains the notion of a \fIcurrent terminal process group ID\fP. Members of this process group (processes whose process group ID is equal to the current terminal process group ID) receive keyboard-generated signals such as .SM .BR SIGINT . These processes are said to be in the .IR foreground . .I Background processes are those whose process group ID differs from the terminal's; such processes are immune to keyboard-generated signals. Only foreground processes are allowed to read from or write to the terminal. Background processes which attempt to read from (write to) the terminal are sent a .SM .B SIGTTIN (SIGTTOU) signal by the terminal driver, which, unless caught, suspends the process. .PP If the operating system on which .B bash is running supports job control, .B bash contains facilities to use it. Typing the .I suspend character (typically .BR ^Z , Control-Z) while a process is running causes that process to be stopped and returns control to .BR bash . Typing the .I "delayed suspend" character (typically .BR ^Y , Control-Y) causes the process to be stopped when it attempts to read input from the terminal, and control to be returned to .BR bash . The user may then manipulate the state of this job, using the .B bg command to continue it in the background, the .B fg command to continue it in the foreground, or the .B kill command to kill it. A \fB^Z\fP takes effect immediately, and has the additional side effect of causing pending output and typeahead to be discarded. .PP There are a number of ways to refer to a job in the shell. The character .B % introduces a job name. Job number .I n may be referred to as .BR %n . A job may also be referred to using a prefix of the name used to start it, or using a substring that appears in its command line. For example, .B %ce refers to a stopped .B ce job. If a prefix matches more than one job, .B bash reports an error. Using .BR %?ce , on the other hand, refers to any job containing the string .B ce in its command line. If the substring matches more than one job, .B bash reports an error. The symbols .B %% and .B %+ refer to the shell's notion of the .IR "current job" , which is the last job stopped while it was in the foreground or started in the background. The .I "previous job" may be referenced using .BR %\- . In output pertaining to jobs (e.g., the output of the .B jobs command), the current job is always flagged with a .BR + , and the previous job with a .BR \- . .PP Simply naming a job can be used to bring it into the foreground: .B %1 is a synonym for \fB``fg %1''\fP, bringing job 1 from the background into the foreground. Similarly, .B ``%1 &'' resumes job 1 in the background, equivalent to \fB``bg %1''\fP. .PP The shell learns immediately whenever a job changes state. Normally, .B bash waits until it is about to print a prompt before reporting changes in a job's status so as to not interrupt any other output. If the .B \-b option to the .B set builtin command is enabled, .B bash reports such changes immediately. Any trap on .SM .B SIGCHLD is executed for each child that exits. .PP If an attempt to exit .B bash is made while jobs are stopped, the shell prints a warning message. The .B jobs command may then be used to inspect their status. If a second attempt to exit is made without an intervening command, the shell does not print another warning, and the stopped jobs are terminated. .SH PROMPTING When executing interactively, .B bash displays the primary prompt .SM .B PS1 when it is ready to read a command, and the secondary prompt .SM .B PS2 when it needs more input to complete a command. .B Bash allows these prompt strings to be customized by inserting a number of backslash-escaped special characters that are decoded as follows: .RS .PD 0 .TP .B \ea an ASCII bell character (07) .TP .B \ed the date in "Weekday Month Date" format (e.g., "Tue May 26") .TP .B \ee an ASCII escape character (033) .TP .B \eh the hostname up to the first `.' .TP .B \eH the hostname .TP .B \ej the number of jobs currently managed by the shell .TP .B \el the basename of the shell's terminal device name .TP .B \en newline .TP .B \er carriage return .TP .B \es the name of the shell, the basename of .B $0 (the portion following the final slash) .TP .B \et the current time in 24-hour HH:MM:SS format .TP .B \eT the current time in 12-hour HH:MM:SS format .TP .B \e@ the current time in 12-hour am/pm format .TP .B \eA the current time in 24-hour HH:MM format .TP .B \eu the username of the current user .TP .B \ev the version of \fBbash\fP (e.g., 2.00) .TP .B \eV the release of \fBbash\fP, version + patchelvel (e.g., 2.00.0) .TP .B \ew the current working directory .TP .B \eW the basename of the current working directory .TP .B \e! the history number of this command .TP .B \e# the command number of this command .TP .B \e$ if the effective UID is 0, a .BR # , otherwise a .B $ .TP .B \e\fInnn\fP the character corresponding to the octal number \fInnn\fP .TP .B \e\e a backslash .TP .B \e[ begin a sequence of non-printing characters, which could be used to embed a terminal control sequence into the prompt .TP .B \e] end a sequence of non-printing characters .PD .RE .PP The command number and the history number are usually different: the history number of a command is its position in the history list, which may include commands restored from the history file (see .SM .B HISTORY below), while the command number is the position in the sequence of commands executed during the current shell session. After the string is decoded, it is expanded via parameter expansion, command substitution, arithmetic expansion, and quote removal, subject to the value of the .B promptvars shell option (see the description of the .B shopt command under .SM .B "SHELL BUILTIN COMMANDS" below). .SH READLINE This is the library that handles reading input when using an interactive shell, unless the .B \-\-noediting option is given at shell invocation. By default, the line editing commands are similar to those of emacs. A vi-style line editing interface is also available. To turn off line editing after the shell is running, use the .B +o emacs or .B +o vi options to the .B set builtin (see .SM .B SHELL BUILTIN COMMANDS below). .SS "Readline Notation" .PP In this section, the emacs-style notation is used to denote keystrokes. Control keys are denoted by C\-\fIkey\fR, e.g., C\-n means Control\-N. Similarly, .I meta keys are denoted by M\-\fIkey\fR, so M\-x means Meta\-X. (On keyboards without a .I meta key, M\-\fIx\fP means ESC \fIx\fP, i.e., press the Escape key then the .I x key. This makes ESC the \fImeta prefix\fP. The combination M\-C\-\fIx\fP means ESC\-Control\-\fIx\fP, or press the Escape key then hold the Control key while pressing the .I x key.) .PP Readline commands may be given numeric .IR arguments , which normally act as a repeat count. Sometimes, however, it is the sign of the argument that is significant. Passing a negative argument to a command that acts in the forward direction (e.g., \fBkill\-line\fP) causes that command to act in a backward direction. Commands whose behavior with arguments deviates from this are noted below. .PP When a command is described as \fIkilling\fP text, the text deleted is saved for possible future retrieval (\fIyanking\fP). The killed text is saved in a \fIkill ring\fP. Consecutive kills cause the text to be accumulated into one unit, which can be yanked all at once. Commands which do not kill text separate the chunks of text on the kill ring. .SS "Readline Initialization" .PP Readline is customized by putting commands in an initialization file (the \fIinputrc\fP file). The name of this file is taken from the value of the .SM .B INPUTRC variable. If that variable is unset, the default is .IR ~/.inputrc . When a program which uses the readline library starts up, the initialization file is read, and the key bindings and variables are set. There are only a few basic constructs allowed in the readline initialization file. Blank lines are ignored. Lines beginning with a \fB#\fP are comments. Lines beginning with a \fB$\fP indicate conditional constructs. Other lines denote key bindings and variable settings. .PP The default key-bindings may be changed with an .I inputrc file. Other programs that use this library may add their own commands and bindings. .PP For example, placing .RS .PP M\-Control\-u: universal\-argument .RE or .RS C\-Meta\-u: universal\-argument .RE into the .I inputrc would make M\-C\-u execute the readline command .IR universal\-argument . .PP The following symbolic character names are recognized: .IR RUBOUT , .IR DEL , .IR ESC , .IR LFD , .IR NEWLINE , .IR RET , .IR RETURN , .IR SPC , .IR SPACE , and .IR TAB . .PP In addition to command names, readline allows keys to be bound to a string that is inserted when the key is pressed (a \fImacro\fP). .SS "Readline Key Bindings" .PP The syntax for controlling key bindings in the .I inputrc file is simple. All that is required is the name of the command or the text of a macro and a key sequence to which it should be bound. The name may be specified in one of two ways: as a symbolic key name, possibly with \fIMeta\-\fP or \fIControl\-\fP prefixes, or as a key sequence. .PP When using the form \fBkeyname\fP:\^\fIfunction\-name\fP or \fImacro\fP, .I keyname is the name of a key spelled out in English. For example: .sp .RS Control-u: universal\-argument .br Meta-Rubout: backward-kill-word .br Control-o: "> output" .RE .LP In the above example, .I C\-u is bound to the function .BR universal\-argument , .I M\-DEL is bound to the function .BR backward\-kill\-word , and .I C\-o is bound to run the macro expressed on the right hand side (that is, to insert the text .if t \f(CW> output\fP .if n ``> output'' into the line). .PP In the second form, \fB"keyseq"\fP:\^\fIfunction\-name\fP or \fImacro\fP, .B keyseq differs from .B keyname above in that strings denoting an entire key sequence may be specified by placing the sequence within double quotes. Some GNU Emacs style key escapes can be used, as in the following example, but the symbolic character names are not recognized. .sp .RS "\eC\-u": universal\-argument .br "\eC\-x\eC\-r": re\-read\-init\-file .br "\ee[11~": "Function Key 1" .RE .PP In this example, .I C\-u is again bound to the function .BR universal\-argument . .I "C\-x C\-r" is bound to the function .BR re\-read\-init\-file , and .I "ESC [ 1 1 ~" is bound to insert the text .if t \f(CWFunction Key 1\fP. .if n ``Function Key 1''. .PP The full set of GNU Emacs style escape sequences is .RS .PD 0 .TP .B \eC\- control prefix .TP .B \eM\- meta prefix .TP .B \ee an escape character .TP .B \e\e backslash .TP .B \e" literal " .TP .B \e' literal ' .RE .PD .PP In addition to the GNU Emacs style escape sequences, a second set of backslash escapes is available: .RS .PD 0 .TP .B \ea alert (bell) .TP .B \eb backspace .TP .B \ed delete .TP .B \ef form feed .TP .B \en newline .TP .B \er carriage return .TP .B \et horizontal tab .TP .B \ev vertical tab .TP .B \e\fInnn\fP the eight-bit character whose value is the octal value \fInnn\fP (one to three digits) .TP .B \ex\fIHH\fP the eight-bit character whose value is the hexadecimal value \fIHH\fP (one or two hex digits) .RE .PD .PP When entering the text of a macro, single or double quotes must be used to indicate a macro definition. Unquoted text is assumed to be a function name. In the macro body, the backslash escapes described above are expanded. Backslash will quote any other character in the macro text, including " and '. .PP .B Bash allows the current readline key bindings to be displayed or modified with the .B bind builtin command. The editing mode may be switched during interactive use by using the .B \-o option to the .B set builtin command (see .SM .B SHELL BUILTIN COMMANDS below). .SS "Readline Variables" .PP Readline has variables that can be used to further customize its behavior. A variable may be set in the .I inputrc file with a statement of the form .RS .PP \fBset\fP \fIvariable\-name\fP \fIvalue\fP .RE .PP Except where noted, readline variables can take the values .B On or .BR Off . The variables and their default values are: .PP .PD 0 .TP .B bell\-style (audible) Controls what happens when readline wants to ring the terminal bell. If set to \fBnone\fP, readline never rings the bell. If set to \fBvisible\fP, readline uses a visible bell if one is available. If set to \fBaudible\fP, readline attempts to ring the terminal's bell. .TP .B comment\-begin (``#'') The string that is inserted when the readline .B insert\-comment command is executed. This command is bound to .B M\-# in emacs mode and to .B # in vi command mode. .TP .B completion\-ignore\-case (Off) If set to \fBOn\fP, readline performs filename matching and completion in a case\-insensitive fashion. .TP .B completion\-query\-items (100) This determines when the user is queried about viewing the number of possible completions generated by the \fBpossible\-completions\fP command. It may be set to any integer value greater than or equal to zero. If the number of possible completions is greater than or equal to the value of this variable, the user is asked whether or not he wishes to view them; otherwise they are simply listed on the terminal. .TP .B convert\-meta (On) If set to \fBOn\fP, readline will convert characters with the eighth bit set to an ASCII key sequence by stripping the eighth bit and prefixing an escape character (in effect, using escape as the \fImeta prefix\fP). .TP .B disable\-completion (Off) If set to \fBOn\fP, readline will inhibit word completion. Completion characters will be inserted into the line as if they had been mapped to \fBself-insert\fP. .TP .B editing\-mode (emacs) Controls whether readline begins with a set of key bindings similar to \fIemacs\fP or \fIvi\fP. .B editing\-mode can be set to either .B emacs or .BR vi . .TP .B enable\-keypad (Off) When set to \fBOn\fP, readline will try to enable the application keypad when it is called. Some systems need this to enable the arrow keys. .TP .B expand\-tilde (Off) If set to \fBon\fP, tilde expansion is performed when readline attempts word completion. .TP .B history-preserve-point If set to \fBon\fP, the history code attempts to place point at the same location on each history line retrived with \fBprevious-history\fP or \fBnext-history\fP. .TP .B horizontal\-scroll\-mode (Off) When set to \fBOn\fP, makes readline use a single line for display, scrolling the input horizontally on a single screen line when it becomes longer than the screen width rather than wrapping to a new line. .TP .B input\-meta (Off) If set to \fBOn\fP, readline will enable eight-bit input (that is, it will not strip the high bit from the characters it reads), regardless of what the terminal claims it can support. The name .B meta\-flag is a synonym for this variable. .TP .B isearch\-terminators (``C\-[C\-J'') The string of characters that should terminate an incremental search without subsequently executing the character as a command. If this variable has not been given a value, the characters \fIESC\fP and \fIC\-J\fP will terminate an incremental search. .TP .B keymap (emacs) Set the current readline keymap. The set of valid keymap names is \fIemacs, emacs\-standard, emacs\-meta, emacs\-ctlx, vi, vi\-command\fP, and .IR vi\-insert . \fIvi\fP is equivalent to \fIvi\-command\fP; \fIemacs\fP is equivalent to \fIemacs\-standard\fP. The default value is .IR emacs ; the value of .B editing\-mode also affects the default keymap. .TP .B mark\-directories (On) If set to \fBOn\fP, completed directory names have a slash appended. .TP .B mark\-modified\-lines (Off) If set to \fBOn\fP, history lines that have been modified are displayed with a preceding asterisk (\fB*\fP). .TP .B match\-hidden\-files (On) This variable, when set to \fBOn\fP, causes readline to match files whose names begin with a `.' (hidden files) when performing filename completion, unless the leading `.' is supplied by the user in the filename to be completed. .TP .B output\-meta (Off) If set to \fBOn\fP, readline will display characters with the eighth bit set directly rather than as a meta-prefixed escape sequence. .TP .B print\-completions\-horizontally (Off) If set to \fBOn\fP, readline will display completions with matches sorted horizontally in alphabetical order, rather than down the screen. .TP .B show\-all\-if\-ambiguous (Off) This alters the default behavior of the completion functions. If set to .BR on , words which have more than one possible completion cause the matches to be listed immediately instead of ringing the bell. .TP .B visible\-stats (Off) If set to \fBOn\fP, a character denoting a file's type as reported by \fIstat\fP(2) is appended to the filename when listing possible completions. .PD .SS "Readline Conditional Constructs" .PP Readline implements a facility similar in spirit to the conditional compilation features of the C preprocessor which allows key bindings and variable settings to be performed as the result of tests. There are four parser directives used. .IP \fB$if\fP The .B $if construct allows bindings to be made based on the editing mode, the terminal being used, or the application using readline. The text of the test extends to the end of the line; no characters are required to isolate it. .RS .IP \fBmode\fP The \fBmode=\fP form of the \fB$if\fP directive is used to test whether readline is in emacs or vi mode. This may be used in conjunction with the \fBset keymap\fP command, for instance, to set bindings in the \fIemacs\-standard\fP and \fIemacs\-ctlx\fP keymaps only if readline is starting out in emacs mode. .IP \fBterm\fP The \fBterm=\fP form may be used to include terminal-specific key bindings, perhaps to bind the key sequences output by the terminal's function keys. The word on the right side of the .B = is tested against the both full name of the terminal and the portion of the terminal name before the first \fB\-\fP. This allows .I sun to match both .I sun and .IR sun\-cmd , for instance. .IP \fBapplication\fP The \fBapplication\fP construct is used to include application-specific settings. Each program using the readline library sets the \fIapplication name\fP, and an initialization file can test for a particular value. This could be used to bind key sequences to functions useful for a specific program. For instance, the following command adds a key sequence that quotes the current or previous word in Bash: .sp 1 .RS .nf \fB$if\fP Bash # Quote the current or previous word "\eC\-xq": "\eeb\e"\eef\e"" \fB$endif\fP .fi .RE .RE .IP \fB$endif\fP This command, as seen in the previous example, terminates an \fB$if\fP command. .IP \fB$else\fP Commands in this branch of the \fB$if\fP directive are executed if the test fails. .IP \fB$include\fP This directive takes a single filename as an argument and reads commands and bindings from that file. For example, the following directive would read \fI/etc/inputrc\fP: .sp 1 .RS .nf \fB$include\fP \^ \fI/etc/inputrc\fP .fi .RE .SS Searching .PP Readline provides commands for searching through the command history (see .SM .B HISTORY below) for lines containing a specified string. There are two search modes: .I incremental and .IR non-incremental . .PP Incremental searches begin before the user has finished typing the search string. As each character of the search string is typed, readline displays the next entry from the history matching the string typed so far. An incremental search requires only as many characters as needed to find the desired history entry. The characters present in the value of the \fBisearch-terminators\fP variable are used to terminate an incremental search. If that variable has not been assigned a value the Escape and Control-J characters will terminate an incremental search. Control-G will abort an incremental search and restore the original line. When the search is terminated, the history entry containing the search string becomes the current line. .PP To find other matching entries in the history list, type Control-S or Control-R as appropriate. This will search backward or forward in the history for the next entry matching the search string typed so far. Any other key sequence bound to a readline command will terminate the search and execute that command. For instance, a \fInewline\fP will terminate the search and accept the line, thereby executing the command from the history list. .PP Readline remembers the last incremental search string. If two Control-Rs are typed without any intervening characters defining a new search string, any remembered search string is used. .PP Non-incremental searches read the entire search string before starting to search for matching history lines. The search string may be typed by the user or be part of the contents of the current line. .SS "Readline Command Names" .PP The following is a list of the names of the commands and the default key sequences to which they are bound. Command names without an accompanying key sequence are unbound by default. In the following descriptions, \fIpoint\fP refers to the current cursor position, and \fImark\fP refers to a cursor position saved by the \fBset\-mark\fP command. The text between the point and mark is referred to as the \fIregion\fP. .SS Commands for Moving .PP .PD 0 .TP .B beginning\-of\-line (C\-a) Move to the start of the current line. .TP .B end\-of\-line (C\-e) Move to the end of the line. .TP .B forward\-char (C\-f) Move forward a character. .TP .B backward\-char (C\-b) Move back a character. .TP .B forward\-word (M\-f) Move forward to the end of the next word. Words are composed of alphanumeric characters (letters and digits). .TP .B backward\-word (M\-b) Move back to the start of the current or previous word. Words are composed of alphanumeric characters (letters and digits). .TP .B clear\-screen (C\-l) Clear the screen leaving the current line at the top of the screen. With an argument, refresh the current line without clearing the screen. .TP .B redraw\-current\-line Refresh the current line. .PD .SS Commands for Manipulating the History .PP .PD 0 .TP .B accept\-line (Newline, Return) Accept the line regardless of where the cursor is. If this line is non-empty, add it to the history list according to the state of the .SM .B HISTCONTROL variable. If the line is a modified history line, then restore the history line to its original state. .TP .B previous\-history (C\-p) Fetch the previous command from the history list, moving back in the list. .TP .B next\-history (C\-n) Fetch the next command from the history list, moving forward in the list. .TP .B beginning\-of\-history (M\-<) Move to the first line in the history. .TP .B end\-of\-history (M\->) Move to the end of the input history, i.e., the line currently being entered. .TP .B reverse\-search\-history (C\-r) Search backward starting at the current line and moving `up' through the history as necessary. This is an incremental search. .TP .B forward\-search\-history (C\-s) Search forward starting at the current line and moving `down' through the history as necessary. This is an incremental search. .TP .B non\-incremental\-reverse\-search\-history (M\-p) Search backward through the history starting at the current line using a non-incremental search for a string supplied by the user. .TP .B non\-incremental\-forward\-search\-history (M\-n) Search forward through the history using a non-incremental search for a string supplied by the user. .TP .B history\-search\-forward Search forward through the history for the string of characters between the start of the current line and the point. This is a non-incremental search. .TP .B history\-search\-backward Search backward through the history for the string of characters between the start of the current line and the point. This is a non-incremental search. .TP .B yank\-nth\-arg (M\-C\-y) Insert the first argument to the previous command (usually the second word on the previous line) at point. With an argument .IR n , insert the \fIn\fPth word from the previous command (the words in the previous command begin with word 0). A negative argument inserts the \fIn\fPth word from the end of the previous command. .TP .B yank\-last\-arg (M\-.\^, M\-_\^) Insert the last argument to the previous command (the last word of the previous history entry). With an argument, behave exactly like \fByank\-nth\-arg\fP. Successive calls to \fByank\-last\-arg\fP move back through the history list, inserting the last argument of each line in turn. .TP .B shell\-expand\-line (M\-C\-e) Expand the line as the shell does. This performs alias and history expansion as well as all of the shell word expansions. See .SM .B HISTORY EXPANSION below for a description of history expansion. .TP .B history\-expand\-line (M\-^) Perform history expansion on the current line. See .SM .B HISTORY EXPANSION below for a description of history expansion. .TP .B magic\-space Perform history expansion on the current line and insert a space. See .SM .B HISTORY EXPANSION below for a description of history expansion. .TP .B alias\-expand\-line Perform alias expansion on the current line. See .SM .B ALIASES above for a description of alias expansion. .TP .B history\-and\-alias\-expand\-line Perform history and alias expansion on the current line. .TP .B insert\-last\-argument (M\-.\^, M\-_\^) A synonym for \fByank\-last\-arg\fP. .TP .B operate\-and\-get\-next (C\-o) Accept the current line for execution and fetch the next line relative to the current line from the history for editing. Any argument is ignored. .PD .SS Commands for Changing Text .PP .PD 0 .TP .B delete\-char (C\-d) Delete the character at point. If point is at the beginning of the line, there are no characters in the line, and the last character typed was not bound to \fBdelete\-char\fP, then return .SM .BR EOF . .TP .B backward\-delete\-char (Rubout) Delete the character behind the cursor. When given a numeric argument, save the deleted text on the kill ring. .TP .B forward\-backward\-delete\-char Delete the character under the cursor, unless the cursor is at the end of the line, in which case the character behind the cursor is deleted. .TP .B quoted\-insert (C\-q, C\-v) Add the next character typed to the line verbatim. This is how to insert characters like \fBC\-q\fP, for example. .TP .B tab\-insert (C\-v TAB) Insert a tab character. .TP .B self\-insert (a,\ b,\ A,\ 1,\ !,\ ...) Insert the character typed. .TP .B transpose\-chars (C\-t) Drag the character before point forward over the character at point, moving point forward as well. If point is at the end of the line, then this transposes the two characters before point. Negative arguments have no effect. .TP .B transpose\-words (M\-t) Drag the word before point past the word after point, moving point over that word as well. If point is at the end of the line, this transposes the last two words on the line. .TP .B upcase\-word (M\-u) Uppercase the current (or following) word. With a negative argument, uppercase the previous word, but do not move point. .TP .B downcase\-word (M\-l) Lowercase the current (or following) word. With a negative argument, lowercase the previous word, but do not move point. .TP .B capitalize\-word (M\-c) Capitalize the current (or following) word. With a negative argument, capitalize the previous word, but do not move point. .PD .SS Killing and Yanking .PP .PD 0 .TP .B kill\-line (C\-k) Kill the text from point to the end of the line. .TP .B backward\-kill\-line (C\-x Rubout) Kill backward to the beginning of the line. .TP .B unix\-line\-discard (C\-u) Kill backward from point to the beginning of the line. The killed text is saved on the kill-ring. .\" There is no real difference between this and backward-kill-line .TP .B kill\-whole\-line Kill all characters on the current line, no matter where point is. .TP .B kill\-word (M\-d) Kill from point to the end of the current word, or if between words, to the end of the next word. Word boundaries are the same as those used by \fBforward\-word\fP. .TP .B backward\-kill\-word (M\-Rubout) Kill the word behind point. Word boundaries are the same as those used by \fBbackward\-word\fP. .TP .B unix\-word\-rubout (C\-w) Kill the word behind point, using white space as a word boundary. The killed text is saved on the kill-ring. .TP .B delete\-horizontal\-space (M\-\e) Delete all spaces and tabs around point. .TP .B kill\-region Kill the text in the current region. .TP .B copy\-region\-as\-kill Copy the text in the region to the kill buffer. .TP .B copy\-backward\-word Copy the word before point to the kill buffer. The word boundaries are the same as \fBbackward\-word\fP. .TP .B copy\-forward\-word Copy the word following point to the kill buffer. The word boundaries are the same as \fBforward\-word\fP. .TP .B yank (C\-y) Yank the top of the kill ring into the buffer at point. .TP .B yank\-pop (M\-y) Rotate the kill ring, and yank the new top. Only works following .B yank or .BR yank\-pop . .PD .SS Numeric Arguments .PP .PD 0 .TP .B digit\-argument (M\-0, M\-1, ..., M\-\-) Add this digit to the argument already accumulating, or start a new argument. M\-\- starts a negative argument. .TP .B universal\-argument This is another way to specify an argument. If this command is followed by one or more digits, optionally with a leading minus sign, those digits define the argument. If the command is followed by digits, executing .B universal\-argument again ends the numeric argument, but is otherwise ignored. As a special case, if this command is immediately followed by a character that is neither a digit or minus sign, the argument count for the next command is multiplied by four. The argument count is initially one, so executing this function the first time makes the argument count four, a second time makes the argument count sixteen, and so on. .PD .SS Completing .PP .PD 0 .TP .B complete (TAB) Attempt to perform completion on the text before point. .B Bash attempts completion treating the text as a variable (if the text begins with \fB$\fP), username (if the text begins with \fB~\fP), hostname (if the text begins with \fB@\fP), or command (including aliases and functions) in turn. If none of these produces a match, filename completion is attempted. .TP .B possible\-completions (M\-?) List the possible completions of the text before point. .TP .B insert\-completions (M\-*) Insert all completions of the text before point that would have been generated by \fBpossible\-completions\fP. .TP .B menu\-complete Similar to \fBcomplete\fP, but replaces the word to be completed with a single match from the list of possible completions. Repeated execution of \fBmenu\-complete\fP steps through the list of possible completions, inserting each match in turn. At the end of the list of completions, the bell is rung (subject to the setting of \fBbell\-style\fP) and the original text is restored. An argument of \fIn\fP moves \fIn\fP positions forward in the list of matches; a negative argument may be used to move backward through the list. This command is intended to be bound to \fBTAB\fP, but is unbound by default. .TP .B delete\-char\-or\-list Deletes the character under the cursor if not at the beginning or end of the line (like \fBdelete\-char\fP). If at the end of the line, behaves identically to \fBpossible\-completions\fP. This command is unbound by default. .TP .B complete\-filename (M\-/) Attempt filename completion on the text before point. .TP .B possible\-filename\-completions (C\-x /) List the possible completions of the text before point, treating it as a filename. .TP .B complete\-username (M\-~) Attempt completion on the text before point, treating it as a username. .TP .B possible\-username\-completions (C\-x ~) List the possible completions of the text before point, treating it as a username. .TP .B complete\-variable (M\-$) Attempt completion on the text before point, treating it as a shell variable. .TP .B possible\-variable\-completions (C\-x $) List the possible completions of the text before point, treating it as a shell variable. .TP .B complete\-hostname (M\-@) Attempt completion on the text before point, treating it as a hostname. .TP .B possible\-hostname\-completions (C\-x @) List the possible completions of the text before point, treating it as a hostname. .TP .B complete\-command (M\-!) Attempt completion on the text before point, treating it as a command name. Command completion attempts to match the text against aliases, reserved words, shell functions, shell builtins, and finally executable filenames, in that order. .TP .B possible\-command\-completions (C\-x !) List the possible completions of the text before point, treating it as a command name. .TP .B dynamic\-complete\-history (M\-TAB) Attempt completion on the text before point, comparing the text against lines from the history list for possible completion matches. .TP .B complete\-into\-braces (M\-{) Perform filename completion and insert the list of possible completions enclosed within braces so the list is available to the shell (see .B Brace Expansion above). .PD .SS Keyboard Macros .PP .PD 0 .TP .B start\-kbd\-macro (C\-x (\^) Begin saving the characters typed into the current keyboard macro. .TP .B end\-kbd\-macro (C\-x )\^) Stop saving the characters typed into the current keyboard macro and store the definition. .TP .B call\-last\-kbd\-macro (C\-x e) Re-execute the last keyboard macro defined, by making the characters in the macro appear as if typed at the keyboard. .PD .SS Miscellaneous .PP .PD 0 .TP .B re\-read\-init\-file (C\-x C\-r) Read in the contents of the \fIinputrc\fP file, and incorporate any bindings or variable assignments found there. .TP .B abort (C\-g) Abort the current editing command and ring the terminal's bell (subject to the setting of .BR bell\-style ). .TP .B do\-uppercase\-version (M\-a, M\-b, M\-\fIx\fP, ...) If the metafied character \fIx\fP is lowercase, run the command that is bound to the corresponding uppercase character. .TP .B prefix\-meta (ESC) Metafy the next character typed. .SM .B ESC .B f is equivalent to .BR Meta\-f . .TP .B undo (C\-_, C\-x C\-u) Incremental undo, separately remembered for each line. .TP .B revert\-line (M\-r) Undo all changes made to this line. This is like executing the .B undo command enough times to return the line to its initial state. .TP .B tilde\-expand (M\-&) Perform tilde expansion on the current word. .TP .B set\-mark (C\-@, M\-) Set the mark to the point. If a numeric argument is supplied, the mark is set to that position. .TP .B exchange\-point\-and\-mark (C\-x C\-x) Swap the point with the mark. The current cursor position is set to the saved position, and the old cursor position is saved as the mark. .TP .B character\-search (C\-]) A character is read and point is moved to the next occurrence of that character. A negative count searches for previous occurrences. .TP .B character\-search\-backward (M\-C\-]) A character is read and point is moved to the previous occurrence of that character. A negative count searches for subsequent occurrences. .TP .B insert\-comment (M\-#) The value of the readline .B comment\-begin variable is inserted at the beginning of the current line, and the line is accepted as if a newline had been typed. The default value of \fBcomment\-begin\fP causes this command to make the current line a shell comment. .TP .B glob\-expand\-word (C\-x *) The word before point is treated as a pattern for pathname expansion, and the list of matching file names is inserted, replacing the word. .TP .B glob\-list\-expansions (C\-x g) The list of expansions that would have been generated by .B glob\-expand\-word is displayed, and the line is redrawn. .TP .B dump\-functions Print all of the functions and their key bindings to the readline output stream. If a numeric argument is supplied, the output is formatted in such a way that it can be made part of an \fIinputrc\fP file. .TP .B dump\-variables Print all of the settable readline variables and their values to the readline output stream. If a numeric argument is supplied, the output is formatted in such a way that it can be made part of an \fIinputrc\fP file. .TP .B dump\-macros Print all of the readline key sequences bound to macros and the strings they ouput. If a numeric argument is supplied, the output is formatted in such a way that it can be made part of an \fIinputrc\fP file. .TP .B display\-shell\-version (C\-x C\-v) Display version information about the current instance of .BR bash . .PD .SS Programmable Completion .PP When word completion is attempted for an argument to a command for which a completion specification (a \fIcompspec\fP) has been defined using the \fBcomplete\fP builtin (see .SM .B "SHELL BUILTIN COMMANDS" below), the programmable completion facilities are invoked. .PP First, the command name is identified. If a compspec has been defined for that command, the compspec is used to generate the list of possible completions for the word. If the command word is a full pathname, a compspec for the full pathname is searched for first. If no compspec is found for the full pathname, an attempt is made to find a compspec for the portion following the final slash. .PP Once a compspec has been found, it is used to generate the list of matching words. If a compspec is not found, the default \fBbash\fP completion as described above under \fBCompleting\fP is performed. .PP First, the actions specified by the compspec are used. Only matches which are prefixed by the word being completed are returned. When the .B \-f or .B \-d option is used for filename or directory name completion, the shell variable .SM .B FIGNORE is used to filter the matches. .PP Any completions specified by a filename expansion pattern to the \fB\-G\fP option are generated next. The words generated by the pattern need not match the word being completed. The .SM .B GLOBIGNORE shell variable is not used to filter the matches, but the .SM .B FIGNORE variable is used. .PP Next, the string specified as the argument to the \fB\-W\fP option is considered. The string is first split using the characters in the .SM .B IFS special variable as delimiters. Shell quoting is honored. Each word is then expanded using brace expansion, tilde expansion, parameter and variable expansion, command substitution, arithmetic expansion, and pathname expansion, as described above under .SM .BR EXPANSION . The results are split using the rules described above under \fBWord Splitting\fP. The results of the expansion are prefix-matched against the word being completed, and the matching words become the possible completions. .PP After these matches have been generated, any shell function or command specified with the \fB\-F\fP and \fB\-C\fP options is invoked. When the command or function is invoked, the .SM .B COMP_LINE and .SM .B COMP_POINT variables are assigned values as described above under \fBShell Variables\fP. If a shell function is being invoked, the .SM .B COMP_WORDS and .SM .B COMP_CWORD variables are also set. When the function or command is invoked, the first argument is the name of the command whose arguments are being completed, the second argument is the word being completed, and the third argument is the word preceding the word being completed on the current command line. No filtering of the generated completions against the word being completed is performed; the function or command has complete freedom in generating the matches. .PP Any function specified with \fB\-F\fP is invoked first. The function may use any of the shell facilities, including the \fBcompgen\fP builtin described below, to generate the matches. It must put the possible completions in the .SM .B COMPREPLY array variable. .PP Next, any command specified with the \fB\-C\fP option is invoked in an environment equivalent to command substitution. It should print a list of completions, one per line, to the standard output. Backslash may be used to escape a newline, if necessary. .PP After all of the possible completions are generated, any filter specified with the \fB\-X\fP option is applied to the list. The filter is a pattern as used for pathname expansion; a \fB&\fP in the pattern is replaced with the text of the word being completed. A literal \fB&\fP may be escaped with a backslash; the backslash is removed before attempting a match. Any completion that matches the pattern will be removed from the list. A leading \fB!\fP negates the pattern; in this case any completion not matching the pattern will be removed. .PP Finally, any prefix and suffix specified with the \fB\-P\fP and \fB\-S\fP options are added to each member of the completion list, and the result is returned to the readline completion code as the list of possible completions. .PP If the previously-applied actions do not generate any matches, and the \fB\-o dirnames\fP option was supplied to \fBcomplete\fP when the compspec was defined, directory name completion is attempted. .PP By default, if a compspec is found, whatever it generates is returned to the completion code as the full set of possible completions. The default \fBbash\fP completions are not attempted, and the readline default of filename completion is disabled. If the \fB-o default\fP option was supplied to \fBcomplete\fP when the compspec was defined, readline's default completion will be performed if the compspec generates no matches. .SH HISTORY When the .B \-o history option to the .B set builtin is enabled, the shell provides access to the \fIcommand history\fP, the list of commands previously typed. The value of the \fBHISTSIZE\fP variable is used as the number of commands to save in a history list. The text of the last .SM .B HISTSIZE commands (default 500) is saved. The shell stores each command in the history list prior to parameter and variable expansion (see .SM .B EXPANSION above) but after history expansion is performed, subject to the values of the shell variables .SM .B HISTIGNORE and .SM .BR HISTCONTROL . .PP On startup, the history is initialized from the file named by the variable .SM .B HISTFILE (default \fI~/.bash_history\fP). The file named by the value of .SM .B HISTFILE is truncated, if necessary, to contain no more than the number of lines specified by the value of .SM .BR HISTFILESIZE . When an interactive shell exits, the last .SM .B $HISTSIZE lines are copied from the history list to .SM .BR $HISTFILE . If the .B histappend shell option is enabled (see the description of .B shopt under .SM .B "SHELL BUILTIN COMMANDS" below), the lines are appended to the history file, otherwise the history file is overwritten. If .SM .B HISTFILE is unset, or if the history file is unwritable, the history is not saved. After saving the history, the history file is truncated to contain no more than .SM .B HISTFILESIZE lines. If .SM .B HISTFILESIZE is not set, no truncation is performed. .PP The builtin command .B fc (see .SM .B SHELL BUILTIN COMMANDS below) may be used to list or edit and re-execute a portion of the history list. The .B history builtin may be used to display or modify the history list and manipulate the history file. When using command-line editing, search commands are available in each editing mode that provide access to the history list. .PP The shell allows control over which commands are saved on the history list. The .SM .B HISTCONTROL and .SM .B HISTIGNORE variables may be set to cause the shell to save only a subset of the commands entered. The .B cmdhist shell option, if enabled, causes the shell to attempt to save each line of a multi-line command in the same history entry, adding semicolons where necessary to preserve syntactic correctness. The .B lithist shell option causes the shell to save the command with embedded newlines instead of semicolons. See the description of the .B shopt builtin below under .SM .B "SHELL BUILTIN COMMANDS" for information on setting and unsetting shell options. .SH "HISTORY EXPANSION" .PP The shell supports a history expansion feature that is similar to the history expansion in .BR csh. This section describes what syntax features are available. This feature is enabled by default for interactive shells, and can be disabled using the .B \+H option to the .B set builtin command (see .SM .B SHELL BUILTIN COMMANDS below). Non-interactive shells do not perform history expansion by default. .PP History expansions introduce words from the history list into the input stream, making it easy to repeat commands, insert the arguments to a previous command into the current input line, or fix errors in previous commands quickly. .PP History expansion is performed immediately after a complete line is read, before the shell breaks it into words. It takes place in two parts. The first is to determine which line from the history list to use during substitution. The second is to select portions of that line for inclusion into the current one. The line selected from the history is the \fIevent\fP, and the portions of that line that are acted upon are \fIwords\fP. Various \fImodifiers\fP are available to manipulate the selected words. The line is broken into words in the same fashion as when reading input, so that several \fImetacharacter\fP-separated words surrounded by quotes are considered one word. History expansions are introduced by the appearance of the history expansion character, which is \^\fB!\fP\^ by default. Only backslash (\^\fB\e\fP\^) and single quotes can quote the history expansion character. .PP Several shell options settable with the .B shopt builtin may be used to tailor the behavior of history expansion. If the .B histverify shell option is enabled (see the description of the .B shopt builtin), and .B readline is being used, history substitutions are not immediately passed to the shell parser. Instead, the expanded line is reloaded into the .B readline editing buffer for further modification. If .B readline is being used, and the .B histreedit shell option is enabled, a failed history substitution will be reloaded into the .B readline editing buffer for correction. The .B \-p option to the .B history builtin command may be used to see what a history expansion will do before using it. The .B \-s option to the .B history builtin may be used to add commands to the end of the history list without actually executing them, so that they are available for subsequent recall. .PP The shell allows control of the various characters used by the history expansion mechanism (see the description of .B histchars above under .BR "Shell Variables" ). .SS Event Designators .PP An event designator is a reference to a command line entry in the history list. .PP .PD 0 .TP .B ! Start a history substitution, except when followed by a .BR blank , newline, = or (. .TP .B !\fIn\fR Refer to command line .IR n . .TP .B !\-\fIn\fR Refer to the current command line minus .IR n . .TP .B !! Refer to the previous command. This is a synonym for `!\-1'. .TP .B !\fIstring\fR Refer to the most recent command starting with .IR string . .TP .B !?\fIstring\fR\fB[?]\fR Refer to the most recent command containing .IR string . The trailing \fB?\fP may be omitted if .I string is followed immediately by a newline. .TP .B \d\s+2^\s-2\u\fIstring1\fP\d\s+2^\s-2\u\fIstring2\fP\d\s+2^\s-2\u Quick substitution. Repeat the last command, replacing .I string1 with .IR string2 . Equivalent to ``!!:s/\fIstring1\fP/\fIstring2\fP/'' (see \fBModifiers\fP below). .TP .B !# The entire command line typed so far. .PD .SS Word Designators .PP Word designators are used to select desired words from the event. A .B : separates the event specification from the word designator. It may be omitted if the word designator begins with a .BR ^ , .BR $ , .BR * , .BR \- , or .BR % . Words are numbered from the beginning of the line, with the first word being denoted by 0 (zero). Words are inserted into the current line separated by single spaces. .PP .PD 0 .TP .B 0 (zero) The zeroth word. For the shell, this is the command word. .TP .I n The \fIn\fRth word. .TP .B ^ The first argument. That is, word 1. .TP .B $ The last argument. .TP .B % The word matched by the most recent `?\fIstring\fR?' search. .TP .I x\fB\-\fPy A range of words; `\-\fIy\fR' abbreviates `0\-\fIy\fR'. .TP .B * All of the words but the zeroth. This is a synonym for `\fI1\-$\fP'. It is not an error to use .B * if there is just one word in the event; the empty string is returned in that case. .TP .B x* Abbreviates \fIx\-$\fP. .TP .B x\- Abbreviates \fIx\-$\fP like \fBx*\fP, but omits the last word. .PD .PP If a word designator is supplied without an event specification, the previous command is used as the event. .SS Modifiers .PP After the optional word designator, there may appear a sequence of one or more of the following modifiers, each preceded by a `:'. .PP .PD 0 .PP .TP .B h Remove a trailing file name component, leaving only the head. .TP .B t Remove all leading file name components, leaving the tail. .TP .B r Remove a trailing suffix of the form \fI.xxx\fP, leaving the basename. .TP .B e Remove all but the trailing suffix. .TP .B p Print the new command but do not execute it. .TP .B q Quote the substituted words, escaping further substitutions. .TP .B x Quote the substituted words as with .BR q , but break into words at .B blanks and newlines. .TP .B s/\fIold\fP/\fInew\fP/ Substitute .I new for the first occurrence of .I old in the event line. Any delimiter can be used in place of /. The final delimiter is optional if it is the last character of the event line. The delimiter may be quoted in .I old and .I new with a single backslash. If & appears in .IR new , it is replaced by .IR old . A single backslash will quote the &. If .I old is null, it is set to the last .I old substituted, or, if no previous history substitutions took place, the last .I string in a .B !?\fIstring\fR\fB[?]\fR search. .TP .B & Repeat the previous substitution. .TP .B g Cause changes to be applied over the entire event line. This is used in conjunction with `\fB:s\fP' (e.g., `\fB:gs/\fIold\fP/\fInew\fP/\fR') or `\fB:&\fP'. If used with `\fB:s\fP', any delimiter can be used in place of /, and the final delimiter is optional if it is the last character of the event line. .PD .SH "SHELL BUILTIN COMMANDS" .\" start of bash_builtins .zZ .PP Unless otherwise noted, each builtin command documented in this section as accepting options preceded by .B \- accepts .B \-\- to signify the end of the options. .sp .5 .PD 0 .TP \fB:\fP [\fIarguments\fP] .PD No effect; the command does nothing beyond expanding .I arguments and performing any specified redirections. A zero exit code is returned. .TP .PD 0 \fB .\| \fP \fIfilename\fP [\fIarguments\fP] .TP \fBsource\fP \fIfilename\fP [\fIarguments\fP] .PD Read and execute commands from .I filename in the current shell environment and return the exit status of the last command executed from .IR filename . If .I filename does not contain a slash, file names in .SM .B PATH are used to find the directory containing .IR filename . The file searched for in .SM .B PATH need not be executable. When \fBbash\fP is not in \fIposix mode\fP, the current directory is searched if no file is found in .SM .BR PATH . If the .B sourcepath option to the .B shopt builtin command is turned off, the .SM .B PATH is not searched. If any \fIarguments\fP are supplied, they become the positional parameters when \fIfilename\fP is executed. Otherwise the positional parameters are unchanged. The return status is the status of the last command exited within the script (0 if no commands are executed), and false if .I filename is not found or cannot be read. .TP \fBalias\fP [\fB\-p\fP] [\fIname\fP[=\fIvalue\fP] ...] \fBAlias\fP with no arguments or with the .B \-p option prints the list of aliases in the form \fBalias\fP \fIname\fP=\fIvalue\fP on standard output. When arguments are supplied, an alias is defined for each \fIname\fP whose \fIvalue\fP is given. A trailing space in \fIvalue\fP causes the next word to be checked for alias substitution when the alias is expanded. For each \fIname\fP in the argument list for which no \fIvalue\fP is supplied, the name and value of the alias is printed. \fBAlias\fP returns true unless a \fIname\fP is given for which no alias has been defined. .TP \fBbg\fP [\fIjobspec\fP] Resume the suspended job \fIjobspec\fP in the background, as if it had been started with .BR & . If \fIjobspec\fP is not present, the shell's notion of the \fIcurrent job\fP is used. .B bg .I jobspec returns 0 unless run when job control is disabled or, when run with job control enabled, if \fIjobspec\fP was not found or started without job control. .TP .PD 0 \fBbind\fP [\fB\-m\fP \fIkeymap\fP] [\fB\-lpsvPSV\fP] .TP \fBbind\fP [\fB\-m\fP \fIkeymap\fP] [\fB\-q\fP \fIfunction\fP] [\fB\-u\fP \fIfunction\fP] [\fB\-r\fP \fIkeyseq\fP] .TP \fBbind\fP [\fB\-m\fP \fIkeymap\fP] \fB\-f\fP \fIfilename\fP .TP \fBbind\fP [\fB\-m\fP \fIkeymap\fP] \fB\-x\fP \fIkeyseq\fP:\fIshell\-command\fP .TP \fBbind\fP [\fB\-m\fP \fIkeymap\fP] \fIkeyseq\fP:\fIfunction\-name\fP .PD Display current .B readline key and function bindings, or bind a key sequence to a .B readline function or macro. The binding syntax accepted is identical to that of .IR .inputrc , but each binding must be passed as a separate argument; e.g., '"\eC\-x\eC\-r": re\-read\-init\-file'. Options, if supplied, have the following meanings: .RS .PD 0 .TP .B \-m \fIkeymap\fP Use .I keymap as the keymap to be affected by the subsequent bindings. Acceptable .I keymap names are \fIemacs, emacs\-standard, emacs\-meta, emacs\-ctlx, vi, vi\-move, vi\-command\fP, and .IR vi\-insert . \fIvi\fP is equivalent to \fIvi\-command\fP; \fIemacs\fP is equivalent to \fIemacs\-standard\fP. .TP .B \-l List the names of all \fBreadline\fP functions. .TP .B \-p Display \fBreadline\fP function names and bindings in such a way that they can be re-read. .TP .B \-P List current \fBreadline\fP function names and bindings. .TP .B \-v Display \fBreadline\fP variable names and values in such a way that they can be re-read. .TP .B \-V List current \fBreadline\fP variable names and values. .TP .B \-s Display \fBreadline\fP key sequences bound to macros and the strings they output in such a way that they can be re-read. .TP .B \-S Display \fBreadline\fP key sequences bound to macros and the strings they output. .TP .B \-f \fIfilename\fP Read key bindings from \fIfilename\fP. .TP .B \-q \fIfunction\fP Query about which keys invoke the named \fIfunction\fP. .TP .B \-u \fIfunction\fP Unbind all keys bound to the named \fIfunction\fP. .TP .B \-r \fIkeyseq\fP Remove any current binding for \fIkeyseq\fP. .TP .B \-x \fIkeyseq\fP:\fIshell\-command\fP Cause \fIshell\-command\fP to be executed whenever \fIkeyseq\fP is entered. .PD .PP The return value is 0 unless an unrecognized option is given or an error occurred. .RE .TP \fBbreak\fP [\fIn\fP] Exit from within a .BR for , .BR while , .BR until , or .B select loop. If \fIn\fP is specified, break \fIn\fP levels. .I n must be \(>= 1. If .I n is greater than the number of enclosing loops, all enclosing loops are exited. The return value is 0 unless the shell is not executing a loop when .B break is executed. .TP \fBbuiltin\fP \fIshell\-builtin\fP [\fIarguments\fP] Execute the specified shell builtin, passing it .IR arguments , and return its exit status. This is useful when defining a function whose name is the same as a shell builtin, retaining the functionality of the builtin within the function. The \fBcd\fP builtin is commonly redefined this way. The return status is false if .I shell\-builtin is not a shell builtin command. .TP \fBcd\fP [\fB\-LP\fP] [\fIdir\fP] Change the current directory to \fIdir\fP. The variable .SM .B HOME is the default .IR dir . The variable .SM .B CDPATH defines the search path for the directory containing .IR dir . Alternative directory names in .SM .B CDPATH are separated by a colon (:). A null directory name in .SM .B CDPATH is the same as the current directory, i.e., ``\fB.\fP''. If .I dir begins with a slash (/), then .SM .B CDPATH is not used. The .B \-P option says to use the physical directory structure instead of following symbolic links (see also the .B \-P option to the .B set builtin command); the .B \-L option forces symbolic links to be followed. An argument of .B \- is equivalent to .SM .BR $OLDPWD . The return value is true if the directory was successfully changed; false otherwise. .TP \fBcommand\fP [\fB\-pVv\fP] \fIcommand\fP [\fIarg\fP ...] Run .I command with .I args suppressing the normal shell function lookup. Only builtin commands or commands found in the .SM .B PATH are executed. If the .B \-p option is given, the search for .I command is performed using a default value for .B PATH that is guaranteed to find all of the standard utilities. If either the .B \-V or .B \-v option is supplied, a description of .I command is printed. The .B \-v option causes a single word indicating the command or file name used to invoke .I command to be displayed; the .B \-V option produces a more verbose description. If the .B \-V or .B \-v option is supplied, the exit status is 0 if .I command was found, and 1 if not. If neither option is supplied and an error occurred or .I command cannot be found, the exit status is 127. Otherwise, the exit status of the .B command builtin is the exit status of .IR command . .TP \fBcompgen\fP [\fIoption\fP] [\fIword\fP] Generate possible completion matches for \fIword\fP according to the \fIoption\fPs, which may be any option accepted by the .B complete builtin with the exception of \fB\-p\fP and \fB\-r\fP, and write the matches to the standard output. When using the \fB\-F\fP or \fB\-C\fP options, the various shell variables set by the programmable completion facilities, while available, will not have useful values. .sp 1 The matches will be generated in the same way as if the programmable completion code had generated them directly from a completion specification with the same flags. If \fIword\fP is specified, only those completions matching \fIword\fP will be displayed. .sp 1 The return value is true unless an invalid option is supplied, or no matches were generated. .TP .PD 0 \fBcomplete\fP [\fB\-abcdefgjkvu\fP] [\fB\-o\fP \fIcomp-option\fP] [\fB\-A\fP \fIaction\fP] [\fB\-G\fP \fIglobpat\fP] [\fB\-W\fP \fIwordlist\fP] [\fB\-P\fP \fIprefix\fP] [\fB\-S\fP \fIsuffix\fP] .br [\fB\-X\fP \fIfilterpat\fP] [\fB\-F\fP \fIfunction\fP] [\fB\-C\fP \fIcommand\fP] \fIname\fP [\fIname ...\fP] .TP \fBcomplete\fP \fB\-pr\fP [\fIname\fP ...] .PD Specify how arguments to each \fIname\fP should be completed. If the \fB\-p\fP option is supplied, or if no options are supplied, existing completion specifications are printed in a way that allows them to be reused as input. The \fB\-r\fP option removes a completion specification for each \fIname\fP, or, if no \fIname\fPs are supplied, all completion specifications. .sp 1 The process of applying these completion specifications when word completion is attempted is described above under \fBProgrammable Completion\fP. .sp 1 Other options, if specified, have the following meanings. The arguments to the \fB\-G\fP, \fB\-W\fP, and \fB\-X\fP options (and, if necessary, the \fB\-P\fP and \fB\-S\fP options) should be quoted to protect them from expansion before the .B complete builtin is invoked. .RS .PD 0 .TP 8 \fB\-o\fP \fIcomp-option\fP The \fIcomp-option\fP controls several aspects of the compspec's behavior beyond the simple generation of completions. \fIcomp-option\fP may be one of: .RS .TP 8 .B default Use readline's default completion if the compspec generates no matches. .TP 8 .B dirnames Perform directory name completion if the compspec generates no matches. .TP 8 .B filenames Tell readline that the compspec generates filenames, so it can perform any filename\-specific processing (like adding a slash to directory names or suppressing trailing spaces). Intended to be used with shell functions. .RE .TP 8 \fB\-A\fP \fIaction\fP The \fIaction\fP may be one of the following to generate a list of possible completions: .RS .TP 8 .B alias Alias names. May also be specified as \fB\-a\fP. .TP 8 .B arrayvar Array variable names. .TP 8 .B binding \fBReadline\fP key binding names. .TP 8 .B builtin Names of shell builtin commands. May also be specified as \fB\-b\fP. .TP 8 .B command Command names. May also be specified as \fB\-c\fP. .TP 8 .B directory Directory names. May also be specified as \fB\-d\fP. .TP 8 .B disabled Names of disabled shell builtins. .TP 8 .B enabled Names of enabled shell builtins. .TP 8 .B export Names of exported shell variables. May also be specified as \fB\-e\fP. .TP 8 .B file File names. May also be specified as \fB\-f\fP. .TP 8 .B function Names of shell functions. .TP 8 .B group Group names. May also be specified as \fB\-g\fP. .TP 8 .B helptopic Help topics as accepted by the \fBhelp\fP builtin. .TP 8 .B hostname Hostnames, as taken from the file specified by the .SM .B HOSTFILE shell variable. .TP 8 .B job Job names, if job control is active. May also be specified as \fB\-j\fP. .TP 8 .B keyword Shell reserved words. May also be specified as \fB\-k\fP. .TP 8 .B running Names of running jobs, if job control is active. .TP 8 .B setopt Valid arguments for the \fB\-o\fP option to the \fBset\fP builtin. .TP 8 .B shopt Shell option names as accepted by the \fBshopt\fP builtin. .TP 8 .B signal Signal names. .TP 8 .B stopped Names of stopped jobs, if job control is active. .TP 8 .B user User names. May also be specified as \fB\-u\fP. .TP 8 .B variable Names of all shell variables. May also be specified as \fB\-v\fP. .RE .TP 8 \fB\-G\fP \fIglobpat\fP The filename expansion pattern \fIglobpat\fP is expanded to generate the possible completions. .TP 8 \fB\-W\fP \fIwordlist\fP The \fIwordlist\fP is split using the characters in the .SM .B IFS special variable as delimiters, and each resultant word is expanded. The possible completions are the members of the resultant list which match the word being completed. .TP 8 \fB\-C\fP \fIcommand\fP \fIcommand\fP is executed in a subshell environment, and its output is used as the possible completions. .TP 8 \fB\-F\fP \fIfunction\fP The shell function \fIfunction\fP is executed in the current shell environment. When it finishes, the possible completions are retrieved from the value of the .SM .B COMPREPLY array variable. .TP 8 \fB\-X\fP \fIfilterpat\fP \fIfilterpat\fP is a pattern as used for filename expansion. It is applied to the list of possible completions generated by the preceding options and arguments, and each completion matching \fIfilterpat\fP is removed from the list. A leading \fB!\fP in \fIfilterpat\fP negates the pattern; in this case, any completion not matching \fIfilterpat\fP is removed. .TP 8 \fB\-P\fP \fIprefix\fP \fIprefix\fP is added at the beginning of each possible completion after all other options have been applied. .TP 8 \fB\-S\fP \fIsuffix\fP \fIsuffix\fP is appended to each possible completion after all other options have been applied. .PD .PP The return value is true unless an invalid option is supplied, an option other than \fB\-p\fP or \fB\-r\fP is supplied without a \fIname\fP argument, an attempt is made to remove a completion specification for a \fIname\fP for which no specification exists, or an error occurs adding a completion specification. .RE .TP \fBcontinue\fP [\fIn\fP] Resume the next iteration of the enclosing .BR for , .BR while , .BR until , or .B select loop. If .I n is specified, resume at the \fIn\fPth enclosing loop. .I n must be \(>= 1. If .I n is greater than the number of enclosing loops, the last enclosing loop (the ``top-level'' loop) is resumed. The return value is 0 unless the shell is not executing a loop when .B continue is executed. .TP .PD 0 \fBdeclare\fP [\fB\-afFirx\fP] [\fB\-p\fP] [\fIname\fP[=\fIvalue\fP]] .TP \fBtypeset\fP [\fB\-afFirx\fP] [\fB\-p\fP] [\fIname\fP[=\fIvalue\fP]] .PD Declare variables and/or give them attributes. If no \fIname\fPs are given then display the values of variables. The .B \-p option will display the attributes and values of each .IR name . When .B \-p is used, additional options are ignored. The .B \-F option inhibits the display of function definitions; only the function name and attributes are printed. The .B \-F option implies .BR \-f . The following options can be used to restrict output to variables with the specified attribute or to give variables attributes: .RS .PD 0 .TP .B \-a Each \fIname\fP is an array variable (see .B Arrays above). .TP .B \-f Use function names only. .TP .B \-i The variable is treated as an integer; arithmetic evaluation (see .SM .B "ARITHMETIC EVALUATION" ") " is performed when the variable is assigned a value. .TP .B \-r Make \fIname\fPs readonly. These names cannot then be assigned values by subsequent assignment statements or unset. .TP .B \-x Mark \fIname\fPs for export to subsequent commands via the environment. .PD .PP Using `+' instead of `\-' turns off the attribute instead, with the exception that \fB+a\fP may not be used to destroy an array variable. When used in a function, makes each \fIname\fP local, as with the .B local command. The return value is 0 unless an invalid option is encountered, an attempt is made to define a function using .if n ``\-f foo=bar'', .if t \f(CW\-f foo=bar\fP, an attempt is made to assign a value to a readonly variable, an attempt is made to assign a value to an array variable without using the compound assignment syntax (see .B Arrays above), one of the \fInames\fP is not a valid shell variable name, an attempt is made to turn off readonly status for a readonly variable, an attempt is made to turn off array status for an array variable, or an attempt is made to display a non-existent function with \fB\-f\fP. .RE .TP .B dirs [\fB\-clpv\fP] [+\fIn\fP] [\-\fIn\fP] Without options, displays the list of currently remembered directories. The default display is on a single line with directory names separated by spaces. Directories are added to the list with the .B pushd command; the .B popd command removes entries from the list. .RS .PD 0 .TP \fB+\fP\fIn\fP Displays the \fIn\fPth entry counting from the left of the list shown by .B dirs when invoked without options, starting with zero. .TP \fB\-\fP\fIn\fP Displays the \fIn\fPth entry counting from the right of the list shown by .B dirs when invoked without options, starting with zero. .TP .B \-c Clears the directory stack by deleting all of the entries. .TP .B \-l Produces a longer listing; the default listing format uses a tilde to denote the home directory. .TP .B \-p Print the directory stack with one entry per line. .TP .B \-v Print the directory stack with one entry per line, prefixing each entry with its index in the stack. .PD .PP The return value is 0 unless an invalid option is supplied or \fIn\fP indexes beyond the end of the directory stack. .RE .TP \fBdisown\fP [\fB\-ar\fP] [\fB\-h\fP] [\fIjobspec\fP ...] Without options, each .I jobspec is removed from the table of active jobs. If the \fB\-h\fP option is given, each .I jobspec is not removed from the table, but is marked so that .SM .B SIGHUP is not sent to the job if the shell receives a .SM .BR SIGHUP . If no .I jobspec is present, and neither the .B \-a nor the .B \-r option is supplied, the \fIcurrent job\fP is used. If no .I jobspec is supplied, the .B \-a option means to remove or mark all jobs; the .B \-r option without a .I jobspec argument restricts operation to running jobs. The return value is 0 unless a .I jobspec does not specify a valid job. .TP \fBecho\fP [\fB\-neE\fP] [\fIarg\fP ...] Output the \fIarg\fPs, separated by spaces, followed by a newline. The return status is always 0. If \fB\-n\fP is specified, the trailing newline is suppressed. If the \fB\-e\fP option is given, interpretation of the following backslash-escaped characters is enabled. The .B \-E option disables the interpretation of these escape characters, even on systems where they are interpreted by default. The \fBxpg_echo\fP shell option may be used to dynamically determine whether or not \fBecho\fP expands these escape characters by default. .B echo does not interpret .B \-\- to mean the end of options. .B echo interprets the following escape sequences: .RS .PD 0 .TP .B \ea alert (bell) .TP .B \eb backspace .TP .B \ec suppress trailing newline .TP .B \ee an escape character .TP .B \ef form feed .TP .B \en new line .TP .B \er carriage return .TP .B \et horizontal tab .TP .B \ev vertical tab .TP .B \e\e backslash .TP .B \e\fInnn\fP the eight-bit character whose value is the octal value \fInnn\fP (one to three digits) .TP .B \ex\fIHH\fP the eight-bit character whose value is the hexadecimal value \fIHH\fP (one or two hex digits) .PD .RE .TP \fBenable\fP [\fB\-adnps\fP] [\fB\-f\fP \fIfilename\fP] [\fIname\fP ...] Enable and disable builtin shell commands. Disabling a builtin allows a disk command which has the same name as a shell builtin to be executed without specifying a full pathname, even though the shell normally searches for builtins before disk commands. If \fB\-n\fP is used, each \fIname\fP is disabled; otherwise, \fInames\fP are enabled. For example, to use the .B test binary found via the .SM .B PATH instead of the shell builtin version, run .if t \f(CWenable -n test\fP. .if n ``enable -n test''. The .B \-f option means to load the new builtin command .I name from shared object .IR filename , on systems that support dynamic loading. The .B \-d option will delete a builtin previously loaded with .BR \-f . If no \fIname\fP arguments are given, or if the .B \-p option is supplied, a list of shell builtins is printed. With no other option arguments, the list consists of all enabled shell builtins. If \fB\-n\fP is supplied, only disabled builtins are printed. If \fB\-a\fP is supplied, the list printed includes all builtins, with an indication of whether or not each is enabled. If \fB\-s\fP is supplied, the output is restricted to the POSIX \fIspecial\fP builtins. The return value is 0 unless a .I name is not a shell builtin or there is an error loading a new builtin from a shared object. .TP \fBeval\fP [\fIarg\fP ...] The \fIarg\fPs are read and concatenated together into a single command. This command is then read and executed by the shell, and its exit status is returned as the value of .BR eval . If there are no .IR args , or only null arguments, .B eval returns 0. .TP \fBexec\fP [\fB\-cl\fP] [\fB\-a\fP \fIname\fP] [\fIcommand\fP [\fIarguments\fP]] If .I command is specified, it replaces the shell. No new process is created. The .I arguments become the arguments to \fIcommand\fP. If the .B \-l option is supplied, the shell places a dash at the beginning of the zeroth arg passed to .IR command . This is what .IR login (1) does. The .B \-c option causes .I command to be executed with an empty environment. If .B \-a is supplied, the shell passes .I name as the zeroth argument to the executed command. If .I command cannot be executed for some reason, a non-interactive shell exits, unless the shell option .B execfail is enabled, in which case it returns failure. An interactive shell returns failure if the file cannot be executed. If .I command is not specified, any redirections take effect in the current shell, and the return status is 0. If there is a redirection error, the return status is 1. .TP \fBexit\fP [\fIn\fP] Cause the shell to exit with a status of \fIn\fP. If .I n is omitted, the exit status is that of the last command executed. A trap on .SM .B EXIT is executed before the shell terminates. .TP .PD 0 \fBexport\fP [\fB\-fn\fP\^] [\fIname\fP[=\fIword\fP]] ... .TP .B export \-p .PD The supplied .I names are marked for automatic export to the environment of subsequently executed commands. If the .B \-f option is given, the .I names refer to functions. If no .I names are given, or if the .B \-p option is supplied, a list of all names that are exported in this shell is printed. The .B \-n option causes the export property to be removed from the named variables. .B export returns an exit status of 0 unless an invalid option is encountered, one of the \fInames\fP is not a valid shell variable name, or .B \-f is supplied with a .I name that is not a function. .TP .PD 0 \fBfc\fP [\fB\-e\fP \fIename\fP] [\fB\-nlr\fP] [\fIfirst\fP] [\fIlast\fP] .TP \fBfc\fP \fB\-s\fP [\fIpat\fP=\fIrep\fP] [\fIcmd\fP] .PD Fix Command. In the first form, a range of commands from .I first to .I last is selected from the history list. .I First and .I last may be specified as a string (to locate the last command beginning with that string) or as a number (an index into the history list, where a negative number is used as an offset from the current command number). If .I last is not specified it is set to the current command for listing (so that .if n ``fc \-l \-10'' .if t \f(CWfc \-l \-10\fP prints the last 10 commands) and to .I first otherwise. If .I first is not specified it is set to the previous command for editing and \-16 for listing. .sp 1 The .B \-n option suppresses the command numbers when listing. The .B \-r option reverses the order of the commands. If the .B \-l option is given, the commands are listed on standard output. Otherwise, the editor given by .I ename is invoked on a file containing those commands. If .I ename is not given, the value of the .SM .B FCEDIT variable is used, and the value of .SM .B EDITOR if .SM .B FCEDIT is not set. If neither variable is set, .FN vi is used. When editing is complete, the edited commands are echoed and executed. .sp 1 In the second form, \fIcommand\fP is re-executed after each instance of \fIpat\fP is replaced by \fIrep\fP. A useful alias to use with this is .if n ``r=fc -s'', .if t \f(CWr='fc \-s'\fP, so that typing .if n ``r cc'' .if t \f(CWr cc\fP runs the last command beginning with .if n ``cc'' .if t \f(CWcc\fP and typing .if n ``r'' .if t \f(CWr\fP re-executes the last command. .sp 1 If the first form is used, the return value is 0 unless an invalid option is encountered or .I first or .I last specify history lines out of range. If the .B \-e option is supplied, the return value is the value of the last command executed or failure if an error occurs with the temporary file of commands. If the second form is used, the return status is that of the command re-executed, unless .I cmd does not specify a valid history line, in which case .B fc returns failure. .TP \fBfg\fP [\fIjobspec\fP] Resume .I jobspec in the foreground, and make it the current job. If .I jobspec is not present, the shell's notion of the \fIcurrent job\fP is used. The return value is that of the command placed into the foreground, or failure if run when job control is disabled or, when run with job control enabled, if .I jobspec does not specify a valid job or .I jobspec specifies a job that was started without job control. .TP \fBgetopts\fP \fIoptstring\fP \fIname\fP [\fIargs\fP] .B getopts is used by shell procedures to parse positional parameters. .I optstring contains the option characters to be recognized; if a character is followed by a colon, the option is expected to have an argument, which should be separated from it by white space. The colon and question mark characters may not be used as option characters. Each time it is invoked, .B getopts places the next option in the shell variable .IR name , initializing .I name if it does not exist, and the index of the next argument to be processed into the variable .SM .BR OPTIND . .SM .B OPTIND is initialized to 1 each time the shell or a shell script is invoked. When an option requires an argument, .B getopts places that argument into the variable .SM .BR OPTARG . The shell does not reset .SM .B OPTIND automatically; it must be manually reset between multiple calls to .B getopts within the same shell invocation if a new set of parameters is to be used. .sp 1 When the end of options is encountered, \fBgetopts\fP exits with a return value greater than zero. \fBOPTIND\fP is set to the index of the first non-option argument, and \fBname\fP is set to ?. .sp 1 .B getopts normally parses the positional parameters, but if more arguments are given in .IR args , .B getopts parses those instead. .sp 1 .B getopts can report errors in two ways. If the first character of .I optstring is a colon, .I silent error reporting is used. In normal operation diagnostic messages are printed when invalid options or missing option arguments are encountered. If the variable .SM .B OPTERR is set to 0, no error messages will be displayed, even if the first character of .I optstring is not a colon. .sp 1 If an invalid option is seen, .B getopts places ? into .I name and, if not silent, prints an error message and unsets .SM .BR OPTARG . If .B getopts is silent, the option character found is placed in .SM .B OPTARG and no diagnostic message is printed. .sp 1 If a required argument is not found, and .B getopts is not silent, a question mark (\^\fB?\fP\^) is placed in .IR name , .SM .B OPTARG is unset, and a diagnostic message is printed. If .B getopts is silent, then a colon (\^\fB:\fP\^) is placed in .I name and .SM .B OPTARG is set to the option character found. .sp 1 .B getopts returns true if an option, specified or unspecified, is found. It returns false if the end of options is encountered or an error occurs. .TP \fBhash\fP [\fB\-r\fP] [\fB\-p\fP \fIfilename\fP] [\fB\-t\fP] [\fIname\fP] For each .IR name , the full file name of the command is determined by searching the directories in .B $PATH and remembered. If the .B \-p option is supplied, no path search is performed, and .I filename is used as the full file name of the command. The .B \-r option causes the shell to forget all remembered locations. If the .B \-t option is supplied, the full pathname to which each \fIname\fP corresponds is printed. If multiple \fIname\fP arguments are supplied with \fB\-t\fP, the \fIname\fP is printed before the hashed full pathname. If no arguments are given, information about remembered commands is printed. The return status is true unless a .I name is not found or an invalid option is supplied. .TP \fBhelp\fP [\fB\-s\fP] [\fIpattern\fP] Display helpful information about builtin commands. If .I pattern is specified, .B help gives detailed help on all commands matching .IR pattern ; otherwise help for all the builtins and shell control structures is printed. The \fB\-s\fP option restricts the information displayed to a short usage synopsis. The return status is 0 unless no command matches .IR pattern . .TP .PD 0 \fBhistory [\fIn\fP] .TP \fBhistory\fP \fB\-c\fP .TP \fBhistory \-d\fP \fIoffset\fP .TP \fBhistory\fP \fB\-anrw\fP [\fIfilename\fP] .TP \fBhistory\fP \fB\-p\fP \fIarg\fP [\fIarg ...\fP] .TP \fBhistory\fP \fB\-s\fP \fIarg\fP [\fIarg ...\fP] .PD With no options, display the command history list with line numbers. Lines listed with a .B * have been modified. An argument of .I n lists only the last .I n lines. If \fIfilename\fP is supplied, it is used as the name of the history file; if not, the value of .SM .B HISTFILE is used. Options, if supplied, have the following meanings: .RS .PD 0 .TP .B \-c Clear the history list by deleting all the entries. .TP \fB\-d\fP \fIoffset\fP Delete the history entry at position \fIoffset\fP. .TP .B \-a Append the ``new'' history lines (history lines entered since the beginning of the current \fBbash\fP session) to the history file. .TP .B \-n Read the history lines not already read from the history file into the current history list. These are lines appended to the history file since the beginning of the current \fBbash\fP session. .TP .B \-r Read the contents of the history file and use them as the current history. .TP .B \-w Write the current history to the history file, overwriting the history file's contents. .TP .B \-p Perform history substitution on the following \fIargs\fP and display the result on the standard output. Does not store the results in the history list. Each \fIarg\fP must be quoted to disable normal history expansion. .TP .B \-s Store the .I args in the history list as a single entry. The last command in the history list is removed before the .I args are added. .PD .PP The return value is 0 unless an invalid option is encountered, an error occurs while reading or writing the history file, an invalid \fIoffset\fP is supplied as an argument to \fB\-d\fP, or the history expansion supplied as an argument to \fB\-p\fP fails. .RE .TP .PD 0 \fBjobs\fP [\fB\-lnprs\fP] [ \fIjobspec\fP ... ] .TP \fBjobs\fP \fB\-x\fP \fIcommand\fP [ \fIargs\fP ... ] .PD The first form lists the active jobs. The options have the following meanings: .RS .PD 0 .TP .B \-l List process IDs in addition to the normal information. .TP .B \-p List only the process ID of the job's process group leader. .TP .B \-n Display information only about jobs that have changed status since the user was last notified of their status. .TP .B \-r Restrict output to running jobs. .TP .B \-s Restrict output to stopped jobs. .PD .PP If .I jobspec is given, output is restricted to information about that job. The return status is 0 unless an invalid option is encountered or an invalid .I jobspec is supplied. .PP If the .B \-x option is supplied, .B jobs replaces any .I jobspec found in .I command or .I args with the corresponding process group ID, and executes .I command passing it .IR args , returning its exit status. .RE .TP .PD 0 \fBkill\fP [\fB\-s\fP \fIsigspec\fP | \fB\-n\fP \fIsignum\fP | \fB\-\fP\fIsigspec\fP] [\fIpid\fP | \fIjobspec\fP] ... .TP \fBkill\fP \fB\-l\fP [\fIsigspec\fP | \fIexit_status\fP] .PD Send the signal named by .I sigspec or .I signum to the processes named by .I pid or .IR jobspec . .I sigspec is either a signal name such as .SM .B SIGKILL or a signal number; .I signum is a signal number. If .I sigspec is a signal name, the name may be given with or without the .SM .B SIG prefix. If .I sigspec is not present, then .SM .B SIGTERM is assumed. An argument of .B \-l lists the signal names. If any arguments are supplied when .B \-l is given, the names of the signals corresponding to the arguments are listed, and the return status is 0. The \fIexit_status\fP argument to .B \-l is a number specifying either a signal number or the exit status of a process terminated by a signal. .B kill returns true if at least one signal was successfully sent, or false if an error occurs or an invalid option is encountered. .TP \fBlet\fP \fIarg\fP [\fIarg\fP ...] Each .I arg is an arithmetic expression to be evaluated (see .SM .BR "ARITHMETIC EVALUATION" ). If the last .I arg evaluates to 0, .B let returns 1; 0 is returned otherwise. .TP \fBlocal\fP [\fIoption\fP] [\fIname\fP[=\fIvalue\fP] ...] For each argument, a local variable named .I name is created, and assigned .IR value . The \fIoption\fP can be any of the options accepted by \fBdeclare\fP. When .B local is used within a function, it causes the variable .I name to have a visible scope restricted to that function and its children. With no operands, .B local writes a list of local variables to the standard output. It is an error to use .B local when not within a function. The return status is 0 unless .B local is used outside a function, an invalid .I name is supplied, or \fIname\fP is a readonly variable. .TP .B logout Exit a login shell. .TP \fBpopd\fP [\-\fBn\fP] [+\fIn\fP] [\-\fIn\fP] Removes entries from the directory stack. With no arguments, removes the top directory from the stack, and performs a .B cd to the new top directory. Arguments, if supplied, have the following meanings: .RS .PD 0 .TP \fB+\fP\fIn\fP Removes the \fIn\fPth entry counting from the left of the list shown by .BR dirs , starting with zero. For example: .if n ``popd +0'' .if t \f(CWpopd +0\fP removes the first directory, .if n ``popd +1'' .if t \f(CWpopd +1\fP the second. .TP \fB\-\fP\fIn\fP Removes the \fIn\fPth entry counting from the right of the list shown by .BR dirs , starting with zero. For example: .if n ``popd -0'' .if t \f(CWpopd -0\fP removes the last directory, .if n ``popd -1'' .if t \f(CWpopd -1\fP the next to last. .TP .B \-n Suppresses the normal change of directory when removing directories from the stack, so that only the stack is manipulated. .PD .PP If the .B popd command is successful, a .B dirs is performed as well, and the return status is 0. .B popd returns false if an invalid option is encountered, the directory stack is empty, a non-existent directory stack entry is specified, or the directory change fails. .RE .TP \fBprintf\fP \fIformat\fP [\fIarguments\fP] Write the formatted \fIarguments\fP to the standard output under the control of the \fIformat\fP. The \fIformat\fP is a character string which contains three types of objects: plain characters, which are simply copied to standard output, character escape sequences, which are converted and copied to the standard output, and format specifications, each of which causes printing of the next successive \fIargument\fP. In addition to the standard \fIprintf\fP(1) formats, \fB%b\fP causes \fBprintf\fP to expand backslash escape sequences in the corresponding \fIargument\fP, and \fB%q\fP causes \fBprintf\fP to output the corresponding \fIargument\fP in a format that can be reused as shell input. .sp 1 The \fIformat\fP is reused as necessary to consume all of the \fIarguments\fP. If the \fIformat\fP requires more \fIarguments\fP than are supplied, the extra format specifications behave as if a zero value or null string, as appropriate, had been supplied. The return value is zero on success, non-zero on failure. .TP .PD 0 \fBpushd\fP [\fB\-n\fP] [\fIdir\fP] .TP \fBpushd\fP [\fB\-n\fP] [+\fIn\fP] [\-\fIn\fP] .PD Adds a directory to the top of the directory stack, or rotates the stack, making the new top of the stack the current working directory. With no arguments, exchanges the top two directories and returns 0, unless the directory stack is empty. Arguments, if supplied, have the following meanings: .RS .PD 0 .TP \fB+\fP\fIn\fP Rotates the stack so that the \fIn\fPth directory (counting from the left of the list shown by .BR dirs , starting with zero) is at the top. .TP \fB\-\fP\fIn\fP Rotates the stack so that the \fIn\fPth directory (counting from the right of the list shown by .BR dirs , starting with zero) is at the top. .TP .B \-n Suppresses the normal change of directory when adding directories to the stack, so that only the stack is manipulated. .TP .I dir Adds .I dir to the directory stack at the top, making it the new current working directory. .PD .PP If the .B pushd command is successful, a .B dirs is performed as well. If the first form is used, .B pushd returns 0 unless the cd to .I dir fails. With the second form, .B pushd returns 0 unless the directory stack is empty, a non-existent directory stack element is specified, or the directory change to the specified new current directory fails. .RE .TP \fBpwd\fP [\fB\-LP\fP] Print the absolute pathname of the current working directory. The pathname printed contains no symbolic links if the .B \-P option is supplied or the .B \-o physical option to the .B set builtin command is enabled. If the .B \-L option is used, the pathname printed may contain symbolic links. The return status is 0 unless an error occurs while reading the name of the current directory or an invalid option is supplied. .TP \fBread\fP [\fB\-ers\fP] [\fB\-t\fP \fItimeout\fP] [\fB\-a\fP \fIaname\fP] [\fB\-p\fP \fIprompt\fP] [\fB\-n\fP \fInchars\fP] [\fB\-d\fP \fIdelim\fP] [\fIname\fP ...] One line is read from the standard input, and the first word is assigned to the first .IR name , the second word to the second .IR name , and so on, with leftover words and their intervening separators assigned to the last .IR name . If there are fewer words read from the standard input than names, the remaining names are assigned empty values. The characters in .SM .B IFS are used to split the line into words. The backslash character (\fB\e\fP) may be used to remove any special meaning for the next character read and for line continuation. Options, if supplied, have the following meanings: .RS .PD 0 .TP .B \-a \fIaname\fP The words are assigned to sequential indices of the array variable .IR aname , starting at 0. .I aname is unset before any new values are assigned. Other \fIname\fP arguments are ignored. .TP .B \-d \fIdelim\fP The first character of \fIdelim\fP is used to terminate the input line, rather than newline. .TP .B \-e If the standard input is coming from a terminal, .B readline (see .SM .B READLINE above) is used to obtain the line. .TP .B \-n \fInchars\fP \fBread\fP returns after reading \fInchars\fP characters rather than waiting for a complete line of input. .TP .B \-p \fIprompt\fP Display \fIprompt\fP on standard error, without a trailing newline, before attempting to read any input. The prompt is displayed only if input is coming from a terminal. .TP .B \-r Backslash does not act as an escape character. The backslash is considered to be part of the line. In particular, a backslash-newline pair may not be used as a line continuation. .TP .B \-s Silent mode. If input is coming from a terminal, characters are not echoed. .TP .B \-t \fItimeout\fP Cause \fBread\fP to time out and return failure if a complete line of input is not read within \fItimeout\fP seconds. This option has no effect if \fBread\fP is not reading input from the terminal or a pipe. .PD .PP If no .I names are supplied, the line read is assigned to the variable .SM .BR REPLY . The return code is zero, unless end-of-file is encountered or \fBread\fP times out. .RE .TP \fBreadonly\fP [\fB\-apf\fP] [\fIname\fP ...] .PD The given \fInames\fP are marked readonly; the values of these .I names may not be changed by subsequent assignment. If the .B \-f option is supplied, the functions corresponding to the \fInames\fP are so marked. The .B \-a option restricts the variables to arrays. If no .I name arguments are given, or if the .B \-p option is supplied, a list of all readonly names is printed. The .B \-p option causes output to be displayed in a format that may be reused as input. The return status is 0 unless an invalid option is encountered, one of the .I names is not a valid shell variable name, or .B \-f is supplied with a .I name that is not a function. .TP \fBreturn\fP [\fIn\fP] Causes a function to exit with the return value specified by .IR n . If .I n is omitted, the return status is that of the last command executed in the function body. If used outside a function, but during execution of a script by the .B . (\fBsource\fP) command, it causes the shell to stop executing that script and return either .I n or the exit status of the last command executed within the script as the exit status of the script. If used outside a function and not during execution of a script by \fB.\fP\^, the return status is false. .TP \fBset\fP [\fB\-\-abefhkmnptuvxBCHP\fP] [\fB\-o\fP \fIoption\fP] [\fIarg\fP ...] Without options, the name and value of each shell variable are displayed in a format that can be reused as input. The output is sorted according to the current locale. When options are specified, they set or unset shell attributes. Any arguments remaining after the options are processed are treated as values for the positional parameters and are assigned, in order, to .BR $1 , .BR $2 , .B ... .BR $\fIn\fP . Options, if specified, have the following meanings: .RS .PD 0 .TP 8 .B \-a Automatically mark variables and functions which are modified or created for export to the environment of subsequent commands. .TP 8 .B \-b Report the status of terminated background jobs immediately, rather than before the next primary prompt. This is effective only when job control is enabled. .TP 8 .B \-e Exit immediately if a \fIsimple command\fP (see .SM .B SHELL GRAMMAR above) exits with a non-zero status. The shell does not exit if the command that fails is part of an .I until or .I while loop, part of an .I if statement, part of a .B && or .B \(bv\(bv list, or if the command's return value is being inverted via .BR ! . A trap on \fBERR\fP, if set, is executed before the shell exits. .TP 8 .B \-f Disable pathname expansion. .TP 8 .B \-h Remember the location of commands as they are looked up for execution. This is enabled by default. .TP 8 .B \-k All arguments in the form of assignment statements are placed in the environment for a command, not just those that precede the command name. .TP 8 .B \-m Monitor mode. Job control is enabled. This option is on by default for interactive shells on systems that support it (see .SM .B JOB CONTROL above). Background processes run in a separate process group and a line containing their exit status is printed upon their completion. .TP 8 .B \-n Read commands but do not execute them. This may be used to check a shell script for syntax errors. This is ignored by interactive shells. .TP 8 .B \-o \fIoption\-name\fP The \fIoption\-name\fP can be one of the following: .RS .TP 8 .B allexport Same as .BR \-a . .TP 8 .B braceexpand Same as .BR \-B . .TP 8 .B emacs Use an emacs-style command line editing interface. This is enabled by default when the shell is interactive, unless the shell is started with the .B \-\-noediting option. .TP 8 .B errexit Same as .BR \-e . .TP 8 .B hashall Same as .BR \-h . .TP 8 .B histexpand Same as .BR \-H . .TP 8 .B history Enable command history, as described above under .SM .BR HISTORY . This option is on by default in interactive shells. .TP 8 .B ignoreeof The effect is as if the shell command .if t \f(CWIGNOREEOF=10\fP .if n ``IGNOREEOF=10'' had been executed (see .B Shell Variables above). .TP 8 .B keyword Same as .BR \-k . .TP 8 .B monitor Same as .BR \-m . .TP 8 .B noclobber Same as .BR \-C . .TP 8 .B noexec Same as .BR \-n . .TP 8 .B noglob Same as .BR \-f . .B nolog Currently ignored. .TP 8 .B notify Same as .BR \-b . .TP 8 .B nounset Same as .BR \-u . .TP 8 .B onecmd Same as .BR \-t . .TP 8 .B physical Same as .BR \-P . .TP 8 .B posix Change the behavior of .B bash where the default operation differs from the POSIX 1003.2 standard to match the standard (\fIposix mode\fP). .TP 8 .B privileged Same as .BR \-p . .TP 8 .B verbose Same as .BR \-v . .TP 8 .B vi Use a vi-style command line editing interface. .TP 8 .B xtrace Same as .BR \-x . .sp .5 .PP If .B \-o is supplied with no \fIoption\-name\fP, the values of the current options are printed. If .B +o is supplied with no \fIoption\-name\fP, a series of .B set commands to recreate the current option settings is displayed on the standard output. .RE .TP 8 .B \-p Turn on .I privileged mode. In this mode, the .SM .B $ENV and .SM .B $BASH_ENV files are not processed, shell functions are not inherited from the environment, and the .SM .B SHELLOPTS variable, if it appears in the environment, is ignored. If the shell is started with the effective user (group) id not equal to the real user (group) id, and the \fB\-p\fP option is not supplied, these actions are taken and the effective user id is set to the real user id. If the \fB\-p\fP option is supplied at startup, the effective user id is not reset. Turning this option off causes the effective user and group ids to be set to the real user and group ids. .TP 8 .B \-t Exit after reading and executing one command. .TP 8 .B \-u Treat unset variables as an error when performing parameter expansion. If expansion is attempted on an unset variable, the shell prints an error message, and, if not interactive, exits with a non-zero status. .TP 8 .B \-v Print shell input lines as they are read. .TP 8 .B \-x After expanding each \fIsimple command\fP, display the expanded value of .SM .BR PS4 , followed by the command and its expanded arguments. .TP 8 .B \-B The shell performs brace expansion (see .B Brace Expansion above). This is on by default. .TP 8 .B \-C If set, .B bash does not overwrite an existing file with the .BR > , .BR >& , and .B <> redirection operators. This may be overridden when creating output files by using the redirection operator .B >| instead of .BR > . .TP 8 .B \-H Enable .B ! style history substitution. This option is on by default when the shell is interactive. .TP 8 .B \-P If set, the shell does not follow symbolic links when executing commands such as .B cd that change the current working directory. It uses the physical directory structure instead. By default, .B bash follows the logical chain of directories when performing commands which change the current directory. .TP 8 .B \-\- If no arguments follow this option, then the positional parameters are unset. Otherwise, the positional parameters are set to the \fIarg\fPs, even if some of them begin with a .BR \- . .TP 8 .B \- Signal the end of options, cause all remaining \fIarg\fPs to be assigned to the positional parameters. The .B \-x and .B \-v options are turned off. If there are no \fIarg\fPs, the positional parameters remain unchanged. .PD .PP The options are off by default unless otherwise noted. Using + rather than \- causes these options to be turned off. The options can also be specified as arguments to an invocation of the shell. The current set of options may be found in .BR $\- . The return status is always true unless an invalid option is encountered. .RE .TP \fBshift\fP [\fIn\fP] The positional parameters from \fIn\fP+1 ... are renamed to .B $1 .B .... Parameters represented by the numbers \fB$#\fP down to \fB$#\fP\-\fIn\fP+1 are unset. .I n must be a non-negative number less than or equal to \fB$#\fP. If .I n is 0, no parameters are changed. If .I n is not given, it is assumed to be 1. If .I n is greater than \fB$#\fP, the positional parameters are not changed. The return status is greater than zero if .I n is greater than .B $# or less than zero; otherwise 0. .TP \fBshopt\fP [\fB\-pqsu\fP] [\fB\-o\fP] [\fIoptname\fP ...] Toggle the values of variables controlling optional shell behavior. With no options, or with the .B \-p option, a list of all settable options is displayed, with an indication of whether or not each is set. The \fB\-p\fP option causes output to be displayed in a form that may be reused as input. Other options have the following meanings: .RS .PD 0 .TP .B \-s Enable (set) each \fIoptname\fP. .TP .B \-u Disable (unset) each \fIoptname\fP. .TP .B \-q Suppresses normal output (quiet mode); the return status indicates whether the \fIoptname\fP is set or unset. If multiple \fIoptname\fP arguments are given with .BR \-q , the return status is zero if all \fIoptnames\fP are enabled; non-zero otherwise. .TP .B \-o Restricts the values of \fIoptname\fP to be those defined for the .B \-o option to the .B set builtin. .PD .PP If either .B \-s or .B \-u is used with no \fIoptname\fP arguments, the display is limited to those options which are set or unset, respectively. Unless otherwise noted, the \fBshopt\fP options are disabled (unset) by default. .PP The return status when listing options is zero if all \fIoptnames\fP are enabled, non-zero otherwise. When setting or unsetting options, the return status is zero unless an \fIoptname\fP is not a valid shell option. .PP The list of \fBshopt\fP options is: .if t .sp .5v .if n .sp 1v .PD 0 .TP 8 .B cdable_vars If set, an argument to the .B cd builtin command that is not a directory is assumed to be the name of a variable whose value is the directory to change to. .TP 8 .B cdspell If set, minor errors in the spelling of a directory component in a .B cd command will be corrected. The errors checked for are transposed characters, a missing character, and one character too many. If a correction is found, the corrected file name is printed, and the command proceeds. This option is only used by interactive shells. .TP 8 .B checkhash If set, \fBbash\fP checks that a command found in the hash table exists before trying to execute it. If a hashed command no longer exists, a normal path search is performed. .TP 8 .B checkwinsize If set, \fBbash\fP checks the window size after each command and, if necessary, updates the values of .SM .B LINES and .SM .BR COLUMNS . .TP 8 .B cmdhist If set, .B bash attempts to save all lines of a multiple-line command in the same history entry. This allows easy re-editing of multi-line commands. .TP 8 .B dotglob If set, .B bash includes filenames beginning with a `.' in the results of pathname expansion. .TP 8 .B execfail If set, a non-interactive shell will not exit if it cannot execute the file specified as an argument to the .B exec builtin command. An interactive shell does not exit if .B exec fails. .TP 8 .B expand_aliases If set, aliases are expanded as described above under .SM .BR ALIASES . This option is enabled by default for interactive shells. .TP 8 .B extglob If set, the extended pattern matching features described above under \fBPathname Expansion\fP are enabled. .TP 8 .B histappend If set, the history list is appended to the file named by the value of the .B HISTFILE variable when the shell exits, rather than overwriting the file. .TP 8 .B histreedit If set, and .B readline is being used, a user is given the opportunity to re-edit a failed history substitution. .TP 8 .B histverify If set, and .B readline is being used, the results of history substitution are not immediately passed to the shell parser. Instead, the resulting line is loaded into the \fBreadline\fP editing buffer, allowing further modification. .TP 8 .B hostcomplete If set, and .B readline is being used, \fBbash\fP will attempt to perform hostname completion when a word containing a \fB@\fP is being completed (see .B Completing under .SM .B READLINE above). This is enabled by default. .TP 8 .B huponexit If set, \fBbash\fP will send .SM .B SIGHUP to all jobs when an interactive login shell exits. .TP 8 .B interactive_comments If set, allow a word beginning with .B # to cause that word and all remaining characters on that line to be ignored in an interactive shell (see .SM .B COMMENTS above). This option is enabled by default. .TP 8 .B lithist If set, and the .B cmdhist option is enabled, multi-line commands are saved to the history with embedded newlines rather than using semicolon separators where possible. .TP 8 .B login_shell The shell sets this option if it is started as a login shell (see .SM .B "INVOCATION" above). The value may not be changed. .TP 8 .B mailwarn If set, and a file that \fBbash\fP is checking for mail has been accessed since the last time it was checked, the message ``The mail in \fImailfile\fP has been read'' is displayed. .TP 8 .B no_empty_cmd_completion If set, and .B readline is being used, .B bash will not attempt to search the \fBPATH\fP for possible completions when completion is attempted on an empty line. .TP 8 .B nocaseglob If set, .B bash matches filenames in a case\-insensitive fashion when performing pathname expansion (see .B Pathname Expansion above). .TP 8 .B nullglob If set, .B bash allows patterns which match no files (see .B Pathname Expansion above) to expand to a null string, rather than themselves. .TP 8 .B progcomp If set, the programmable completion facilities (see \fBProgrammable Completion\fP above) are enabled. This option is enabled by default. .TP 8 .B promptvars If set, prompt strings undergo variable and parameter expansion after being expanded as described in .SM .B PROMPTING above. This option is enabled by default. .TP 8 .B restricted_shell The shell sets this option if it is started in restricted mode (see .SM .B "RESTRICTED SHELL" below). The value may not be changed. This is not reset when the startup files are executed, allowing the startup files to discover whether or not a shell is restricted. .TP 8 .B shift_verbose If set, the .B shift builtin prints an error message when the shift count exceeds the number of positional parameters. .TP 8 .B sourcepath If set, the \fBsource\fP (\fB.\fP) builtin uses the value of .SM .B PATH to find the directory containing the file supplied as an argument. This option is enabled by default. .TP 8 .B xpg_echo If set, the \fBecho\fP builtin expands backslash-escape sequences by default. .RE .TP \fBsuspend\fP [\fB\-f\fP] Suspend the execution of this shell until it receives a .SM .B SIGCONT signal. The .B \-f option says not to complain if this is a login shell; just suspend anyway. The return status is 0 unless the shell is a login shell and .B \-f is not supplied, or if job control is not enabled. .TP .PD 0 \fBtest\fP \fIexpr\fP .TP \fB[\fP \fIexpr\fP \fB]\fP Return a status of 0 or 1 depending on the evaluation of the conditional expression .IR expr . Each operator and operand must be a separate argument. Expressions are composed of the primaries described above under .SM .BR "CONDITIONAL EXPRESSIONS" . .if t .sp 0.5 .if n .sp 1 Expressions may be combined using the following operators, listed in decreasing order of precedence. .RS .PD 0 .TP .B ! \fIexpr\fP True if .I expr is false. .TP .B ( \fIexpr\fP ) Returns the value of \fIexpr\fP. This may be used to override the normal precedence of operators. .TP \fIexpr1\fP \-\fBa\fP \fIexpr2\fP True if both .I expr1 and .I expr2 are true. .TP \fIexpr1\fP \-\fBo\fP \fIexpr2\fP True if either .I expr1 or .I expr2 is true. .PD .PP \fBtest\fP and \fB[\fP evaluate conditional expressions using a set of rules based on the number of arguments. .if t .sp 0.5 .if n .sp 1 .PD 0 .TP 0 arguments The expression is false. .TP 1 argument The expression is true if and only if the argument is not null. .TP 2 arguments If the first argument is \fB!\fP, the expression is true if and only if the second argument is null. If the first argument is one of the unary conditional operators listed above under .SM .BR "CONDITIONAL EXPRESSIONS" , the expression is true if the unary test is true. If the first argument is not a valid unary conditional operator, the expression is false. .TP 3 arguments If the second argument is one of the binary conditional operators listed above under .SM .BR "CONDITIONAL EXPRESSIONS" , the result of the expression is the result of the binary test using the first and third arguments as operands. If the first argument is \fB!\fP, the value is the negation of the two-argument test using the second and third arguments. If the first argument is exactly \fB(\fP and the third argument is exactly \fB)\fP, the result is the one-argument test of the second argument. Otherwise, the expression is false. The \fB\-a\fP and \fB\-o\fP operators are considered binary operators in this case. .TP 4 arguments If the first argument is \fB!\fP, the result is the negation of the three-argument expression composed of the remaining arguments. Otherwise, the expression is parsed and evaluated according to precedence using the rules listed above. .TP 5 or more arguments The expression is parsed and evaluated according to precedence using the rules listed above. .RE .PD .TP .B times Print the accumulated user and system times for the shell and for processes run from the shell. The return status is 0. .TP \fBtrap\fP [\fB\-lp\fP] [\fIarg\fP] [\fIsigspec\fP ...] The command .I arg is to be read and executed when the shell receives signal(s) .IR sigspec . If .I arg is absent or .BR \- , all specified signals are reset to their original values (the values they had upon entrance to the shell). If .I arg is the null string the signal specified by each .I sigspec is ignored by the shell and by the commands it invokes. If .I arg is not present and .B \-p has been supplied, then the trap commands associated with each .I sigspec are displayed. If no arguments are supplied or if only .B \-p is given, .B trap prints the list of commands associated with each signal number. Each .I sigspec is either a signal name defined in <\fIsignal.h\fP>, or a signal number. If a .I sigspec is .SM .B EXIT (0) the command .I arg is executed on exit from the shell. If a .I sigspec is .SM .BR DEBUG , the command .I arg is executed after every \fIsimple command\fP (see .SM .B SHELL GRAMMAR above). If a .I sigspec is .SM .BR ERR , the command .I arg is executed whenever a simple command has a non\-zero exit status. The .SM .BR ERR trap is not executed if the failed command is part of an .I until or .I while loop, part of an .I if statement, part of a .B && or .B \(bv\(bv list, or if the command's return value is being inverted via .BR ! . The .B \-l option causes the shell to print a list of signal names and their corresponding numbers. Signals ignored upon entry to the shell cannot be trapped or reset. Trapped signals are reset to their original values in a child process when it is created. The return status is false if any .I sigspec is invalid; otherwise .B trap returns true. .TP \fBtype\fP [\fB\-atp\fP] \fIname\fP [\fIname\fP ...] With no options, indicate how each .I name would be interpreted if used as a command name. If the .B \-t option is used, .B type prints a string which is one of .IR alias , .IR keyword , .IR function , .IR builtin , or .I file if .I name is an alias, shell reserved word, function, builtin, or disk file, respectively. If the .I name is not found, then nothing is printed, and an exit status of false is returned. If the .B \-p option is used, .B type either returns the name of the disk file that would be executed if .I name were specified as a command name, or nothing if .if t \f(CWtype -t name\fP .if n ``type -t name'' would not return .IR file . If a command is hashed, .B \-p prints the hashed value, not necessarily the file that appears first in .SM .BR PATH . If the .B \-a option is used, .B type prints all of the places that contain an executable named .IR name . This includes aliases and functions, if and only if the .B \-p option is not also used. The table of hashed commands is not consulted when using .BR \-a . .B type returns true if any of the arguments are found, false if none are found. .TP \fBulimit\fP [\fB\-SHacdflmnpstuv\fP [\fIlimit\fP]] Provides control over the resources available to the shell and to processes started by it, on systems that allow such control. The \fB\-H\fP and \fB\-S\fP options specify that the hard or soft limit is set for the given resource. A hard limit cannot be increased once it is set; a soft limit may be increased up to the value of the hard limit. If neither \fB\-H\fP nor \fB\-S\fP is specified, both the soft and hard limits are set. The value of .I limit can be a number in the unit specified for the resource or one of the special values .BR hard , .BR soft , or .BR unlimited , which stand for the current hard limit, the current soft limit, and no limit, respectively. If .I limit is omitted, the current value of the soft limit of the resource is printed, unless the \fB\-H\fP option is given. When more than one resource is specified, the limit name and unit are printed before the value. Other options are interpreted as follows: .RS .PD 0 .TP .B \-a All current limits are reported .TP .B \-c The maximum size of core files created .TP .B \-d The maximum size of a process's data segment .TP .B \-f The maximum size of files created by the shell .TP .B \-l The maximum size that may be locked into memory .TP .B \-m The maximum resident set size .TP .B \-n The maximum number of open file descriptors (most systems do not allow this value to be set) .TP .B \-p The pipe size in 512-byte blocks (this may not be set) .TP .B \-s The maximum stack size .TP .B \-t The maximum amount of cpu time in seconds .TP .B \-u The maximum number of processes available to a single user .TP .B \-v The maximum amount of virtual memory available to the shell .PD .PP If .I limit is given, it is the new value of the specified resource (the .B \-a option is display only). If no option is given, then .B \-f is assumed. Values are in 1024-byte increments, except for .BR \-t , which is in seconds, .BR \-p , which is in units of 512-byte blocks, and .B \-n and .BR \-u , which are unscaled values. The return status is 0 unless an invalid option or argument is supplied, or an error occurs while setting a new limit. .RE .TP \fBumask\fP [\fB\-p\fP] [\fB\-S\fP] [\fImode\fP] The user file-creation mask is set to .IR mode . If .I mode begins with a digit, it is interpreted as an octal number; otherwise it is interpreted as a symbolic mode mask similar to that accepted by .IR chmod (1). If .I mode is omitted, the current value of the mask is printed. The .B \-S option causes the mask to be printed in symbolic form; the default output is an octal number. If the .B \-p option is supplied, and .I mode is omitted, the output is in a form that may be reused as input. The return status is 0 if the mode was successfully changed or if no \fImode\fP argument was supplied, and false otherwise. .TP \fBunalias\fP [\-\fBa\fP] [\fIname\fP ...] Remove each \fIname\fP from the list of defined aliases. If .B \-a is supplied, all alias definitions are removed. The return value is true unless a supplied .I name is not a defined alias. .TP \fBunset\fP [\-\fBfv\fP] [\fIname\fP ...] For each .IR name , remove the corresponding variable or function. If no options are supplied, or the .B \-v option is given, each .I name refers to a shell variable. Read-only variables may not be unset. If .B \-f is specifed, each .I name refers to a shell function, and the function definition is removed. Each unset variable or function is removed from the environment passed to subsequent commands. If any of .SM .BR RANDOM , .SM .BR SECONDS , .SM .BR LINENO , .SM .BR HISTCMD , .SM .BR FUNCNAME , .SM .BR GROUPS , or .SM .B DIRSTACK are unset, they lose their special properties, even if they are subsequently reset. The exit status is true unless a .I name does not exist or is readonly. .TP \fBwait\fP [\fIn\fP] Wait for the specified process and return its termination status. .I n may be a process ID or a job specification; if a job spec is given, all processes in that job's pipeline are waited for. If .I n is not given, all currently active child processes are waited for, and the return status is zero. If .I n specifies a non-existent process or job, the return status is 127. Otherwise, the return status is the exit status of the last process or job waited for. .\" bash_builtins .if \n(zZ=1 .ig zZ .SH "RESTRICTED SHELL" .\" rbash.1 .zY .PP If .B bash is started with the name .BR rbash , or the .B \-r option is supplied at invocation, the shell becomes restricted. A restricted shell is used to set up an environment more controlled than the standard shell. It behaves identically to .B bash with the exception that the following are disallowed or not performed: .IP \(bu changing directories with \fBcd\fP .IP \(bu setting or unsetting the values of .BR SHELL , .BR PATH , .BR ENV , or .B BASH_ENV .IP \(bu specifying command names containing .B / .IP \(bu specifying a file name containing a .B / as an argument to the .B . builtin command .IP \(bu Specifying a filename containing a slash as an argument to the .B \-p option to the .B hash builtin command .IP \(bu importing function definitions from the shell environment at startup .IP \(bu parsing the value of \fBSHELLOPTS\fP from the shell environment at startup .IP \(bu redirecting output using the >, >|, <>, >&, &>, and >> redirection operators .IP \(bu using the .B exec builtin command to replace the shell with another command .IP \(bu adding or deleting builtin commands with the .B \-f and .B \-d options to the .B enable builtin command .IP \(bu specifying the .B \-p option to the .B command builtin command .IP \(bu turning off restricted mode with \fBset +r\fP or \fBset +o restricted\fP. .PP These restrictions are enforced after any startup files are read. .PP When a command that is found to be a shell script is executed (see .SM .B "COMMAND EXECUTION" above), .B rbash turns off any restrictions in the shell spawned to execute the script. .\" end of rbash.1 .if \n(zY=1 .ig zY .SH "SEE ALSO" .PD 0 .TP \fIBash Reference Manual\fP, Brian Fox and Chet Ramey .TP \fIThe Gnu Readline Library\fP, Brian Fox and Chet Ramey .TP \fIThe Gnu History Library\fP, Brian Fox and Chet Ramey .TP \fIPortable Operating System Interface (POSIX) Part 2: Shell and Utilities\fP, IEEE .TP \fIsh\fP(1), \fIksh\fP(1), \fIcsh\fP(1) .TP \fIemacs\fP(1), \fIvi\fP(1) .TP \fIreadline\fP(3) .PD .SH FILES .PD 0 .TP .FN /bin/bash The \fBbash\fP executable .TP .FN /etc/profile The systemwide initialization file, executed for login shells .TP .FN ~/.bash_profile The personal initialization file, executed for login shells .TP .FN ~/.bashrc The individual per-interactive-shell startup file .TP .FN ~/.bash_logout The individual login shell cleanup file, executed when a login shell exits .TP .FN ~/.inputrc Individual \fIreadline\fP initialization file .PD .SH AUTHORS Brian Fox, Free Software Foundation .br bfox@gnu.org .PP Chet Ramey, Case Western Reserve University .br chet@ins.CWRU.Edu .SH BUG REPORTS If you find a bug in .B bash, you should report it. But first, you should make sure that it really is a bug, and that it appears in the latest version of .B bash that you have. .PP Once you have determined that a bug actually exists, use the .I bashbug command to submit a bug report. If you have a fix, you are encouraged to mail that as well! Suggestions and `philosophical' bug reports may be mailed to \fIbug-bash@gnu.org\fP or posted to the Usenet newsgroup .BR gnu.bash.bug . .PP ALL bug reports should include: .PP .PD 0 .TP 20 The version number of \fBbash\fR .TP The hardware and operating system .TP The compiler used to compile .TP A description of the bug behaviour .TP A short script or `recipe' which exercises the bug .PD .PP .I bashbug inserts the first three items automatically into the template it provides for filing a bug report. .PP Comments and bug reports concerning this manual page should be directed to .IR chet@ins.CWRU.Edu . .SH BUGS .PP It's too big and too slow. .PP There are some subtle differences between .B bash and traditional versions of .BR sh , mostly because of the .SM .B POSIX specification. .PP Aliases are confusing in some uses. .PP Shell builtin commands and functions are not stoppable/restartable. .PP Compound commands and command sequences of the form `a ; b ; c' are not handled gracefully when process suspension is attempted. When a process is stopped, the shell immediately executes the next command in the sequence. It suffices to place the sequence of commands between parentheses to force it into a subshell, which may be stopped as a unit. .PP Commands inside of \fB$(\fP...\fB)\fP command substitution are not parsed until substitution is attempted. This will delay error reporting until some time after the command is entered. .PP Array variables may not (yet) be exported. .zZ .zY bash-2.05a/doc/bashbug.1100644 436 0 2477 6560153031 13206 0ustar chetwheel.TH BASHBUG 1 "1998 July 30" GNU .SH NAME bashbug \- report a bug in bash .SH SYNOPSIS \fBbashbug\fP [\fIaddress\fP] .SH DESCRIPTION .B bashbug is a shell script to help the user compose and mail bug reports concerning bash in a standard format. .B bashbug invokes the editor specified by the environment variable .SM .B EDITOR on a temporary copy of the bug report format outline. The user must fill in the appropriate fields and exit the editor. .B bashbug then mails the completed report to \fIbug-bash@gnu.org\fP, or \fIaddress\fP. If the report cannot be mailed, it is saved in the file \fIdead.bashbug\fP in the invoking user's home directory. .PP The bug report format outline consists of several sections. The first section provides information about the machine, operating system, the bash version, and the compilation environment. The second section should be filled in with a description of the bug. The third section should be a description of how to reproduce the bug. The optional fourth section is for a proposed fix. Fixes are encouraged. .SH ENVIRONMENT .B bashbug will utilize the following environment variables if they exist: .TP .B EDITOR Specifies the preferred editor. If .SM .B EDITOR is not set, .B bashbug defaults to .BR emacs . .TP .B HOME Directory in which the failed bug report is saved if the mail fails. bash-2.05a/doc/builtins.1100664 436 0 1330 7367267730 13433 0ustar chetwheel.\" This is a hack to force bash builtins into the whatis database .\" and to get the list of builtins to come up with the man command. .TH BASH_BUILTINS 1 "2001 October 29" "GNU Bash-2.05a" .SH NAME bash, :, ., [, alias, bg, bind, break, builtin, case, cd, command, compgen, complete, continue, declare, dirs, disown, echo, enable, eval, exec, exit, export, fc, fg, for, getopts, hash, help, history, if, jobs, kill, let, local, logout, popd, printf, pushd, pwd, read, readonly, return, set, shift, shopt, source, suspend, test, times, trap, type, typeset, ulimit, umask, unalias, unset, until, wait, while \- bash built-in commands, see \fBbash\fR(1) .SH BASH BUILTIN COMMANDS .nr zZ 1 .so bash.1 .SH SEE ALSO bash(1), sh(1) bash-2.05a/doc/rbash.1100664 436 0 221 7020570133 12633 0ustar chetwheel.TH RBASH 1 "1999 Nov 29" GNU .SH NAME rbash \- restricted bash, see \fBbash\fR(1) .SH RESTRICTED SHELL .nr zY 1 .so bash.1 .SH SEE ALSO bash(1) bash-2.05a/doc/README100664 436 0 2074 6662630554 12401 0ustar chetwheelThis directory contains the bash documentation. FAQ - a set of frequently-asked questions about Bash with answers INTRO - a short introduction to bash article.ms - an article I wrote about bash for The Linux Journal bash.1 - the bash man page builtins.1 - a man page that documents the builtins, extracted from bash.1 bashref.texi - the `bash reference manual' bashref.info - the `bash reference manual' processed by `makeinfo' readline.3 - the readline man page The `.ps' files are postscript versions of the above. The `.html' files are HTML versions of the man page and reference manual. The `.0' files are formatted manual pages. The `.txt' versions are ascii -- the output of `groff -Tascii'. The rest of this file explains how to use the `builtins.1' man page. For each command in the list of builtins create a file in man/man1 called: ${command}.1 eg. for.1 type.1 alias.1 etc. All these files are identical as follows: jaws@jaws(264)$ cat alias.1 .so man1/builtins.1 jaws@jaws(265)$ Make sure you adjust the .so line in builtins.1 to reflect where you put it. bash-2.05a/doc/INTRO100664 436 0 15640 6662630406 12356 0ustar chetwheel BASH - The Bourne-Again Shell Bash is the shell, or command language interpreter, that will appear in the GNU operating system. Bash is an sh-compatible shell that incorporates useful features from the Korn shell (ksh) and C shell (csh). It is intended to conform to the IEEE POSIX P1003.2/ISO 9945.2 Shell and Tools standard. It offers functional improvements over sh for both programming and interactive use. In addition, most sh scripts can be run by Bash without modification. Bash is quite portable. It uses a configuration system that discovers characteristics of the compilation platform at build time, and may therefore be built on nearly every version of UNIX. Ports to UNIX-like systems such as QNX and Minix and to non-UNIX systems such as OS/2, Windows 95, and Windows NT are available. Bash includes the following features: Editing and Completion Bash offers a command-line editing facility which permits users to edit command lines using familiar emacs or vi-style editing commands. Editing allows corrections to be made without having to erase back to the point of error or start the command line anew. The editing facilities include a feature that allows users to complete command and file names. The Bash line editing library is fully customizable. Users may define their own key bindings -- the action taken when a key is pressed. A number of variables to fine-tune editing behavior are also available. History and Command Re-entry The Bash history feature remembers commands entered to the shell and allows them to be recalled and re-executed. The history list may be of unlimited size. Bash allows users to search for previous commands and reuse portions of those commands when composing new ones. The history list may be saved across shell sessions. Bash allows users to control which commands are saved on the history list. Job Control On systems that support it, Bash provides an interface to the operating system's job control facilities, which allow processes to be suspended and restarted, and moved between the foreground and background. Bash allows users to selectively `forget' about background jobs. Shell Functions and Aliases These mechanisms are available to bind a user-selected identifier to a list of commands that will be executed when the identifier is used as a command name. Functions allow local variables and recursion, and have access to the environment of the calling shell. Aliases may be used to create a mnemonic for a command name, expand a single word to a complex command, or ensure that a command is called with a basic set of options. Arrays Bash-2.0 supports indexed arrays of unlimited size. The subscript for an array is an arithmetic expression. Arrays may be assigned to with a new compound assignment syntax, and several builtins have options to operate on array variables. Bash includes a number of built-in array variables. Arithmetic Bash allows users to perform integer arithmetic in any base from two to sixty-four. Nearly all of the C language arithmetic operators are available with the same syntax and precedence as in C. Arithmetic expansion allows an arithmetic expression to be evaluated and the result substituted into the command line. Shell variables can be used as operands, and the value of an expression may be assigned to a variable. An arithmetic expression may be used as a command; the exit status of the command is the value of the expression. ANSI-C Quoting There is a new quoting syntax that allows backslash-escaped characters in strings to be expanded according to the ANSI C standard. Tilde Expansion Users' home directories may be expanded using this feature. Words beginning with a tilde may also be expanded to the current or previous working directory. Brace Expansion Brace expansion is a convenient way to generate a list of strings that share a common prefix or suffix. Substring Capabilities Bash allows new strings to be created by removing leading or trailing substrings from existing variable values, or by specifying a starting offset and length. Portions of variable values may be matched against shell patterns and the matching portion removed or a new value substituted. Indirect Variable Expansion Bash makes it easy to find the value of a shell variable whose name is the value of another variable. Expanded I/O Capabilities Bash provides several input and output features not available in sh, including the ability to: o specify a file or file descriptor for both input and output o read from or write to asynchronous processes using named pipes o read lines ending in backslash o display a prompt on the terminal before a read o format menus and interpret responses to them o echo lines exactly as input without escape processing Control of Builtin Commands Bash implements several builtin commands to give users more control over which commands are executed. The enable builtin allows other builtin commands to be selectively enabled or disabled. The command and builtin builtins change the order in which the shell searches for commands. On systems that provide dynamic loading, new builtins may be loaded into a running shell from a shared object file. These new builtins have access to all of the shell facilities. Help Bash includes a built-in help facility. Shell Optional Behavior There is a great deal of customizable shell behavior. The shopt builtin command provides a unified interface that allows users to alter shell defaults. Prompt Customization Bash allows the primary and secondary prompts to be customized by interpreting a number of backslash-escaped special characters. Parameter and variable expansion is also performed on the values of the primary and secondary prompt strings before they are displayed. Security Bash provides a restricted shell environment. It is also possible to control the execution of setuid/setgid scripts. Directory Stack Bash provides a `directory stack', to which directories may be added and removed. The current directory may be changed to any directory in the stack. It is easy to toggle between two directories in the stack. The directory stack may be saved and restored across different shell invocations. POSIX Mode Bash is nearly completely conformant to POSIX.2. POSIX mode changes those few areas where the Bash default behavior differs from the standard to match the standard. In POSIX mode, Bash is POSIX.2 compliant. Internationalization Bash provides a new quoting syntax that allows strings to be translated according to the current locale. The locale in which the shell itself runs may also be changed, so that the shell messages themselves may be language-specific. The command-line editing facilities allow the input of eight-bit characters, so most of the ISO-8859 family of character sets are supported. Command Timing Bash allows external commands, shell builtin commands and shell functions to be timed. The format used to display the timing information may be changed by the user. bash-2.05a/doc/texinfo.tex100664 436 0 607003 7200277514 13752 0ustar chetwheel% texinfo.tex -- TeX macros to handle Texinfo files. % % Load plain if necessary, i.e., if running under initex. \expandafter\ifx\csname fmtname\endcsname\relax\input plain\fi % \def\texinfoversion{1999-09-25.10} % % Copyright (C) 1985, 86, 88, 90, 91, 92, 93, 94, 95, 96, 97, 98, 99 % Free Software Foundation, Inc. % % This texinfo.tex file is free software; you can redistribute it and/or % modify it under the terms of the GNU General Public License as % published by the Free Software Foundation; either version 2, or (at % your option) any later version. % % This texinfo.tex file 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 texinfo.tex file; see the file COPYING. If not, write % to the Free Software Foundation, Inc., 59 Temple Place - Suite 330, % Boston, MA 02111-1307, USA. % % In other words, you are welcome to use, share and improve this program. % You are forbidden to forbid anyone else to use, share and improve % what you give them. Help stamp out software-hoarding! % % Please try the latest version of texinfo.tex before submitting bug % reports; you can get the latest version from: % ftp://ftp.gnu.org/gnu/texinfo.tex % (and all GNU mirrors, see http://www.gnu.org/order/ftp.html) % ftp://texinfo.org/tex/texinfo.tex % ftp://us.ctan.org/macros/texinfo/texinfo.tex % (and all CTAN mirrors, finger ctan@us.ctan.org for a list). % /home/gd/gnu/doc/texinfo.tex on the GNU machines. % The texinfo.tex in any given Texinfo distribution could well be out % of date, so if that's what you're using, please check. % Texinfo has a small home page at http://texinfo.org/. % % Send bug reports to bug-texinfo@gnu.org. Please include including a % complete document in each bug report with which we can reproduce the % problem. Patches are, of course, greatly appreciated. % % To process a Texinfo manual with TeX, it's most reliable to use the % texi2dvi shell script that comes with the distribution. For a simple % manual foo.texi, however, you can get away with this: % tex foo.texi % texindex foo.?? % tex foo.texi % tex foo.texi % dvips foo.dvi -o # or whatever, to process the dvi file; this makes foo.ps. % The extra runs of TeX get the cross-reference information correct. % Sometimes one run after texindex suffices, and sometimes you need more % than two; texi2dvi does it as many times as necessary. % % It is possible to adapt texinfo.tex for other languages. You can get % the existing language-specific files from ftp://ftp.gnu.org/gnu/texinfo/. \message{Loading texinfo [version \texinfoversion]:} % If in a .fmt file, print the version number % and turn on active characters that we couldn't do earlier because % they might have appeared in the input file name. \everyjob{\message{[Texinfo version \texinfoversion]}% \catcode`+=\active \catcode`\_=\active} % Save some parts of plain tex whose names we will redefine. \let\ptexb=\b \let\ptexbullet=\bullet \let\ptexc=\c \let\ptexcomma=\, \let\ptexdot=\. \let\ptexdots=\dots \let\ptexend=\end \let\ptexequiv=\equiv \let\ptexexclam=\! \let\ptexi=\i \let\ptexlbrace=\{ \let\ptexrbrace=\} \let\ptexstar=\* \let\ptext=\t % We never want plain's outer \+ definition in Texinfo. % For @tex, we can use \tabalign. \let\+ = \relax \message{Basics,} \chardef\other=12 % If this character appears in an error message or help string, it % starts a new line in the output. \newlinechar = `^^J % Set up fixed words for English if not already set. \ifx\putwordAppendix\undefined \gdef\putwordAppendix{Appendix}\fi \ifx\putwordChapter\undefined \gdef\putwordChapter{Chapter}\fi \ifx\putwordfile\undefined \gdef\putwordfile{file}\fi \ifx\putwordin\undefined \gdef\putwordin{in}\fi \ifx\putwordIndexIsEmpty\undefined \gdef\putwordIndexIsEmpty{(Index is empty)}\fi \ifx\putwordIndexNonexistent\undefined \gdef\putwordIndexNonexistent{(Index is nonexistent)}\fi \ifx\putwordInfo\undefined \gdef\putwordInfo{Info}\fi \ifx\putwordInstanceVariableof\undefined \gdef\putwordInstanceVariableof{Instance Variable of}\fi \ifx\putwordMethodon\undefined \gdef\putwordMethodon{Method on}\fi \ifx\putwordNoTitle\undefined \gdef\putwordNoTitle{No Title}\fi \ifx\putwordof\undefined \gdef\putwordof{of}\fi \ifx\putwordon\undefined \gdef\putwordon{on}\fi \ifx\putwordpage\undefined \gdef\putwordpage{page}\fi \ifx\putwordsection\undefined \gdef\putwordsection{section}\fi \ifx\putwordSection\undefined \gdef\putwordSection{Section}\fi \ifx\putwordsee\undefined \gdef\putwordsee{see}\fi \ifx\putwordSee\undefined \gdef\putwordSee{See}\fi \ifx\putwordShortTOC\undefined \gdef\putwordShortTOC{Short Contents}\fi \ifx\putwordTOC\undefined \gdef\putwordTOC{Table of Contents}\fi % \ifx\putwordMJan\undefined \gdef\putwordMJan{January}\fi \ifx\putwordMFeb\undefined \gdef\putwordMFeb{February}\fi \ifx\putwordMMar\undefined \gdef\putwordMMar{March}\fi \ifx\putwordMApr\undefined \gdef\putwordMApr{April}\fi \ifx\putwordMMay\undefined \gdef\putwordMMay{May}\fi \ifx\putwordMJun\undefined \gdef\putwordMJun{June}\fi \ifx\putwordMJul\undefined \gdef\putwordMJul{July}\fi \ifx\putwordMAug\undefined \gdef\putwordMAug{August}\fi \ifx\putwordMSep\undefined \gdef\putwordMSep{September}\fi \ifx\putwordMOct\undefined \gdef\putwordMOct{October}\fi \ifx\putwordMNov\undefined \gdef\putwordMNov{November}\fi \ifx\putwordMDec\undefined \gdef\putwordMDec{December}\fi % \ifx\putwordDefmac\undefined \gdef\putwordDefmac{Macro}\fi \ifx\putwordDefspec\undefined \gdef\putwordDefspec{Special Form}\fi \ifx\putwordDefvar\undefined \gdef\putwordDefvar{Variable}\fi \ifx\putwordDefopt\undefined \gdef\putwordDefopt{User Option}\fi \ifx\putwordDeftypevar\undefined\gdef\putwordDeftypevar{Variable}\fi \ifx\putwordDeffunc\undefined \gdef\putwordDeffunc{Function}\fi \ifx\putwordDeftypefun\undefined\gdef\putwordDeftypefun{Function}\fi % Ignore a token. % \def\gobble#1{} \hyphenation{ap-pen-dix} \hyphenation{mini-buf-fer mini-buf-fers} \hyphenation{eshell} \hyphenation{white-space} % Margin to add to right of even pages, to left of odd pages. \newdimen \bindingoffset \newdimen \normaloffset \newdimen\pagewidth \newdimen\pageheight % Sometimes it is convenient to have everything in the transcript file % and nothing on the terminal. We don't just call \tracingall here, % since that produces some useless output on the terminal. % \def\gloggingall{\begingroup \globaldefs = 1 \loggingall \endgroup}% \ifx\eTeXversion\undefined \def\loggingall{\tracingcommands2 \tracingstats2 \tracingpages1 \tracingoutput1 \tracinglostchars1 \tracingmacros2 \tracingparagraphs1 \tracingrestores1 \showboxbreadth\maxdimen\showboxdepth\maxdimen }% \else \def\loggingall{\tracingcommands3 \tracingstats2 \tracingpages1 \tracingoutput1 \tracinglostchars1 \tracingmacros2 \tracingparagraphs1 \tracingrestores1 \tracingscantokens1 \tracingassigns1 \tracingifs1 \tracinggroups1 \tracingnesting2 \showboxbreadth\maxdimen\showboxdepth\maxdimen }% \fi % For @cropmarks command. % Do @cropmarks to get crop marks. % \newif\ifcropmarks \let\cropmarks = \cropmarkstrue % % Dimensions to add cropmarks at corners. % Added by P. A. MacKay, 12 Nov. 1986 % \newdimen\outerhsize \newdimen\outervsize % set by the paper size routines \newdimen\cornerlong \cornerlong=1pc \newdimen\cornerthick \cornerthick=.3pt \newdimen\topandbottommargin \topandbottommargin=.75in % Main output routine. \chardef\PAGE = 255 \output = {\onepageout{\pagecontents\PAGE}} \newbox\headlinebox \newbox\footlinebox % \onepageout takes a vbox as an argument. Note that \pagecontents % does insertions, but you have to call it yourself. \def\onepageout#1{% \ifcropmarks \hoffset=0pt \else \hoffset=\normaloffset \fi % \ifodd\pageno \advance\hoffset by \bindingoffset \else \advance\hoffset by -\bindingoffset\fi % % Do this outside of the \shipout so @code etc. will be expanded in % the headline as they should be, not taken literally (outputting ''code). \setbox\headlinebox = \vbox{\let\hsize=\pagewidth \makeheadline}% \setbox\footlinebox = \vbox{\let\hsize=\pagewidth \makefootline}% % {% % Have to do this stuff outside the \shipout because we want it to % take effect in \write's, yet the group defined by the \vbox ends % before the \shipout runs. % \escapechar = `\\ % use backslash in output files. \indexdummies % don't expand commands in the output. \normalturnoffactive % \ in index entries must not stay \, e.g., if % the page break happens to be in the middle of an example. \shipout\vbox{% \ifcropmarks \vbox to \outervsize\bgroup \hsize = \outerhsize \vskip-\topandbottommargin \vtop to0pt{% \line{\ewtop\hfil\ewtop}% \nointerlineskip \line{% \vbox{\moveleft\cornerthick\nstop}% \hfill \vbox{\moveright\cornerthick\nstop}% }% \vss}% \vskip\topandbottommargin \line\bgroup \hfil % center the page within the outer (page) hsize. \ifodd\pageno\hskip\bindingoffset\fi \vbox\bgroup \fi % \unvbox\headlinebox \pagebody{#1}% \ifdim\ht\footlinebox > 0pt % Only leave this space if the footline is nonempty. % (We lessened \vsize for it in \oddfootingxxx.) % The \baselineskip=24pt in plain's \makefootline has no effect. \vskip 2\baselineskip \unvbox\footlinebox \fi % \ifpdfmakepagedest \pdfmkdest{\the\pageno} \fi % \ifcropmarks \egroup % end of \vbox\bgroup \hfil\egroup % end of (centering) \line\bgroup \vskip\topandbottommargin plus1fill minus1fill \boxmaxdepth = \cornerthick \vbox to0pt{\vss \line{% \vbox{\moveleft\cornerthick\nsbot}% \hfill \vbox{\moveright\cornerthick\nsbot}% }% \nointerlineskip \line{\ewbot\hfil\ewbot}% }% \egroup % \vbox from first cropmarks clause \fi }% end of \shipout\vbox }% end of group with \turnoffactive \advancepageno \ifnum\outputpenalty>-20000 \else\dosupereject\fi } \newinsert\margin \dimen\margin=\maxdimen \def\pagebody#1{\vbox to\pageheight{\boxmaxdepth=\maxdepth #1}} {\catcode`\@ =11 \gdef\pagecontents#1{\ifvoid\topins\else\unvbox\topins\fi % marginal hacks, juha@viisa.uucp (Juha Takala) \ifvoid\margin\else % marginal info is present \rlap{\kern\hsize\vbox to\z@{\kern1pt\box\margin \vss}}\fi \dimen@=\dp#1 \unvbox#1 \ifvoid\footins\else\vskip\skip\footins\footnoterule \unvbox\footins\fi \ifr@ggedbottom \kern-\dimen@ \vfil \fi} } % Here are the rules for the cropmarks. Note that they are % offset so that the space between them is truly \outerhsize or \outervsize % (P. A. MacKay, 12 November, 1986) % \def\ewtop{\vrule height\cornerthick depth0pt width\cornerlong} \def\nstop{\vbox {\hrule height\cornerthick depth\cornerlong width\cornerthick}} \def\ewbot{\vrule height0pt depth\cornerthick width\cornerlong} \def\nsbot{\vbox {\hrule height\cornerlong depth\cornerthick width\cornerthick}} % Parse an argument, then pass it to #1. The argument is the rest of % the input line (except we remove a trailing comment). #1 should be a % macro which expects an ordinary undelimited TeX argument. % \def\parsearg#1{% \let\next = #1% \begingroup \obeylines \futurelet\temp\parseargx } % If the next token is an obeyed space (from an @example environment or % the like), remove it and recurse. Otherwise, we're done. \def\parseargx{% % \obeyedspace is defined far below, after the definition of \sepspaces. \ifx\obeyedspace\temp \expandafter\parseargdiscardspace \else \expandafter\parseargline \fi } % Remove a single space (as the delimiter token to the macro call). {\obeyspaces % \gdef\parseargdiscardspace {\futurelet\temp\parseargx}} {\obeylines % \gdef\parseargline#1^^M{% \endgroup % End of the group started in \parsearg. % % First remove any @c comment, then any @comment. % Result of each macro is put in \toks0. \argremovec #1\c\relax % \expandafter\argremovecomment \the\toks0 \comment\relax % % % Call the caller's macro, saved as \next in \parsearg. \expandafter\next\expandafter{\the\toks0}% }% } % Since all \c{,omment} does is throw away the argument, we can let TeX % do that for us. The \relax here is matched by the \relax in the call % in \parseargline; it could be more or less anything, its purpose is % just to delimit the argument to the \c. \def\argremovec#1\c#2\relax{\toks0 = {#1}} \def\argremovecomment#1\comment#2\relax{\toks0 = {#1}} % \argremovec{,omment} might leave us with trailing spaces, though; e.g., % @end itemize @c foo % will have two active spaces as part of the argument with the % `itemize'. Here we remove all active spaces from #1, and assign the % result to \toks0. % % This loses if there are any *other* active characters besides spaces % in the argument -- _ ^ +, for example -- since they get expanded. % Fortunately, Texinfo does not define any such commands. (If it ever % does, the catcode of the characters in questionwill have to be changed % here.) But this means we cannot call \removeactivespaces as part of % \argremovec{,omment}, since @c uses \parsearg, and thus the argument % that \parsearg gets might well have any character at all in it. % \def\removeactivespaces#1{% \begingroup \ignoreactivespaces \edef\temp{#1}% \global\toks0 = \expandafter{\temp}% \endgroup } % Change the active space to expand to nothing. % \begingroup \obeyspaces \gdef\ignoreactivespaces{\obeyspaces\let =\empty} \endgroup \def\flushcr{\ifx\par\lisppar \def\next##1{}\else \let\next=\relax \fi \next} %% These are used to keep @begin/@end levels from running away %% Call \inENV within environments (after a \begingroup) \newif\ifENV \ENVfalse \def\inENV{\ifENV\relax\else\ENVtrue\fi} \def\ENVcheck{% \ifENV\errmessage{Still within an environment; press RETURN to continue} \endgroup\fi} % This is not perfect, but it should reduce lossage % @begin foo is the same as @foo, for now. \newhelp\EMsimple{Press RETURN to continue.} \outer\def\begin{\parsearg\beginxxx} \def\beginxxx #1{% \expandafter\ifx\csname #1\endcsname\relax {\errhelp=\EMsimple \errmessage{Undefined command @begin #1}}\else \csname #1\endcsname\fi} % @end foo executes the definition of \Efoo. % \def\end{\parsearg\endxxx} \def\endxxx #1{% \removeactivespaces{#1}% \edef\endthing{\the\toks0}% % \expandafter\ifx\csname E\endthing\endcsname\relax \expandafter\ifx\csname \endthing\endcsname\relax % There's no \foo, i.e., no ``environment'' foo. \errhelp = \EMsimple \errmessage{Undefined command `@end \endthing'}% \else \unmatchedenderror\endthing \fi \else % Everything's ok; the right environment has been started. \csname E\endthing\endcsname \fi } % There is an environment #1, but it hasn't been started. Give an error. % \def\unmatchedenderror#1{% \errhelp = \EMsimple \errmessage{This `@end #1' doesn't have a matching `@#1'}% } % Define the control sequence \E#1 to give an unmatched @end error. % \def\defineunmatchedend#1{% \expandafter\def\csname E#1\endcsname{\unmatchedenderror{#1}}% } % Single-spacing is done by various environments (specifically, in % \nonfillstart and \quotations). \newskip\singlespaceskip \singlespaceskip = 12.5pt \def\singlespace{% % Why was this kern here? It messes up equalizing space above and below % environments. --karl, 6may93 %{\advance \baselineskip by -\singlespaceskip %\kern \baselineskip}% \setleading \singlespaceskip } %% Simple single-character @ commands % @@ prints an @ % Kludge this until the fonts are right (grr). \def\@{{\tt\char64}} % This is turned off because it was never documented % and you can use @w{...} around a quote to suppress ligatures. %% Define @` and @' to be the same as ` and ' %% but suppressing ligatures. %\def\`{{`}} %\def\'{{'}} % Used to generate quoted braces. \def\mylbrace {{\tt\char123}} \def\myrbrace {{\tt\char125}} \let\{=\mylbrace \let\}=\myrbrace \begingroup % Definitions to produce actual \{ & \} command in an index. \catcode`\{ = 12 \catcode`\} = 12 \catcode`\[ = 1 \catcode`\] = 2 \catcode`\@ = 0 \catcode`\\ = 12 @gdef@lbracecmd[\{]% @gdef@rbracecmd[\}]% @endgroup % Accents: @, @dotaccent @ringaccent @ubaraccent @udotaccent % Others are defined by plain TeX: @` @' @" @^ @~ @= @v @H. \let\, = \c \let\dotaccent = \. \def\ringaccent#1{{\accent23 #1}} \let\tieaccent = \t \let\ubaraccent = \b \let\udotaccent = \d % Other special characters: @questiondown @exclamdown % Plain TeX defines: @AA @AE @O @OE @L (and lowercase versions) @ss. \def\questiondown{?`} \def\exclamdown{!`} % Dotless i and dotless j, used for accents. \def\imacro{i} \def\jmacro{j} \def\dotless#1{% \def\temp{#1}% \ifx\temp\imacro \ptexi \else\ifx\temp\jmacro \j \else \errmessage{@dotless can be used only with i or j}% \fi\fi } % Be sure we're in horizontal mode when doing a tie, since we make space % equivalent to this in @example-like environments. Otherwise, a space % at the beginning of a line will start with \penalty -- and % since \penalty is valid in vertical mode, we'd end up putting the % penalty on the vertical list instead of in the new paragraph. {\catcode`@ = 11 % Avoid using \@M directly, because that causes trouble % if the definition is written into an index file. \global\let\tiepenalty = \@M \gdef\tie{\leavevmode\penalty\tiepenalty\ } } % @: forces normal size whitespace following. \def\:{\spacefactor=1000 } % @* forces a line break. \def\*{\hfil\break\hbox{}\ignorespaces} % @. is an end-of-sentence period. \def\.{.\spacefactor=3000 } % @! is an end-of-sentence bang. \def\!{!\spacefactor=3000 } % @? is an end-of-sentence query. \def\?{?\spacefactor=3000 } % @w prevents a word break. Without the \leavevmode, @w at the % beginning of a paragraph, when TeX is still in vertical mode, would % produce a whole line of output instead of starting the paragraph. \def\w#1{\leavevmode\hbox{#1}} % @group ... @end group forces ... to be all on one page, by enclosing % it in a TeX vbox. We use \vtop instead of \vbox to construct the box % to keep its height that of a normal line. According to the rules for % \topskip (p.114 of the TeXbook), the glue inserted is % max (\topskip - \ht (first item), 0). If that height is large, % therefore, no glue is inserted, and the space between the headline and % the text is small, which looks bad. % \def\group{\begingroup \ifnum\catcode13=\active \else \errhelp = \groupinvalidhelp \errmessage{@group invalid in context where filling is enabled}% \fi % % The \vtop we start below produces a box with normal height and large % depth; thus, TeX puts \baselineskip glue before it, and (when the % next line of text is done) \lineskip glue after it. (See p.82 of % the TeXbook.) Thus, space below is not quite equal to space % above. But it's pretty close. \def\Egroup{% \egroup % End the \vtop. \endgroup % End the \group. }% % \vtop\bgroup % We have to put a strut on the last line in case the @group is in % the midst of an example, rather than completely enclosing it. % Otherwise, the interline space between the last line of the group % and the first line afterwards is too small. But we can't put the % strut in \Egroup, since there it would be on a line by itself. % Hence this just inserts a strut at the beginning of each line. \everypar = {\strut}% % % Since we have a strut on every line, we don't need any of TeX's % normal interline spacing. \offinterlineskip % % OK, but now we have to do something about blank % lines in the input in @example-like environments, which normally % just turn into \lisppar, which will insert no space now that we've % turned off the interline space. Simplest is to make them be an % empty paragraph. \ifx\par\lisppar \edef\par{\leavevmode \par}% % % Reset ^^M's definition to new definition of \par. \obeylines \fi % % Do @comment since we are called inside an environment such as % @example, where each end-of-line in the input causes an % end-of-line in the output. We don't want the end-of-line after % the `@group' to put extra space in the output. Since @group % should appear on a line by itself (according to the Texinfo % manual), we don't worry about eating any user text. \comment } % % TeX puts in an \escapechar (i.e., `@') at the beginning of the help % message, so this ends up printing `@group can only ...'. % \newhelp\groupinvalidhelp{% group can only be used in environments such as @example,^^J% where each line of input produces a line of output.} % @need space-in-mils % forces a page break if there is not space-in-mils remaining. \newdimen\mil \mil=0.001in \def\need{\parsearg\needx} % Old definition--didn't work. %\def\needx #1{\par % %% This method tries to make TeX break the page naturally %% if the depth of the box does not fit. %{\baselineskip=0pt% %\vtop to #1\mil{\vfil}\kern -#1\mil\nobreak %\prevdepth=-1000pt %}} \def\needx#1{% % Ensure vertical mode, so we don't make a big box in the middle of a % paragraph. \par % % If the @need value is less than one line space, it's useless. \dimen0 = #1\mil \dimen2 = \ht\strutbox \advance\dimen2 by \dp\strutbox \ifdim\dimen0 > \dimen2 % % Do a \strut just to make the height of this box be normal, so the % normal leading is inserted relative to the preceding line. % And a page break here is fine. \vtop to #1\mil{\strut\vfil}% % % TeX does not even consider page breaks if a penalty added to the % main vertical list is 10000 or more. But in order to see if the % empty box we just added fits on the page, we must make it consider % page breaks. On the other hand, we don't want to actually break the % page after the empty box. So we use a penalty of 9999. % % There is an extremely small chance that TeX will actually break the % page at this \penalty, if there are no other feasible breakpoints in % sight. (If the user is using lots of big @group commands, which % almost-but-not-quite fill up a page, TeX will have a hard time doing % good page breaking, for example.) However, I could not construct an % example where a page broke at this \penalty; if it happens in a real % document, then we can reconsider our strategy. \penalty9999 % % Back up by the size of the box, whether we did a page break or not. \kern -#1\mil % % Do not allow a page break right after this kern. \nobreak \fi } % @br forces paragraph break \let\br = \par % @dots{} output an ellipsis using the current font. % We do .5em per period so that it has the same spacing in a typewriter % font as three actual period characters. % \def\dots{% \leavevmode \hbox to 1.5em{% \hskip 0pt plus 0.25fil minus 0.25fil .\hss.\hss.% \hskip 0pt plus 0.5fil minus 0.5fil }% } % @enddots{} is an end-of-sentence ellipsis. % \def\enddots{% \leavevmode \hbox to 2em{% \hskip 0pt plus 0.25fil minus 0.25fil .\hss.\hss.\hss.% \hskip 0pt plus 0.5fil minus 0.5fil }% \spacefactor=3000 } % @page forces the start of a new page % \def\page{\par\vfill\supereject} % @exdent text.... % outputs text on separate line in roman font, starting at standard page margin % This records the amount of indent in the innermost environment. % That's how much \exdent should take out. \newskip\exdentamount % This defn is used inside fill environments such as @defun. \def\exdent{\parsearg\exdentyyy} \def\exdentyyy #1{{\hfil\break\hbox{\kern -\exdentamount{\rm#1}}\hfil\break}} % This defn is used inside nofill environments such as @example. \def\nofillexdent{\parsearg\nofillexdentyyy} \def\nofillexdentyyy #1{{\advance \leftskip by -\exdentamount \leftline{\hskip\leftskip{\rm#1}}}} % @inmargin{TEXT} puts TEXT in the margin next to the current paragraph. \def\inmargin#1{% \strut\vadjust{\nobreak\kern-\strutdepth \vtop to \strutdepth{\baselineskip\strutdepth\vss \llap{\rightskip=\inmarginspacing \vbox{\noindent #1}}\null}}} \newskip\inmarginspacing \inmarginspacing=1cm \def\strutdepth{\dp\strutbox} %\hbox{{\rm#1}}\hfil\break}} % @include file insert text of that file as input. % Allow normal characters that we make active in the argument (a file name). \def\include{\begingroup \catcode`\\=12 \catcode`~=12 \catcode`^=12 \catcode`_=12 \catcode`|=12 \catcode`<=12 \catcode`>=12 \catcode`+=12 \parsearg\includezzz} % Restore active chars for included file. \def\includezzz#1{\endgroup\begingroup % Read the included file in a group so nested @include's work. \def\thisfile{#1}% \input\thisfile \endgroup} \def\thisfile{} % @center line outputs that line, centered \def\center{\parsearg\centerzzz} \def\centerzzz #1{{\advance\hsize by -\leftskip \advance\hsize by -\rightskip \centerline{#1}}} % @sp n outputs n lines of vertical space \def\sp{\parsearg\spxxx} \def\spxxx #1{\vskip #1\baselineskip} % @comment ...line which is ignored... % @c is the same as @comment % @ignore ... @end ignore is another way to write a comment \def\comment{\begingroup \catcode`\^^M=\other% \catcode`\@=\other \catcode`\{=\other \catcode`\}=\other% \commentxxx} {\catcode`\^^M=\other \gdef\commentxxx#1^^M{\endgroup}} \let\c=\comment % @paragraphindent NCHARS % We'll use ems for NCHARS, close enough. % We cannot implement @paragraphindent asis, though. % \def\asisword{asis} % no translation, these are keywords \def\noneword{none} % \def\paragraphindent{\parsearg\doparagraphindent} \def\doparagraphindent#1{% \def\temp{#1}% \ifx\temp\asisword \else \ifx\temp\noneword \defaultparindent = 0pt \else \defaultparindent = #1em \fi \fi \parindent = \defaultparindent } % @exampleindent NCHARS % We'll use ems for NCHARS like @paragraphindent. % It seems @exampleindent asis isn't necessary, but % I preserve it to make it similar to @paragraphindent. \def\exampleindent{\parsearg\doexampleindent} \def\doexampleindent#1{% \def\temp{#1}% \ifx\temp\asisword \else \ifx\temp\noneword \lispnarrowing = 0pt \else \lispnarrowing = #1em \fi \fi } % @asis just yields its argument. Used with @table, for example. % \def\asis#1{#1} % @math means output in math mode. % We don't use $'s directly in the definition of \math because control % sequences like \math are expanded when the toc file is written. Then, % we read the toc file back, the $'s will be normal characters (as they % should be, according to the definition of Texinfo). So we must use a % control sequence to switch into and out of math mode. % % This isn't quite enough for @math to work properly in indices, but it % seems unlikely it will ever be needed there. % \let\implicitmath = $ \def\math#1{\implicitmath #1\implicitmath} % @bullet and @minus need the same treatment as @math, just above. \def\bullet{\implicitmath\ptexbullet\implicitmath} \def\minus{\implicitmath-\implicitmath} % @refill is a no-op. \let\refill=\relax % If working on a large document in chapters, it is convenient to % be able to disable indexing, cross-referencing, and contents, for test runs. % This is done with @novalidate (before @setfilename). % \newif\iflinks \linkstrue % by default we want the aux files. \let\novalidate = \linksfalse % @setfilename is done at the beginning of every texinfo file. % So open here the files we need to have open while reading the input. % This makes it possible to make a .fmt file for texinfo. \def\setfilename{% \iflinks \readauxfile \fi % \openindices needs to do some work in any case. \openindices \fixbackslash % Turn off hack to swallow `\input texinfo'. \global\let\setfilename=\comment % Ignore extra @setfilename cmds. % % If texinfo.cnf is present on the system, read it. % Useful for site-wide @afourpaper, etc. % Just to be on the safe side, close the input stream before the \input. \openin 1 texinfo.cnf \ifeof1 \let\temp=\relax \else \def\temp{\input texinfo.cnf }\fi \closein1 \temp % \comment % Ignore the actual filename. } % Called from \setfilename. % \def\openindices{% \newindex{cp}% \newcodeindex{fn}% \newcodeindex{vr}% \newcodeindex{tp}% \newcodeindex{ky}% \newcodeindex{pg}% } % @bye. \outer\def\bye{\pagealignmacro\tracingstats=1\ptexend} \message{pdf,} % adobe `portable' document format \newcount\tempnum \newcount\lnkcount \newtoks\filename \newcount\filenamelength \newcount\pgn \newtoks\toksA \newtoks\toksB \newtoks\toksC \newtoks\toksD \newbox\boxA \newcount\countA \newif\ifpdf \newif\ifpdfmakepagedest \ifx\pdfoutput\undefined \pdffalse \let\pdfmkdest = \gobble \let\pdfurl = \gobble \let\endlink = \relax \let\linkcolor = \relax \let\pdfmakeoutlines = \relax \else \pdftrue \pdfoutput = 1 \input pdfcolor \def\dopdfimage#1#2#3{% \def\imagewidth{#2}% \def\imageheight{#3}% \ifnum\pdftexversion < 14 \pdfimage \else \pdfximage \fi \ifx\empty\imagewidth\else width \imagewidth \fi \ifx\empty\imageheight\else height \imageheight \fi {#1.pdf}% \ifnum\pdftexversion < 14 \else \pdfrefximage \pdflastximage \fi} \def\pdfmkdest#1{\pdfdest name{#1@} xyz} \def\pdfmkpgn#1{#1@} \let\linkcolor = \Cyan \def\endlink{\Black\pdfendlink} % Adding outlines to PDF; macros for calculating structure of outlines % come from Petr Olsak \def\expnumber#1{\expandafter\ifx\csname#1\endcsname\relax 0% \else \csname#1\endcsname \fi} \def\advancenumber#1{\tempnum=\expnumber{#1}\relax \advance\tempnum by1 \expandafter\xdef\csname#1\endcsname{\the\tempnum}} \def\pdfmakeoutlines{{% \openin 1 \jobname.toc \ifeof 1\else\bgroup \closein 1 \indexnofonts \def\tt{} % thanh's hack / proper braces in bookmarks \edef\mylbrace{\iftrue \string{\else}\fi}\let\{=\mylbrace \edef\myrbrace{\iffalse{\else\string}\fi}\let\}=\myrbrace % \def\chapentry ##1##2##3{} \def\unnumbchapentry ##1##2{} \def\secentry ##1##2##3##4{\advancenumber{chap##2}} \def\unnumbsecentry ##1##2{} \def\subsecentry ##1##2##3##4##5{\advancenumber{sec##2.##3}} \def\unnumbsubsecentry ##1##2{} \def\subsubsecentry ##1##2##3##4##5##6{\advancenumber{subsec##2.##3.##4}} \def\unnumbsubsubsecentry ##1##2{} \input \jobname.toc \def\chapentry ##1##2##3{% \pdfoutline goto name{\pdfmkpgn{##3}}count-\expnumber{chap##2}{##1}} \def\unnumbchapentry ##1##2{% \pdfoutline goto name{\pdfmkpgn{##2}}{##1}} \def\secentry ##1##2##3##4{% \pdfoutline goto name{\pdfmkpgn{##4}}count-\expnumber{sec##2.##3}{##1}} \def\unnumbsecentry ##1##2{% \pdfoutline goto name{\pdfmkpgn{##2}}{##1}} \def\subsecentry ##1##2##3##4##5{% \pdfoutline goto name{\pdfmkpgn{##5}}count-\expnumber{subsec##2.##3.##4}{##1}} \def\unnumbsubsecentry ##1##2{% \pdfoutline goto name{\pdfmkpgn{##2}}{##1}} \def\subsubsecentry ##1##2##3##4##5##6{% \pdfoutline goto name{\pdfmkpgn{##6}}{##1}} \def\unnumbsubsubsecentry ##1##2{% \pdfoutline goto name{\pdfmkpgn{##2}}{##1}} \input \jobname.toc \egroup\fi }} \def\makelinks #1,{% \def\params{#1}\def\E{END}% \ifx\params\E \let\nextmakelinks=\relax \else \let\nextmakelinks=\makelinks \ifnum\lnkcount>0,\fi \picknum{#1}% \startlink attr{/Border [0 0 0]} goto name{\pdfmkpgn{\the\pgn}}% \linkcolor #1% \advance\lnkcount by 1% \endlink \fi \nextmakelinks } \def\picknum#1{\expandafter\pn#1} \def\pn#1{% \def\p{#1}% \ifx\p\lbrace \let\nextpn=\ppn \else \let\nextpn=\ppnn \def\first{#1} \fi \nextpn } \def\ppn#1{\pgn=#1\gobble} \def\ppnn{\pgn=\first} \def\pdfmklnk#1{\lnkcount=0\makelinks #1,END,} \def\addtokens#1#2{\edef\addtoks{\noexpand#1={\the#1#2}}\addtoks} \def\skipspaces#1{\def\PP{#1}\def\D{|}% \ifx\PP\D\let\nextsp\relax \else\let\nextsp\skipspaces \ifx\p\space\else\addtokens{\filename}{\PP}% \advance\filenamelength by 1 \fi \fi \nextsp} \def\getfilename#1{\filenamelength=0\expandafter\skipspaces#1|\relax} \ifnum\pdftexversion < 14 \let \startlink \pdfannotlink \else \let \startlink \pdfstartlink \fi \def\pdfurl#1{% \begingroup \normalturnoffactive\def\@{@}% \leavevmode\Red \startlink attr{/Border [0 0 0]}% user{/Subtype /Link /A << /S /URI /URI (#1) >>}% % #1 \endgroup} \def\pdfgettoks#1.{\setbox\boxA=\hbox{\toksA={#1.}\toksB={}\maketoks}} \def\addtokens#1#2{\edef\addtoks{\noexpand#1={\the#1#2}}\addtoks} \def\adn#1{\addtokens{\toksC}{#1}\global\countA=1\let\next=\maketoks} \def\poptoks#1#2|ENDTOKS|{\let\first=#1\toksD={#1}\toksA={#2}} \def\maketoks{% \expandafter\poptoks\the\toksA|ENDTOKS| \ifx\first0\adn0 \else\ifx\first1\adn1 \else\ifx\first2\adn2 \else\ifx\first3\adn3 \else\ifx\first4\adn4 \else\ifx\first5\adn5 \else\ifx\first6\adn6 \else\ifx\first7\adn7 \else\ifx\first8\adn8 \else\ifx\first9\adn9 \else \ifnum0=\countA\else\makelink\fi \ifx\first.\let\next=\done\else \let\next=\maketoks \addtokens{\toksB}{\the\toksD} \ifx\first,\addtokens{\toksB}{\space}\fi \fi \fi\fi\fi\fi\fi\fi\fi\fi\fi\fi \next} \def\makelink{\addtokens{\toksB}% {\noexpand\pdflink{\the\toksC}}\toksC={}\global\countA=0} \def\pdflink#1{% \startlink attr{/Border [0 0 0]} goto name{\mkpgn{#1}} \linkcolor #1\endlink} \def\mkpgn#1{#1@} \def\done{\edef\st{\global\noexpand\toksA={\the\toksB}}\st} \fi % \ifx\pdfoutput \message{fonts,} % Font-change commands. % Texinfo sort of supports the sans serif font style, which plain TeX does not. % So we set up a \sf analogous to plain's \rm, etc. \newfam\sffam \def\sf{\fam=\sffam \tensf} \let\li = \sf % Sometimes we call it \li, not \sf. % We don't need math for this one. \def\ttsl{\tenttsl} % Use Computer Modern fonts at \magstephalf (11pt). \newcount\mainmagstep \mainmagstep=\magstephalf % Set the font macro #1 to the font named #2, adding on the % specified font prefix (normally `cm'). % #3 is the font's design size, #4 is a scale factor \def\setfont#1#2#3#4{\font#1=\fontprefix#2#3 scaled #4} % Use cm as the default font prefix. % To specify the font prefix, you must define \fontprefix % before you read in texinfo.tex. \ifx\fontprefix\undefined \def\fontprefix{cm} \fi % Support font families that don't use the same naming scheme as CM. \def\rmshape{r} \def\rmbshape{bx} %where the normal face is bold \def\bfshape{b} \def\bxshape{bx} \def\ttshape{tt} \def\ttbshape{tt} \def\ttslshape{sltt} \def\itshape{ti} \def\itbshape{bxti} \def\slshape{sl} \def\slbshape{bxsl} \def\sfshape{ss} \def\sfbshape{ss} \def\scshape{csc} \def\scbshape{csc} \ifx\bigger\relax \let\mainmagstep=\magstep1 \setfont\textrm\rmshape{12}{1000} \setfont\texttt\ttshape{12}{1000} \else \setfont\textrm\rmshape{10}{\mainmagstep} \setfont\texttt\ttshape{10}{\mainmagstep} \fi % Instead of cmb10, you many want to use cmbx10. % cmbx10 is a prettier font on its own, but cmb10 % looks better when embedded in a line with cmr10. \setfont\textbf\bfshape{10}{\mainmagstep} \setfont\textit\itshape{10}{\mainmagstep} \setfont\textsl\slshape{10}{\mainmagstep} \setfont\textsf\sfshape{10}{\mainmagstep} \setfont\textsc\scshape{10}{\mainmagstep} \setfont\textttsl\ttslshape{10}{\mainmagstep} \font\texti=cmmi10 scaled \mainmagstep \font\textsy=cmsy10 scaled \mainmagstep % A few fonts for @defun, etc. \setfont\defbf\bxshape{10}{\magstep1} %was 1314 \setfont\deftt\ttshape{10}{\magstep1} \def\df{\let\tentt=\deftt \let\tenbf = \defbf \bf} % Fonts for indices, footnotes, small examples (9pt). \setfont\smallrm\rmshape{9}{1000} \setfont\smalltt\ttshape{9}{1000} \setfont\smallbf\bfshape{10}{900} \setfont\smallit\itshape{9}{1000} \setfont\smallsl\slshape{9}{1000} \setfont\smallsf\sfshape{9}{1000} \setfont\smallsc\scshape{10}{900} \setfont\smallttsl\ttslshape{10}{900} \font\smalli=cmmi9 \font\smallsy=cmsy9 % Fonts for title page: \setfont\titlerm\rmbshape{12}{\magstep3} \setfont\titleit\itbshape{10}{\magstep4} \setfont\titlesl\slbshape{10}{\magstep4} \setfont\titlett\ttbshape{12}{\magstep3} \setfont\titlettsl\ttslshape{10}{\magstep4} \setfont\titlesf\sfbshape{17}{\magstep1} \let\titlebf=\titlerm \setfont\titlesc\scbshape{10}{\magstep4} \font\titlei=cmmi12 scaled \magstep3 \font\titlesy=cmsy10 scaled \magstep4 \def\authorrm{\secrm} % Chapter (and unnumbered) fonts (17.28pt). \setfont\chaprm\rmbshape{12}{\magstep2} \setfont\chapit\itbshape{10}{\magstep3} \setfont\chapsl\slbshape{10}{\magstep3} \setfont\chaptt\ttbshape{12}{\magstep2} \setfont\chapttsl\ttslshape{10}{\magstep3} \setfont\chapsf\sfbshape{17}{1000} \let\chapbf=\chaprm \setfont\chapsc\scbshape{10}{\magstep3} \font\chapi=cmmi12 scaled \magstep2 \font\chapsy=cmsy10 scaled \magstep3 % Section fonts (14.4pt). \setfont\secrm\rmbshape{12}{\magstep1} \setfont\secit\itbshape{10}{\magstep2} \setfont\secsl\slbshape{10}{\magstep2} \setfont\sectt\ttbshape{12}{\magstep1} \setfont\secttsl\ttslshape{10}{\magstep2} \setfont\secsf\sfbshape{12}{\magstep1} \let\secbf\secrm \setfont\secsc\scbshape{10}{\magstep2} \font\seci=cmmi12 scaled \magstep1 \font\secsy=cmsy10 scaled \magstep2 % \setfont\ssecrm\bxshape{10}{\magstep1} % This size an font looked bad. % \setfont\ssecit\itshape{10}{\magstep1} % The letters were too crowded. % \setfont\ssecsl\slshape{10}{\magstep1} % \setfont\ssectt\ttshape{10}{\magstep1} % \setfont\ssecsf\sfshape{10}{\magstep1} %\setfont\ssecrm\bfshape{10}{1315} % Note the use of cmb rather than cmbx. %\setfont\ssecit\itshape{10}{1315} % Also, the size is a little larger than %\setfont\ssecsl\slshape{10}{1315} % being scaled magstep1. %\setfont\ssectt\ttshape{10}{1315} %\setfont\ssecsf\sfshape{10}{1315} %\let\ssecbf=\ssecrm % Subsection fonts (13.15pt). \setfont\ssecrm\rmbshape{12}{\magstephalf} \setfont\ssecit\itbshape{10}{1315} \setfont\ssecsl\slbshape{10}{1315} \setfont\ssectt\ttbshape{12}{\magstephalf} \setfont\ssecttsl\ttslshape{10}{1315} \setfont\ssecsf\sfbshape{12}{\magstephalf} \let\ssecbf\ssecrm \setfont\ssecsc\scbshape{10}{\magstep1} \font\sseci=cmmi12 scaled \magstephalf \font\ssecsy=cmsy10 scaled 1315 % The smallcaps and symbol fonts should actually be scaled \magstep1.5, % but that is not a standard magnification. % In order for the font changes to affect most math symbols and letters, % we have to define the \textfont of the standard families. Since % texinfo doesn't allow for producing subscripts and superscripts, we % don't bother to reset \scriptfont and \scriptscriptfont (which would % also require loading a lot more fonts). % \def\resetmathfonts{% \textfont0 = \tenrm \textfont1 = \teni \textfont2 = \tensy \textfont\itfam = \tenit \textfont\slfam = \tensl \textfont\bffam = \tenbf \textfont\ttfam = \tentt \textfont\sffam = \tensf } % The font-changing commands redefine the meanings of \tenSTYLE, instead % of just \STYLE. We do this so that font changes will continue to work % in math mode, where it is the current \fam that is relevant in most % cases, not the current font. Plain TeX does \def\bf{\fam=\bffam % \tenbf}, for example. By redefining \tenbf, we obviate the need to % redefine \bf itself. \def\textfonts{% \let\tenrm=\textrm \let\tenit=\textit \let\tensl=\textsl \let\tenbf=\textbf \let\tentt=\texttt \let\smallcaps=\textsc \let\tensf=\textsf \let\teni=\texti \let\tensy=\textsy \let\tenttsl=\textttsl \resetmathfonts} \def\titlefonts{% \let\tenrm=\titlerm \let\tenit=\titleit \let\tensl=\titlesl \let\tenbf=\titlebf \let\tentt=\titlett \let\smallcaps=\titlesc \let\tensf=\titlesf \let\teni=\titlei \let\tensy=\titlesy \let\tenttsl=\titlettsl \resetmathfonts \setleading{25pt}} \def\titlefont#1{{\titlefonts\rm #1}} \def\chapfonts{% \let\tenrm=\chaprm \let\tenit=\chapit \let\tensl=\chapsl \let\tenbf=\chapbf \let\tentt=\chaptt \let\smallcaps=\chapsc \let\tensf=\chapsf \let\teni=\chapi \let\tensy=\chapsy \let\tenttsl=\chapttsl \resetmathfonts \setleading{19pt}} \def\secfonts{% \let\tenrm=\secrm \let\tenit=\secit \let\tensl=\secsl \let\tenbf=\secbf \let\tentt=\sectt \let\smallcaps=\secsc \let\tensf=\secsf \let\teni=\seci \let\tensy=\secsy \let\tenttsl=\secttsl \resetmathfonts \setleading{16pt}} \def\subsecfonts{% \let\tenrm=\ssecrm \let\tenit=\ssecit \let\tensl=\ssecsl \let\tenbf=\ssecbf \let\tentt=\ssectt \let\smallcaps=\ssecsc \let\tensf=\ssecsf \let\teni=\sseci \let\tensy=\ssecsy \let\tenttsl=\ssecttsl \resetmathfonts \setleading{15pt}} \let\subsubsecfonts = \subsecfonts % Maybe make sssec fonts scaled magstephalf? \def\smallfonts{% \let\tenrm=\smallrm \let\tenit=\smallit \let\tensl=\smallsl \let\tenbf=\smallbf \let\tentt=\smalltt \let\smallcaps=\smallsc \let\tensf=\smallsf \let\teni=\smalli \let\tensy=\smallsy \let\tenttsl=\smallttsl \resetmathfonts \setleading{11pt}} % Set up the default fonts, so we can use them for creating boxes. % \textfonts % Define these so they can be easily changed for other fonts. \def\angleleft{$\langle$} \def\angleright{$\rangle$} % Count depth in font-changes, for error checks \newcount\fontdepth \fontdepth=0 % Fonts for short table of contents. \setfont\shortcontrm\rmshape{12}{1000} \setfont\shortcontbf\bxshape{12}{1000} \setfont\shortcontsl\slshape{12}{1000} %% Add scribe-like font environments, plus @l for inline lisp (usually sans %% serif) and @ii for TeX italic % \smartitalic{ARG} outputs arg in italics, followed by an italic correction % unless the following character is such as not to need one. \def\smartitalicx{\ifx\next,\else\ifx\next-\else\ifx\next.\else\/\fi\fi\fi} \def\smartslanted#1{{\sl #1}\futurelet\next\smartitalicx} \def\smartitalic#1{{\it #1}\futurelet\next\smartitalicx} \let\i=\smartitalic \let\var=\smartslanted \let\dfn=\smartslanted \let\emph=\smartitalic \let\cite=\smartslanted \def\b#1{{\bf #1}} \let\strong=\b % We can't just use \exhyphenpenalty, because that only has effect at % the end of a paragraph. Restore normal hyphenation at the end of the % group within which \nohyphenation is presumably called. % \def\nohyphenation{\hyphenchar\font = -1 \aftergroup\restorehyphenation} \def\restorehyphenation{\hyphenchar\font = `- } \def\t#1{% {\tt \rawbackslash \frenchspacing #1}% \null } \let\ttfont=\t \def\samp#1{`\tclose{#1}'\null} \setfont\keyrm\rmshape{8}{1000} \font\keysy=cmsy9 \def\key#1{{\keyrm\textfont2=\keysy \leavevmode\hbox{% \raise0.4pt\hbox{\angleleft}\kern-.08em\vtop{% \vbox{\hrule\kern-0.4pt \hbox{\raise0.4pt\hbox{\vphantom{\angleleft}}#1}}% \kern-0.4pt\hrule}% \kern-.06em\raise0.4pt\hbox{\angleright}}}} % The old definition, with no lozenge: %\def\key #1{{\ttsl \nohyphenation \uppercase{#1}}\null} \def\ctrl #1{{\tt \rawbackslash \hat}#1} % @file, @option are the same as @samp. \let\file=\samp \let\option=\samp % @code is a modification of @t, % which makes spaces the same size as normal in the surrounding text. \def\tclose#1{% {% % Change normal interword space to be same as for the current font. \spaceskip = \fontdimen2\font % % Switch to typewriter. \tt % % But `\ ' produces the large typewriter interword space. \def\ {{\spaceskip = 0pt{} }}% % % Turn off hyphenation. \nohyphenation % \rawbackslash \frenchspacing #1% }% \null } % We *must* turn on hyphenation at `-' and `_' in \code. % Otherwise, it is too hard to avoid overfull hboxes % in the Emacs manual, the Library manual, etc. % Unfortunately, TeX uses one parameter (\hyphenchar) to control % both hyphenation at - and hyphenation within words. % We must therefore turn them both off (\tclose does that) % and arrange explicitly to hyphenate at a dash. % -- rms. { \catcode`\-=\active \catcode`\_=\active % \global\def\code{\begingroup \catcode`\-=\active \let-\codedash \catcode`\_=\active \let_\codeunder \codex } % % If we end up with any active - characters when handling the index, % just treat them as a normal -. \global\def\indexbreaks{\catcode`\-=\active \let-\realdash} } \def\realdash{-} \def\codedash{-\discretionary{}{}{}} \def\codeunder{\ifusingtt{\normalunderscore\discretionary{}{}{}}{\_}} \def\codex #1{\tclose{#1}\endgroup} %\let\exp=\tclose %Was temporary % @kbd is like @code, except that if the argument is just one @key command, % then @kbd has no effect. % @kbdinputstyle -- arg is `distinct' (@kbd uses slanted tty font always), % `example' (@kbd uses ttsl only inside of @example and friends), % or `code' (@kbd uses normal tty font always). \def\kbdinputstyle{\parsearg\kbdinputstylexxx} \def\kbdinputstylexxx#1{% \def\arg{#1}% \ifx\arg\worddistinct \gdef\kbdexamplefont{\ttsl}\gdef\kbdfont{\ttsl}% \else\ifx\arg\wordexample \gdef\kbdexamplefont{\ttsl}\gdef\kbdfont{\tt}% \else\ifx\arg\wordcode \gdef\kbdexamplefont{\tt}\gdef\kbdfont{\tt}% \fi\fi\fi } \def\worddistinct{distinct} \def\wordexample{example} \def\wordcode{code} % Default is kbdinputdistinct. (Too much of a hassle to call the macro, % the catcodes are wrong for parsearg to work.) \gdef\kbdexamplefont{\ttsl}\gdef\kbdfont{\ttsl} \def\xkey{\key} \def\kbdfoo#1#2#3\par{\def\one{#1}\def\three{#3}\def\threex{??}% \ifx\one\xkey\ifx\threex\three \key{#2}% \else{\tclose{\kbdfont\look}}\fi \else{\tclose{\kbdfont\look}}\fi} % For @url, @env, @command quotes seem unnecessary, so use \code. \let\url=\code \let\env=\code \let\command=\code % @uref (abbreviation for `urlref') takes an optional (comma-separated) % second argument specifying the text to display and an optional third % arg as text to display instead of (rather than in addition to) the url % itself. First (mandatory) arg is the url. Perhaps eventually put in % a hypertex \special here. % \def\uref#1{\douref #1,,,\finish} \def\douref#1,#2,#3,#4\finish{\begingroup \unsepspaces \pdfurl{#1}% \setbox0 = \hbox{\ignorespaces #3}% \ifdim\wd0 > 0pt \unhbox0 % third arg given, show only that \else \setbox0 = \hbox{\ignorespaces #2}% \ifdim\wd0 > 0pt \ifpdf \unhbox0 % PDF: 2nd arg given, show only it \else \unhbox0\ (\code{#1})% DVI: 2nd arg given, show both it and url \fi \else \code{#1}% only url given, so show it \fi \fi \endlink \endgroup} % rms does not like angle brackets --karl, 17may97. % So now @email is just like @uref, unless we are pdf. % %\def\email#1{\angleleft{\tt #1}\angleright} \ifpdf \def\email#1{\doemail#1,,\finish} \def\doemail#1,#2,#3\finish{\begingroup \unsepspaces \pdfurl{mailto:#1}% \setbox0 = \hbox{\ignorespaces #2}% \ifdim\wd0>0pt\unhbox0\else\code{#1}\fi \endlink \endgroup} \else \let\email=\uref \fi % Check if we are currently using a typewriter font. Since all the % Computer Modern typewriter fonts have zero interword stretch (and % shrink), and it is reasonable to expect all typewriter fonts to have % this property, we can check that font parameter. % \def\ifmonospace{\ifdim\fontdimen3\font=0pt } % Typeset a dimension, e.g., `in' or `pt'. The only reason for the % argument is to make the input look right: @dmn{pt} instead of @dmn{}pt. % \def\dmn#1{\thinspace #1} \def\kbd#1{\def\look{#1}\expandafter\kbdfoo\look??\par} % @l was never documented to mean ``switch to the Lisp font'', % and it is not used as such in any manual I can find. We need it for % Polish suppressed-l. --karl, 22sep96. %\def\l#1{{\li #1}\null} % Explicit font changes: @r, @sc, undocumented @ii. \def\r#1{{\rm #1}} % roman font \def\sc#1{{\smallcaps#1}} % smallcaps font \def\ii#1{{\it #1}} % italic font % @acronym downcases the argument and prints in smallcaps. \def\acronym#1{{\smallcaps \lowercase{#1}}} % @pounds{} is a sterling sign. \def\pounds{{\it\$}} \message{page headings,} \newskip\titlepagetopglue \titlepagetopglue = 1.5in \newskip\titlepagebottomglue \titlepagebottomglue = 2pc % First the title page. Must do @settitle before @titlepage. \newif\ifseenauthor \newif\iffinishedtitlepage % Do an implicit @contents or @shortcontents after @end titlepage if the % user says @setcontentsaftertitlepage or @setshortcontentsaftertitlepage. % \newif\ifsetcontentsaftertitlepage \let\setcontentsaftertitlepage = \setcontentsaftertitlepagetrue \newif\ifsetshortcontentsaftertitlepage \let\setshortcontentsaftertitlepage = \setshortcontentsaftertitlepagetrue \def\shorttitlepage{\parsearg\shorttitlepagezzz} \def\shorttitlepagezzz #1{\begingroup\hbox{}\vskip 1.5in \chaprm \centerline{#1}% \endgroup\page\hbox{}\page} \def\titlepage{\begingroup \parindent=0pt \textfonts \let\subtitlerm=\tenrm \def\subtitlefont{\subtitlerm \normalbaselineskip = 13pt \normalbaselines}% % \def\authorfont{\authorrm \normalbaselineskip = 16pt \normalbaselines}% % % Leave some space at the very top of the page. \vglue\titlepagetopglue % % Now you can print the title using @title. \def\title{\parsearg\titlezzz}% \def\titlezzz##1{\leftline{\titlefonts\rm ##1} % print a rule at the page bottom also. \finishedtitlepagefalse \vskip4pt \hrule height 4pt width \hsize \vskip4pt}% % No rule at page bottom unless we print one at the top with @title. \finishedtitlepagetrue % % Now you can put text using @subtitle. \def\subtitle{\parsearg\subtitlezzz}% \def\subtitlezzz##1{{\subtitlefont \rightline{##1}}}% % % @author should come last, but may come many times. \def\author{\parsearg\authorzzz}% \def\authorzzz##1{\ifseenauthor\else\vskip 0pt plus 1filll\seenauthortrue\fi {\authorfont \leftline{##1}}}% % % Most title ``pages'' are actually two pages long, with space % at the top of the second. We don't want the ragged left on the second. \let\oldpage = \page \def\page{% \iffinishedtitlepage\else \finishtitlepage \fi \oldpage \let\page = \oldpage \hbox{}}% % \def\page{\oldpage \hbox{}} } \def\Etitlepage{% \iffinishedtitlepage\else \finishtitlepage \fi % It is important to do the page break before ending the group, % because the headline and footline are only empty inside the group. % If we use the new definition of \page, we always get a blank page % after the title page, which we certainly don't want. \oldpage \endgroup % % If they want short, they certainly want long too. \ifsetshortcontentsaftertitlepage \shortcontents \contents \global\let\shortcontents = \relax \global\let\contents = \relax \fi % \ifsetcontentsaftertitlepage \contents \global\let\contents = \relax \global\let\shortcontents = \relax \fi % \ifpdf \pdfmakepagedesttrue \fi % \HEADINGSon } \def\finishtitlepage{% \vskip4pt \hrule height 2pt width \hsize \vskip\titlepagebottomglue \finishedtitlepagetrue } %%% Set up page headings and footings. \let\thispage=\folio \newtoks\evenheadline % headline on even pages \newtoks\oddheadline % headline on odd pages \newtoks\evenfootline % footline on even pages \newtoks\oddfootline % footline on odd pages % Now make Tex use those variables \headline={{\textfonts\rm \ifodd\pageno \the\oddheadline \else \the\evenheadline \fi}} \footline={{\textfonts\rm \ifodd\pageno \the\oddfootline \else \the\evenfootline \fi}\HEADINGShook} \let\HEADINGShook=\relax % Commands to set those variables. % For example, this is what @headings on does % @evenheading @thistitle|@thispage|@thischapter % @oddheading @thischapter|@thispage|@thistitle % @evenfooting @thisfile|| % @oddfooting ||@thisfile \def\evenheading{\parsearg\evenheadingxxx} \def\oddheading{\parsearg\oddheadingxxx} \def\everyheading{\parsearg\everyheadingxxx} \def\evenfooting{\parsearg\evenfootingxxx} \def\oddfooting{\parsearg\oddfootingxxx} \def\everyfooting{\parsearg\everyfootingxxx} {\catcode`\@=0 % \gdef\evenheadingxxx #1{\evenheadingyyy #1@|@|@|@|\finish} \gdef\evenheadingyyy #1@|#2@|#3@|#4\finish{% \global\evenheadline={\rlap{\centerline{#2}}\line{#1\hfil#3}}} \gdef\oddheadingxxx #1{\oddheadingyyy #1@|@|@|@|\finish} \gdef\oddheadingyyy #1@|#2@|#3@|#4\finish{% \global\oddheadline={\rlap{\centerline{#2}}\line{#1\hfil#3}}} \gdef\everyheadingxxx#1{\oddheadingxxx{#1}\evenheadingxxx{#1}}% \gdef\evenfootingxxx #1{\evenfootingyyy #1@|@|@|@|\finish} \gdef\evenfootingyyy #1@|#2@|#3@|#4\finish{% \global\evenfootline={\rlap{\centerline{#2}}\line{#1\hfil#3}}} \gdef\oddfootingxxx #1{\oddfootingyyy #1@|@|@|@|\finish} \gdef\oddfootingyyy #1@|#2@|#3@|#4\finish{% \global\oddfootline = {\rlap{\centerline{#2}}\line{#1\hfil#3}}% % % Leave some space for the footline. Hopefully ok to assume % @evenfooting will not be used by itself. \global\advance\pageheight by -\baselineskip \global\advance\vsize by -\baselineskip } \gdef\everyfootingxxx#1{\oddfootingxxx{#1}\evenfootingxxx{#1}} % }% unbind the catcode of @. % @headings double turns headings on for double-sided printing. % @headings single turns headings on for single-sided printing. % @headings off turns them off. % @headings on same as @headings double, retained for compatibility. % @headings after turns on double-sided headings after this page. % @headings doubleafter turns on double-sided headings after this page. % @headings singleafter turns on single-sided headings after this page. % By default, they are off at the start of a document, % and turned `on' after @end titlepage. \def\headings #1 {\csname HEADINGS#1\endcsname} \def\HEADINGSoff{ \global\evenheadline={\hfil} \global\evenfootline={\hfil} \global\oddheadline={\hfil} \global\oddfootline={\hfil}} \HEADINGSoff % When we turn headings on, set the page number to 1. % For double-sided printing, put current file name in lower left corner, % chapter name on inside top of right hand pages, document % title on inside top of left hand pages, and page numbers on outside top % edge of all pages. \def\HEADINGSdouble{ \global\pageno=1 \global\evenfootline={\hfil} \global\oddfootline={\hfil} \global\evenheadline={\line{\folio\hfil\thistitle}} \global\oddheadline={\line{\thischapter\hfil\folio}} \global\let\contentsalignmacro = \chapoddpage } \let\contentsalignmacro = \chappager % For single-sided printing, chapter title goes across top left of page, % page number on top right. \def\HEADINGSsingle{ \global\pageno=1 \global\evenfootline={\hfil} \global\oddfootline={\hfil} \global\evenheadline={\line{\thischapter\hfil\folio}} \global\oddheadline={\line{\thischapter\hfil\folio}} \global\let\contentsalignmacro = \chappager } \def\HEADINGSon{\HEADINGSdouble} \def\HEADINGSafter{\let\HEADINGShook=\HEADINGSdoublex} \let\HEADINGSdoubleafter=\HEADINGSafter \def\HEADINGSdoublex{% \global\evenfootline={\hfil} \global\oddfootline={\hfil} \global\evenheadline={\line{\folio\hfil\thistitle}} \global\oddheadline={\line{\thischapter\hfil\folio}} \global\let\contentsalignmacro = \chapoddpage } \def\HEADINGSsingleafter{\let\HEADINGShook=\HEADINGSsinglex} \def\HEADINGSsinglex{% \global\evenfootline={\hfil} \global\oddfootline={\hfil} \global\evenheadline={\line{\thischapter\hfil\folio}} \global\oddheadline={\line{\thischapter\hfil\folio}} \global\let\contentsalignmacro = \chappager } % Subroutines used in generating headings % Produces Day Month Year style of output. \def\today{% \number\day\space \ifcase\month \or\putwordMJan\or\putwordMFeb\or\putwordMMar\or\putwordMApr \or\putwordMMay\or\putwordMJun\or\putwordMJul\or\putwordMAug \or\putwordMSep\or\putwordMOct\or\putwordMNov\or\putwordMDec \fi \space\number\year} % @settitle line... specifies the title of the document, for headings. % It generates no output of its own. \def\thistitle{\putwordNoTitle} \def\settitle{\parsearg\settitlezzz} \def\settitlezzz #1{\gdef\thistitle{#1}} \message{tables,} % Tables -- @table, @ftable, @vtable, @item(x), @kitem(x), @xitem(x). % default indentation of table text \newdimen\tableindent \tableindent=.8in % default indentation of @itemize and @enumerate text \newdimen\itemindent \itemindent=.3in % margin between end of table item and start of table text. \newdimen\itemmargin \itemmargin=.1in % used internally for \itemindent minus \itemmargin \newdimen\itemmax % Note @table, @vtable, and @vtable define @item, @itemx, etc., with % these defs. % They also define \itemindex % to index the item name in whatever manner is desired (perhaps none). \newif\ifitemxneedsnegativevskip \def\itemxpar{\par\ifitemxneedsnegativevskip\nobreak\vskip-\parskip\nobreak\fi} \def\internalBitem{\smallbreak \parsearg\itemzzz} \def\internalBitemx{\itemxpar \parsearg\itemzzz} \def\internalBxitem "#1"{\def\xitemsubtopix{#1} \smallbreak \parsearg\xitemzzz} \def\internalBxitemx "#1"{\def\xitemsubtopix{#1} \itemxpar \parsearg\xitemzzz} \def\internalBkitem{\smallbreak \parsearg\kitemzzz} \def\internalBkitemx{\itemxpar \parsearg\kitemzzz} \def\kitemzzz #1{\dosubind {kw}{\code{#1}}{for {\bf \lastfunction}}% \itemzzz {#1}} \def\xitemzzz #1{\dosubind {kw}{\code{#1}}{for {\bf \xitemsubtopic}}% \itemzzz {#1}} \def\itemzzz #1{\begingroup % \advance\hsize by -\rightskip \advance\hsize by -\tableindent \setbox0=\hbox{\itemfont{#1}}% \itemindex{#1}% \nobreak % This prevents a break before @itemx. % % If the item text does not fit in the space we have, put it on a line % by itself, and do not allow a page break either before or after that % line. We do not start a paragraph here because then if the next % command is, e.g., @kindex, the whatsit would get put into the % horizontal list on a line by itself, resulting in extra blank space. \ifdim \wd0>\itemmax % % Make this a paragraph so we get the \parskip glue and wrapping, % but leave it ragged-right. \begingroup \advance\leftskip by-\tableindent \advance\hsize by\tableindent \advance\rightskip by0pt plus1fil \leavevmode\unhbox0\par \endgroup % % We're going to be starting a paragraph, but we don't want the % \parskip glue -- logically it's part of the @item we just started. \nobreak \vskip-\parskip % % Stop a page break at the \parskip glue coming up. Unfortunately % we can't prevent a possible page break at the following % \baselineskip glue. \nobreak \endgroup \itemxneedsnegativevskipfalse \else % The item text fits into the space. Start a paragraph, so that the % following text (if any) will end up on the same line. \noindent % Do this with kerns and \unhbox so that if there is a footnote in % the item text, it can migrate to the main vertical list and % eventually be printed. \nobreak\kern-\tableindent \dimen0 = \itemmax \advance\dimen0 by \itemmargin \advance\dimen0 by -\wd0 \unhbox0 \nobreak\kern\dimen0 \endgroup \itemxneedsnegativevskiptrue \fi } \def\item{\errmessage{@item while not in a table}} \def\itemx{\errmessage{@itemx while not in a table}} \def\kitem{\errmessage{@kitem while not in a table}} \def\kitemx{\errmessage{@kitemx while not in a table}} \def\xitem{\errmessage{@xitem while not in a table}} \def\xitemx{\errmessage{@xitemx while not in a table}} % Contains a kludge to get @end[description] to work. \def\description{\tablez{\dontindex}{1}{}{}{}{}} % @table, @ftable, @vtable. \def\table{\begingroup\inENV\obeylines\obeyspaces\tablex} {\obeylines\obeyspaces% \gdef\tablex #1^^M{% \tabley\dontindex#1 \endtabley}} \def\ftable{\begingroup\inENV\obeylines\obeyspaces\ftablex} {\obeylines\obeyspaces% \gdef\ftablex #1^^M{% \tabley\fnitemindex#1 \endtabley \def\Eftable{\endgraf\afterenvbreak\endgroup}% \let\Etable=\relax}} \def\vtable{\begingroup\inENV\obeylines\obeyspaces\vtablex} {\obeylines\obeyspaces% \gdef\vtablex #1^^M{% \tabley\vritemindex#1 \endtabley \def\Evtable{\endgraf\afterenvbreak\endgroup}% \let\Etable=\relax}} \def\dontindex #1{} \def\fnitemindex #1{\doind {fn}{\code{#1}}}% \def\vritemindex #1{\doind {vr}{\code{#1}}}% {\obeyspaces % \gdef\tabley#1#2 #3 #4 #5 #6 #7\endtabley{\endgroup% \tablez{#1}{#2}{#3}{#4}{#5}{#6}}} \def\tablez #1#2#3#4#5#6{% \aboveenvbreak % \begingroup % \def\Edescription{\Etable}% Necessary kludge. \let\itemindex=#1% \ifnum 0#3>0 \advance \leftskip by #3\mil \fi % \ifnum 0#4>0 \tableindent=#4\mil \fi % \ifnum 0#5>0 \advance \rightskip by #5\mil \fi % \def\itemfont{#2}% \itemmax=\tableindent % \advance \itemmax by -\itemmargin % \advance \leftskip by \tableindent % \exdentamount=\tableindent \parindent = 0pt \parskip = \smallskipamount \ifdim \parskip=0pt \parskip=2pt \fi% \def\Etable{\endgraf\afterenvbreak\endgroup}% \let\item = \internalBitem % \let\itemx = \internalBitemx % \let\kitem = \internalBkitem % \let\kitemx = \internalBkitemx % \let\xitem = \internalBxitem % \let\xitemx = \internalBxitemx % } % This is the counter used by @enumerate, which is really @itemize \newcount \itemno \def\itemize{\parsearg\itemizezzz} \def\itemizezzz #1{% \begingroup % ended by the @end itemize \itemizey {#1}{\Eitemize} } \def\itemizey #1#2{% \aboveenvbreak % \itemmax=\itemindent % \advance \itemmax by -\itemmargin % \advance \leftskip by \itemindent % \exdentamount=\itemindent \parindent = 0pt % \parskip = \smallskipamount % \ifdim \parskip=0pt \parskip=2pt \fi% \def#2{\endgraf\afterenvbreak\endgroup}% \def\itemcontents{#1}% \let\item=\itemizeitem} % Set sfcode to normal for the chars that usually have another value. % These are `.?!:;,' \def\frenchspacing{\sfcode46=1000 \sfcode63=1000 \sfcode33=1000 \sfcode58=1000 \sfcode59=1000 \sfcode44=1000 } % \splitoff TOKENS\endmark defines \first to be the first token in % TOKENS, and \rest to be the remainder. % \def\splitoff#1#2\endmark{\def\first{#1}\def\rest{#2}}% % Allow an optional argument of an uppercase letter, lowercase letter, % or number, to specify the first label in the enumerated list. No % argument is the same as `1'. % \def\enumerate{\parsearg\enumeratezzz} \def\enumeratezzz #1{\enumeratey #1 \endenumeratey} \def\enumeratey #1 #2\endenumeratey{% \begingroup % ended by the @end enumerate % % If we were given no argument, pretend we were given `1'. \def\thearg{#1}% \ifx\thearg\empty \def\thearg{1}\fi % % Detect if the argument is a single token. If so, it might be a % letter. Otherwise, the only valid thing it can be is a number. % (We will always have one token, because of the test we just made. % This is a good thing, since \splitoff doesn't work given nothing at % all -- the first parameter is undelimited.) \expandafter\splitoff\thearg\endmark \ifx\rest\empty % Only one token in the argument. It could still be anything. % A ``lowercase letter'' is one whose \lccode is nonzero. % An ``uppercase letter'' is one whose \lccode is both nonzero, and % not equal to itself. % Otherwise, we assume it's a number. % % We need the \relax at the end of the \ifnum lines to stop TeX from % continuing to look for a . % \ifnum\lccode\expandafter`\thearg=0\relax \numericenumerate % a number (we hope) \else % It's a letter. \ifnum\lccode\expandafter`\thearg=\expandafter`\thearg\relax \lowercaseenumerate % lowercase letter \else \uppercaseenumerate % uppercase letter \fi \fi \else % Multiple tokens in the argument. We hope it's a number. \numericenumerate \fi } % An @enumerate whose labels are integers. The starting integer is % given in \thearg. % \def\numericenumerate{% \itemno = \thearg \startenumeration{\the\itemno}% } % The starting (lowercase) letter is in \thearg. \def\lowercaseenumerate{% \itemno = \expandafter`\thearg \startenumeration{% % Be sure we're not beyond the end of the alphabet. \ifnum\itemno=0 \errmessage{No more lowercase letters in @enumerate; get a bigger alphabet}% \fi \char\lccode\itemno }% } % The starting (uppercase) letter is in \thearg. \def\uppercaseenumerate{% \itemno = \expandafter`\thearg \startenumeration{% % Be sure we're not beyond the end of the alphabet. \ifnum\itemno=0 \errmessage{No more uppercase letters in @enumerate; get a bigger alphabet} \fi \char\uccode\itemno }% } % Call itemizey, adding a period to the first argument and supplying the % common last two arguments. Also subtract one from the initial value in % \itemno, since @item increments \itemno. % \def\startenumeration#1{% \advance\itemno by -1 \itemizey{#1.}\Eenumerate\flushcr } % @alphaenumerate and @capsenumerate are abbreviations for giving an arg % to @enumerate. % \def\alphaenumerate{\enumerate{a}} \def\capsenumerate{\enumerate{A}} \def\Ealphaenumerate{\Eenumerate} \def\Ecapsenumerate{\Eenumerate} % Definition of @item while inside @itemize. \def\itemizeitem{% \advance\itemno by 1 {\let\par=\endgraf \smallbreak}% \ifhmode \errmessage{In hmode at itemizeitem}\fi {\parskip=0in \hskip 0pt \hbox to 0pt{\hss \itemcontents\hskip \itemmargin}% \vadjust{\penalty 1200}}% \flushcr} % @multitable macros % Amy Hendrickson, 8/18/94, 3/6/96 % % @multitable ... @end multitable will make as many columns as desired. % Contents of each column will wrap at width given in preamble. Width % can be specified either with sample text given in a template line, % or in percent of \hsize, the current width of text on page. % Table can continue over pages but will only break between lines. % To make preamble: % % Either define widths of columns in terms of percent of \hsize: % @multitable @columnfractions .25 .3 .45 % @item ... % % Numbers following @columnfractions are the percent of the total % current hsize to be used for each column. You may use as many % columns as desired. % Or use a template: % @multitable {Column 1 template} {Column 2 template} {Column 3 template} % @item ... % using the widest term desired in each column. % % For those who want to use more than one line's worth of words in % the preamble, break the line within one argument and it % will parse correctly, i.e., % % @multitable {Column 1 template} {Column 2 template} {Column 3 % template} % Not: % @multitable {Column 1 template} {Column 2 template} % {Column 3 template} % Each new table line starts with @item, each subsequent new column % starts with @tab. Empty columns may be produced by supplying @tab's % with nothing between them for as many times as empty columns are needed, % ie, @tab@tab@tab will produce two empty columns. % @item, @tab, @multitable or @end multitable do not need to be on their % own lines, but it will not hurt if they are. % Sample multitable: % @multitable {Column 1 template} {Column 2 template} {Column 3 template} % @item first col stuff @tab second col stuff @tab third col % @item % first col stuff % @tab % second col stuff % @tab % third col % @item first col stuff @tab second col stuff % @tab Many paragraphs of text may be used in any column. % % They will wrap at the width determined by the template. % @item@tab@tab This will be in third column. % @end multitable % Default dimensions may be reset by user. % @multitableparskip is vertical space between paragraphs in table. % @multitableparindent is paragraph indent in table. % @multitablecolmargin is horizontal space to be left between columns. % @multitablelinespace is space to leave between table items, baseline % to baseline. % 0pt means it depends on current normal line spacing. % \newskip\multitableparskip \newskip\multitableparindent \newdimen\multitablecolspace \newskip\multitablelinespace \multitableparskip=0pt \multitableparindent=6pt \multitablecolspace=12pt \multitablelinespace=0pt % Macros used to set up halign preamble: % \let\endsetuptable\relax \def\xendsetuptable{\endsetuptable} \let\columnfractions\relax \def\xcolumnfractions{\columnfractions} \newif\ifsetpercent % #1 is the part of the @columnfraction before the decimal point, which % is presumably either 0 or the empty string (but we don't check, we % just throw it away). #2 is the decimal part, which we use as the % percent of \hsize for this column. \def\pickupwholefraction#1.#2 {% \global\advance\colcount by 1 \expandafter\xdef\csname col\the\colcount\endcsname{.#2\hsize}% \setuptable } \newcount\colcount \def\setuptable#1{% \def\firstarg{#1}% \ifx\firstarg\xendsetuptable \let\go = \relax \else \ifx\firstarg\xcolumnfractions \global\setpercenttrue \else \ifsetpercent \let\go\pickupwholefraction \else \global\advance\colcount by 1 \setbox0=\hbox{#1\unskip }% Add a normal word space as a separator; % typically that is always in the input, anyway. \expandafter\xdef\csname col\the\colcount\endcsname{\the\wd0}% \fi \fi \ifx\go\pickupwholefraction % Put the argument back for the \pickupwholefraction call, so % we'll always have a period there to be parsed. \def\go{\pickupwholefraction#1}% \else \let\go = \setuptable \fi% \fi \go } % This used to have \hskip1sp. But then the space in a template line is % not enough. That is bad. So let's go back to just & until we % encounter the problem it was intended to solve again. % --karl, nathan@acm.org, 20apr99. \def\tab{&} % @multitable ... @end multitable definitions: % \def\multitable{\parsearg\dotable} \def\dotable#1{\bgroup \vskip\parskip \let\item\crcr \tolerance=9500 \hbadness=9500 \setmultitablespacing \parskip=\multitableparskip \parindent=\multitableparindent \overfullrule=0pt \global\colcount=0 \def\Emultitable{\global\setpercentfalse\cr\egroup\egroup}% % % To parse everything between @multitable and @item: \setuptable#1 \endsetuptable % % \everycr will reset column counter, \colcount, at the end of % each line. Every column entry will cause \colcount to advance by one. % The table preamble % looks at the current \colcount to find the correct column width. \everycr{\noalign{% % % \filbreak%% keeps underfull box messages off when table breaks over pages. % Maybe so, but it also creates really weird page breaks when the table % breaks over pages. Wouldn't \vfil be better? Wait until the problem % manifests itself, so it can be fixed for real --karl. \global\colcount=0\relax}}% % % This preamble sets up a generic column definition, which will % be used as many times as user calls for columns. % \vtop will set a single line and will also let text wrap and % continue for many paragraphs if desired. \halign\bgroup&\global\advance\colcount by 1\relax \multistrut\vtop{\hsize=\expandafter\csname col\the\colcount\endcsname % % In order to keep entries from bumping into each other % we will add a \leftskip of \multitablecolspace to all columns after % the first one. % % If a template has been used, we will add \multitablecolspace % to the width of each template entry. % % If the user has set preamble in terms of percent of \hsize we will % use that dimension as the width of the column, and the \leftskip % will keep entries from bumping into each other. Table will start at % left margin and final column will justify at right margin. % % Make sure we don't inherit \rightskip from the outer environment. \rightskip=0pt \ifnum\colcount=1 % The first column will be indented with the surrounding text. \advance\hsize by\leftskip \else \ifsetpercent \else % If user has not set preamble in terms of percent of \hsize % we will advance \hsize by \multitablecolspace. \advance\hsize by \multitablecolspace \fi % In either case we will make \leftskip=\multitablecolspace: \leftskip=\multitablecolspace \fi % Ignoring space at the beginning and end avoids an occasional spurious % blank line, when TeX decides to break the line at the space before the % box from the multistrut, so the strut ends up on a line by itself. % For example: % @multitable @columnfractions .11 .89 % @item @code{#} % @tab Legal holiday which is valid in major parts of the whole country. % Is automatically provided with highlighting sequences respectively marking % characters. \noindent\ignorespaces##\unskip\multistrut}\cr } \def\setmultitablespacing{% test to see if user has set \multitablelinespace. % If so, do nothing. If not, give it an appropriate dimension based on % current baselineskip. \ifdim\multitablelinespace=0pt \setbox0=\vbox{X}\global\multitablelinespace=\the\baselineskip \global\advance\multitablelinespace by-\ht0 %% strut to put in table in case some entry doesn't have descenders, %% to keep lines equally spaced \let\multistrut = \strut \else %% FIXME: what is \box0 supposed to be? \gdef\multistrut{\vrule height\multitablelinespace depth\dp0 width0pt\relax} \fi %% Test to see if parskip is larger than space between lines of %% table. If not, do nothing. %% If so, set to same dimension as multitablelinespace. \ifdim\multitableparskip>\multitablelinespace \global\multitableparskip=\multitablelinespace \global\advance\multitableparskip-7pt %% to keep parskip somewhat smaller %% than skip between lines in the table. \fi% \ifdim\multitableparskip=0pt \global\multitableparskip=\multitablelinespace \global\advance\multitableparskip-7pt %% to keep parskip somewhat smaller %% than skip between lines in the table. \fi} \message{conditionals,} % Prevent errors for section commands. % Used in @ignore and in failing conditionals. \def\ignoresections{% \let\chapter=\relax \let\unnumbered=\relax \let\top=\relax \let\unnumberedsec=\relax \let\unnumberedsection=\relax \let\unnumberedsubsec=\relax \let\unnumberedsubsection=\relax \let\unnumberedsubsubsec=\relax \let\unnumberedsubsubsection=\relax \let\section=\relax \let\subsec=\relax \let\subsubsec=\relax \let\subsection=\relax \let\subsubsection=\relax \let\appendix=\relax \let\appendixsec=\relax \let\appendixsection=\relax \let\appendixsubsec=\relax \let\appendixsubsection=\relax \let\appendixsubsubsec=\relax \let\appendixsubsubsection=\relax \let\contents=\relax \let\smallbook=\relax \let\titlepage=\relax } % Used in nested conditionals, where we have to parse the Texinfo source % and so want to turn off most commands, in case they are used % incorrectly. % \def\ignoremorecommands{% \let\defcodeindex = \relax \let\defcv = \relax \let\deffn = \relax \let\deffnx = \relax \let\defindex = \relax \let\defivar = \relax \let\defmac = \relax \let\defmethod = \relax \let\defop = \relax \let\defopt = \relax \let\defspec = \relax \let\deftp = \relax \let\deftypefn = \relax \let\deftypefun = \relax \let\deftypeivar = \relax \let\deftypeop = \relax \let\deftypevar = \relax \let\deftypevr = \relax \let\defun = \relax \let\defvar = \relax \let\defvr = \relax \let\ref = \relax \let\xref = \relax \let\printindex = \relax \let\pxref = \relax \let\settitle = \relax \let\setchapternewpage = \relax \let\setchapterstyle = \relax \let\everyheading = \relax \let\evenheading = \relax \let\oddheading = \relax \let\everyfooting = \relax \let\evenfooting = \relax \let\oddfooting = \relax \let\headings = \relax \let\include = \relax \let\lowersections = \relax \let\down = \relax \let\raisesections = \relax \let\up = \relax \let\set = \relax \let\clear = \relax \let\item = \relax } % Ignore @ignore ... @end ignore. % \def\ignore{\doignore{ignore}} % Ignore @ifinfo, @ifhtml, @ifnottex, @html, @menu, and @direntry text. % \def\ifinfo{\doignore{ifinfo}} \def\ifhtml{\doignore{ifhtml}} \def\ifnottex{\doignore{ifnottex}} \def\html{\doignore{html}} \def\menu{\doignore{menu}} \def\direntry{\doignore{direntry}} % @dircategory CATEGORY -- specify a category of the dir file % which this file should belong to. Ignore this in TeX. \let\dircategory = \comment % Ignore text until a line `@end #1'. % \def\doignore#1{\begingroup % Don't complain about control sequences we have declared \outer. \ignoresections % % Define a command to swallow text until we reach `@end #1'. % This @ is a catcode 12 token (that is the normal catcode of @ in % this texinfo.tex file). We change the catcode of @ below to match. \long\def\doignoretext##1@end #1{\enddoignore}% % % Make sure that spaces turn into tokens that match what \doignoretext wants. \catcode32 = 10 % % Ignore braces, too, so mismatched braces don't cause trouble. \catcode`\{ = 9 \catcode`\} = 9 % % We must not have @c interpreted as a control sequence. \catcode`\@ = 12 % % Make the letter c a comment character so that the rest of the line % will be ignored. This way, the document can have (for example) % @c @end ifinfo % and the @end ifinfo will be properly ignored. % (We've just changed @ to catcode 12.) \catcode`\c = 14 % % And now expand that command. \doignoretext } % What we do to finish off ignored text. % \def\enddoignore{\endgroup\ignorespaces}% \newif\ifwarnedobs\warnedobsfalse \def\obstexwarn{% \ifwarnedobs\relax\else % We need to warn folks that they may have trouble with TeX 3.0. % This uses \immediate\write16 rather than \message to get newlines. \immediate\write16{} \immediate\write16{WARNING: for users of Unix TeX 3.0!} \immediate\write16{This manual trips a bug in TeX version 3.0 (tex hangs).} \immediate\write16{If you are running another version of TeX, relax.} \immediate\write16{If you are running Unix TeX 3.0, kill this TeX process.} \immediate\write16{ Then upgrade your TeX installation if you can.} \immediate\write16{ (See ftp://ftp.gnu.org/pub/gnu/TeX.README.)} \immediate\write16{If you are stuck with version 3.0, run the} \immediate\write16{ script ``tex3patch'' from the Texinfo distribution} \immediate\write16{ to use a workaround.} \immediate\write16{} \global\warnedobstrue \fi } % **In TeX 3.0, setting text in \nullfont hangs tex. For a % workaround (which requires the file ``dummy.tfm'' to be installed), % uncomment the following line: %%%%%\font\nullfont=dummy\let\obstexwarn=\relax % Ignore text, except that we keep track of conditional commands for % purposes of nesting, up to an `@end #1' command. % \def\nestedignore#1{% \obstexwarn % We must actually expand the ignored text to look for the @end % command, so that nested ignore constructs work. Thus, we put the % text into a \vbox and then do nothing with the result. To minimize % the change of memory overflow, we follow the approach outlined on % page 401 of the TeXbook: make the current font be a dummy font. % \setbox0 = \vbox\bgroup % Don't complain about control sequences we have declared \outer. \ignoresections % % Define `@end #1' to end the box, which will in turn undefine the % @end command again. \expandafter\def\csname E#1\endcsname{\egroup\ignorespaces}% % % We are going to be parsing Texinfo commands. Most cause no % trouble when they are used incorrectly, but some commands do % complicated argument parsing or otherwise get confused, so we % undefine them. % % We can't do anything about stray @-signs, unfortunately; % they'll produce `undefined control sequence' errors. \ignoremorecommands % % Set the current font to be \nullfont, a TeX primitive, and define % all the font commands to also use \nullfont. We don't use % dummy.tfm, as suggested in the TeXbook, because not all sites % might have that installed. Therefore, math mode will still % produce output, but that should be an extremely small amount of % stuff compared to the main input. % \nullfont \let\tenrm=\nullfont \let\tenit=\nullfont \let\tensl=\nullfont \let\tenbf=\nullfont \let\tentt=\nullfont \let\smallcaps=\nullfont \let\tensf=\nullfont % Similarly for index fonts (mostly for their use in smallexample). \let\smallrm=\nullfont \let\smallit=\nullfont \let\smallsl=\nullfont \let\smallbf=\nullfont \let\smalltt=\nullfont \let\smallsc=\nullfont \let\smallsf=\nullfont % % Don't complain when characters are missing from the fonts. \tracinglostchars = 0 % % Don't bother to do space factor calculations. \frenchspacing % % Don't report underfull hboxes. \hbadness = 10000 % % Do minimal line-breaking. \pretolerance = 10000 % % Do not execute instructions in @tex \def\tex{\doignore{tex}}% % Do not execute macro definitions. % `c' is a comment character, so the word `macro' will get cut off. \def\macro{\doignore{ma}}% } % @set VAR sets the variable VAR to an empty value. % @set VAR REST-OF-LINE sets VAR to the value REST-OF-LINE. % % Since we want to separate VAR from REST-OF-LINE (which might be % empty), we can't just use \parsearg; we have to insert a space of our % own to delimit the rest of the line, and then take it out again if we % didn't need it. Make sure the catcode of space is correct to avoid % losing inside @example, for instance. % \def\set{\begingroup\catcode` =10 \catcode`\-=12 \catcode`\_=12 % Allow - and _ in VAR. \parsearg\setxxx} \def\setxxx#1{\setyyy#1 \endsetyyy} \def\setyyy#1 #2\endsetyyy{% \def\temp{#2}% \ifx\temp\empty \global\expandafter\let\csname SET#1\endcsname = \empty \else \setzzz{#1}#2\endsetzzz % Remove the trailing space \setxxx inserted. \fi \endgroup } % Can't use \xdef to pre-expand #2 and save some time, since \temp or % \next or other control sequences that we've defined might get us into % an infinite loop. Consider `@set foo @cite{bar}'. \def\setzzz#1#2 \endsetzzz{\expandafter\gdef\csname SET#1\endcsname{#2}} % @clear VAR clears (i.e., unsets) the variable VAR. % \def\clear{\parsearg\clearxxx} \def\clearxxx#1{\global\expandafter\let\csname SET#1\endcsname=\relax} % @value{foo} gets the text saved in variable foo. { \catcode`\_ = \active % % We might end up with active _ or - characters in the argument if % we're called from @code, as @code{@value{foo-bar_}}. So \let any % such active characters to their normal equivalents. \gdef\value{\begingroup \catcode`\-=12 \catcode`\_=12 \indexbreaks \let_\normalunderscore \valuexxx} } \def\valuexxx#1{\expandablevalue{#1}\endgroup} % We have this subroutine so that we can handle at least some @value's % properly in indexes (we \let\value to this in \indexdummies). Ones % whose names contain - or _ still won't work, but we can't do anything % about that. The command has to be fully expandable, since the result % winds up in the index file. This means that if the variable's value % contains other Texinfo commands, it's almost certain it will fail % (although perhaps we could fix that with sufficient work to do a % one-level expansion on the result, instead of complete). % \def\expandablevalue#1{% \expandafter\ifx\csname SET#1\endcsname\relax {[No value for ``#1'']}% \else \csname SET#1\endcsname \fi } % @ifset VAR ... @end ifset reads the `...' iff VAR has been defined % with @set. % \def\ifset{\parsearg\ifsetxxx} \def\ifsetxxx #1{% \expandafter\ifx\csname SET#1\endcsname\relax \expandafter\ifsetfail \else \expandafter\ifsetsucceed \fi } \def\ifsetsucceed{\conditionalsucceed{ifset}} \def\ifsetfail{\nestedignore{ifset}} \defineunmatchedend{ifset} % @ifclear VAR ... @end ifclear reads the `...' iff VAR has never been % defined with @set, or has been undefined with @clear. % \def\ifclear{\parsearg\ifclearxxx} \def\ifclearxxx #1{% \expandafter\ifx\csname SET#1\endcsname\relax \expandafter\ifclearsucceed \else \expandafter\ifclearfail \fi } \def\ifclearsucceed{\conditionalsucceed{ifclear}} \def\ifclearfail{\nestedignore{ifclear}} \defineunmatchedend{ifclear} % @iftex, @ifnothtml, @ifnotinfo always succeed; we read the text % following, through the first @end iftex (etc.). Make `@end iftex' % (etc.) valid only after an @iftex. % \def\iftex{\conditionalsucceed{iftex}} \def\ifnothtml{\conditionalsucceed{ifnothtml}} \def\ifnotinfo{\conditionalsucceed{ifnotinfo}} \defineunmatchedend{iftex} \defineunmatchedend{ifnothtml} \defineunmatchedend{ifnotinfo} % We can't just want to start a group at @iftex (for example) and end it % at @end iftex, since then @set commands inside the conditional have no % effect (they'd get reverted at the end of the group). So we must % define \Eiftex to redefine itself to be its previous value. (We can't % just define it to fail again with an ``unmatched end'' error, since % the @ifset might be nested.) % \def\conditionalsucceed#1{% \edef\temp{% % Remember the current value of \E#1. \let\nece{prevE#1} = \nece{E#1}% % % At the `@end #1', redefine \E#1 to be its previous value. \def\nece{E#1}{\let\nece{E#1} = \nece{prevE#1}}% }% \temp } % We need to expand lots of \csname's, but we don't want to expand the % control sequences after we've constructed them. % \def\nece#1{\expandafter\noexpand\csname#1\endcsname} % @defininfoenclose. \let\definfoenclose=\comment \message{indexing,} % Index generation facilities % Define \newwrite to be identical to plain tex's \newwrite % except not \outer, so it can be used within \newindex. {\catcode`\@=11 \gdef\newwrite{\alloc@7\write\chardef\sixt@@n}} % \newindex {foo} defines an index named foo. % It automatically defines \fooindex such that % \fooindex ...rest of line... puts an entry in the index foo. % It also defines \fooindfile to be the number of the output channel for % the file that accumulates this index. The file's extension is foo. % The name of an index should be no more than 2 characters long % for the sake of vms. % \def\newindex#1{% \iflinks \expandafter\newwrite \csname#1indfile\endcsname \openout \csname#1indfile\endcsname \jobname.#1 % Open the file \fi \expandafter\xdef\csname#1index\endcsname{% % Define @#1index \noexpand\doindex{#1}} } % @defindex foo == \newindex{foo} \def\defindex{\parsearg\newindex} % Define @defcodeindex, like @defindex except put all entries in @code. \def\newcodeindex#1{% \iflinks \expandafter\newwrite \csname#1indfile\endcsname \openout \csname#1indfile\endcsname \jobname.#1 \fi \expandafter\xdef\csname#1index\endcsname{% \noexpand\docodeindex{#1}} } \def\defcodeindex{\parsearg\newcodeindex} % @synindex foo bar makes index foo feed into index bar. % Do this instead of @defindex foo if you don't want it as a separate index. % The \closeout helps reduce unnecessary open files; the limit on the % Acorn RISC OS is a mere 16 files. \def\synindex#1 #2 {% \expandafter\let\expandafter\synindexfoo\expandafter=\csname#2indfile\endcsname \expandafter\closeout\csname#1indfile\endcsname \expandafter\let\csname#1indfile\endcsname=\synindexfoo \expandafter\xdef\csname#1index\endcsname{% define \xxxindex \noexpand\doindex{#2}}% } % @syncodeindex foo bar similar, but put all entries made for index foo % inside @code. \def\syncodeindex#1 #2 {% \expandafter\let\expandafter\synindexfoo\expandafter=\csname#2indfile\endcsname \expandafter\closeout\csname#1indfile\endcsname \expandafter\let\csname#1indfile\endcsname=\synindexfoo \expandafter\xdef\csname#1index\endcsname{% define \xxxindex \noexpand\docodeindex{#2}}% } % Define \doindex, the driver for all \fooindex macros. % Argument #1 is generated by the calling \fooindex macro, % and it is "foo", the name of the index. % \doindex just uses \parsearg; it calls \doind for the actual work. % This is because \doind is more useful to call from other macros. % There is also \dosubind {index}{topic}{subtopic} % which makes an entry in a two-level index such as the operation index. \def\doindex#1{\edef\indexname{#1}\parsearg\singleindexer} \def\singleindexer #1{\doind{\indexname}{#1}} % like the previous two, but they put @code around the argument. \def\docodeindex#1{\edef\indexname{#1}\parsearg\singlecodeindexer} \def\singlecodeindexer #1{\doind{\indexname}{\code{#1}}} \def\indexdummies{% \def\ { }% % Take care of the plain tex accent commands. \def\"{\realbackslash "}% \def\`{\realbackslash `}% \def\'{\realbackslash '}% \def\^{\realbackslash ^}% \def\~{\realbackslash ~}% \def\={\realbackslash =}% \def\b{\realbackslash b}% \def\c{\realbackslash c}% \def\d{\realbackslash d}% \def\u{\realbackslash u}% \def\v{\realbackslash v}% \def\H{\realbackslash H}% % Take care of the plain tex special European modified letters. \def\oe{\realbackslash oe}% \def\ae{\realbackslash ae}% \def\aa{\realbackslash aa}% \def\OE{\realbackslash OE}% \def\AE{\realbackslash AE}% \def\AA{\realbackslash AA}% \def\o{\realbackslash o}% \def\O{\realbackslash O}% \def\l{\realbackslash l}% \def\L{\realbackslash L}% \def\ss{\realbackslash ss}% % Take care of texinfo commands likely to appear in an index entry. % (Must be a way to avoid doing expansion at all, and thus not have to % laboriously list every single command here.) \def\@{@}% will be @@ when we switch to @ as escape char. % Need these in case \tex is in effect and \{ is a \delimiter again. % But can't use \lbracecmd and \rbracecmd because texindex assumes % braces and backslashes are used only as delimiters. \let\{ = \mylbrace \let\} = \myrbrace \def\_{{\realbackslash _}}% \def\w{\realbackslash w }% \def\bf{\realbackslash bf }% %\def\rm{\realbackslash rm }% \def\sl{\realbackslash sl }% \def\sf{\realbackslash sf}% \def\tt{\realbackslash tt}% \def\gtr{\realbackslash gtr}% \def\less{\realbackslash less}% \def\hat{\realbackslash hat}% \def\TeX{\realbackslash TeX}% \def\dots{\realbackslash dots }% \def\result{\realbackslash result}% \def\equiv{\realbackslash equiv}% \def\expansion{\realbackslash expansion}% \def\print{\realbackslash print}% \def\error{\realbackslash error}% \def\point{\realbackslash point}% \def\copyright{\realbackslash copyright}% \def\tclose##1{\realbackslash tclose {##1}}% \def\code##1{\realbackslash code {##1}}% \def\uref##1{\realbackslash uref {##1}}% \def\url##1{\realbackslash url {##1}}% \def\env##1{\realbackslash env {##1}}% \def\command##1{\realbackslash command {##1}}% \def\option##1{\realbackslash option {##1}}% \def\dotless##1{\realbackslash dotless {##1}}% \def\samp##1{\realbackslash samp {##1}}% \def\,##1{\realbackslash ,{##1}}% \def\t##1{\realbackslash t {##1}}% \def\r##1{\realbackslash r {##1}}% \def\i##1{\realbackslash i {##1}}% \def\b##1{\realbackslash b {##1}}% \def\sc##1{\realbackslash sc {##1}}% \def\cite##1{\realbackslash cite {##1}}% \def\key##1{\realbackslash key {##1}}% \def\file##1{\realbackslash file {##1}}% \def\var##1{\realbackslash var {##1}}% \def\kbd##1{\realbackslash kbd {##1}}% \def\dfn##1{\realbackslash dfn {##1}}% \def\emph##1{\realbackslash emph {##1}}% \def\acronym##1{\realbackslash acronym {##1}}% % % Handle some cases of @value -- where the variable name does not % contain - or _, and the value does not contain any % (non-fully-expandable) commands. \let\value = \expandablevalue % \unsepspaces % Turn off macro expansion \turnoffmacros } % If an index command is used in an @example environment, any spaces % therein should become regular spaces in the raw index file, not the % expansion of \tie (\\leavevmode \penalty \@M \ ). {\obeyspaces \gdef\unsepspaces{\obeyspaces\let =\space}} % \indexnofonts no-ops all font-change commands. % This is used when outputting the strings to sort the index by. \def\indexdummyfont#1{#1} \def\indexdummytex{TeX} \def\indexdummydots{...} \def\indexnofonts{% % Just ignore accents. \let\,=\indexdummyfont \let\"=\indexdummyfont \let\`=\indexdummyfont \let\'=\indexdummyfont \let\^=\indexdummyfont \let\~=\indexdummyfont \let\==\indexdummyfont \let\b=\indexdummyfont \let\c=\indexdummyfont \let\d=\indexdummyfont \let\u=\indexdummyfont \let\v=\indexdummyfont \let\H=\indexdummyfont \let\dotless=\indexdummyfont % Take care of the plain tex special European modified letters. \def\oe{oe}% \def\ae{ae}% \def\aa{aa}% \def\OE{OE}% \def\AE{AE}% \def\AA{AA}% \def\o{o}% \def\O{O}% \def\l{l}% \def\L{L}% \def\ss{ss}% \let\w=\indexdummyfont \let\t=\indexdummyfont \let\r=\indexdummyfont \let\i=\indexdummyfont \let\b=\indexdummyfont \let\emph=\indexdummyfont \let\strong=\indexdummyfont \let\cite=\indexdummyfont \let\sc=\indexdummyfont %Don't no-op \tt, since it isn't a user-level command % and is used in the definitions of the active chars like <, >, |... %\let\tt=\indexdummyfont \let\tclose=\indexdummyfont \let\code=\indexdummyfont \let\url=\indexdummyfont \let\uref=\indexdummyfont \let\env=\indexdummyfont \let\acronym=\indexdummyfont \let\command=\indexdummyfont \let\option=\indexdummyfont \let\file=\indexdummyfont \let\samp=\indexdummyfont \let\kbd=\indexdummyfont \let\key=\indexdummyfont \let\var=\indexdummyfont \let\TeX=\indexdummytex \let\dots=\indexdummydots \def\@{@}% } % To define \realbackslash, we must make \ not be an escape. % We must first make another character (@) an escape % so we do not become unable to do a definition. {\catcode`\@=0 \catcode`\\=\other @gdef@realbackslash{\}} \let\indexbackslash=0 %overridden during \printindex. \let\SETmarginindex=\relax % put index entries in margin (undocumented)? % For \ifx comparisons. \def\emptymacro{\empty} % Most index entries go through here, but \dosubind is the general case. % \def\doind#1#2{\dosubind{#1}{#2}\empty} % Workhorse for all \fooindexes. % #1 is name of index, #2 is stuff to put there, #3 is subentry -- % \empty if called from \doind, as we usually are. The main exception % is with defuns, which call us directly. % \def\dosubind#1#2#3{% % Put the index entry in the margin if desired. \ifx\SETmarginindex\relax\else \insert\margin{\hbox{\vrule height8pt depth3pt width0pt #2}}% \fi {% \count255=\lastpenalty {% \indexdummies % Must do this here, since \bf, etc expand at this stage \escapechar=`\\ {% \let\folio = 0% We will expand all macros now EXCEPT \folio. \def\rawbackslashxx{\indexbackslash}% \indexbackslash isn't defined now % so it will be output as is; and it will print as backslash. % \def\thirdarg{#3}% % % If third arg is present, precede it with space in sort key. \ifx\thirdarg\emptymacro \let\subentry = \empty \else \def\subentry{ #3}% \fi % % First process the index entry with all font commands turned % off to get the string to sort by. {\indexnofonts \xdef\indexsorttmp{#2\subentry}}% % % Now the real index entry with the fonts. \toks0 = {#2}% % % If third (subentry) arg is present, add it to the index % string. And include a space. \ifx\thirdarg\emptymacro \else \toks0 = \expandafter{\the\toks0 \space #3}% \fi % % Set up the complete index entry, with both the sort key % and the original text, including any font commands. We write % three arguments to \entry to the .?? file, texindex reduces to % two when writing the .??s sorted result. \edef\temp{% \write\csname#1indfile\endcsname{% \realbackslash entry{\indexsorttmp}{\folio}{\the\toks0}}% }% % % If a skip is the last thing on the list now, preserve it % by backing up by \lastskip, doing the \write, then inserting % the skip again. Otherwise, the whatsit generated by the % \write will make \lastskip zero. The result is that sequences % like this: % @end defun % @tindex whatever % @defun ... % will have extra space inserted, because the \medbreak in the % start of the @defun won't see the skip inserted by the @end of % the previous defun. % % But don't do any of this if we're not in vertical mode. We % don't want to do a \vskip and prematurely end a paragraph. % % Avoid page breaks due to these extra skips, too. % \iflinks \ifvmode \skip0 = \lastskip \ifdim\lastskip = 0pt \else \nobreak\vskip-\lastskip \fi \fi % \temp % do the write % % \ifvmode \ifdim\skip0 = 0pt \else \nobreak\vskip\skip0 \fi \fi \fi }% }% \penalty\count255 }% } % The index entry written in the file actually looks like % \entry {sortstring}{page}{topic} % or % \entry {sortstring}{page}{topic}{subtopic} % The texindex program reads in these files and writes files % containing these kinds of lines: % \initial {c} % before the first topic whose initial is c % \entry {topic}{pagelist} % for a topic that is used without subtopics % \primary {topic} % for the beginning of a topic that is used with subtopics % \secondary {subtopic}{pagelist} % for each subtopic. % Define the user-accessible indexing commands % @findex, @vindex, @kindex, @cindex. \def\findex {\fnindex} \def\kindex {\kyindex} \def\cindex {\cpindex} \def\vindex {\vrindex} \def\tindex {\tpindex} \def\pindex {\pgindex} \def\cindexsub {\begingroup\obeylines\cindexsub} {\obeylines % \gdef\cindexsub "#1" #2^^M{\endgroup % \dosubind{cp}{#2}{#1}}} % Define the macros used in formatting output of the sorted index material. % @printindex causes a particular index (the ??s file) to get printed. % It does not print any chapter heading (usually an @unnumbered). % \def\printindex{\parsearg\doprintindex} \def\doprintindex#1{\begingroup \dobreak \chapheadingskip{10000}% % \smallfonts \rm \tolerance = 9500 \indexbreaks % % See if the index file exists and is nonempty. % Change catcode of @ here so that if the index file contains % \initial {@} % as its first line, TeX doesn't complain about mismatched braces % (because it thinks @} is a control sequence). \catcode`\@ = 11 \openin 1 \jobname.#1s \ifeof 1 % \enddoublecolumns gets confused if there is no text in the index, % and it loses the chapter title and the aux file entries for the % index. The easiest way to prevent this problem is to make sure % there is some text. \putwordIndexNonexistent \else % % If the index file exists but is empty, then \openin leaves \ifeof % false. We have to make TeX try to read something from the file, so % it can discover if there is anything in it. \read 1 to \temp \ifeof 1 \putwordIndexIsEmpty \else % Index files are almost Texinfo source, but we use \ as the escape % character. It would be better to use @, but that's too big a change % to make right now. \def\indexbackslash{\rawbackslashxx}% \catcode`\\ = 0 \escapechar = `\\ \begindoublecolumns \input \jobname.#1s \enddoublecolumns \fi \fi \closein 1 \endgroup} % These macros are used by the sorted index file itself. % Change them to control the appearance of the index. \def\initial#1{{% % Some minor font changes for the special characters. \let\tentt=\sectt \let\tt=\sectt \let\sf=\sectt % % Remove any glue we may have, we'll be inserting our own. \removelastskip % % We like breaks before the index initials, so insert a bonus. \penalty -300 % % Typeset the initial. Making this add up to a whole number of % baselineskips increases the chance of the dots lining up from column % to column. It still won't often be perfect, because of the stretch % we need before each entry, but it's better. % % No shrink because it confuses \balancecolumns. \vskip 1.67\baselineskip plus .5\baselineskip \leftline{\secbf #1}% \vskip .33\baselineskip plus .1\baselineskip % % Do our best not to break after the initial. \nobreak }} % This typesets a paragraph consisting of #1, dot leaders, and then #2 % flush to the right margin. It is used for index and table of contents % entries. The paragraph is indented by \leftskip. % \def\entry#1#2{\begingroup % % Start a new paragraph if necessary, so our assignments below can't % affect previous text. \par % % Do not fill out the last line with white space. \parfillskip = 0in % % No extra space above this paragraph. \parskip = 0in % % Do not prefer a separate line ending with a hyphen to fewer lines. \finalhyphendemerits = 0 % % \hangindent is only relevant when the entry text and page number % don't both fit on one line. In that case, bob suggests starting the % dots pretty far over on the line. Unfortunately, a large % indentation looks wrong when the entry text itself is broken across % lines. So we use a small indentation and put up with long leaders. % % \hangafter is reset to 1 (which is the value we want) at the start % of each paragraph, so we need not do anything with that. \hangindent = 2em % % When the entry text needs to be broken, just fill out the first line % with blank space. \rightskip = 0pt plus1fil % % A bit of stretch before each entry for the benefit of balancing columns. \vskip 0pt plus1pt % % Start a ``paragraph'' for the index entry so the line breaking % parameters we've set above will have an effect. \noindent % % Insert the text of the index entry. TeX will do line-breaking on it. #1% % The following is kludged to not output a line of dots in the index if % there are no page numbers. The next person who breaks this will be % cursed by a Unix daemon. \def\tempa{{\rm }}% \def\tempb{#2}% \edef\tempc{\tempa}% \edef\tempd{\tempb}% \ifx\tempc\tempd\ \else% % % If we must, put the page number on a line of its own, and fill out % this line with blank space. (The \hfil is overwhelmed with the % fill leaders glue in \indexdotfill if the page number does fit.) \hfil\penalty50 \null\nobreak\indexdotfill % Have leaders before the page number. % % The `\ ' here is removed by the implicit \unskip that TeX does as % part of (the primitive) \par. Without it, a spurious underfull % \hbox ensues. \ifpdf \pdfgettoks#2.\ \the\toksA % The page number ends the paragraph. \else \ #2% The page number ends the paragraph. \fi \fi% \par \endgroup} % Like \dotfill except takes at least 1 em. \def\indexdotfill{\cleaders \hbox{$\mathsurround=0pt \mkern1.5mu ${\it .}$ \mkern1.5mu$}\hskip 1em plus 1fill} \def\primary #1{\line{#1\hfil}} \newskip\secondaryindent \secondaryindent=0.5cm \def\secondary #1#2{ {\parfillskip=0in \parskip=0in \hangindent =1in \hangafter=1 \noindent\hskip\secondaryindent\hbox{#1}\indexdotfill #2\par }} % Define two-column mode, which we use to typeset indexes. % Adapted from the TeXbook, page 416, which is to say, % the manmac.tex format used to print the TeXbook itself. \catcode`\@=11 \newbox\partialpage \newdimen\doublecolumnhsize \def\begindoublecolumns{\begingroup % ended by \enddoublecolumns % Grab any single-column material above us. \output = {% % % Here is a possibility not foreseen in manmac: if we accumulate a % whole lot of material, we might end up calling this \output % routine twice in a row (see the doublecol-lose test, which is % essentially a couple of indexes with @setchapternewpage off). In % that case we just ship out what is in \partialpage with the normal % output routine. Generally, \partialpage will be empty when this % runs and this will be a no-op. See the indexspread.tex test case. \ifvoid\partialpage \else \onepageout{\pagecontents\partialpage}% \fi % \global\setbox\partialpage = \vbox{% % Unvbox the main output page. \unvbox\PAGE \kern-\topskip \kern\baselineskip }% }% \eject % run that output routine to set \partialpage % % Use the double-column output routine for subsequent pages. \output = {\doublecolumnout}% % % Change the page size parameters. We could do this once outside this % routine, in each of @smallbook, @afourpaper, and the default 8.5x11 % format, but then we repeat the same computation. Repeating a couple % of assignments once per index is clearly meaningless for the % execution time, so we may as well do it in one place. % % First we halve the line length, less a little for the gutter between % the columns. We compute the gutter based on the line length, so it % changes automatically with the paper format. The magic constant % below is chosen so that the gutter has the same value (well, +-<1pt) % as it did when we hard-coded it. % % We put the result in a separate register, \doublecolumhsize, so we % can restore it in \pagesofar, after \hsize itself has (potentially) % been clobbered. % \doublecolumnhsize = \hsize \advance\doublecolumnhsize by -.04154\hsize \divide\doublecolumnhsize by 2 \hsize = \doublecolumnhsize % % Double the \vsize as well. (We don't need a separate register here, % since nobody clobbers \vsize.) \advance\vsize by -\ht\partialpage \vsize = 2\vsize } % The double-column output routine for all double-column pages except % the last. % \def\doublecolumnout{% \splittopskip=\topskip \splitmaxdepth=\maxdepth % Get the available space for the double columns -- the normal % (undoubled) page height minus any material left over from the % previous page. \dimen@ = \vsize \divide\dimen@ by 2 % % box0 will be the left-hand column, box2 the right. \setbox0=\vsplit255 to\dimen@ \setbox2=\vsplit255 to\dimen@ \onepageout\pagesofar \unvbox255 \penalty\outputpenalty } \def\pagesofar{% % Re-output the contents of the output page -- any previous material, % followed by the two boxes we just split, in box0 and box2. \unvbox\partialpage % \hsize = \doublecolumnhsize \wd0=\hsize \wd2=\hsize \hbox to\pagewidth{\box0\hfil\box2}% } \def\enddoublecolumns{% \output = {% % Split the last of the double-column material. Leave it on the % current page, no automatic page break. \balancecolumns % % If we end up splitting too much material for the current page, % though, there will be another page break right after this \output % invocation ends. Having called \balancecolumns once, we do not % want to call it again. Therefore, reset \output to its normal % definition right away. (We hope \balancecolumns will never be % called on to balance too much material, but if it is, this makes % the output somewhat more palatable.) \global\output = {\onepageout{\pagecontents\PAGE}}% }% \eject \endgroup % started in \begindoublecolumns % % \pagegoal was set to the doubled \vsize above, since we restarted % the current page. We're now back to normal single-column % typesetting, so reset \pagegoal to the normal \vsize (after the % \endgroup where \vsize got restored). \pagegoal = \vsize } \def\balancecolumns{% % Called at the end of the double column material. \setbox0 = \vbox{\unvbox255}% like \box255 but more efficient, see p.120. \dimen@ = \ht0 \advance\dimen@ by \topskip \advance\dimen@ by-\baselineskip \divide\dimen@ by 2 % target to split to %debug\message{final 2-column material height=\the\ht0, target=\the\dimen@.}% \splittopskip = \topskip % Loop until we get a decent breakpoint. {% \vbadness = 10000 \loop \global\setbox3 = \copy0 \global\setbox1 = \vsplit3 to \dimen@ \ifdim\ht3>\dimen@ \global\advance\dimen@ by 1pt \repeat }% %debug\message{split to \the\dimen@, column heights: \the\ht1, \the\ht3.}% \setbox0=\vbox to\dimen@{\unvbox1}% \setbox2=\vbox to\dimen@{\unvbox3}% % \pagesofar } \catcode`\@ = \other \message{sectioning,} % Chapters, sections, etc. \newcount\chapno \newcount\secno \secno=0 \newcount\subsecno \subsecno=0 \newcount\subsubsecno \subsubsecno=0 % This counter is funny since it counts through charcodes of letters A, B, ... \newcount\appendixno \appendixno = `\@ % \def\appendixletter{\char\the\appendixno} % We do the following for the sake of pdftex, which needs the actual % letter in the expansion, not just typeset. \def\appendixletter{% \ifnum\appendixno=`A A% \else\ifnum\appendixno=`B B% \else\ifnum\appendixno=`C C% \else\ifnum\appendixno=`D D% \else\ifnum\appendixno=`E E% \else\ifnum\appendixno=`F F% \else\ifnum\appendixno=`G G% \else\ifnum\appendixno=`H H% \else\ifnum\appendixno=`I I% \else\ifnum\appendixno=`J J% \else\ifnum\appendixno=`K K% \else\ifnum\appendixno=`L L% \else\ifnum\appendixno=`M M% \else\ifnum\appendixno=`N N% \else\ifnum\appendixno=`O O% \else\ifnum\appendixno=`P P% \else\ifnum\appendixno=`Q Q% \else\ifnum\appendixno=`R R% \else\ifnum\appendixno=`S S% \else\ifnum\appendixno=`T T% \else\ifnum\appendixno=`U U% \else\ifnum\appendixno=`V V% \else\ifnum\appendixno=`W W% \else\ifnum\appendixno=`X X% \else\ifnum\appendixno=`Y Y% \else\ifnum\appendixno=`Z Z% % The \the is necessary, despite appearances, because \appendixletter is % expanded while writing the .toc file. \char\appendixno is not % expandable, thus it is written literally, thus all appendixes come out % with the same letter (or @) in the toc without it. \else\char\the\appendixno \fi\fi\fi\fi\fi\fi\fi\fi\fi\fi\fi\fi\fi \fi\fi\fi\fi\fi\fi\fi\fi\fi\fi\fi\fi\fi} % Each @chapter defines this as the name of the chapter. % page headings and footings can use it. @section does likewise. \def\thischapter{} \def\thissection{} \newcount\absseclevel % used to calculate proper heading level \newcount\secbase\secbase=0 % @raise/lowersections modify this count % @raisesections: treat @section as chapter, @subsection as section, etc. \def\raisesections{\global\advance\secbase by -1} \let\up=\raisesections % original BFox name % @lowersections: treat @chapter as section, @section as subsection, etc. \def\lowersections{\global\advance\secbase by 1} \let\down=\lowersections % original BFox name % Choose a numbered-heading macro % #1 is heading level if unmodified by @raisesections or @lowersections % #2 is text for heading \def\numhead#1#2{\absseclevel=\secbase\advance\absseclevel by #1 \ifcase\absseclevel \chapterzzz{#2} \or \seczzz{#2} \or \numberedsubseczzz{#2} \or \numberedsubsubseczzz{#2} \else \ifnum \absseclevel<0 \chapterzzz{#2} \else \numberedsubsubseczzz{#2} \fi \fi } % like \numhead, but chooses appendix heading levels \def\apphead#1#2{\absseclevel=\secbase\advance\absseclevel by #1 \ifcase\absseclevel \appendixzzz{#2} \or \appendixsectionzzz{#2} \or \appendixsubseczzz{#2} \or \appendixsubsubseczzz{#2} \else \ifnum \absseclevel<0 \appendixzzz{#2} \else \appendixsubsubseczzz{#2} \fi \fi } % like \numhead, but chooses numberless heading levels \def\unnmhead#1#2{\absseclevel=\secbase\advance\absseclevel by #1 \ifcase\absseclevel \unnumberedzzz{#2} \or \unnumberedseczzz{#2} \or \unnumberedsubseczzz{#2} \or \unnumberedsubsubseczzz{#2} \else \ifnum \absseclevel<0 \unnumberedzzz{#2} \else \unnumberedsubsubseczzz{#2} \fi \fi } % @chapter, @appendix, @unnumbered. \def\thischaptername{No Chapter Title} \outer\def\chapter{\parsearg\chapteryyy} \def\chapteryyy #1{\numhead0{#1}} % normally numhead0 calls chapterzzz \def\chapterzzz #1{% \secno=0 \subsecno=0 \subsubsecno=0 \global\advance \chapno by 1 \message{\putwordChapter\space \the\chapno}% \chapmacro {#1}{\the\chapno}% \gdef\thissection{#1}% \gdef\thischaptername{#1}% % We don't substitute the actual chapter name into \thischapter % because we don't want its macros evaluated now. \xdef\thischapter{\putwordChapter{} \the\chapno: \noexpand\thischaptername}% \toks0 = {#1}% \edef\temp{\noexpand\writetocentry{\realbackslash chapentry{\the\toks0}% {\the\chapno}}}% \temp \donoderef \global\let\section = \numberedsec \global\let\subsection = \numberedsubsec \global\let\subsubsection = \numberedsubsubsec } \outer\def\appendix{\parsearg\appendixyyy} \def\appendixyyy #1{\apphead0{#1}} % normally apphead0 calls appendixzzz \def\appendixzzz #1{% \secno=0 \subsecno=0 \subsubsecno=0 \global\advance \appendixno by 1 \message{\putwordAppendix\space \appendixletter}% \chapmacro {#1}{\putwordAppendix{} \appendixletter}% \gdef\thissection{#1}% \gdef\thischaptername{#1}% \xdef\thischapter{\putwordAppendix{} \appendixletter: \noexpand\thischaptername}% \toks0 = {#1}% \edef\temp{\noexpand\writetocentry{\realbackslash chapentry{\the\toks0}% {\putwordAppendix{} \appendixletter}}}% \temp \appendixnoderef \global\let\section = \appendixsec \global\let\subsection = \appendixsubsec \global\let\subsubsection = \appendixsubsubsec } % @centerchap is like @unnumbered, but the heading is centered. \outer\def\centerchap{\parsearg\centerchapyyy} \def\centerchapyyy #1{{\let\unnumbchapmacro=\centerchapmacro \unnumberedyyy{#1}}} % @top is like @unnumbered. \outer\def\top{\parsearg\unnumberedyyy} \outer\def\unnumbered{\parsearg\unnumberedyyy} \def\unnumberedyyy #1{\unnmhead0{#1}} % normally unnmhead0 calls unnumberedzzz \def\unnumberedzzz #1{% \secno=0 \subsecno=0 \subsubsecno=0 % % This used to be simply \message{#1}, but TeX fully expands the % argument to \message. Therefore, if #1 contained @-commands, TeX % expanded them. For example, in `@unnumbered The @cite{Book}', TeX % expanded @cite (which turns out to cause errors because \cite is meant % to be executed, not expanded). % % Anyway, we don't want the fully-expanded definition of @cite to appear % as a result of the \message, we just want `@cite' itself. We use % \the to achieve this: TeX expands \the only once, % simply yielding the contents of . (We also do this for % the toc entries.) \toks0 = {#1}\message{(\the\toks0)}% % \unnumbchapmacro {#1}% \gdef\thischapter{#1}\gdef\thissection{#1}% \toks0 = {#1}% \edef\temp{\noexpand\writetocentry{\realbackslash unnumbchapentry{\the\toks0}}}% \temp \unnumbnoderef \global\let\section = \unnumberedsec \global\let\subsection = \unnumberedsubsec \global\let\subsubsection = \unnumberedsubsubsec } % Sections. \outer\def\numberedsec{\parsearg\secyyy} \def\secyyy #1{\numhead1{#1}} % normally calls seczzz \def\seczzz #1{% \subsecno=0 \subsubsecno=0 \global\advance \secno by 1 % \gdef\thissection{#1}\secheading {#1}{\the\chapno}{\the\secno}% \toks0 = {#1}% \edef\temp{\noexpand\writetocentry{\realbackslash secentry{\the\toks0}% {\the\chapno}{\the\secno}}}% \temp \donoderef \nobreak } \outer\def\appendixsection{\parsearg\appendixsecyyy} \outer\def\appendixsec{\parsearg\appendixsecyyy} \def\appendixsecyyy #1{\apphead1{#1}} % normally calls appendixsectionzzz \def\appendixsectionzzz #1{% \subsecno=0 \subsubsecno=0 \global\advance \secno by 1 % \gdef\thissection{#1}\secheading {#1}{\appendixletter}{\the\secno}% \toks0 = {#1}% \edef\temp{\noexpand\writetocentry{\realbackslash secentry{\the\toks0}% {\appendixletter}{\the\secno}}}% \temp \appendixnoderef \nobreak } \outer\def\unnumberedsec{\parsearg\unnumberedsecyyy} \def\unnumberedsecyyy #1{\unnmhead1{#1}} % normally calls unnumberedseczzz \def\unnumberedseczzz #1{% \plainsecheading {#1}\gdef\thissection{#1}% \toks0 = {#1}% \edef\temp{\noexpand\writetocentry{\realbackslash unnumbsecentry{\the\toks0}}}% \temp \unnumbnoderef \nobreak } % Subsections. \outer\def\numberedsubsec{\parsearg\numberedsubsecyyy} \def\numberedsubsecyyy #1{\numhead2{#1}} % normally calls numberedsubseczzz \def\numberedsubseczzz #1{% \gdef\thissection{#1}\subsubsecno=0 \global\advance \subsecno by 1 % \subsecheading {#1}{\the\chapno}{\the\secno}{\the\subsecno}% \toks0 = {#1}% \edef\temp{\noexpand\writetocentry{\realbackslash subsecentry{\the\toks0}% {\the\chapno}{\the\secno}{\the\subsecno}}}% \temp \donoderef \nobreak } \outer\def\appendixsubsec{\parsearg\appendixsubsecyyy} \def\appendixsubsecyyy #1{\apphead2{#1}} % normally calls appendixsubseczzz \def\appendixsubseczzz #1{% \gdef\thissection{#1}\subsubsecno=0 \global\advance \subsecno by 1 % \subsecheading {#1}{\appendixletter}{\the\secno}{\the\subsecno}% \toks0 = {#1}% \edef\temp{\noexpand\writetocentry{\realbackslash subsecentry{\the\toks0}% {\appendixletter}{\the\secno}{\the\subsecno}}}% \temp \appendixnoderef \nobreak } \outer\def\unnumberedsubsec{\parsearg\unnumberedsubsecyyy} \def\unnumberedsubsecyyy #1{\unnmhead2{#1}} %normally calls unnumberedsubseczzz \def\unnumberedsubseczzz #1{% \plainsubsecheading {#1}\gdef\thissection{#1}% \toks0 = {#1}% \edef\temp{\noexpand\writetocentry{\realbackslash unnumbsubsecentry% {\the\toks0}}}% \temp \unnumbnoderef \nobreak } % Subsubsections. \outer\def\numberedsubsubsec{\parsearg\numberedsubsubsecyyy} \def\numberedsubsubsecyyy #1{\numhead3{#1}} % normally numberedsubsubseczzz \def\numberedsubsubseczzz #1{% \gdef\thissection{#1}\global\advance \subsubsecno by 1 % \subsubsecheading {#1} {\the\chapno}{\the\secno}{\the\subsecno}{\the\subsubsecno}% \toks0 = {#1}% \edef\temp{\noexpand\writetocentry{\realbackslash subsubsecentry{\the\toks0}% {\the\chapno}{\the\secno}{\the\subsecno}{\the\subsubsecno}}}% \temp \donoderef \nobreak } \outer\def\appendixsubsubsec{\parsearg\appendixsubsubsecyyy} \def\appendixsubsubsecyyy #1{\apphead3{#1}} % normally appendixsubsubseczzz \def\appendixsubsubseczzz #1{% \gdef\thissection{#1}\global\advance \subsubsecno by 1 % \subsubsecheading {#1} {\appendixletter}{\the\secno}{\the\subsecno}{\the\subsubsecno}% \toks0 = {#1}% \edef\temp{\noexpand\writetocentry{\realbackslash subsubsecentry{\the\toks0}% {\appendixletter}{\the\secno}{\the\subsecno}{\the\subsubsecno}}}% \temp \appendixnoderef \nobreak } \outer\def\unnumberedsubsubsec{\parsearg\unnumberedsubsubsecyyy} \def\unnumberedsubsubsecyyy #1{\unnmhead3{#1}} %normally unnumberedsubsubseczzz \def\unnumberedsubsubseczzz #1{% \plainsubsubsecheading {#1}\gdef\thissection{#1}% \toks0 = {#1}% \edef\temp{\noexpand\writetocentry{\realbackslash unnumbsubsubsecentry% {\the\toks0}}}% \temp \unnumbnoderef \nobreak } % These are variants which are not "outer", so they can appear in @ifinfo. % Actually, they should now be obsolete; ordinary section commands should work. \def\infotop{\parsearg\unnumberedzzz} \def\infounnumbered{\parsearg\unnumberedzzz} \def\infounnumberedsec{\parsearg\unnumberedseczzz} \def\infounnumberedsubsec{\parsearg\unnumberedsubseczzz} \def\infounnumberedsubsubsec{\parsearg\unnumberedsubsubseczzz} \def\infoappendix{\parsearg\appendixzzz} \def\infoappendixsec{\parsearg\appendixseczzz} \def\infoappendixsubsec{\parsearg\appendixsubseczzz} \def\infoappendixsubsubsec{\parsearg\appendixsubsubseczzz} \def\infochapter{\parsearg\chapterzzz} \def\infosection{\parsearg\sectionzzz} \def\infosubsection{\parsearg\subsectionzzz} \def\infosubsubsection{\parsearg\subsubsectionzzz} % These macros control what the section commands do, according % to what kind of chapter we are in (ordinary, appendix, or unnumbered). % Define them by default for a numbered chapter. \global\let\section = \numberedsec \global\let\subsection = \numberedsubsec \global\let\subsubsection = \numberedsubsubsec % Define @majorheading, @heading and @subheading % NOTE on use of \vbox for chapter headings, section headings, and such: % 1) We use \vbox rather than the earlier \line to permit % overlong headings to fold. % 2) \hyphenpenalty is set to 10000 because hyphenation in a % heading is obnoxious; this forbids it. % 3) Likewise, headings look best if no \parindent is used, and % if justification is not attempted. Hence \raggedright. \def\majorheading{\parsearg\majorheadingzzz} \def\majorheadingzzz #1{% {\advance\chapheadingskip by 10pt \chapbreak }% {\chapfonts \vbox{\hyphenpenalty=10000\tolerance=5000 \parindent=0pt\raggedright \rm #1\hfill}}\bigskip \par\penalty 200} \def\chapheading{\parsearg\chapheadingzzz} \def\chapheadingzzz #1{\chapbreak % {\chapfonts \vbox{\hyphenpenalty=10000\tolerance=5000 \parindent=0pt\raggedright \rm #1\hfill}}\bigskip \par\penalty 200} % @heading, @subheading, @subsubheading. \def\heading{\parsearg\plainsecheading} \def\subheading{\parsearg\plainsubsecheading} \def\subsubheading{\parsearg\plainsubsubsecheading} % These macros generate a chapter, section, etc. heading only % (including whitespace, linebreaking, etc. around it), % given all the information in convenient, parsed form. %%% Args are the skip and penalty (usually negative) \def\dobreak#1#2{\par\ifdim\lastskip<#1\removelastskip\penalty#2\vskip#1\fi} \def\setchapterstyle #1 {\csname CHAPF#1\endcsname} %%% Define plain chapter starts, and page on/off switching for it % Parameter controlling skip before chapter headings (if needed) \newskip\chapheadingskip \def\chapbreak{\dobreak \chapheadingskip {-4000}} \def\chappager{\par\vfill\supereject} \def\chapoddpage{\chappager \ifodd\pageno \else \hbox to 0pt{} \chappager\fi} \def\setchapternewpage #1 {\csname CHAPPAG#1\endcsname} \def\CHAPPAGoff{% \global\let\contentsalignmacro = \chappager \global\let\pchapsepmacro=\chapbreak \global\let\pagealignmacro=\chappager} \def\CHAPPAGon{% \global\let\contentsalignmacro = \chappager \global\let\pchapsepmacro=\chappager \global\let\pagealignmacro=\chappager \global\def\HEADINGSon{\HEADINGSsingle}} \def\CHAPPAGodd{ \global\let\contentsalignmacro = \chapoddpage \global\let\pchapsepmacro=\chapoddpage \global\let\pagealignmacro=\chapoddpage \global\def\HEADINGSon{\HEADINGSdouble}} \CHAPPAGon \def\CHAPFplain{ \global\let\chapmacro=\chfplain \global\let\unnumbchapmacro=\unnchfplain \global\let\centerchapmacro=\centerchfplain} % Plain chapter opening. % #1 is the text, #2 the chapter number or empty if unnumbered. \def\chfplain#1#2{% \pchapsepmacro {% \chapfonts \rm \def\chapnum{#2}% \setbox0 = \hbox{#2\ifx\chapnum\empty\else\enspace\fi}% \vbox{\hyphenpenalty=10000 \tolerance=5000 \parindent=0pt \raggedright \hangindent = \wd0 \centerparametersmaybe \unhbox0 #1\par}% }% \nobreak\bigskip % no page break after a chapter title \nobreak } % Plain opening for unnumbered. \def\unnchfplain#1{\chfplain{#1}{}} % @centerchap -- centered and unnumbered. \let\centerparametersmaybe = \relax \def\centerchfplain#1{{% \def\centerparametersmaybe{% \advance\rightskip by 3\rightskip \leftskip = \rightskip \parfillskip = 0pt }% \chfplain{#1}{}% }} \CHAPFplain % The default \def\unnchfopen #1{% \chapoddpage {\chapfonts \vbox{\hyphenpenalty=10000\tolerance=5000 \parindent=0pt\raggedright \rm #1\hfill}}\bigskip \par\nobreak } \def\chfopen #1#2{\chapoddpage {\chapfonts \vbox to 3in{\vfil \hbox to\hsize{\hfil #2} \hbox to\hsize{\hfil #1} \vfil}}% \par\penalty 5000 % } \def\centerchfopen #1{% \chapoddpage {\chapfonts \vbox{\hyphenpenalty=10000\tolerance=5000 \parindent=0pt \hfill {\rm #1}\hfill}}\bigskip \par\nobreak } \def\CHAPFopen{ \global\let\chapmacro=\chfopen \global\let\unnumbchapmacro=\unnchfopen \global\let\centerchapmacro=\centerchfopen} % Section titles. \newskip\secheadingskip \def\secheadingbreak{\dobreak \secheadingskip {-1000}} \def\secheading#1#2#3{\sectionheading{sec}{#2.#3}{#1}} \def\plainsecheading#1{\sectionheading{sec}{}{#1}} % Subsection titles. \newskip \subsecheadingskip \def\subsecheadingbreak{\dobreak \subsecheadingskip {-500}} \def\subsecheading#1#2#3#4{\sectionheading{subsec}{#2.#3.#4}{#1}} \def\plainsubsecheading#1{\sectionheading{subsec}{}{#1}} % Subsubsection titles. \let\subsubsecheadingskip = \subsecheadingskip \let\subsubsecheadingbreak = \subsecheadingbreak \def\subsubsecheading#1#2#3#4#5{\sectionheading{subsubsec}{#2.#3.#4.#5}{#1}} \def\plainsubsubsecheading#1{\sectionheading{subsubsec}{}{#1}} % Print any size section title. % % #1 is the section type (sec/subsec/subsubsec), #2 is the section % number (maybe empty), #3 the text. \def\sectionheading#1#2#3{% {% \expandafter\advance\csname #1headingskip\endcsname by \parskip \csname #1headingbreak\endcsname }% {% % Switch to the right set of fonts. \csname #1fonts\endcsname \rm % % Only insert the separating space if we have a section number. \def\secnum{#2}% \setbox0 = \hbox{#2\ifx\secnum\empty\else\enspace\fi}% % \vbox{\hyphenpenalty=10000 \tolerance=5000 \parindent=0pt \raggedright \hangindent = \wd0 % zero if no section number \unhbox0 #3}% }% \ifdim\parskip<10pt \nobreak\kern10pt\nobreak\kern-\parskip\fi \nobreak } \message{toc,} % Table of contents. \newwrite\tocfile % Write an entry to the toc file, opening it if necessary. % Called from @chapter, etc. We supply {\folio} at the end of the % argument, which will end up as the last argument to the \...entry macro. % % We open the .toc file here instead of at @setfilename or any other % given time so that @contents can be put in the document anywhere. % \newif\iftocfileopened \def\writetocentry#1{% \iftocfileopened\else \immediate\openout\tocfile = \jobname.toc \global\tocfileopenedtrue \fi \iflinks \write\tocfile{#1{\folio}}\fi } \newskip\contentsrightmargin \contentsrightmargin=1in \newcount\savepageno \newcount\lastnegativepageno \lastnegativepageno = -1 % Finish up the main text and prepare to read what we've written % to \tocfile. % \def\startcontents#1{% % If @setchapternewpage on, and @headings double, the contents should % start on an odd page, unlike chapters. Thus, we maintain % \contentsalignmacro in parallel with \pagealignmacro. % From: Torbjorn Granlund \contentsalignmacro \immediate\closeout\tocfile % % Don't need to put `Contents' or `Short Contents' in the headline. % It is abundantly clear what they are. \unnumbchapmacro{#1}\def\thischapter{}% \savepageno = \pageno \begingroup % Set up to handle contents files properly. \catcode`\\=0 \catcode`\{=1 \catcode`\}=2 \catcode`\@=11 % We can't do this, because then an actual ^ in a section % title fails, e.g., @chapter ^ -- exponentiation. --karl, 9jul97. %\catcode`\^=7 % to see ^^e4 as \"a etc. juha@piuha.ydi.vtt.fi \raggedbottom % Worry more about breakpoints than the bottom. \advance\hsize by -\contentsrightmargin % Don't use the full line length. % % Roman numerals for page numbers. \ifnum \pageno>0 \pageno = \lastnegativepageno \fi } % Normal (long) toc. \def\contents{% \startcontents{\putwordTOC}% \openin 1 \jobname.toc \ifeof 1 \else \closein 1 \input \jobname.toc \fi \vfill \eject \contentsalignmacro % in case @setchapternewpage odd is in effect \pdfmakeoutlines \endgroup \lastnegativepageno = \pageno \pageno = \savepageno } % And just the chapters. \def\summarycontents{% \startcontents{\putwordShortTOC}% % \let\chapentry = \shortchapentry \let\unnumbchapentry = \shortunnumberedentry % We want a true roman here for the page numbers. \secfonts \let\rm=\shortcontrm \let\bf=\shortcontbf \let\sl=\shortcontsl \rm \hyphenpenalty = 10000 \advance\baselineskip by 1pt % Open it up a little. \def\secentry ##1##2##3##4{} \def\unnumbsecentry ##1##2{} \def\subsecentry ##1##2##3##4##5{} \def\unnumbsubsecentry ##1##2{} \def\subsubsecentry ##1##2##3##4##5##6{} \def\unnumbsubsubsecentry ##1##2{} \openin 1 \jobname.toc \ifeof 1 \else \closein 1 \input \jobname.toc \fi \vfill \eject \contentsalignmacro % in case @setchapternewpage odd is in effect \endgroup \lastnegativepageno = \pageno \pageno = \savepageno } \let\shortcontents = \summarycontents \ifpdf \pdfcatalog{/PageMode /UseOutlines}% \fi % These macros generate individual entries in the table of contents. % The first argument is the chapter or section name. % The last argument is the page number. % The arguments in between are the chapter number, section number, ... % Chapter-level things, for both the long and short contents. \def\chapentry#1#2#3{\dochapentry{#2\labelspace#1}{#3}} % See comments in \dochapentry re vbox and related settings \def\shortchapentry#1#2#3{% \tocentry{\shortchaplabel{#2}\labelspace #1}{\doshortpageno\bgroup#3\egroup}% } % Typeset the label for a chapter or appendix for the short contents. % The arg is, e.g. `Appendix A' for an appendix, or `3' for a chapter. % We could simplify the code here by writing out an \appendixentry % command in the toc file for appendices, instead of using \chapentry % for both, but it doesn't seem worth it. % \newdimen\shortappendixwidth % \def\shortchaplabel#1{% % Compute width of word "Appendix", may change with language. \setbox0 = \hbox{\shortcontrm \putwordAppendix}% \shortappendixwidth = \wd0 % % We typeset #1 in a box of constant width, regardless of the text of % #1, so the chapter titles will come out aligned. \setbox0 = \hbox{#1}% \dimen0 = \ifdim\wd0 > \shortappendixwidth \shortappendixwidth \else 0pt \fi % % This space should be plenty, since a single number is .5em, and the % widest letter (M) is 1em, at least in the Computer Modern fonts. % (This space doesn't include the extra space that gets added after % the label; that gets put in by \shortchapentry above.) \advance\dimen0 by 1.1em \hbox to \dimen0{#1\hfil}% } \def\unnumbchapentry#1#2{\dochapentry{#1}{#2}} \def\shortunnumberedentry#1#2{\tocentry{#1}{\doshortpageno\bgroup#2\egroup}} % Sections. \def\secentry#1#2#3#4{\dosecentry{#2.#3\labelspace#1}{#4}} \def\unnumbsecentry#1#2{\dosecentry{#1}{#2}} % Subsections. \def\subsecentry#1#2#3#4#5{\dosubsecentry{#2.#3.#4\labelspace#1}{#5}} \def\unnumbsubsecentry#1#2{\dosubsecentry{#1}{#2}} % And subsubsections. \def\subsubsecentry#1#2#3#4#5#6{% \dosubsubsecentry{#2.#3.#4.#5\labelspace#1}{#6}} \def\unnumbsubsubsecentry#1#2{\dosubsubsecentry{#1}{#2}} % This parameter controls the indentation of the various levels. \newdimen\tocindent \tocindent = 3pc % Now for the actual typesetting. In all these, #1 is the text and #2 is the % page number. % % If the toc has to be broken over pages, we want it to be at chapters % if at all possible; hence the \penalty. \def\dochapentry#1#2{% \penalty-300 \vskip1\baselineskip plus.33\baselineskip minus.25\baselineskip \begingroup \chapentryfonts \tocentry{#1}{\dopageno\bgroup#2\egroup}% \endgroup \nobreak\vskip .25\baselineskip plus.1\baselineskip } \def\dosecentry#1#2{\begingroup \secentryfonts \leftskip=\tocindent \tocentry{#1}{\dopageno\bgroup#2\egroup}% \endgroup} \def\dosubsecentry#1#2{\begingroup \subsecentryfonts \leftskip=2\tocindent \tocentry{#1}{\dopageno\bgroup#2\egroup}% \endgroup} \def\dosubsubsecentry#1#2{\begingroup \subsubsecentryfonts \leftskip=3\tocindent \tocentry{#1}{\dopageno\bgroup#2\egroup}% \endgroup} % Final typesetting of a toc entry; we use the same \entry macro as for % the index entries, but we want to suppress hyphenation here. (We % can't do that in the \entry macro, since index entries might consist % of hyphenated-identifiers-that-do-not-fit-on-a-line-and-nothing-else.) \def\tocentry#1#2{\begingroup \vskip 0pt plus1pt % allow a little stretch for the sake of nice page breaks % Do not use \turnoffactive in these arguments. Since the toc is % typeset in cmr, so characters such as _ would come out wrong; we % have to do the usual translation tricks. \entry{#1}{#2}% \endgroup} % Space between chapter (or whatever) number and the title. \def\labelspace{\hskip1em \relax} \def\dopageno#1{{\rm #1}} \def\doshortpageno#1{{\rm #1}} \def\chapentryfonts{\secfonts \rm} \def\secentryfonts{\textfonts} \let\subsecentryfonts = \textfonts \let\subsubsecentryfonts = \textfonts \message{environments,} % @foo ... @end foo. % Since these characters are used in examples, it should be an even number of % \tt widths. Each \tt character is 1en, so two makes it 1em. % Furthermore, these definitions must come after we define our fonts. \newbox\dblarrowbox \newbox\longdblarrowbox \newbox\pushcharbox \newbox\bullbox \newbox\equivbox \newbox\errorbox %{\tentt %\global\setbox\dblarrowbox = \hbox to 1em{\hfil$\Rightarrow$\hfil} %\global\setbox\longdblarrowbox = \hbox to 1em{\hfil$\mapsto$\hfil} %\global\setbox\pushcharbox = \hbox to 1em{\hfil$\dashv$\hfil} %\global\setbox\equivbox = \hbox to 1em{\hfil$\ptexequiv$\hfil} % Adapted from the manmac format (p.420 of TeXbook) %\global\setbox\bullbox = \hbox to 1em{\kern.15em\vrule height .75ex width .85ex % depth .1ex\hfil} %} % @point{}, @result{}, @expansion{}, @print{}, @equiv{}. \def\point{$\star$} \def\result{\leavevmode\raise.15ex\hbox to 1em{\hfil$\Rightarrow$\hfil}} \def\expansion{\leavevmode\raise.1ex\hbox to 1em{\hfil$\mapsto$\hfil}} \def\print{\leavevmode\lower.1ex\hbox to 1em{\hfil$\dashv$\hfil}} \def\equiv{\leavevmode\lower.1ex\hbox to 1em{\hfil$\ptexequiv$\hfil}} % Adapted from the TeXbook's \boxit. {\tentt \global\dimen0 = 3em}% Width of the box. \dimen2 = .55pt % Thickness of rules % The text. (`r' is open on the right, `e' somewhat less so on the left.) \setbox0 = \hbox{\kern-.75pt \tensf error\kern-1.5pt} \global\setbox\errorbox=\hbox to \dimen0{\hfil \hsize = \dimen0 \advance\hsize by -5.8pt % Space to left+right. \advance\hsize by -2\dimen2 % Rules. \vbox{ \hrule height\dimen2 \hbox{\vrule width\dimen2 \kern3pt % Space to left of text. \vtop{\kern2.4pt \box0 \kern2.4pt}% Space above/below. \kern3pt\vrule width\dimen2}% Space to right. \hrule height\dimen2} \hfil} % The @error{} command. \def\error{\leavevmode\lower.7ex\copy\errorbox} % @tex ... @end tex escapes into raw Tex temporarily. % One exception: @ is still an escape character, so that @end tex works. % But \@ or @@ will get a plain tex @ character. \def\tex{\begingroup \catcode `\\=0 \catcode `\{=1 \catcode `\}=2 \catcode `\$=3 \catcode `\&=4 \catcode `\#=6 \catcode `\^=7 \catcode `\_=8 \catcode `\~=13 \let~=\tie \catcode `\%=14 \catcode 43=12 % plus \catcode`\"=12 \catcode`\==12 \catcode`\|=12 \catcode`\<=12 \catcode`\>=12 \escapechar=`\\ % \let\b=\ptexb \let\bullet=\ptexbullet \let\c=\ptexc \let\,=\ptexcomma \let\.=\ptexdot \let\dots=\ptexdots \let\equiv=\ptexequiv \let\!=\ptexexclam \let\i=\ptexi \let\{=\ptexlbrace \let\+=\tabalign \let\}=\ptexrbrace \let\*=\ptexstar \let\t=\ptext % \def\endldots{\mathinner{\ldots\ldots\ldots\ldots}}% \def\enddots{\relax\ifmmode\endldots\else$\mathsurround=0pt \endldots\,$\fi}% \def\@{@}% \let\Etex=\endgroup} % Define @lisp ... @endlisp. % @lisp does a \begingroup so it can rebind things, % including the definition of @endlisp (which normally is erroneous). % Amount to narrow the margins by for @lisp. \newskip\lispnarrowing \lispnarrowing=0.4in % This is the definition that ^^M gets inside @lisp, @example, and other % such environments. \null is better than a space, since it doesn't % have any width. \def\lisppar{\null\endgraf} % Make each space character in the input produce a normal interword % space in the output. Don't allow a line break at this space, as this % is used only in environments like @example, where each line of input % should produce a line of output anyway. % {\obeyspaces % \gdef\sepspaces{\obeyspaces\let =\tie}} % Define \obeyedspace to be our active space, whatever it is. This is % for use in \parsearg. {\sepspaces% \global\let\obeyedspace= } % This space is always present above and below environments. \newskip\envskipamount \envskipamount = 0pt % Make spacing and below environment symmetrical. We use \parskip here % to help in doing that, since in @example-like environments \parskip % is reset to zero; thus the \afterenvbreak inserts no space -- but the % start of the next paragraph will insert \parskip % \def\aboveenvbreak{{\advance\envskipamount by \parskip \endgraf \ifdim\lastskip<\envskipamount \removelastskip \penalty-50 \vskip\envskipamount \fi}} \let\afterenvbreak = \aboveenvbreak % \nonarrowing is a flag. If "set", @lisp etc don't narrow margins. \let\nonarrowing=\relax % @cartouche ... @end cartouche: draw rectangle w/rounded corners around % environment contents. \font\circle=lcircle10 \newdimen\circthick \newdimen\cartouter\newdimen\cartinner \newskip\normbskip\newskip\normpskip\newskip\normlskip \circthick=\fontdimen8\circle % \def\ctl{{\circle\char'013\hskip -6pt}}% 6pt from pl file: 1/2charwidth \def\ctr{{\hskip 6pt\circle\char'010}} \def\cbl{{\circle\char'012\hskip -6pt}} \def\cbr{{\hskip 6pt\circle\char'011}} \def\carttop{\hbox to \cartouter{\hskip\lskip \ctl\leaders\hrule height\circthick\hfil\ctr \hskip\rskip}} \def\cartbot{\hbox to \cartouter{\hskip\lskip \cbl\leaders\hrule height\circthick\hfil\cbr \hskip\rskip}} % \newskip\lskip\newskip\rskip \long\def\cartouche{% \begingroup \lskip=\leftskip \rskip=\rightskip \leftskip=0pt\rightskip=0pt %we want these *outside*. \cartinner=\hsize \advance\cartinner by-\lskip \advance\cartinner by-\rskip \cartouter=\hsize \advance\cartouter by 18.4pt % allow for 3pt kerns on either % side, and for 6pt waste from % each corner char, and rule thickness \normbskip=\baselineskip \normpskip=\parskip \normlskip=\lineskip % Flag to tell @lisp, etc., not to narrow margin. \let\nonarrowing=\comment \vbox\bgroup \baselineskip=0pt\parskip=0pt\lineskip=0pt \carttop \hbox\bgroup \hskip\lskip \vrule\kern3pt \vbox\bgroup \hsize=\cartinner \kern3pt \begingroup \baselineskip=\normbskip \lineskip=\normlskip \parskip=\normpskip \vskip -\parskip \def\Ecartouche{% \endgroup \kern3pt \egroup \kern3pt\vrule \hskip\rskip \egroup \cartbot \egroup \endgroup }} % This macro is called at the beginning of all the @example variants, % inside a group. \def\nonfillstart{% \aboveenvbreak \inENV % This group ends at the end of the body \hfuzz = 12pt % Don't be fussy \sepspaces % Make spaces be word-separators rather than space tokens. \singlespace \let\par = \lisppar % don't ignore blank lines \obeylines % each line of input is a line of output \parskip = 0pt \parindent = 0pt \emergencystretch = 0pt % don't try to avoid overfull boxes % @cartouche defines \nonarrowing to inhibit narrowing % at next level down. \ifx\nonarrowing\relax \advance \leftskip by \lispnarrowing \exdentamount=\lispnarrowing \let\exdent=\nofillexdent \let\nonarrowing=\relax \fi } % Define the \E... control sequence only if we are inside the particular % environment, so the error checking in \end will work. % % To end an @example-like environment, we first end the paragraph (via % \afterenvbreak's vertical glue), and then the group. That way we keep % the zero \parskip that the environments set -- \parskip glue will be % inserted at the beginning of the next paragraph in the document, after % the environment. % \def\nonfillfinish{\afterenvbreak\endgroup} % @lisp: indented, narrowed, typewriter font. \def\lisp{\begingroup \nonfillstart \let\Elisp = \nonfillfinish \tt \let\kbdfont = \kbdexamplefont % Allow @kbd to do something special. \gobble % eat return } % @example: Same as @lisp. \def\example{\begingroup \def\Eexample{\nonfillfinish\endgroup}\lisp} % @small... is usually equivalent to the non-small (@smallbook % redefines). We must call \example (or whatever) last in the % definition, since it reads the return following the @example (or % whatever) command. % % This actually allows (for example) @end display inside an % @smalldisplay. Too bad, but makeinfo will catch the error anyway. % \def\smalldisplay{\begingroup\def\Esmalldisplay{\nonfillfinish\endgroup}\display} \def\smallexample{\begingroup\def\Esmallexample{\nonfillfinish\endgroup}\lisp} \def\smallformat{\begingroup\def\Esmallformat{\nonfillfinish\endgroup}\format} \def\smalllisp{\begingroup\def\Esmalllisp{\nonfillfinish\endgroup}\lisp} % Real @smallexample and @smalllisp (when @smallbook): use smaller fonts. % Originally contributed by Pavel@xerox. \def\smalllispx{\begingroup \def\Esmalllisp{\nonfillfinish\endgroup}% \def\Esmallexample{\nonfillfinish\endgroup}% \smallfonts \lisp } % @display: same as @lisp except keep current font. % \def\display{\begingroup \nonfillstart \let\Edisplay = \nonfillfinish \gobble } % @smalldisplay (when @smallbook): @display plus smaller fonts. % \def\smalldisplayx{\begingroup \def\Esmalldisplay{\nonfillfinish\endgroup}% \smallfonts \rm \display } % @format: same as @display except don't narrow margins. % \def\format{\begingroup \let\nonarrowing = t \nonfillstart \let\Eformat = \nonfillfinish \gobble } % @smallformat (when @smallbook): @format plus smaller fonts. % \def\smallformatx{\begingroup \def\Esmallformat{\nonfillfinish\endgroup}% \smallfonts \rm \format } % @flushleft (same as @format). % \def\flushleft{\begingroup \def\Eflushleft{\nonfillfinish\endgroup}\format} % @flushright. % \def\flushright{\begingroup \let\nonarrowing = t \nonfillstart \let\Eflushright = \nonfillfinish \advance\leftskip by 0pt plus 1fill \gobble } % @quotation does normal linebreaking (hence we can't use \nonfillstart) % and narrows the margins. % \def\quotation{% \begingroup\inENV %This group ends at the end of the @quotation body {\parskip=0pt \aboveenvbreak}% because \aboveenvbreak inserts \parskip \singlespace \parindent=0pt % We have retained a nonzero parskip for the environment, since we're % doing normal filling. So to avoid extra space below the environment... \def\Equotation{\parskip = 0pt \nonfillfinish}% % % @cartouche defines \nonarrowing to inhibit narrowing at next level down. \ifx\nonarrowing\relax \advance\leftskip by \lispnarrowing \advance\rightskip by \lispnarrowing \exdentamount = \lispnarrowing \let\nonarrowing = \relax \fi } \message{defuns,} % @defun etc. % Allow user to change definition object font (\df) internally \def\setdeffont #1 {\csname DEF#1\endcsname} \newskip\defbodyindent \defbodyindent=.4in \newskip\defargsindent \defargsindent=50pt \newskip\deftypemargin \deftypemargin=12pt \newskip\deflastargmargin \deflastargmargin=18pt \newcount\parencount % define \functionparens, which makes ( and ) and & do special things. % \functionparens affects the group it is contained in. \def\activeparens{% \catcode`\(=\active \catcode`\)=\active \catcode`\&=\active \catcode`\[=\active \catcode`\]=\active} % Make control sequences which act like normal parenthesis chars. \let\lparen = ( \let\rparen = ) {\activeparens % Now, smart parens don't turn on until &foo (see \amprm) % Be sure that we always have a definition for `(', etc. For example, % if the fn name has parens in it, \boldbrax will not be in effect yet, % so TeX would otherwise complain about undefined control sequence. \global\let(=\lparen \global\let)=\rparen \global\let[=\lbrack \global\let]=\rbrack \gdef\functionparens{\boldbrax\let&=\amprm\parencount=0 } \gdef\boldbrax{\let(=\opnr\let)=\clnr\let[=\lbrb\let]=\rbrb} % This is used to turn on special parens % but make & act ordinary (given that it's active). \gdef\boldbraxnoamp{\let(=\opnr\let)=\clnr\let[=\lbrb\let]=\rbrb\let&=\ampnr} % Definitions of (, ) and & used in args for functions. % This is the definition of ( outside of all parentheses. \gdef\oprm#1 {{\rm\char`\(}#1 \bf \let(=\opnested \global\advance\parencount by 1 } % % This is the definition of ( when already inside a level of parens. \gdef\opnested{\char`\(\global\advance\parencount by 1 } % \gdef\clrm{% Print a paren in roman if it is taking us back to depth of 0. % also in that case restore the outer-level definition of (. \ifnum \parencount=1 {\rm \char `\)}\sl \let(=\oprm \else \char `\) \fi \global\advance \parencount by -1 } % If we encounter &foo, then turn on ()-hacking afterwards \gdef\amprm#1 {{\rm\}\let(=\oprm \let)=\clrm\ } % \gdef\normalparens{\boldbrax\let&=\ampnr} } % End of definition inside \activeparens %% These parens (in \boldbrax) actually are a little bolder than the %% contained text. This is especially needed for [ and ] \def\opnr{{\sf\char`\(}\global\advance\parencount by 1 } \def\clnr{{\sf\char`\)}\global\advance\parencount by -1 } \let\ampnr = \& \def\lbrb{{\bf\char`\[}} \def\rbrb{{\bf\char`\]}} % Active &'s sneak into the index arguments, so make sure it's defined. { \catcode`& = 13 \global\let& = \ampnr } % First, defname, which formats the header line itself. % #1 should be the function name. % #2 should be the type of definition, such as "Function". \def\defname #1#2{% % Get the values of \leftskip and \rightskip as they were % outside the @def... \dimen2=\leftskip \advance\dimen2 by -\defbodyindent \noindent \setbox0=\hbox{\hskip \deflastargmargin{\rm #2}\hskip \deftypemargin}% \dimen0=\hsize \advance \dimen0 by -\wd0 % compute size for first line \dimen1=\hsize \advance \dimen1 by -\defargsindent %size for continuations \parshape 2 0in \dimen0 \defargsindent \dimen1 % Now output arg 2 ("Function" or some such) % ending at \deftypemargin from the right margin, % but stuck inside a box of width 0 so it does not interfere with linebreaking {% Adjust \hsize to exclude the ambient margins, % so that \rightline will obey them. \advance \hsize by -\dimen2 \rlap{\rightline{{\rm #2}\hskip -1.25pc }}}% % Make all lines underfull and no complaints: \tolerance=10000 \hbadness=10000 \advance\leftskip by -\defbodyindent \exdentamount=\defbodyindent {\df #1}\enskip % Generate function name } % Actually process the body of a definition % #1 should be the terminating control sequence, such as \Edefun. % #2 should be the "another name" control sequence, such as \defunx. % #3 should be the control sequence that actually processes the header, % such as \defunheader. \def\defparsebody #1#2#3{\begingroup\inENV% Environment for definitionbody \medbreak % % Define the end token that this defining construct specifies % so that it will exit this group. \def#1{\endgraf\endgroup\medbreak}% \def#2{\begingroup\obeylines\activeparens\spacesplit#3}% \parindent=0in \advance\leftskip by \defbodyindent \exdentamount=\defbodyindent \begingroup % \catcode 61=\active % 61 is `=' \obeylines\activeparens\spacesplit#3} % #1 is the \E... control sequence to end the definition (which we define). % #2 is the \...x control sequence for consecutive fns (which we define). % #3 is the control sequence to call to resume processing. % #4, delimited by the space, is the class name. % \def\defmethparsebody#1#2#3#4 {\begingroup\inENV % \medbreak % % Define the end token that this defining construct specifies % so that it will exit this group. \def#1{\endgraf\endgroup\medbreak}% \def#2##1 {\begingroup\obeylines\activeparens\spacesplit{#3{##1}}}% \parindent=0in \advance\leftskip by \defbodyindent \exdentamount=\defbodyindent \begingroup\obeylines\activeparens\spacesplit{#3{#4}}} % Used for @deftypemethod and @deftypeivar. % #1 is the \E... control sequence to end the definition (which we define). % #2 is the \...x control sequence for consecutive fns (which we define). % #3 is the control sequence to call to resume processing. % #4, delimited by a space, is the class name. % #5 is the method's return type. % \def\deftypemethparsebody#1#2#3#4 #5 {\begingroup\inENV \medbreak \def#1{\endgraf\endgroup\medbreak}% \def#2##1 ##2 {\begingroup\obeylines\activeparens\spacesplit{#3{##1}{##2}}}% \parindent=0in \advance\leftskip by \defbodyindent \exdentamount=\defbodyindent \begingroup\obeylines\activeparens\spacesplit{#3{#4}{#5}}} % Used for @deftypeop. The change from \deftypemethparsebody is an % extra argument at the beginning which is the `category', instead of it % being the hardwired string `Method' or `Instance Variable'. We have % to account for this both in the \...x definition and in parsing the % input at hand. Thus also need a control sequence (passed as #5) for % the \E... definition to assign the category name to. % \def\deftypeopparsebody#1#2#3#4#5 #6 {\begingroup\inENV \medbreak \def#1{\endgraf\endgroup\medbreak}% \def#2##1 ##2 ##3 {% \def#4{##1}% \begingroup\obeylines\activeparens\spacesplit{#3{##2}{##3}}}% \parindent=0in \advance\leftskip by \defbodyindent \exdentamount=\defbodyindent \begingroup\obeylines\activeparens\spacesplit{#3{#5}{#6}}} \def\defopparsebody #1#2#3#4#5 {\begingroup\inENV % \medbreak % % Define the end token that this defining construct specifies % so that it will exit this group. \def#1{\endgraf\endgroup\medbreak}% \def#2##1 ##2 {\def#4{##1}% \begingroup\obeylines\activeparens\spacesplit{#3{##2}}}% \parindent=0in \advance\leftskip by \defbodyindent \exdentamount=\defbodyindent \begingroup\obeylines\activeparens\spacesplit{#3{#5}}} % These parsing functions are similar to the preceding ones % except that they do not make parens into active characters. % These are used for "variables" since they have no arguments. \def\defvarparsebody #1#2#3{\begingroup\inENV% Environment for definitionbody \medbreak % % Define the end token that this defining construct specifies % so that it will exit this group. \def#1{\endgraf\endgroup\medbreak}% \def#2{\begingroup\obeylines\spacesplit#3}% \parindent=0in \advance\leftskip by \defbodyindent \exdentamount=\defbodyindent \begingroup % \catcode 61=\active % \obeylines\spacesplit#3} % This is used for \def{tp,vr}parsebody. It could probably be used for % some of the others, too, with some judicious conditionals. % \def\parsebodycommon#1#2#3{% \begingroup\inENV % \medbreak % % Define the end token that this defining construct specifies % so that it will exit this group. \def#1{\endgraf\endgroup\medbreak}% \def#2##1 {\begingroup\obeylines\spacesplit{#3{##1}}}% \parindent=0in \advance\leftskip by \defbodyindent \exdentamount=\defbodyindent \begingroup\obeylines } \def\defvrparsebody#1#2#3#4 {% \parsebodycommon{#1}{#2}{#3}% \spacesplit{#3{#4}}% } % This loses on `@deftp {Data Type} {struct termios}' -- it thinks the % type is just `struct', because we lose the braces in `{struct % termios}' when \spacesplit reads its undelimited argument. Sigh. % \let\deftpparsebody=\defvrparsebody % % So, to get around this, we put \empty in with the type name. That % way, TeX won't find exactly `{...}' as an undelimited argument, and % won't strip off the braces. % \def\deftpparsebody #1#2#3#4 {% \parsebodycommon{#1}{#2}{#3}% \spacesplit{\parsetpheaderline{#3{#4}}}\empty } % Fine, but then we have to eventually remove the \empty *and* the % braces (if any). That's what this does. % \def\removeemptybraces\empty#1\relax{#1} % After \spacesplit has done its work, this is called -- #1 is the final % thing to call, #2 the type name (which starts with \empty), and #3 % (which might be empty) the arguments. % \def\parsetpheaderline#1#2#3{% #1{\removeemptybraces#2\relax}{#3}% }% \def\defopvarparsebody #1#2#3#4#5 {\begingroup\inENV % \medbreak % % Define the end token that this defining construct specifies % so that it will exit this group. \def#1{\endgraf\endgroup\medbreak}% \def#2##1 ##2 {\def#4{##1}% \begingroup\obeylines\spacesplit{#3{##2}}}% \parindent=0in \advance\leftskip by \defbodyindent \exdentamount=\defbodyindent \begingroup\obeylines\spacesplit{#3{#5}}} % Split up #2 at the first space token. % call #1 with two arguments: % the first is all of #2 before the space token, % the second is all of #2 after that space token. % If #2 contains no space token, all of it is passed as the first arg % and the second is passed as empty. {\obeylines \gdef\spacesplit#1#2^^M{\endgroup\spacesplitfoo{#1}#2 \relax\spacesplitfoo}% \long\gdef\spacesplitfoo#1#2 #3#4\spacesplitfoo{% \ifx\relax #3% #1{#2}{}\else #1{#2}{#3#4}\fi}} % So much for the things common to all kinds of definitions. % Define @defun. % First, define the processing that is wanted for arguments of \defun % Use this to expand the args and terminate the paragraph they make up \def\defunargs#1{\functionparens \sl % Expand, preventing hyphenation at `-' chars. % Note that groups don't affect changes in \hyphenchar. % Set the font temporarily and use \font in case \setfont made \tensl a macro. {\tensl\hyphenchar\font=0}% #1% {\tensl\hyphenchar\font=45}% \ifnum\parencount=0 \else \errmessage{Unbalanced parentheses in @def}\fi% \interlinepenalty=10000 \advance\rightskip by 0pt plus 1fil \endgraf\nobreak\vskip -\parskip\nobreak } \def\deftypefunargs #1{% % Expand, preventing hyphenation at `-' chars. % Note that groups don't affect changes in \hyphenchar. % Use \boldbraxnoamp, not \functionparens, so that & is not special. \boldbraxnoamp \tclose{#1}% avoid \code because of side effects on active chars \interlinepenalty=10000 \advance\rightskip by 0pt plus 1fil \endgraf\nobreak\vskip -\parskip\nobreak } % Do complete processing of one @defun or @defunx line already parsed. % @deffn Command forward-char nchars \def\deffn{\defmethparsebody\Edeffn\deffnx\deffnheader} \def\deffnheader #1#2#3{\doind {fn}{\code{#2}}% \begingroup\defname {#2}{#1}\defunargs{#3}\endgroup % \catcode 61=\other % Turn off change made in \defparsebody } % @defun == @deffn Function \def\defun{\defparsebody\Edefun\defunx\defunheader} \def\defunheader #1#2{\doind {fn}{\code{#1}}% Make entry in function index \begingroup\defname {#1}{\putwordDeffunc}% \defunargs {#2}\endgroup % \catcode 61=\other % Turn off change made in \defparsebody } % @deftypefun int foobar (int @var{foo}, float @var{bar}) \def\deftypefun{\defparsebody\Edeftypefun\deftypefunx\deftypefunheader} % #1 is the data type. #2 is the name and args. \def\deftypefunheader #1#2{\deftypefunheaderx{#1}#2 \relax} % #1 is the data type, #2 the name, #3 the args. \def\deftypefunheaderx #1#2 #3\relax{% \doind {fn}{\code{#2}}% Make entry in function index \begingroup\defname {\defheaderxcond#1\relax$$$#2}{\putwordDeftypefun}% \deftypefunargs {#3}\endgroup % \catcode 61=\other % Turn off change made in \defparsebody } % @deftypefn {Library Function} int foobar (int @var{foo}, float @var{bar}) \def\deftypefn{\defmethparsebody\Edeftypefn\deftypefnx\deftypefnheader} % \defheaderxcond#1\relax$$$ % puts #1 in @code, followed by a space, but does nothing if #1 is null. \def\defheaderxcond#1#2$$${\ifx#1\relax\else\code{#1#2} \fi} % #1 is the classification. #2 is the data type. #3 is the name and args. \def\deftypefnheader #1#2#3{\deftypefnheaderx{#1}{#2}#3 \relax} % #1 is the classification, #2 the data type, #3 the name, #4 the args. \def\deftypefnheaderx #1#2#3 #4\relax{% \doind {fn}{\code{#3}}% Make entry in function index \begingroup \normalparens % notably, turn off `&' magic, which prevents % at least some C++ text from working \defname {\defheaderxcond#2\relax$$$#3}{#1}% \deftypefunargs {#4}\endgroup % \catcode 61=\other % Turn off change made in \defparsebody } % @defmac == @deffn Macro \def\defmac{\defparsebody\Edefmac\defmacx\defmacheader} \def\defmacheader #1#2{\doind {fn}{\code{#1}}% Make entry in function index \begingroup\defname {#1}{\putwordDefmac}% \defunargs {#2}\endgroup % \catcode 61=\other % Turn off change made in \defparsebody } % @defspec == @deffn Special Form \def\defspec{\defparsebody\Edefspec\defspecx\defspecheader} \def\defspecheader #1#2{\doind {fn}{\code{#1}}% Make entry in function index \begingroup\defname {#1}{\putwordDefspec}% \defunargs {#2}\endgroup % \catcode 61=\other % Turn off change made in \defparsebody } % @defop CATEGORY CLASS OPERATION ARG... % \def\defop #1 {\def\defoptype{#1}% \defopparsebody\Edefop\defopx\defopheader\defoptype} % \def\defopheader#1#2#3{% \dosubind {fn}{\code{#2}}{\putwordon\ #1}% Make entry in function index \begingroup\defname {#2}{\defoptype\ \putwordon\ #1}% \defunargs {#3}\endgroup % } % @deftypeop CATEGORY CLASS TYPE OPERATION ARG... % \def\deftypeop #1 {\def\deftypeopcategory{#1}% \deftypeopparsebody\Edeftypeop\deftypeopx\deftypeopheader \deftypeopcategory} % % #1 is the class name, #2 the data type, #3 the operation name, #4 the args. \def\deftypeopheader#1#2#3#4{% \dosubind{fn}{\code{#3}}{\putwordon\ \code{#1}}% entry in function index \begingroup \defname{\defheaderxcond#2\relax$$$#3} {\deftypeopcategory\ \putwordon\ \code{#1}}% \deftypefunargs{#4}% \endgroup } % @deftypemethod CLASS TYPE METHOD ARG... % \def\deftypemethod{% \deftypemethparsebody\Edeftypemethod\deftypemethodx\deftypemethodheader} % % #1 is the class name, #2 the data type, #3 the method name, #4 the args. \def\deftypemethodheader#1#2#3#4{% \dosubind{fn}{\code{#3}}{\putwordon\ \code{#1}}% entry in function index \begingroup \defname{\defheaderxcond#2\relax$$$#3}{\putwordMethodon\ \code{#1}}% \deftypefunargs{#4}% \endgroup } % @deftypeivar CLASS TYPE VARNAME % \def\deftypeivar{% \deftypemethparsebody\Edeftypeivar\deftypeivarx\deftypeivarheader} % % #1 is the class name, #2 the data type, #3 the variable name. \def\deftypeivarheader#1#2#3{% \dosubind{vr}{\code{#3}}{\putwordof\ \code{#1}}% entry in variable index \begingroup \defname{#3}{\putwordInstanceVariableof\ \code{#1}}% \defvarargs{#3}% \endgroup } % @defmethod == @defop Method % \def\defmethod{\defmethparsebody\Edefmethod\defmethodx\defmethodheader} % % #1 is the class name, #2 the method name, #3 the args. \def\defmethodheader#1#2#3{% \dosubind{fn}{\code{#2}}{\putwordon\ \code{#1}}% entry in function index \begingroup \defname{#2}{\putwordMethodon\ \code{#1}}% \defunargs{#3}% \endgroup } % @defcv {Class Option} foo-class foo-flag \def\defcv #1 {\def\defcvtype{#1}% \defopvarparsebody\Edefcv\defcvx\defcvarheader\defcvtype} \def\defcvarheader #1#2#3{% \dosubind {vr}{\code{#2}}{\putwordof\ #1}% Make entry in var index \begingroup\defname {#2}{\defcvtype\ \putwordof\ #1}% \defvarargs {#3}\endgroup % } % @defivar CLASS VARNAME == @defcv {Instance Variable} CLASS VARNAME % \def\defivar{\defvrparsebody\Edefivar\defivarx\defivarheader} % \def\defivarheader#1#2#3{% \dosubind {vr}{\code{#2}}{\putwordof\ #1}% entry in var index \begingroup \defname{#2}{\putwordInstanceVariableof\ #1}% \defvarargs{#3}% \endgroup } % @defvar % First, define the processing that is wanted for arguments of @defvar. % This is actually simple: just print them in roman. % This must expand the args and terminate the paragraph they make up \def\defvarargs #1{\normalparens #1% \interlinepenalty=10000 \endgraf\nobreak\vskip -\parskip\nobreak} % @defvr Counter foo-count \def\defvr{\defvrparsebody\Edefvr\defvrx\defvrheader} \def\defvrheader #1#2#3{\doind {vr}{\code{#2}}% \begingroup\defname {#2}{#1}\defvarargs{#3}\endgroup} % @defvar == @defvr Variable \def\defvar{\defvarparsebody\Edefvar\defvarx\defvarheader} \def\defvarheader #1#2{\doind {vr}{\code{#1}}% Make entry in var index \begingroup\defname {#1}{\putwordDefvar}% \defvarargs {#2}\endgroup % } % @defopt == @defvr {User Option} \def\defopt{\defvarparsebody\Edefopt\defoptx\defoptheader} \def\defoptheader #1#2{\doind {vr}{\code{#1}}% Make entry in var index \begingroup\defname {#1}{\putwordDefopt}% \defvarargs {#2}\endgroup % } % @deftypevar int foobar \def\deftypevar{\defvarparsebody\Edeftypevar\deftypevarx\deftypevarheader} % #1 is the data type. #2 is the name, perhaps followed by text that % is actually part of the data type, which should not be put into the index. \def\deftypevarheader #1#2{% \dovarind#2 \relax% Make entry in variables index \begingroup\defname {\defheaderxcond#1\relax$$$#2}{\putwordDeftypevar}% \interlinepenalty=10000 \endgraf\nobreak\vskip -\parskip\nobreak \endgroup} \def\dovarind#1 #2\relax{\doind{vr}{\code{#1}}} % @deftypevr {Global Flag} int enable \def\deftypevr{\defvrparsebody\Edeftypevr\deftypevrx\deftypevrheader} \def\deftypevrheader #1#2#3{\dovarind#3 \relax% \begingroup\defname {\defheaderxcond#2\relax$$$#3}{#1} \interlinepenalty=10000 \endgraf\nobreak\vskip -\parskip\nobreak \endgroup} % Now define @deftp % Args are printed in bold, a slight difference from @defvar. \def\deftpargs #1{\bf \defvarargs{#1}} % @deftp Class window height width ... \def\deftp{\deftpparsebody\Edeftp\deftpx\deftpheader} \def\deftpheader #1#2#3{\doind {tp}{\code{#2}}% \begingroup\defname {#2}{#1}\deftpargs{#3}\endgroup} % These definitions are used if you use @defunx (etc.) % anywhere other than immediately after a @defun or @defunx. % \def\defcvx#1 {\errmessage{@defcvx in invalid context}} \def\deffnx#1 {\errmessage{@deffnx in invalid context}} \def\defivarx#1 {\errmessage{@defivarx in invalid context}} \def\defmacx#1 {\errmessage{@defmacx in invalid context}} \def\defmethodx#1 {\errmessage{@defmethodx in invalid context}} \def\defoptx #1 {\errmessage{@defoptx in invalid context}} \def\defopx#1 {\errmessage{@defopx in invalid context}} \def\defspecx#1 {\errmessage{@defspecx in invalid context}} \def\deftpx#1 {\errmessage{@deftpx in invalid context}} \def\deftypefnx#1 {\errmessage{@deftypefnx in invalid context}} \def\deftypefunx#1 {\errmessage{@deftypefunx in invalid context}} \def\deftypeivarx#1 {\errmessage{@deftypeivarx in invalid context}} \def\deftypemethodx#1 {\errmessage{@deftypemethodx in invalid context}} \def\deftypeopx#1 {\errmessage{@deftypeopx in invalid context}} \def\deftypevarx#1 {\errmessage{@deftypevarx in invalid context}} \def\deftypevrx#1 {\errmessage{@deftypevrx in invalid context}} \def\defunx#1 {\errmessage{@defunx in invalid context}} \def\defvarx#1 {\errmessage{@defvarx in invalid context}} \def\defvrx#1 {\errmessage{@defvrx in invalid context}} \message{macros,} % @macro. % To do this right we need a feature of e-TeX, \scantokens, % which we arrange to emulate with a temporary file in ordinary TeX. \ifx\eTeXversion\undefined \newwrite\macscribble \def\scanmacro#1{% \begingroup \newlinechar`\^^M % Undo catcode changes of \startcontents and \doprintindex \catcode`\@=0 \catcode`\\=12 \escapechar=`\@ % Append \endinput to make sure that TeX does not see the ending newline. \toks0={#1\endinput}% \immediate\openout\macscribble=\jobname.tmp \immediate\write\macscribble{\the\toks0}% \immediate\closeout\macscribble \let\xeatspaces\eatspaces \input \jobname.tmp \endgroup } \else \def\scanmacro#1{% \begingroup \newlinechar`\^^M % Undo catcode changes of \startcontents and \doprintindex \catcode`\@=0 \catcode`\\=12 \escapechar=`\@ \let\xeatspaces\eatspaces\scantokens{#1\endinput}\endgroup} \fi \newcount\paramno % Count of parameters \newtoks\macname % Macro name \newif\ifrecursive % Is it recursive? \def\macrolist{} % List of all defined macros in the form % \do\macro1\do\macro2... % Utility routines. % Thisdoes \let #1 = #2, except with \csnames. \def\cslet#1#2{% \expandafter\expandafter \expandafter\let \expandafter\expandafter \csname#1\endcsname \csname#2\endcsname} % Trim leading and trailing spaces off a string. % Concepts from aro-bend problem 15 (see CTAN). {\catcode`\@=11 \gdef\eatspaces #1{\expandafter\trim@\expandafter{#1 }} \gdef\trim@ #1{\trim@@ @#1 @ #1 @ @@} \gdef\trim@@ #1@ #2@ #3@@{\trim@@@\empty #2 @} \def\unbrace#1{#1} \unbrace{\gdef\trim@@@ #1 } #2@{#1} } % Trim a single trailing ^^M off a string. {\catcode`\^^M=12\catcode`\Q=3% \gdef\eatcr #1{\eatcra #1Q^^MQ}% \gdef\eatcra#1^^MQ{\eatcrb#1Q}% \gdef\eatcrb#1Q#2Q{#1}% } % Macro bodies are absorbed as an argument in a context where % all characters are catcode 10, 11 or 12, except \ which is active % (as in normal texinfo). It is necessary to change the definition of \. % It's necessary to have hard CRs when the macro is executed. This is % done by making ^^M (\endlinechar) catcode 12 when reading the macro % body, and then making it the \newlinechar in \scanmacro. \def\macrobodyctxt{% \catcode`\~=12 \catcode`\^=12 \catcode`\_=12 \catcode`\|=12 \catcode`\<=12 \catcode`\>=12 \catcode`\+=12 \catcode`\{=12 \catcode`\}=12 \catcode`\@=12 \catcode`\^^M=12 \usembodybackslash} \def\macroargctxt{% \catcode`\~=12 \catcode`\^=12 \catcode`\_=12 \catcode`\|=12 \catcode`\<=12 \catcode`\>=12 \catcode`\+=12 \catcode`\@=12 \catcode`\\=12} % \mbodybackslash is the definition of \ in @macro bodies. % It maps \foo\ => \csname macarg.foo\endcsname => #N % where N is the macro parameter number. % We define \csname macarg.\endcsname to be \realbackslash, so % \\ in macro replacement text gets you a backslash. {\catcode`@=0 @catcode`@\=@active @gdef@usembodybackslash{@let\=@mbodybackslash} @gdef@mbodybackslash#1\{@csname macarg.#1@endcsname} } \expandafter\def\csname macarg.\endcsname{\realbackslash} \def\macro{\recursivefalse\parsearg\macroxxx} \def\rmacro{\recursivetrue\parsearg\macroxxx} \def\macroxxx#1{% \getargs{#1}% now \macname is the macname and \argl the arglist \ifx\argl\empty % no arguments \paramno=0% \else \expandafter\parsemargdef \argl;% \fi \if1\csname ismacro.\the\macname\endcsname \message{Warning: redefining \the\macname}% \else \expandafter\ifx\csname \the\macname\endcsname \relax \else \errmessage{The name \the\macname\space is reserved}\fi \global\cslet{macsave.\the\macname}{\the\macname}% \global\expandafter\let\csname ismacro.\the\macname\endcsname=1% % Add the macroname to \macrolist \toks0 = \expandafter{\macrolist\do}% \xdef\macrolist{\the\toks0 \expandafter\noexpand\csname\the\macname\endcsname}% \fi \begingroup \macrobodyctxt \ifrecursive \expandafter\parsermacbody \else \expandafter\parsemacbody \fi} \def\unmacro{\parsearg\unmacroxxx} \def\unmacroxxx#1{% \if1\csname ismacro.#1\endcsname \global\cslet{#1}{macsave.#1}% \global\expandafter\let \csname ismacro.#1\endcsname=0% % Remove the macro name from \macrolist \begingroup \edef\tempa{\expandafter\noexpand\csname#1\endcsname}% \def\do##1{% \def\tempb{##1}% \ifx\tempa\tempb % remove this \else \toks0 = \expandafter{\newmacrolist\do}% \edef\newmacrolist{\the\toks0\expandafter\noexpand\tempa}% \fi}% \def\newmacrolist{}% % Execute macro list to define \newmacrolist \macrolist \global\let\macrolist\newmacrolist \endgroup \else \errmessage{Macro #1 not defined}% \fi } % This makes use of the obscure feature that if the last token of a % is #, then the preceding argument is delimited by % an opening brace, and that opening brace is not consumed. \def\getargs#1{\getargsxxx#1{}} \def\getargsxxx#1#{\getmacname #1 \relax\getmacargs} \def\getmacname #1 #2\relax{\macname={#1}} \def\getmacargs#1{\def\argl{#1}} % Parse the optional {params} list. Set up \paramno and \paramlist % so \defmacro knows what to do. Define \macarg.blah for each blah % in the params list, to be ##N where N is the position in that list. % That gets used by \mbodybackslash (above). % We need to get `macro parameter char #' into several definitions. % The technique used is stolen from LaTeX: let \hash be something % unexpandable, insert that wherever you need a #, and then redefine % it to # just before using the token list produced. % % The same technique is used to protect \eatspaces till just before % the macro is used. \def\parsemargdef#1;{\paramno=0\def\paramlist{}% \let\hash\relax\let\xeatspaces\relax\parsemargdefxxx#1,;,} \def\parsemargdefxxx#1,{% \if#1;\let\next=\relax \else \let\next=\parsemargdefxxx \advance\paramno by 1% \expandafter\edef\csname macarg.\eatspaces{#1}\endcsname {\xeatspaces{\hash\the\paramno}}% \edef\paramlist{\paramlist\hash\the\paramno,}% \fi\next} % These two commands read recursive and nonrecursive macro bodies. % (They're different since rec and nonrec macros end differently.) \long\def\parsemacbody#1@end macro% {\xdef\temp{\eatcr{#1}}\endgroup\defmacro}% \long\def\parsermacbody#1@end rmacro% {\xdef\temp{\eatcr{#1}}\endgroup\defmacro}% % This defines the macro itself. There are six cases: recursive and % nonrecursive macros of zero, one, and many arguments. % Much magic with \expandafter here. % \xdef is used so that macro definitions will survive the file % they're defined in; @include reads the file inside a group. \def\defmacro{% \let\hash=##% convert placeholders to macro parameter chars \ifrecursive \ifcase\paramno % 0 \expandafter\xdef\csname\the\macname\endcsname{% \noexpand\scanmacro{\temp}}% \or % 1 \expandafter\xdef\csname\the\macname\endcsname{% \bgroup\noexpand\macroargctxt \noexpand\braceorline \expandafter\noexpand\csname\the\macname xxx\endcsname}% \expandafter\xdef\csname\the\macname xxx\endcsname##1{% \egroup\noexpand\scanmacro{\temp}}% \else % many \expandafter\xdef\csname\the\macname\endcsname{% \bgroup\noexpand\macroargctxt \noexpand\csname\the\macname xx\endcsname}% \expandafter\xdef\csname\the\macname xx\endcsname##1{% \expandafter\noexpand\csname\the\macname xxx\endcsname ##1,}% \expandafter\expandafter \expandafter\xdef \expandafter\expandafter \csname\the\macname xxx\endcsname \paramlist{\egroup\noexpand\scanmacro{\temp}}% \fi \else \ifcase\paramno % 0 \expandafter\xdef\csname\the\macname\endcsname{% \noexpand\norecurse{\the\macname}% \noexpand\scanmacro{\temp}\egroup}% \or % 1 \expandafter\xdef\csname\the\macname\endcsname{% \bgroup\noexpand\macroargctxt \noexpand\braceorline \expandafter\noexpand\csname\the\macname xxx\endcsname}% \expandafter\xdef\csname\the\macname xxx\endcsname##1{% \egroup \noexpand\norecurse{\the\macname}% \noexpand\scanmacro{\temp}\egroup}% \else % many \expandafter\xdef\csname\the\macname\endcsname{% \bgroup\noexpand\macroargctxt \expandafter\noexpand\csname\the\macname xx\endcsname}% \expandafter\xdef\csname\the\macname xx\endcsname##1{% \expandafter\noexpand\csname\the\macname xxx\endcsname ##1,}% \expandafter\expandafter \expandafter\xdef \expandafter\expandafter \csname\the\macname xxx\endcsname \paramlist{% \egroup \noexpand\norecurse{\the\macname}% \noexpand\scanmacro{\temp}\egroup}% \fi \fi} \def\norecurse#1{\bgroup\cslet{#1}{macsave.#1}} % \braceorline decides whether the next nonwhitespace character is a % {. If so it reads up to the closing }, if not, it reads the whole % line. Whatever was read is then fed to the next control sequence % as an argument (by \parsebrace or \parsearg) \def\braceorline#1{\let\next=#1\futurelet\nchar\braceorlinexxx} \def\braceorlinexxx{% \ifx\nchar\bgroup\else \expandafter\parsearg \fi \next} % We mant to disable all macros during \shipout so that they are not % expanded by \write. \def\turnoffmacros{\begingroup \def\do##1{\let\noexpand##1=\relax}% \edef\next{\macrolist}\expandafter\endgroup\next} % @alias. % We need some trickery to remove the optional spaces around the equal % sign. Just make them active and then expand them all to nothing. \def\alias{\begingroup\obeyspaces\parsearg\aliasxxx} \def\aliasxxx #1{\aliasyyy#1\relax} \def\aliasyyy #1=#2\relax{\ignoreactivespaces \edef\next{\global\let\expandafter\noexpand\csname#1\endcsname=% \expandafter\noexpand\csname#2\endcsname}% \expandafter\endgroup\next} \message{cross references,} % @xref etc. \newwrite\auxfile \newif\ifhavexrefs % True if xref values are known. \newif\ifwarnedxrefs % True if we warned once that they aren't known. % @inforef is relatively simple. \def\inforef #1{\inforefzzz #1,,,,**} \def\inforefzzz #1,#2,#3,#4**{\putwordSee{} \putwordInfo{} \putwordfile{} \file{\ignorespaces #3{}}, node \samp{\ignorespaces#1{}}} % @node's job is to define \lastnode. \def\node{\ENVcheck\parsearg\nodezzz} \def\nodezzz#1{\nodexxx [#1,]} \def\nodexxx[#1,#2]{\gdef\lastnode{#1}} \let\nwnode=\node \let\lastnode=\relax % The sectioning commands (@chapter, etc.) call these. \def\donoderef{% \ifx\lastnode\relax\else \expandafter\expandafter\expandafter\setref{\lastnode}% {Ysectionnumberandtype}% \global\let\lastnode=\relax \fi } \def\unnumbnoderef{% \ifx\lastnode\relax\else \expandafter\expandafter\expandafter\setref{\lastnode}{Ynothing}% \global\let\lastnode=\relax \fi } \def\appendixnoderef{% \ifx\lastnode\relax\else \expandafter\expandafter\expandafter\setref{\lastnode}% {Yappendixletterandtype}% \global\let\lastnode=\relax \fi } % @anchor{NAME} -- define xref target at arbitrary point. % \newcount\savesfregister \gdef\savesf{\relax \ifhmode \savesfregister=\spacefactor \fi} \gdef\restoresf{\relax \ifhmode \spacefactor=\savesfregister \fi} \gdef\anchor#1{\savesf \setref{#1}{Ynothing}\restoresf \ignorespaces} % \setref{NAME}{SNT} defines a cross-reference point NAME, namely % NAME-title, NAME-pg, and NAME-SNT. Called from \foonoderef. We have % to set \indexdummies so commands such as @code in a section title % aren't expanded. It would be nicer not to expand the titles in the % first place, but there's so many layers that that is hard to do. % \def\setref#1#2{{% \indexdummies \pdfmkdest{#1}% \dosetq{#1-title}{Ytitle}% \dosetq{#1-pg}{Ypagenumber}% \dosetq{#1-snt}{#2}% }} % @xref, @pxref, and @ref generate cross-references. For \xrefX, #1 is % the node name, #2 the name of the Info cross-reference, #3 the printed % node name, #4 the name of the Info file, #5 the name of the printed % manual. All but the node name can be omitted. % \def\pxref#1{\putwordsee{} \xrefX[#1,,,,,,,]} \def\xref#1{\putwordSee{} \xrefX[#1,,,,,,,]} \def\ref#1{\xrefX[#1,,,,,,,]} \def\xrefX[#1,#2,#3,#4,#5,#6]{\begingroup \unsepspaces \def\printedmanual{\ignorespaces #5}% \def\printednodename{\ignorespaces #3}% \setbox1=\hbox{\printedmanual}% \setbox0=\hbox{\printednodename}% \ifdim \wd0 = 0pt % No printed node name was explicitly given. \expandafter\ifx\csname SETxref-automatic-section-title\endcsname\relax % Use the node name inside the square brackets. \def\printednodename{\ignorespaces #1}% \else % Use the actual chapter/section title appear inside % the square brackets. Use the real section title if we have it. \ifdim \wd1 > 0pt % It is in another manual, so we don't have it. \def\printednodename{\ignorespaces #1}% \else \ifhavexrefs % We know the real title if we have the xref values. \def\printednodename{\refx{#1-title}{}}% \else % Otherwise just copy the Info node name. \def\printednodename{\ignorespaces #1}% \fi% \fi \fi \fi % % If we use \unhbox0 and \unhbox1 to print the node names, TeX does not % insert empty discretionaries after hyphens, which means that it will % not find a line break at a hyphen in a node names. Since some manuals % are best written with fairly long node names, containing hyphens, this % is a loss. Therefore, we give the text of the node name again, so it % is as if TeX is seeing it for the first time. \ifpdf \leavevmode \getfilename{#4}% \ifnum\filenamelength>0 \startlink attr{/Border [0 0 0]}% goto file{\the\filename.pdf} name{#1@}% \else \startlink attr{/Border [0 0 0]}% goto name{#1@}% \fi \linkcolor \fi % \ifdim \wd1 > 0pt \putwordsection{} ``\printednodename'' \putwordin{} \cite{\printedmanual}% \else % _ (for example) has to be the character _ for the purposes of the % control sequence corresponding to the node, but it has to expand % into the usual \leavevmode...\vrule stuff for purposes of % printing. So we \turnoffactive for the \refx-snt, back on for the % printing, back off for the \refx-pg. {\normalturnoffactive % Only output a following space if the -snt ref is nonempty; for % @unnumbered and @anchor, it won't be. \setbox2 = \hbox{\ignorespaces \refx{#1-snt}{}}% \ifdim \wd2 > 0pt \refx{#1-snt}\space\fi }% % [mynode], [\printednodename],\space % page 3 \turnoffactive \putwordpage\tie\refx{#1-pg}{}% \fi \endlink \endgroup} % \dosetq is the interface for calls from other macros % Use \normalturnoffactive so that punctuation chars such as underscore % and backslash work in node names. (\turnoffactive doesn't do \.) \def\dosetq#1#2{% {\let\folio=0% \normalturnoffactive \edef\next{\write\auxfile{\internalsetq{#1}{#2}}}% \iflinks \next \fi }% } % \internalsetq {foo}{page} expands into % CHARACTERS 'xrdef {foo}{...expansion of \Ypage...} % When the aux file is read, ' is the escape character \def\internalsetq #1#2{'xrdef {#1}{\csname #2\endcsname}} % Things to be expanded by \internalsetq \def\Ypagenumber{\folio} \def\Ytitle{\thissection} \def\Ynothing{} \def\Ysectionnumberandtype{% \ifnum\secno=0 \putwordChapter\xreftie\the\chapno % \else \ifnum \subsecno=0 \putwordSection\xreftie\the\chapno.\the\secno % \else \ifnum \subsubsecno=0 % \putwordSection\xreftie\the\chapno.\the\secno.\the\subsecno % \else % \putwordSection\xreftie\the\chapno.\the\secno.\the\subsecno.\the\subsubsecno % \fi \fi \fi } \def\Yappendixletterandtype{% \ifnum\secno=0 \putwordAppendix\xreftie'char\the\appendixno{}% \else \ifnum \subsecno=0 \putwordSection\xreftie'char\the\appendixno.\the\secno % \else \ifnum \subsubsecno=0 % \putwordSection\xreftie'char\the\appendixno.\the\secno.\the\subsecno % \else % \putwordSection\xreftie'char\the\appendixno.\the\secno.\the\subsecno.\the\subsubsecno % \fi \fi \fi } \gdef\xreftie{'tie} % Use TeX 3.0's \inputlineno to get the line number, for better error % messages, but if we're using an old version of TeX, don't do anything. % \ifx\inputlineno\thisisundefined \let\linenumber = \empty % Non-3.0. \else \def\linenumber{\the\inputlineno:\space} \fi % Define \refx{NAME}{SUFFIX} to reference a cross-reference string named NAME. % If its value is nonempty, SUFFIX is output afterward. \def\refx#1#2{% \expandafter\ifx\csname X#1\endcsname\relax % If not defined, say something at least. \angleleft un\-de\-fined\angleright \iflinks \ifhavexrefs \message{\linenumber Undefined cross reference `#1'.}% \else \ifwarnedxrefs\else \global\warnedxrefstrue \message{Cross reference values unknown; you must run TeX again.}% \fi \fi \fi \else % It's defined, so just use it. \csname X#1\endcsname \fi #2% Output the suffix in any case. } % This is the macro invoked by entries in the aux file. % \def\xrdef#1{\begingroup % Reenable \ as an escape while reading the second argument. \catcode`\\ = 0 \afterassignment\endgroup \expandafter\gdef\csname X#1\endcsname } % Read the last existing aux file, if any. No error if none exists. \def\readauxfile{\begingroup \catcode`\^^@=\other \catcode`\^^A=\other \catcode`\^^B=\other \catcode`\^^C=\other \catcode`\^^D=\other \catcode`\^^E=\other \catcode`\^^F=\other \catcode`\^^G=\other \catcode`\^^H=\other \catcode`\^^K=\other \catcode`\^^L=\other \catcode`\^^N=\other \catcode`\^^P=\other \catcode`\^^Q=\other \catcode`\^^R=\other \catcode`\^^S=\other \catcode`\^^T=\other \catcode`\^^U=\other \catcode`\^^V=\other \catcode`\^^W=\other \catcode`\^^X=\other \catcode`\^^Z=\other \catcode`\^^[=\other \catcode`\^^\=\other \catcode`\^^]=\other \catcode`\^^^=\other \catcode`\^^_=\other \catcode`\@=\other \catcode`\^=\other % It was suggested to define this as 7, which would allow ^^e4 etc. % in xref tags, i.e., node names. But since ^^e4 notation isn't % supported in the main text, it doesn't seem desirable. Furthermore, % that is not enough: for node names that actually contain a ^ % character, we would end up writing a line like this: 'xrdef {'hat % b-title}{'hat b} and \xrdef does a \csname...\endcsname on the first % argument, and \hat is not an expandable control sequence. It could % all be worked out, but why? Either we support ^^ or we don't. % % The other change necessary for this was to define \auxhat: % \def\auxhat{\def^{'hat }}% extra space so ok if followed by letter % and then to call \auxhat in \setq. % \catcode`\~=\other \catcode`\[=\other \catcode`\]=\other \catcode`\"=\other \catcode`\_=\other \catcode`\|=\other \catcode`\<=\other \catcode`\>=\other \catcode`\$=\other \catcode`\#=\other \catcode`\&=\other \catcode`+=\other % avoid \+ for paranoia even though we've turned it off % Make the characters 128-255 be printing characters {% \count 1=128 \def\loop{% \catcode\count 1=\other \advance\count 1 by 1 \ifnum \count 1<256 \loop \fi }% }% % The aux file uses ' as the escape (for now). % Turn off \ as an escape so we do not lose on % entries which were dumped with control sequences in their names. % For example, 'xrdef {$\leq $-fun}{page ...} made by @defun ^^ % Reference to such entries still does not work the way one would wish, % but at least they do not bomb out when the aux file is read in. \catcode`\{=1 \catcode`\}=2 \catcode`\%=\other \catcode`\'=0 \catcode`\\=\other % \openin 1 \jobname.aux \ifeof 1 \else \closein 1 \input \jobname.aux \global\havexrefstrue \global\warnedobstrue \fi % Open the new aux file. TeX will close it automatically at exit. \openout\auxfile=\jobname.aux \endgroup} % Footnotes. \newcount \footnoteno % The trailing space in the following definition for supereject is % vital for proper filling; pages come out unaligned when you do a % pagealignmacro call if that space before the closing brace is % removed. (Generally, numeric constants should always be followed by a % space to prevent strange expansion errors.) \def\supereject{\par\penalty -20000\footnoteno =0 } % @footnotestyle is meaningful for info output only. \let\footnotestyle=\comment \let\ptexfootnote=\footnote {\catcode `\@=11 % % Auto-number footnotes. Otherwise like plain. \gdef\footnote{% \global\advance\footnoteno by \@ne \edef\thisfootno{$^{\the\footnoteno}$}% % % In case the footnote comes at the end of a sentence, preserve the % extra spacing after we do the footnote number. \let\@sf\empty \ifhmode\edef\@sf{\spacefactor\the\spacefactor}\/\fi % % Remove inadvertent blank space before typesetting the footnote number. \unskip \thisfootno\@sf \footnotezzz }% % Don't bother with the trickery in plain.tex to not require the % footnote text as a parameter. Our footnotes don't need to be so general. % % Oh yes, they do; otherwise, @ifset and anything else that uses % \parseargline fail inside footnotes because the tokens are fixed when % the footnote is read. --karl, 16nov96. % \long\gdef\footnotezzz{\insert\footins\bgroup % We want to typeset this text as a normal paragraph, even if the % footnote reference occurs in (for example) a display environment. % So reset some parameters. \interlinepenalty\interfootnotelinepenalty \splittopskip\ht\strutbox % top baseline for broken footnotes \splitmaxdepth\dp\strutbox \floatingpenalty\@MM \leftskip\z@skip \rightskip\z@skip \spaceskip\z@skip \xspaceskip\z@skip \parindent\defaultparindent % \smallfonts \rm % % Hang the footnote text off the number. \hang \textindent{\thisfootno}% % % Don't crash into the line above the footnote text. Since this % expands into a box, it must come within the paragraph, lest it % provide a place where TeX can split the footnote. \footstrut \futurelet\next\fo@t } \def\fo@t{\ifcat\bgroup\noexpand\next \let\next\f@@t \else\let\next\f@t\fi \next} \def\f@@t{\bgroup\aftergroup\@foot\let\next} \def\f@t#1{#1\@foot} \def\@foot{\strut\par\egroup} }%end \catcode `\@=11 % Set the baselineskip to #1, and the lineskip and strut size % correspondingly. There is no deep meaning behind these magic numbers % used as factors; they just match (closely enough) what Knuth defined. % \def\lineskipfactor{.08333} \def\strutheightpercent{.70833} \def\strutdepthpercent {.29167} % \def\setleading#1{% \normalbaselineskip = #1\relax \normallineskip = \lineskipfactor\normalbaselineskip \normalbaselines \setbox\strutbox =\hbox{% \vrule width0pt height\strutheightpercent\baselineskip depth \strutdepthpercent \baselineskip }% } % @| inserts a changebar to the left of the current line. It should % surround any changed text. This approach does *not* work if the % change spans more than two lines of output. To handle that, we would % have adopt a much more difficult approach (putting marks into the main % vertical list for the beginning and end of each change). % \def\|{% % \vadjust can only be used in horizontal mode. \leavevmode % % Append this vertical mode material after the current line in the output. \vadjust{% % We want to insert a rule with the height and depth of the current % leading; that is exactly what \strutbox is supposed to record. \vskip-\baselineskip % % \vadjust-items are inserted at the left edge of the type. So % the \llap here moves out into the left-hand margin. \llap{% % % For a thicker or thinner bar, change the `1pt'. \vrule height\baselineskip width1pt % % This is the space between the bar and the text. \hskip 12pt }% }% } % For a final copy, take out the rectangles % that mark overfull boxes (in case you have decided % that the text looks ok even though it passes the margin). % \def\finalout{\overfullrule=0pt} % @image. We use the macros from epsf.tex to support this. % If epsf.tex is not installed and @image is used, we complain. % % Check for and read epsf.tex up front. If we read it only at @image % time, we might be inside a group, and then its definitions would get % undone and the next image would fail. \openin 1 = epsf.tex \ifeof 1 \else \closein 1 % Do not bother showing banner with post-v2.7 epsf.tex (available in % doc/epsf.tex until it shows up on ctan). \def\epsfannounce{\toks0 = }% \input epsf.tex \fi % % We will only complain once about lack of epsf.tex. \newif\ifwarnednoepsf \newhelp\noepsfhelp{epsf.tex must be installed for images to work. It is also included in the Texinfo distribution, or you can get it from ftp://tug.org/tex/epsf.tex.} % \def\image#1{% \ifx\epsfbox\undefined \ifwarnednoepsf \else \errhelp = \noepsfhelp \errmessage{epsf.tex not found, images will be ignored}% \global\warnednoepsftrue \fi \else \imagexxx #1,,,\finish \fi } % % Arguments to @image: % #1 is (mandatory) image filename; we tack on .eps extension. % #2 is (optional) width, #3 is (optional) height. % #4 is just the usual extra ignored arg for parsing this stuff. \def\imagexxx#1,#2,#3,#4\finish{% \ifpdf \centerline{\dopdfimage{#1}{#2}{#3}}% \else % \epsfbox itself resets \epsf?size at each figure. \setbox0 = \hbox{\ignorespaces #2}\ifdim\wd0 > 0pt \epsfxsize=#2\relax \fi \setbox0 = \hbox{\ignorespaces #3}\ifdim\wd0 > 0pt \epsfysize=#3\relax \fi \begingroup \catcode`\^^M = 5 % in case we're inside an example % If the image is by itself, center it. \ifvmode \nobreak\bigskip % Usually we'll have text after the image which will insert % \parskip glue, so insert it here too to equalize the space % above and below. \nobreak\vskip\parskip \nobreak \centerline{\epsfbox{#1.eps}}% \bigbreak \else % In the middle of a paragraph, no extra space. \epsfbox{#1.eps}% \fi \endgroup \fi } \message{localization,} % and i18n. % @documentlanguage is usually given very early, just after % @setfilename. If done too late, it may not override everything % properly. Single argument is the language abbreviation. % It would be nice if we could set up a hyphenation file here. % \def\documentlanguage{\parsearg\dodocumentlanguage} \def\dodocumentlanguage#1{% \tex % read txi-??.tex file in plain TeX. % Read the file if it exists. \openin 1 txi-#1.tex \ifeof1 \errhelp = \nolanghelp \errmessage{Cannot read language file txi-#1.tex}% \let\temp = \relax \else \def\temp{\input txi-#1.tex }% \fi \temp \endgroup } \newhelp\nolanghelp{The given language definition file cannot be found or is empty. Maybe you need to install it? In the current directory should work if nowhere else does.} % @documentencoding should change something in TeX eventually, most % likely, but for now just recognize it. \let\documentencoding = \comment % Page size parameters. % \newdimen\defaultparindent \defaultparindent = 15pt \chapheadingskip = 15pt plus 4pt minus 2pt \secheadingskip = 12pt plus 3pt minus 2pt \subsecheadingskip = 9pt plus 2pt minus 2pt % Prevent underfull vbox error messages. \vbadness = 10000 % Don't be so finicky about underfull hboxes, either. \hbadness = 2000 % Following George Bush, just get rid of widows and orphans. \widowpenalty=10000 \clubpenalty=10000 % Use TeX 3.0's \emergencystretch to help line breaking, but if we're % using an old version of TeX, don't do anything. We want the amount of % stretch added to depend on the line length, hence the dependence on % \hsize. We call this whenever the paper size is set. % \def\setemergencystretch{% \ifx\emergencystretch\thisisundefined % Allow us to assign to \emergencystretch anyway. \def\emergencystretch{\dimen0}% \else \emergencystretch = .15\hsize \fi } % Parameters in order: 1) textheight; 2) textwidth; 3) voffset; % 4) hoffset; 5) binding offset; 6) topskip. Then whoever calls us can % set \parskip and call \setleading for \baselineskip. % \def\internalpagesizes#1#2#3#4#5#6{% \voffset = #3\relax \topskip = #6\relax \splittopskip = \topskip % \vsize = #1\relax \advance\vsize by \topskip \outervsize = \vsize \advance\outervsize by 2\topandbottommargin \pageheight = \vsize % \hsize = #2\relax \outerhsize = \hsize \advance\outerhsize by 0.5in \pagewidth = \hsize % \normaloffset = #4\relax \bindingoffset = #5\relax % \parindent = \defaultparindent \setemergencystretch } % @letterpaper (the default). \def\letterpaper{{\globaldefs = 1 \parskip = 3pt plus 2pt minus 1pt \setleading{13.2pt}% % % If page is nothing but text, make it come out even. \internalpagesizes{46\baselineskip}{6in}{\voffset}{.25in}{\bindingoffset}{36pt}% }} % Use @smallbook to reset parameters for 7x9.5 (or so) format. \def\smallbook{{\globaldefs = 1 \parskip = 2pt plus 1pt \setleading{12pt}% % \internalpagesizes{7.5in}{5.in}{\voffset}{.25in}{\bindingoffset}{16pt}% % \lispnarrowing = 0.3in \tolerance = 700 \hfuzz = 1pt \contentsrightmargin = 0pt \deftypemargin = 0pt \defbodyindent = .5cm % \let\smalldisplay = \smalldisplayx \let\smallexample = \smalllispx \let\smallformat = \smallformatx \let\smalllisp = \smalllispx }} % Use @afourpaper to print on European A4 paper. \def\afourpaper{{\globaldefs = 1 \setleading{12pt}% \parskip = 3pt plus 2pt minus 1pt % \internalpagesizes{53\baselineskip}{160mm}{\voffset}{4mm}{\bindingoffset}{44pt}% % \tolerance = 700 \hfuzz = 1pt }} % A specific text layout, 24x15cm overall, intended for A4 paper. Top margin % 29mm, hence bottom margin 28mm, nominal side margin 3cm. \def\afourlatex{{\globaldefs = 1 \setleading{13.6pt}% % \afourpaper \internalpagesizes{237mm}{150mm}{3.6mm}{3.6mm}{3mm}{7mm}% % \globaldefs = 0 }} % Use @afourwide to print on European A4 paper in wide format. \def\afourwide{% \afourpaper \internalpagesizes{9.5in}{6.5in}{\hoffset}{\normaloffset}{\bindingoffset}{7mm}% % \globaldefs = 0 } % @pagesizes TEXTHEIGHT[,TEXTWIDTH] % Perhaps we should allow setting the margins, \topskip, \parskip, % and/or leading, also. Or perhaps we should compute them somehow. % \def\pagesizes{\parsearg\pagesizesxxx} \def\pagesizesxxx#1{\pagesizesyyy #1,,\finish} \def\pagesizesyyy#1,#2,#3\finish{{% \setbox0 = \hbox{\ignorespaces #2}\ifdim\wd0 > 0pt \hsize=#2\relax \fi \globaldefs = 1 % \parskip = 3pt plus 2pt minus 1pt \setleading{13.2pt}% % \internalpagesizes{#1}{\hsize}{\voffset}{\normaloffset}{\bindingoffset}{44pt}% }} % Set default to letter. % \letterpaper \message{and turning on texinfo input format.} % Define macros to output various characters with catcode for normal text. \catcode`\"=\other \catcode`\~=\other \catcode`\^=\other \catcode`\_=\other \catcode`\|=\other \catcode`\<=\other \catcode`\>=\other \catcode`\+=\other \catcode`\$=\other \def\normaldoublequote{"} \def\normaltilde{~} \def\normalcaret{^} \def\normalunderscore{_} \def\normalverticalbar{|} \def\normalless{<} \def\normalgreater{>} \def\normalplus{+} \def\normaldollar{$} % This macro is used to make a character print one way in ttfont % where it can probably just be output, and another way in other fonts, % where something hairier probably needs to be done. % % #1 is what to print if we are indeed using \tt; #2 is what to print % otherwise. Since all the Computer Modern typewriter fonts have zero % interword stretch (and shrink), and it is reasonable to expect all % typewriter fonts to have this, we can check that font parameter. % \def\ifusingtt#1#2{\ifdim \fontdimen3\font=0pt #1\else #2\fi} % Same as above, but check for italic font. Actually this also catches % non-italic slanted fonts since it is impossible to distinguish them from % italic fonts. But since this is only used by $ and it uses \sl anyway % this is not a problem. \def\ifusingit#1#2{\ifdim \fontdimen1\font>0pt #1\else #2\fi} % Turn off all special characters except @ % (and those which the user can use as if they were ordinary). % Most of these we simply print from the \tt font, but for some, we can % use math or other variants that look better in normal text. \catcode`\"=\active \def\activedoublequote{{\tt\char34}} \let"=\activedoublequote \catcode`\~=\active \def~{{\tt\char126}} \chardef\hat=`\^ \catcode`\^=\active \def^{{\tt \hat}} \catcode`\_=\active \def_{\ifusingtt\normalunderscore\_} % Subroutine for the previous macro. \def\_{\leavevmode \kern.06em \vbox{\hrule width.3em height.1ex}} \catcode`\|=\active \def|{{\tt\char124}} \chardef \less=`\< \catcode`\<=\active \def<{{\tt \less}} \chardef \gtr=`\> \catcode`\>=\active \def>{{\tt \gtr}} \catcode`\+=\active \def+{{\tt \char 43}} \catcode`\$=\active \def${\ifusingit{{\sl\$}}\normaldollar} %\catcode 27=\active %\def^^[{$\diamondsuit$} % Set up an active definition for =, but don't enable it most of the time. {\catcode`\==\active \global\def={{\tt \char 61}}} \catcode`+=\active \catcode`\_=\active % If a .fmt file is being used, characters that might appear in a file % name cannot be active until we have parsed the command line. % So turn them off again, and have \everyjob (or @setfilename) turn them on. % \otherifyactive is called near the end of this file. \def\otherifyactive{\catcode`+=\other \catcode`\_=\other} \catcode`\@=0 % \rawbackslashxx output one backslash character in current font \global\chardef\rawbackslashxx=`\\ %{\catcode`\\=\other %@gdef@rawbackslashxx{\}} % \rawbackslash redefines \ as input to do \rawbackslashxx. {\catcode`\\=\active @gdef@rawbackslash{@let\=@rawbackslashxx }} % \normalbackslash outputs one backslash in fixed width font. \def\normalbackslash{{\tt\rawbackslashxx}} % \catcode 17=0 % Define control-q \catcode`\\=\active % Used sometimes to turn off (effectively) the active characters % even after parsing them. @def@turnoffactive{@let"=@normaldoublequote @let\=@realbackslash @let~=@normaltilde @let^=@normalcaret @let_=@normalunderscore @let|=@normalverticalbar @let<=@normalless @let>=@normalgreater @let+=@normalplus @let$=@normaldollar} @def@normalturnoffactive{@let"=@normaldoublequote @let\=@normalbackslash @let~=@normaltilde @let^=@normalcaret @let_=@normalunderscore @let|=@normalverticalbar @let<=@normalless @let>=@normalgreater @let+=@normalplus @let$=@normaldollar} % Make _ and + \other characters, temporarily. % This is canceled by @fixbackslash. @otherifyactive % If a .fmt file is being used, we don't want the `\input texinfo' to show up. % That is what \eatinput is for; after that, the `\' should revert to printing % a backslash. % @gdef@eatinput input texinfo{@fixbackslash} @global@let\ = @eatinput % On the other hand, perhaps the file did not have a `\input texinfo'. Then % the first `\{ in the file would cause an error. This macro tries to fix % that, assuming it is called before the first `\' could plausibly occur. % Also back turn on active characters that might appear in the input % file name, in case not using a pre-dumped format. % @gdef@fixbackslash{% @ifx\@eatinput @let\ = @normalbackslash @fi @catcode`+=@active @catcode`@_=@active } % Say @foo, not \foo, in error messages. @escapechar = `@@ % These look ok in all fonts, so just make them not special. @catcode`@& = @other @catcode`@# = @other @catcode`@% = @other @c Set initial fonts. @textfonts @rm @c Local variables: @c eval: (add-hook 'write-file-hooks 'time-stamp) @c page-delimiter: "^\\\\message" @c time-stamp-start: "def\\\\texinfoversion{" @c time-stamp-format: "%:y-%02m-%02d.%02H" @c time-stamp-end: "}" @c End: bash-2.05a/doc/bashref.texi100664 436 0 722221 7374257167 14077 0ustar chetwheel\input texinfo.tex @c -*- texinfo -*- @c %**start of header @setfilename bashref.info @settitle Bash Reference Manual @c %**end of header @ignore Last Change: Tue Nov 13 12:48:51 EST 2001 @end ignore @set EDITION 2.5a @set VERSION 2.05a @set UPDATED 13 November 2001 @set UPDATE-MONTH November 2001 @iftex @finalout @end iftex @setchapternewpage odd @defcodeindex bt @defcodeindex rw @set BashFeatures @ifinfo @dircategory Utilities @direntry * Bash: (bash). The GNU Bourne-Again SHell. @end direntry @format This text is a brief description of the features that are present in the Bash shell. This is Edition @value{EDITION}, last updated @value{UPDATED}, of @cite{The GNU Bash Reference Manual}, for @code{Bash}, Version @value{VERSION}. Copyright (C) 1991-2001 Free Software Foundation, Inc. Permission is granted to make and distribute verbatim copies of this manual provided the copyright notice and this permission notice are preserved on all copies. @ignore Permission is granted to process this file through TeX and print the results, provided the printed document carries copying permission notice identical to this one except for the removal of this paragraph (this paragraph not being relevant to the printed manual). @end ignore Permission is granted to copy and distribute modified versions of this manual under the conditions for verbatim copying, provided that the entire resulting derived work is distributed under the terms of a permission notice identical to this one. Permission is granted to copy and distribute translations of this manual into another language, under the above conditions for modified versions, except that this permission notice may be stated in a translation approved by the Free Software Foundation. @end format @end ifinfo @titlepage @title Bash Reference Manual @subtitle Reference Documentation for Bash @subtitle Edition @value{EDITION}, for @code{Bash} Version @value{VERSION}. @subtitle @value{UPDATE-MONTH} @author Chet Ramey, Case Western Reserve University @author Brian Fox, Free Software Foundation @page @vskip 0pt plus 1filll Copyright @copyright{} 1991-1999 Free Software Foundation, Inc. Permission is granted to make and distribute verbatim copies of this manual provided the copyright notice and this permission notice are preserved on all copies. Permission is granted to copy and distribute modified versions of this manual under the conditions for verbatim copying, provided that the entire resulting derived work is distributed under the terms of a permission notice identical to this one. Permission is granted to copy and distribute translations of this manual into another language, under the above conditions for modified versions, except that this permission notice may be stated in a translation approved by the Free Software Foundation. @end titlepage @ifinfo @node Top, Introduction, (dir), (dir) @top Bash Features @end ifinfo @ifinfo This text is a brief description of the features that are present in the Bash shell. This is Edition @value{EDITION}, last updated @value{UPDATED}, of @cite{The GNU Bash Reference Manual}, for @code{Bash}, Version @value{VERSION}. Copyright (C) 1991, 1993, 1996 Free Software Foundation, Inc. Bash contains features that appear in other popular shells, and some features that only appear in Bash. Some of the shells that Bash has borrowed concepts from are the Bourne Shell (@file{sh}), the Korn Shell (@file{ksh}), and the C-shell (@file{csh} and its successor, @file{tcsh}). The following menu breaks the features up into categories based upon which one of these other shells inspired the feature. This manual is meant as a brief introduction to features found in Bash. The Bash manual page should be used as the definitive reference on shell behavior. @menu * Introduction:: An introduction to the shell. * Definitions:: Some definitions used in the rest of this manual. * Basic Shell Features:: The shell "building blocks". * Shell Builtin Commands:: Commands that are a part of the shell. * Shell Variables:: Variables used or set by Bash. * Bash Features:: Features found only in Bash. * Job Control:: A chapter describing what job control is and how Bash allows you to use it. * Using History Interactively:: Chapter dealing with history expansion rules. * Command Line Editing:: Chapter describing the command line editing features. * Installing Bash:: How to build and install Bash on your system. * Reporting Bugs:: How to report bugs in Bash. * Major Differences From The Bourne Shell:: A terse list of the differences between Bash and historical versions of /bin/sh. * Builtin Index:: Index of Bash builtin commands. * Reserved Word Index:: Index of Bash reserved words. * Variable Index:: Quick reference helps you find the variable you want. * Function Index:: Index of bindable Readline functions. * Concept Index:: General index for concepts described in this manual. @end menu @end ifinfo @node Introduction @chapter Introduction @menu * What is Bash?:: A short description of Bash. * What is a shell?:: A brief introduction to shells. @end menu @node What is Bash? @section What is Bash? Bash is the shell, or command language interpreter, for the @sc{gnu} operating system. The name is an acronym for the @samp{Bourne-Again SHell}, a pun on Stephen Bourne, the author of the direct ancestor of the current Unix shell @code{/bin/sh}, which appeared in the Seventh Edition Bell Labs Research version of Unix. Bash is largely compatible with @code{sh} and incorporates useful features from the Korn shell @code{ksh} and the C shell @code{csh}. It is intended to be a conformant implementation of the @sc{ieee} @sc{posix} Shell and Tools specification (@sc{ieee} Working Group 1003.2). It offers functional improvements over @code{sh} for both interactive and programming use. While the @sc{gnu} operating system provides other shells, including a version of @code{csh}, Bash is the default shell. Like other @sc{gnu} software, Bash is quite portable. It currently runs on nearly every version of Unix and a few other operating systems @minus{} independently-supported ports exist for @sc{ms-dos}, @sc{os/2}, Windows @sc{95/98}, and Windows @sc{nt}. @node What is a shell? @section What is a shell? At its base, a shell is simply a macro processor that executes commands. A Unix shell is both a command interpreter, which provides the user interface to the rich set of @sc{gnu} utilities, and a programming language, allowing these utilitites to be combined. Files containing commands can be created, and become commands themselves. These new commands have the same status as system commands in directories such as @file{/bin}, allowing users or groups to establish custom environments. A shell allows execution of @sc{gnu} commands, both synchronously and asynchronously. The shell waits for synchronous commands to complete before accepting more input; asynchronous commands continue to execute in parallel with the shell while it reads and executes additional commands. The @dfn{redirection} constructs permit fine-grained control of the input and output of those commands. Moreover, the shell allows control over the contents of commands' environments. Shells may be used interactively or non-interactively: they accept input typed from the keyboard or from a file. Shells also provide a small set of built-in commands (@dfn{builtins}) implementing functionality impossible or inconvenient to obtain via separate utilities. For example, @code{cd}, @code{break}, @code{continue}, and @code{exec}) cannot be implemented outside of the shell because they directly manipulate the shell itself. The @code{history}, @code{getopts}, @code{kill}, or @code{pwd} builtins, among others, could be implemented in separate utilities, but they are more convenient to use as builtin commands. All of the shell builtins are described in subsequent sections. While executing commands is essential, most of the power (and complexity) of shells is due to their embedded programming languages. Like any high-level language, the shell provides variables, flow control constructs, quoting, and functions. Shells offer features geared specifically for interactive use rather than to augment the programming language. These interactive features include job control, command line editing, history and aliases. Each of these features is described in this manual. @node Definitions @chapter Definitions These definitions are used throughout the remainder of this manual. @table @code @item POSIX @cindex POSIX A family of open system standards based on Unix. Bash is concerned with @sc{posix} 1003.2, the Shell and Tools Standard. @item blank A space or tab character. @item builtin @cindex builtin A command that is implemented internally by the shell itself, rather than by an executable program somewhere in the file system. @item control operator @cindex control operator A @code{word} that performs a control function. It is a @code{newline} or one of the following: @samp{||}, @samp{&&}, @samp{&}, @samp{;}, @samp{;;}, @samp{|}, @samp{(}, or @samp{)}. @item exit status @cindex exit status The value returned by a command to its caller. The value is restricted to eight bits, so the maximum value is 255. @item field @cindex field A unit of text that is the result of one of the shell expansions. After expansion, when executing a command, the resulting fields are used as the command name and arguments. @item filename @cindex filename A string of characters used to identify a file. @item job @cindex job A set of processes comprising a pipeline, and any processes descended from it, that are all in the same process group. @item job control @cindex job control A mechanism by which users can selectively stop (suspend) and restart (resume) execution of processes. @item metacharacter @cindex metacharacter A character that, when unquoted, separates words. A metacharacter is a @code{blank} or one of the following characters: @samp{|}, @samp{&}, @samp{;}, @samp{(}, @samp{)}, @samp{<}, or @samp{>}. @item name @cindex name @cindex identifier A @code{word} consisting solely of letters, numbers, and underscores, and beginning with a letter or underscore. @code{Name}s are used as shell variable and function names. Also referred to as an @code{identifier}. @item operator @cindex operator, shell A @code{control operator} or a @code{redirection operator}. @xref{Redirections}, for a list of redirection operators. @item process group @cindex process group A collection of related processes each having the same process group @sc{id}. @item process group ID @cindex process group ID A unique identifer that represents a @code{process group} during its lifetime. @item reserved word @cindex reserved word A @code{word} that has a special meaning to the shell. Most reserved words introduce shell flow control constructs, such as @code{for} and @code{while}. @item return status @cindex return status A synonym for @code{exit status}. @item signal @cindex signal A mechanism by which a process may be notified by the kernel of an event occurring in the system. @item special builtin @cindex special builtin A shell builtin command that has been classified as special by the @sc{posix} 1003.2 standard. @item token @cindex token A sequence of characters considered a single unit by the shell. It is either a @code{word} or an @code{operator}. @item word @cindex word A @code{token} that is not an @code{operator}. @end table @node Basic Shell Features @chapter Basic Shell Features @cindex Bourne shell Bash is an acronym for @samp{Bourne-Again SHell}. The Bourne shell is the traditional Unix shell originally written by Stephen Bourne. All of the Bourne shell builtin commands are available in Bash, and the rules for evaluation and quoting are taken from the @sc{posix} 1003.2 specification for the `standard' Unix shell. This chapter briefly summarizes the shell's `building blocks': commands, control structures, shell functions, shell @i{parameters}, shell expansions, @i{redirections}, which are a way to direct input and output from and to named files, and how the shell executes commands. @menu * Shell Syntax:: What your input means to the shell. * Shell Commands:: The types of commands you can use. * Shell Functions:: Grouping commands by name. * Shell Parameters:: Special shell variables. * Shell Expansions:: How Bash expands variables and the various expansions available. * Redirections:: A way to control where input and output go. * Executing Commands:: What happens when you run a command. * Shell Scripts:: Executing files of shell commands. @end menu @node Shell Syntax @section Shell Syntax @menu * Shell Operation:: The basic operation of the shell. * Quoting:: How to remove the special meaning from characters. * Comments:: How to specify comments. @end menu When the shell reads input, it proceeds through a sequence of operations. If the input indicates the beginning of a comment, the shell ignores the comment symbol (@samp{#}), and the rest of that line. Otherwise, roughly speaking, the shell reads its input and divides the input into words and operators, employing the quoting rules to select which meanings to assign various words and characters. The shell then parses these tokens into commands and other constructs, removes the special meaning of certain words or characters, expands others, redirects input and output as needed, executes the specified command, waits for the command's exit status, and makes that exit status available for further inspection or processing. @node Shell Operation @subsection Shell Operation The following is a brief description of the shell's operation when it reads and executes a command. Basically, the shell does the following: @enumerate @item Reads its input from a file (@pxref{Shell Scripts}), from a string supplied as an argument to the @option{-c} invocation option (@pxref{Invoking Bash}), or from the user's terminal. @item Breaks the input into words and operators, obeying the quoting rules described in @ref{Quoting}. These tokens are separated by @code{metacharacters}. Alias expansion is performed by this step (@pxref{Aliases}). @item Parses the tokens into simple and compound commands (@pxref{Shell Commands}). @item Performs the various shell expansions (@pxref{Shell Expansions}), breaking the expanded tokens into lists of filenames (@pxref{Filename Expansion}) and commands and arguments. @item Performs any necessary redirections (@pxref{Redirections}) and removes the redirection operators and their operands from the argument list. @item Executes the command (@pxref{Executing Commands}). @item Optionally waits for the command to complete and collects its exit status (@pxref{Exit Status}). @end enumerate @node Quoting @subsection Quoting @cindex quoting @menu * Escape Character:: How to remove the special meaning from a single character. * Single Quotes:: How to inhibit all interpretation of a sequence of characters. * Double Quotes:: How to suppress most of the interpretation of a sequence of characters. * ANSI-C Quoting:: How to expand ANSI-C sequences in quoted strings. * Locale Translation:: How to translate strings into different languages. @end menu Quoting is used to remove the special meaning of certain characters or words to the shell. Quoting can be used to disable special treatment for special characters, to prevent reserved words from being recognized as such, and to prevent parameter expansion. Each of the shell metacharacters (@pxref{Definitions}) has special meaning to the shell and must be quoted if it is to represent itself. When the command history expansion facilities are being used, the @var{history expansion} character, usually @samp{!}, must be quoted to prevent history expansion. @xref{Bash History Facilities}, for more details concerning history expansion. There are three quoting mechanisms: the @var{escape character}, single quotes, and double quotes. @node Escape Character @subsubsection Escape Character A non-quoted backslash @samp{\} is the Bash escape character. It preserves the literal value of the next character that follows, with the exception of @code{newline}. If a @code{\newline} pair appears, and the backslash itself is not quoted, the @code{\newline} is treated as a line continuation (that is, it is removed from the input stream and effectively ignored). @node Single Quotes @subsubsection Single Quotes Enclosing characters in single quotes (@samp{'}) preserves the literal value of each character within the quotes. A single quote may not occur between single quotes, even when preceded by a backslash. @node Double Quotes @subsubsection Double Quotes Enclosing characters in double quotes (@samp{"}) preserves the literal value of all characters within the quotes, with the exception of @samp{$}, @samp{`}, and @samp{\}. The characters @samp{$} and @samp{`} retain their special meaning within double quotes (@pxref{Shell Expansions}). The backslash retains its special meaning only when followed by one of the following characters: @samp{$}, @samp{`}, @samp{"}, @samp{\}, or @code{newline}. Within double quotes, backslashes that are followed by one of these characters are removed. Backslashes preceding characters without a special meaning are left unmodified. A double quote may be quoted within double quotes by preceding it with a backslash. The special parameters @samp{*} and @samp{@@} have special meaning when in double quotes (@pxref{Shell Parameter Expansion}). @node ANSI-C Quoting @subsubsection ANSI-C Quoting @cindex quoting, ANSI Words of the form @code{$'@var{string}'} are treated specially. The word expands to @var{string}, with backslash-escaped characters replaced as specified by the ANSI C standard. Backslash escape sequences, if present, are decoded as follows: @table @code @item \a alert (bell) @item \b backspace @item \e an escape character (not ANSI C) @item \f form feed @item \n newline @item \r carriage return @item \t horizontal tab @item \v vertical tab @item \\ backslash @item \' single quote @item \@var{nnn} the eight-bit character whose value is the octal value @var{nnn} (one to three digits) @item \x@var{HH} the eight-bit character whose value is the hexadecimal value @var{HH} (one or two hex digits) @end table @noindent The expanded result is single-quoted, as if the dollar sign had not been present. @node Locale Translation @subsubsection Locale-Specific Translation @cindex localization @cindex internationalization @cindex native languages @cindex translation, native languages A double-quoted string preceded by a dollar sign (@samp{$}) will cause the string to be translated according to the current locale. If the current locale is @code{C} or @code{POSIX}, the dollar sign is ignored. If the string is translated and replaced, the replacement is double-quoted. @vindex LC_MESSAGES @vindex TEXTDOMAIN @vindex TEXTDOMAINDIR Some systems use the message catalog selected by the @env{LC_MESSAGES} shell variable. Others create the name of the message catalog from the value of the @env{TEXTDOMAIN} shell variable, possibly adding a suffix of @samp{.mo}. If you use the @env{TEXTDOMAIN} variable, you may need to set the @env{TEXTDOMAINDIR} variable to the location of the message catalog files. Still others use both variables in this fashion: @env{TEXTDOMAINDIR}/@env{LC_MESSAGES}/LC_MESSAGES/@env{TEXTDOMAIN}.mo. @node Comments @subsection Comments @cindex comments, shell In a non-interactive shell, or an interactive shell in which the @code{interactive_comments} option to the @code{shopt} builtin is enabled (@pxref{Bash Builtins}), a word beginning with @samp{#} causes that word and all remaining characters on that line to be ignored. An interactive shell without the @code{interactive_comments} option enabled does not allow comments. The @code{interactive_comments} option is on by default in interactive shells. @xref{Interactive Shells}, for a description of what makes a shell interactive. @node Shell Commands @section Shell Commands @cindex commands, shell A simple shell command such as @code{echo a b c} consists of the command itself followed by arguments, separated by spaces. More complex shell commands are composed of simple commands arranged together in a variety of ways: in a pipeline in which the output of one command becomes the input of a second, in a loop or conditional construct, or in some other grouping. @menu * Simple Commands:: The most common type of command. * Pipelines:: Connecting the input and output of several commands. * Lists:: How to execute commands sequentially. * Looping Constructs:: Shell commands for iterative action. * Conditional Constructs:: Shell commands for conditional execution. * Command Grouping:: Ways to group commands. @end menu @node Simple Commands @subsection Simple Commands @cindex commands, simple A simple command is the kind of command encountered most often. It's just a sequence of words separated by @code{blank}s, terminated by one of the shell's control operators (@pxref{Definitions}). The first word generally specifies a command to be executed, with the rest of the words being that command's arguments. The return status (@pxref{Exit Status}) of a simple command is its exit status as provided by the @sc{posix} 1003.1 @code{waitpid} function, or 128+@var{n} if the command was terminated by signal @var{n}. @node Pipelines @subsection Pipelines @cindex pipeline @cindex commands, pipelines A @code{pipeline} is a sequence of simple commands separated by @samp{|}. @rwindex time @rwindex ! @cindex command timing The format for a pipeline is @example [@code{time} [@code{-p}]] [@code{!}] @var{command1} [@code{|} @var{command2} @dots{}] @end example @noindent The output of each command in the pipeline is connected via a pipe to the input of the next command. That is, each command reads the previous command's output. The reserved word @code{time} causes timing statistics to be printed for the pipeline once it finishes. The statistics currently consist of elapsed (wall-clock) time and user and system time consumed by the command's execution. The @option{-p} option changes the output format to that specified by @sc{posix}. The @env{TIMEFORMAT} variable may be set to a format string that specifies how the timing information should be displayed. @xref{Bash Variables}, for a description of the available formats. The use of @code{time} as a reserved word permits the timing of shell builtins, shell functions, and pipelines. An external @code{time} command cannot time these easily. If the pipeline is not executed asynchronously (@pxref{Lists}), the shell waits for all commands in the pipeline to complete. Each command in a pipeline is executed in its own subshell (@pxref{Command Execution Environment}). The exit status of a pipeline is the exit status of the last command in the pipeline. If the reserved word @samp{!} precedes the pipeline, the exit status is the logical negation of the exit status of the last command. @node Lists @subsection Lists of Commands @cindex commands, lists A @code{list} is a sequence of one or more pipelines separated by one of the operators @samp{;}, @samp{&}, @samp{&&}, or @samp{||}, and optionally terminated by one of @samp{;}, @samp{&}, or a @code{newline}. Of these list operators, @samp{&&} and @samp{||} have equal precedence, followed by @samp{;} and @samp{&}, which have equal precedence. If a command is terminated by the control operator @samp{&}, the shell executes the command asynchronously in a subshell. This is known as executing the command in the @var{background}. The shell does not wait for the command to finish, and the return status is 0 (true). When job control is not active (@pxref{Job Control}), the standard input for asynchronous commands, in the absence of any explicit redirections, is redirected from @code{/dev/null}. Commands separated by a @samp{;} are executed sequentially; the shell waits for each command to terminate in turn. The return status is the exit status of the last command executed. The control operators @samp{&&} and @samp{||} denote @sc{and} lists and @sc{or} lists, respectively. An @sc{and} list has the form @example @var{command1} && @var{command2} @end example @noindent @var{command2} is executed if, and only if, @var{command1} returns an exit status of zero. An @sc{or} list has the form @example @var{command1} || @var{command2} @end example @noindent @var{command2} is executed if, and only if, @var{command1} returns a non-zero exit status. The return status of @sc{and} and @sc{or} lists is the exit status of the last command executed in the list. @node Looping Constructs @subsection Looping Constructs @cindex commands, looping Bash supports the following looping constructs. Note that wherever a @samp{;} appears in the description of a command's syntax, it may be replaced with one or more newlines. @table @code @item until @rwindex until @rwindex do @rwindex done The syntax of the @code{until} command is: @example until @var{test-commands}; do @var{consequent-commands}; done @end example Execute @var{consequent-commands} as long as @var{test-commands} has an exit status which is not zero. The return status is the exit status of the last command executed in @var{consequent-commands}, or zero if none was executed. @item while @rwindex while The syntax of the @code{while} command is: @example while @var{test-commands}; do @var{consequent-commands}; done @end example Execute @var{consequent-commands} as long as @var{test-commands} has an exit status of zero. The return status is the exit status of the last command executed in @var{consequent-commands}, or zero if none was executed. @item for @rwindex for The syntax of the @code{for} command is: @example for @var{name} [in @var{words} @dots{}]; do @var{commands}; done @end example Expand @var{words}, and execute @var{commands} once for each member in the resultant list, with @var{name} bound to the current member. If @samp{in @var{words}} is not present, the @code{for} command executes the @var{commands} once for each positional parameter that is set, as if @samp{in "$@@"} had been specified (@pxref{Special Parameters}). The return status is the exit status of the last command that executes. If there are no items in the expansion of @var{words}, no commands are executed, and the return status is zero. An alternate form of the @code{for} command is also supported: @example for (( @var{expr1} ; @var{expr2} ; @var{expr3} )) ; do @var{commands} ; done @end example First, the arithmetic expression @var{expr1} is evaluated according to the rules described below (@pxref{Shell Arithmetic}). The arithmetic expression @var{expr2} is then evaluated repeatedly until it evaluates to zero. Each time @var{expr2} evaluates to a non-zero value, @var{commands} are executed and the arithmetic expression @var{expr3} is evaluated. If any expression is omitted, it behaves as if it evaluates to 1. The return value is the exit status of the last command in @var{list} that is executed, or false if any of the expressions is invalid. @end table The @code{break} and @code{continue} builtins (@pxref{Bourne Shell Builtins}) may be used to control loop execution. @node Conditional Constructs @subsection Conditional Constructs @cindex commands, conditional @table @code @item if @rwindex if @rwindex then @rwindex else @rwindex elif @rwindex fi The syntax of the @code{if} command is: @example if @var{test-commands}; then @var{consequent-commands}; [elif @var{more-test-commands}; then @var{more-consequents};] [else @var{alternate-consequents};] fi @end example The @var{test-commands} list is executed, and if its return status is zero, the @var{consequent-commands} list is executed. If @var{test-commands} returns a non-zero status, each @code{elif} list is executed in turn, and if its exit status is zero, the corresponding @var{more-consequents} is executed and the command completes. If @samp{else @var{alternate-consequents}} is present, and the final command in the final @code{if} or @code{elif} clause has a non-zero exit status, then @var{alternate-consequents} is executed. The return status is the exit status of the last command executed, or zero if no condition tested true. @item case @rwindex case @rwindex in @rwindex esac The syntax of the @code{case} command is: @example @code{case @var{word} in [ [(] @var{pattern} [| @var{pattern}]@dots{}) @var{command-list} ;;]@dots{} esac} @end example @code{case} will selectively execute the @var{command-list} corresponding to the first @var{pattern} that matches @var{word}. The @samp{|} is used to separate multiple patterns, and the @samp{)} operator terminates a pattern list. A list of patterns and an associated command-list is known as a @var{clause}. Each clause must be terminated with @samp{;;}. The @var{word} undergoes tilde expansion, parameter expansion, command substitution, arithmetic expansion, and quote removal before matching is attempted. Each @var{pattern} undergoes tilde expansion, parameter expansion, command substitution, and arithmetic expansion. There may be an arbitrary number of @code{case} clauses, each terminated by a @samp{;;}. The first pattern that matches determines the command-list that is executed. Here is an example using @code{case} in a script that could be used to describe one interesting feature of an animal: @example echo -n "Enter the name of an animal: " read ANIMAL echo -n "The $ANIMAL has " case $ANIMAL in horse | dog | cat) echo -n "four";; man | kangaroo ) echo -n "two";; *) echo -n "an unknown number of";; esac echo " legs." @end example @noindent The return status is zero if no @var{pattern} is matched. Otherwise, the return status is the exit status of the @var{command-list} executed. @item select @rwindex select The @code{select} construct allows the easy generation of menus. It has almost the same syntax as the @code{for} command: @example select @var{name} [in @var{words} @dots{}]; do @var{commands}; done @end example The list of words following @code{in} is expanded, generating a list of items. The set of expanded words is printed on the standard error output stream, each preceded by a number. If the @samp{in @var{words}} is omitted, the positional parameters are printed, as if @samp{in "$@@"} had been specifed. The @env{PS3} prompt is then displayed and a line is read from the standard input. If the line consists of a number corresponding to one of the displayed words, then the value of @var{name} is set to that word. If the line is empty, the words and prompt are displayed again. If @code{EOF} is read, the @code{select} command completes. Any other value read causes @var{name} to be set to null. The line read is saved in the variable @env{REPLY}. The @var{commands} are executed after each selection until a @code{break} command is executed, at which point the @code{select} command completes. Here is an example that allows the user to pick a filename from the current directory, and displays the name and index of the file selected. @example select fname in *; do echo you picked $fname \($REPLY\) break; done @end example @item ((@dots{})) @example (( @var{expression} )) @end example The arithmetic @var{expression} is evaluated according to the rules described below (@pxref{Shell Arithmetic}). If the value of the expression is non-zero, the return status is 0; otherwise the return status is 1. This is exactly equivalent to @example let "@var{expression}" @end example @noindent @xref{Bash Builtins}, for a full description of the @code{let} builtin. @item [[@dots{}]] @rwindex [[ @rwindex ]] @example [[ @var{expression} ]] @end example Return a status of 0 or 1 depending on the evaluation of the conditional expression @var{expression}. Expressions are composed of the primaries described below in @ref{Bash Conditional Expressions}. Word splitting and filename expansion are not performed on the words between the @samp{[[} and @samp{]]}; tilde expansion, parameter and variable expansion, arithmetic expansion, command substitution, process substitution, and quote removal are performed. When the @samp{==} and @samp{!=} operators are used, the string to the right of the operator is considered a pattern and matched according to the rules described below in @ref{Pattern Matching}. The return value is 0 if the string matches or does not match the pattern, respectively, and 1 otherwise. Any part of the pattern may be quoted to force it to be matched as a string. Expressions may be combined using the following operators, listed in decreasing order of precedence: @table @code @item ( @var{expression} ) Returns the value of @var{expression}. This may be used to override the normal precedence of operators. @item ! @var{expression} True if @var{expression} is false. @item @var{expression1} && @var{expression2} True if both @var{expression1} and @var{expression2} are true. @item @var{expression1} || @var{expression2} True if either @var{expression1} or @var{expression2} is true. @end table @noindent The @code{&&} and @code{||} commands do not execute @var{expression2} if the value of @var{expression1} is sufficient to determine the return value of the entire conditional expression. @end table @node Command Grouping @subsection Grouping Commands @cindex commands, grouping Bash provides two ways to group a list of commands to be executed as a unit. When commands are grouped, redirections may be applied to the entire command list. For example, the output of all the commands in the list may be redirected to a single stream. @table @code @item () @example ( @var{list} ) @end example Placing a list of commands between parentheses causes a subshell to be created, and each of the commands in @var{list} to be executed in that subshell. Since the @var{list} is executed in a subshell, variable assignments do not remain in effect after the subshell completes. @item @{@} @rwindex @{ @rwindex @} @example @{ @var{list}; @} @end example Placing a list of commands between curly braces causes the list to be executed in the current shell context. No subshell is created. The semicolon (or newline) following @var{list} is required. @end table In addition to the creation of a subshell, there is a subtle difference between these two constructs due to historical reasons. The braces are @code{reserved words}, so they must be separated from the @var{list} by @code{blank}s. The parentheses are @code{operators}, and are recognized as separate tokens by the shell even if they are not separated from the @var{list} by whitespace. The exit status of both of these constructs is the exit status of @var{list}. @node Shell Functions @section Shell Functions @cindex shell function @cindex functions, shell Shell functions are a way to group commands for later execution using a single name for the group. They are executed just like a "regular" command. When the name of a shell function is used as a simple command name, the list of commands associated with that function name is executed. Shell functions are executed in the current shell context; no new process is created to interpret them. Functions are declared using this syntax: @rwindex function @example [ @code{function} ] @var{name} () @{ @var{command-list}; @} @end example This defines a shell function named @var{name}. The reserved word @code{function} is optional. If the @code{function} reserved word is supplied, the parentheses are optional. The @var{body} of the function is the @var{command-list} between @{ and @}. This list is executed whenever @var{name} is specified as the name of a command. The exit status of a function is the exit status of the last command executed in the body. Note that for historical reasons, the curly braces that surround the body of the function must be separated from the body by @code{blank}s or newlines. This is because the braces are reserved words and are only recognized as such when they are separated by whitespace. Also, the @var{command-list} must be terminated with a semicolon or a newline. When a function is executed, the arguments to the function become the positional parameters during its execution (@pxref{Positional Parameters}). The special parameter @samp{#} that expands to the number of positional parameters is updated to reflect the change. Positional parameter @code{0} is unchanged. The @env{FUNCNAME} variable is set to the name of the function while the function is executing. If the builtin command @code{return} is executed in a function, the function completes and execution resumes with the next command after the function call. When a function completes, the values of the positional parameters and the special parameter @samp{#} are restored to the values they had prior to the function's execution. If a numeric argument is given to @code{return}, that is the function's return status; otherwise the function's return status is the exit status of the last command executed before the @code{return}. Variables local to the function may be declared with the @code{local} builtin. These variables are visible only to the function and the commands it invokes. Functions may be recursive. No limit is placed on the number of recursive calls. @node Shell Parameters @section Shell Parameters @cindex parameters @cindex variable, shell @cindex shell variable @menu * Positional Parameters:: The shell's command-line arguments. * Special Parameters:: Parameters with special meanings. @end menu A @var{parameter} is an entity that stores values. It can be a @code{name}, a number, or one of the special characters listed below. For the shell's purposes, a @var{variable} is a parameter denoted by a @code{name}. A variable has a @var{value} and zero or more @var{attributes}. Attributes are assigned using the @code{declare} builtin command (see the description of the @code{declare} builtin in @ref{Bash Builtins}). A parameter is set if it has been assigned a value. The null string is a valid value. Once a variable is set, it may be unset only by using the @code{unset} builtin command. A variable may be assigned to by a statement of the form @example @var{name}=[@var{value}] @end example @noindent If @var{value} is not given, the variable is assigned the null string. All @var{value}s undergo tilde expansion, parameter and variable expansion, command substitution, arithmetic expansion, and quote removal (detailed below). If the variable has its @code{integer} attribute set, then @var{value} is subject to arithmetic expansion even if the @code{$((@dots{}))} expansion is not used (@pxref{Arithmetic Expansion}). Word splitting is not performed, with the exception of @code{"$@@"} as explained below. Filename expansion is not performed. Assignment statements may also appear as arguments to the @code{declare}, @code{typeset}, @code{export}, @code{readonly}, and @code{local} builtin commands. @node Positional Parameters @subsection Positional Parameters @cindex parameters, positional A @var{positional parameter} is a parameter denoted by one or more digits, other than the single digit @code{0}. Positional parameters are assigned from the shell's arguments when it is invoked, and may be reassigned using the @code{set} builtin command. Positional parameter @code{N} may be referenced as @code{$@{N@}}, or as @code{$N} when @code{N} consists of a single digit. Positional parameters may not be assigned to with assignment statements. The @code{set} and @code{shift} builtins are used to set and unset them (@pxref{Shell Builtin Commands}). The positional parameters are temporarily replaced when a shell function is executed (@pxref{Shell Functions}). When a positional parameter consisting of more than a single digit is expanded, it must be enclosed in braces. @node Special Parameters @subsection Special Parameters @cindex parameters, special The shell treats several parameters specially. These parameters may only be referenced; assignment to them is not allowed. @vtable @code @item * Expands to the positional parameters, starting from one. When the expansion occurs within double quotes, it expands to a single word with the value of each parameter separated by the first character of the @env{IFS} special variable. That is, @code{"$*"} is equivalent to @code{"$1@var{c}$2@var{c}@dots{}"}, where @var{c} is the first character of the value of the @code{IFS} variable. If @env{IFS} is unset, the parameters are separated by spaces. If @env{IFS} is null, the parameters are joined without intervening separators. @item @@ Expands to the positional parameters, starting from one. When the expansion occurs within double quotes, each parameter expands to a separate word. That is, @code{"$@@"} is equivalent to @code{"$1" "$2" @dots{}}. When there are no positional parameters, @code{"$@@"} and @code{$@@} expand to nothing (i.e., they are removed). @item # Expands to the number of positional parameters in decimal. @item ? Expands to the exit status of the most recently executed foreground pipeline. @item - (A hyphen.) Expands to the current option flags as specified upon invocation, by the @code{set} builtin command, or those set by the shell itself (such as the @option{-i} option). @item $ Expands to the process @sc{id} of the shell. In a @code{()} subshell, it expands to the process @sc{id} of the invoking shell, not the subshell. @item ! Expands to the process @sc{id} of the most recently executed background (asynchronous) command. @item 0 Expands to the name of the shell or shell script. This is set at shell initialization. If Bash is invoked with a file of commands (@pxref{Shell Scripts}), @code{$0} is set to the name of that file. If Bash is started with the @option{-c} option (@pxref{Invoking Bash}), then @code{$0} is set to the first argument after the string to be executed, if one is present. Otherwise, it is set to the filename used to invoke Bash, as given by argument zero. @item _ (An underscore.) At shell startup, set to the absolute filename of the shell or shell script being executed as passed in the argument list. Subsequently, expands to the last argument to the previous command, after expansion. Also set to the full pathname of each command executed and placed in the environment exported to that command. When checking mail, this parameter holds the name of the mail file. @end vtable @node Shell Expansions @section Shell Expansions @cindex expansion Expansion is performed on the command line after it has been split into @code{token}s. There are seven kinds of expansion performed: @itemize @bullet @item brace expansion @item tilde expansion @item parameter and variable expansion @item command substitution @item arithmetic expansion @item word splitting @item filename expansion @end itemize @menu * Brace Expansion:: Expansion of expressions within braces. * Tilde Expansion:: Expansion of the ~ character. * Shell Parameter Expansion:: How Bash expands variables to their values. * Command Substitution:: Using the output of a command as an argument. * Arithmetic Expansion:: How to use arithmetic in shell expansions. * Process Substitution:: A way to write and read to and from a command. * Word Splitting:: How the results of expansion are split into separate arguments. * Filename Expansion:: A shorthand for specifying filenames matching patterns. * Quote Removal:: How and when quote characters are removed from words. @end menu The order of expansions is: brace expansion, tilde expansion, parameter, variable, and arithmetic expansion and command substitution (done in a left-to-right fashion), word splitting, and filename expansion. On systems that can support it, there is an additional expansion available: @var{process substitution}. This is performed at the same time as parameter, variable, and arithmetic expansion and command substitution. Only brace expansion, word splitting, and filename expansion can change the number of words of the expansion; other expansions expand a single word to a single word. The only exceptions to this are the expansions of @code{"$@@"} (@pxref{Special Parameters}) and @code{"$@{@var{name}[@@]@}"} (@pxref{Arrays}). After all expansions, @code{quote removal} (@pxref{Quote Removal}) is performed. @node Brace Expansion @subsection Brace Expansion @cindex brace expansion @cindex expansion, brace Brace expansion is a mechanism by which arbitrary strings may be generated. This mechanism is similar to @var{filename expansion} (@pxref{Filename Expansion}), but the file names generated need not exist. Patterns to be brace expanded take the form of an optional @var{preamble}, followed by a series of comma-separated strings between a pair of braces, followed by an optional @var{postscript}. The preamble is prefixed to each string contained within the braces, and the postscript is then appended to each resulting string, expanding left to right. Brace expansions may be nested. The results of each expanded string are not sorted; left to right order is preserved. For example, @example bash$ echo a@{d,c,b@}e ade ace abe @end example Brace expansion is performed before any other expansions, and any characters special to other expansions are preserved in the result. It is strictly textual. Bash does not apply any syntactic interpretation to the context of the expansion or the text between the braces. To avoid conflicts with parameter expansion, the string @samp{$@{} is not considered eligible for brace expansion. A correctly-formed brace expansion must contain unquoted opening and closing braces, and at least one unquoted comma. Any incorrectly formed brace expansion is left unchanged. This construct is typically used as shorthand when the common prefix of the strings to be generated is longer than in the above example: @example mkdir /usr/local/src/bash/@{old,new,dist,bugs@} @end example or @example chown root /usr/@{ucb/@{ex,edit@},lib/@{ex?.?*,how_ex@}@} @end example @node Tilde Expansion @subsection Tilde Expansion @cindex tilde expansion @cindex expansion, tilde If a word begins with an unquoted tilde character (@samp{~}), all of the characters up to the first unquoted slash (or all characters, if there is no unquoted slash) are considered a @var{tilde-prefix}. If none of the characters in the tilde-prefix are quoted, the characters in the tilde-prefix following the tilde are treated as a possible @var{login name}. If this login name is the null string, the tilde is replaced with the value of the @env{HOME} shell variable. If @env{HOME} is unset, the home directory of the user executing the shell is substituted instead. Otherwise, the tilde-prefix is replaced with the home directory associated with the specified login name. If the tilde-prefix is @samp{~+}, the value of the shell variable @env{PWD} replaces the tilde-prefix. If the tilde-prefix is @samp{~-}, the value of the shell variable @env{OLDPWD}, if it is set, is substituted. If the characters following the tilde in the tilde-prefix consist of a number @var{N}, optionally prefixed by a @samp{+} or a @samp{-}, the tilde-prefix is replaced with the corresponding element from the directory stack, as it would be displayed by the @code{dirs} builtin invoked with the characters following tilde in the tilde-prefix as an argument (@pxref{The Directory Stack}). If the tilde-prefix, sans the tilde, consists of a number without a leading @samp{+} or @samp{-}, @samp{+} is assumed. If the login name is invalid, or the tilde expansion fails, the word is left unchanged. Each variable assignment is checked for unquoted tilde-prefixes immediately following a @samp{:} or @samp{=}. In these cases, tilde expansion is also performed. Consequently, one may use file names with tildes in assignments to @env{PATH}, @env{MAILPATH}, and @env{CDPATH}, and the shell assigns the expanded value. The following table shows how Bash treats unquoted tilde-prefixes: @table @code @item ~ The value of @code{$HOME} @item ~/foo @file{$HOME/foo} @item ~fred/foo The subdirectory @code{foo} of the home directory of the user @code{fred} @item ~+/foo @file{$PWD/foo} @item ~-/foo @file{$@{OLDPWD-'~-'@}/foo} @item ~@var{N} The string that would be displayed by @samp{dirs +@var{N}} @item ~+@var{N} The string that would be displayed by @samp{dirs +@var{N}} @item ~-@var{N} The string that would be displayed by @samp{dirs -@var{N}} @end table @node Shell Parameter Expansion @subsection Shell Parameter Expansion @cindex parameter expansion @cindex expansion, parameter The @samp{$} character introduces parameter expansion, command substitution, or arithmetic expansion. The parameter name or symbol to be expanded may be enclosed in braces, which are optional but serve to protect the variable to be expanded from characters immediately following it which could be interpreted as part of the name. When braces are used, the matching ending brace is the first @samp{@}} not escaped by a backslash or within a quoted string, and not within an embedded arithmetic expansion, command substitution, or parameter expansion. The basic form of parameter expansion is $@{@var{parameter}@}. The value of @var{parameter} is substituted. The braces are required when @var{parameter} is a positional parameter with more than one digit, or when @var{parameter} is followed by a character that is not to be interpreted as part of its name. If the first character of @var{parameter} is an exclamation point, a level of variable indirection is introduced. Bash uses the value of the variable formed from the rest of @var{parameter} as the name of the variable; this variable is then expanded and that value is used in the rest of the substitution, rather than the value of @var{parameter} itself. This is known as @code{indirect expansion}. The exception to this is the expansion of $@{!@var{prefix*@}} described below. In each of the cases below, @var{word} is subject to tilde expansion, parameter expansion, command substitution, and arithmetic expansion. When not performing substring expansion, Bash tests for a parameter that is unset or null; omitting the colon results in a test only for a parameter that is unset. Put another way, if the colon is included, the operator tests for both existence and that the value is not null; if the colon is omitted, the operator tests only for existence. @table @code @item $@{@var{parameter}:@minus{}@var{word}@} If @var{parameter} is unset or null, the expansion of @var{word} is substituted. Otherwise, the value of @var{parameter} is substituted. @item $@{@var{parameter}:=@var{word}@} If @var{parameter} is unset or null, the expansion of @var{word} is assigned to @var{parameter}. The value of @var{parameter} is then substituted. Positional parameters and special parameters may not be assigned to in this way. @item $@{@var{parameter}:?@var{word}@} If @var{parameter} is null or unset, the expansion of @var{word} (or a message to that effect if @var{word} is not present) is written to the standard error and the shell, if it is not interactive, exits. Otherwise, the value of @var{parameter} is substituted. @item $@{@var{parameter}:+@var{word}@} If @var{parameter} is null or unset, nothing is substituted, otherwise the expansion of @var{word} is substituted. @item $@{@var{parameter}:@var{offset}@} @itemx $@{@var{parameter}:@var{offset}:@var{length}@} Expands to up to @var{length} characters of @var{parameter} starting at the character specified by @var{offset}. If @var{length} is omitted, expands to the substring of @var{parameter} starting at the character specified by @var{offset}. @var{length} and @var{offset} are arithmetic expressions (@pxref{Shell Arithmetic}). This is referred to as Substring Expansion. @var{length} must evaluate to a number greater than or equal to zero. If @var{offset} evaluates to a number less than zero, the value is used as an offset from the end of the value of @var{parameter}. If @var{parameter} is @samp{@@}, the result is @var{length} positional parameters beginning at @var{offset}. If @var{parameter} is an array name indexed by @samp{@@} or @samp{*}, the result is the @var{length} members of the array beginning with @code{$@{@var{parameter}[@var{offset}]@}}. Substring indexing is zero-based unless the positional parameters are used, in which case the indexing starts at 1. @item $@{!@var{prefix}*@} Expands to the names of variables whose names begin with @var{prefix}, separated by the first character of the @env{IFS} special variable. @item $@{#@var{parameter}@} The length in characters of the expanded value of @var{parameter} is substituted. If @var{parameter} is @samp{*} or @samp{@@}, the value substituted is the number of positional parameters. If @var{parameter} is an array name subscripted by @samp{*} or @samp{@@}, the value substituted is the number of elements in the array. @item $@{@var{parameter}#@var{word}@} @itemx $@{@var{parameter}##@var{word}@} The @var{word} is expanded to produce a pattern just as in filename expansion (@pxref{Filename Expansion}). If the pattern matches the beginning of the expanded value of @var{parameter}, then the result of the expansion is the expanded value of @var{parameter} with the shortest matching pattern (the @samp{#} case) or the longest matching pattern (the @samp{##} case) deleted. If @var{parameter} is @samp{@@} or @samp{*}, the pattern removal operation is applied to each positional parameter in turn, and the expansion is the resultant list. If @var{parameter} is an array variable subscripted with @samp{@@} or @samp{*}, the pattern removal operation is applied to each member of the array in turn, and the expansion is the resultant list. @item $@{@var{parameter}%@var{word}@} @itemx $@{@var{parameter}%%@var{word}@} The @var{word} is expanded to produce a pattern just as in filename expansion. If the pattern matches a trailing portion of the expanded value of @var{parameter}, then the result of the expansion is the value of @var{parameter} with the shortest matching pattern (the @samp{%} case) or the longest matching pattern (the @samp{%%} case) deleted. If @var{parameter} is @samp{@@} or @samp{*}, the pattern removal operation is applied to each positional parameter in turn, and the expansion is the resultant list. If @var{parameter} is an array variable subscripted with @samp{@@} or @samp{*}, the pattern removal operation is applied to each member of the array in turn, and the expansion is the resultant list. @item $@{@var{parameter}/@var{pattern}/@var{string}@} @itemx $@{@var{parameter}//@var{pattern}/@var{string}@} The @var{pattern} is expanded to produce a pattern just as in filename expansion. @var{Parameter} is expanded and the longest match of @var{pattern} against its value is replaced with @var{string}. In the first form, only the first match is replaced. The second form causes all matches of @var{pattern} to be replaced with @var{string}. If @var{pattern} begins with @samp{#}, it must match at the beginning of the expanded value of @var{parameter}. If @var{pattern} begins with @samp{%}, it must match at the end of the expanded value of @var{parameter}. If @var{string} is null, matches of @var{pattern} are deleted and the @code{/} following @var{pattern} may be omitted. If @var{parameter} is @samp{@@} or @samp{*}, the substitution operation is applied to each positional parameter in turn, and the expansion is the resultant list. If @var{parameter} is an array variable subscripted with @samp{@@} or @samp{*}, the substitution operation is applied to each member of the array in turn, and the expansion is the resultant list. @end table @node Command Substitution @subsection Command Substitution @cindex command substitution Command substitution allows the output of a command to replace the command itself. Command substitution occurs when a command is enclosed as follows: @example $(@var{command}) @end example @noindent or @example `@var{command}` @end example @noindent Bash performs the expansion by executing @var{command} and replacing the command substitution with the standard output of the command, with any trailing newlines deleted. Embedded newlines are not deleted, but they may be removed during word splitting. The command substitution @code{$(cat @var{file})} can be replaced by the equivalent but faster @code{$(< @var{file})}. When the old-style backquote form of substitution is used, backslash retains its literal meaning except when followed by @samp{$}, @samp{`}, or @samp{\}. The first backquote not preceded by a backslash terminates the command substitution. When using the @code{$(@var{command})} form, all characters between the parentheses make up the command; none are treated specially. Command substitutions may be nested. To nest when using the backquoted form, escape the inner backquotes with backslashes. If the substitution appears within double quotes, word splitting and filename expansion are not performed on the results. @node Arithmetic Expansion @subsection Arithmetic Expansion @cindex expansion, arithmetic @cindex arithmetic expansion Arithmetic expansion allows the evaluation of an arithmetic expression and the substitution of the result. The format for arithmetic expansion is: @example $(( @var{expression} )) @end example The expression is treated as if it were within double quotes, but a double quote inside the parentheses is not treated specially. All tokens in the expression undergo parameter expansion, command substitution, and quote removal. Arithmetic substitutions may be nested. The evaluation is performed according to the rules listed below (@pxref{Shell Arithmetic}). If the expression is invalid, Bash prints a message indicating failure to the standard error and no substitution occurs. @node Process Substitution @subsection Process Substitution @cindex process substitution Process substitution is supported on systems that support named pipes (@sc{fifo}s) or the @file{/dev/fd} method of naming open files. It takes the form of @example <(@var{list}) @end example @noindent or @example >(@var{list}) @end example @noindent The process @var{list} is run with its input or output connected to a @sc{fifo} or some file in @file{/dev/fd}. The name of this file is passed as an argument to the current command as the result of the expansion. If the @code{>(@var{list})} form is used, writing to the file will provide input for @var{list}. If the @code{<(@var{list})} form is used, the file passed as an argument should be read to obtain the output of @var{list}. Note that no space may appear between the @code{<} or @code{>} and the left parenthesis, otherwise the construct would be interpreted as a redirection. When available, process substitution is performed simultaneously with parameter and variable expansion, command substitution, and arithmetic expansion. @node Word Splitting @subsection Word Splitting @cindex word splitting The shell scans the results of parameter expansion, command substitution, and arithmetic expansion that did not occur within double quotes for word splitting. The shell treats each character of @env{$IFS} as a delimiter, and splits the results of the other expansions into words on these characters. If @env{IFS} is unset, or its value is exactly @code{}, the default, then any sequence of @env{IFS} characters serves to delimit words. If @env{IFS} has a value other than the default, then sequences of the whitespace characters @code{space} and @code{tab} are ignored at the beginning and end of the word, as long as the whitespace character is in the value of @env{IFS} (an @env{IFS} whitespace character). Any character in @env{IFS} that is not @env{IFS} whitespace, along with any adjacent @env{IFS} whitespace characters, delimits a field. A sequence of @env{IFS} whitespace characters is also treated as a delimiter. If the value of @env{IFS} is null, no word splitting occurs. Explicit null arguments (@code{""} or @code{''}) are retained. Unquoted implicit null arguments, resulting from the expansion of parameters that have no values, are removed. If a parameter with no value is expanded within double quotes, a null argument results and is retained. Note that if no expansion occurs, no splitting is performed. @node Filename Expansion @subsection Filename Expansion @menu * Pattern Matching:: How the shell matches patterns. @end menu @cindex expansion, filename @cindex expansion, pathname @cindex filename expansion @cindex pathname expansion After word splitting, unless the @option{-f} option has been set (@pxref{The Set Builtin}), Bash scans each word for the characters @samp{*}, @samp{?}, and @samp{[}. If one of these characters appears, then the word is regarded as a @var{pattern}, and replaced with an alphabetically sorted list of file names matching the pattern. If no matching file names are found, and the shell option @code{nullglob} is disabled, the word is left unchanged. If the @code{nullglob} option is set, and no matches are found, the word is removed. If the shell option @code{nocaseglob} is enabled, the match is performed without regard to the case of alphabetic characters. When a pattern is used for filename generation, the character @samp{.} at the start of a filename or immediately following a slash must be matched explicitly, unless the shell option @code{dotglob} is set. When matching a file name, the slash character must always be matched explicitly. In other cases, the @samp{.} character is not treated specially. See the description of @code{shopt} in @ref{Bash Builtins}, for a description of the @code{nocaseglob}, @code{nullglob}, and @code{dotglob} options. The @env{GLOBIGNORE} shell variable may be used to restrict the set of filenames matching a pattern. If @env{GLOBIGNORE} is set, each matching filename that also matches one of the patterns in @env{GLOBIGNORE} is removed from the list of matches. The filenames @file{.} and @file{..} are always ignored, even when @env{GLOBIGNORE} is set. However, setting @env{GLOBIGNORE} has the effect of enabling the @code{dotglob} shell option, so all other filenames beginning with a @samp{.} will match. To get the old behavior of ignoring filenames beginning with a @samp{.}, make @samp{.*} one of the patterns in @env{GLOBIGNORE}. The @code{dotglob} option is disabled when @env{GLOBIGNORE} is unset. @node Pattern Matching @subsubsection Pattern Matching @cindex pattern matching @cindex matching, pattern Any character that appears in a pattern, other than the special pattern characters described below, matches itself. The @sc{nul} character may not occur in a pattern. The special pattern characters must be quoted if they are to be matched literally. The special pattern characters have the following meanings: @table @code @item * Matches any string, including the null string. @item ? Matches any single character. @item [@dots{}] Matches any one of the enclosed characters. A pair of characters separated by a hyphen denotes a @var{range expression}; any character that sorts between those two characters, inclusive, using the current locale's collating sequence and character set, is matched. If the first character following the @samp{[} is a @samp{!} or a @samp{^} then any character not enclosed is matched. A @samp{@minus{}} may be matched by including it as the first or last character in the set. A @samp{]} may be matched by including it as the first character in the set. The sorting order of characters in range expressions is determined by the current locale and the value of the @env{LC_COLLATE} shell variable, if set. For example, in the default C locale, @samp{[a-dx-z]} is equivalent to @samp{[abcdxyz]}. Many locales sort characters in dictionary order, and in these locales @samp{[a-dx-z]} is typically not equivalent to @samp{[abcdxyz]}; it might be equivalent to @samp{[aBbCcDdxXyYz]}, for example. To obtain the traditional interpretation of ranges in bracket expressions, you can force the use of the C locale by setting the @env{LC_COLLATE} or @env{LC_ALL} environment variable to the value @samp{C}. Within @samp{[} and @samp{]}, @var{character classes} can be specified using the syntax @code{[:}@var{class}@code{:]}, where @var{class} is one of the following classes defined in the @sc{posix} 1003.2 standard: @example alnum alpha ascii blank cntrl digit graph lower print punct space upper xdigit @end example @noindent A character class matches any character belonging to that class. Within @samp{[} and @samp{]}, an @var{equivalence class} can be specified using the syntax @code{[=}@var{c}@code{=]}, which matches all characters with the same collation weight (as defined by the current locale) as the character @var{c}. Within @samp{[} and @samp{]}, the syntax @code{[.}@var{symbol}@code{.]} matches the collating symbol @var{symbol}. @end table If the @code{extglob} shell option is enabled using the @code{shopt} builtin, several extended pattern matching operators are recognized. In the following description, a @var{pattern-list} is a list of one or more patterns separated by a @samp{|}. Composite patterns may be formed using one or more of the following sub-patterns: @table @code @item ?(@var{pattern-list}) Matches zero or one occurrence of the given patterns. @item *(@var{pattern-list}) Matches zero or more occurrences of the given patterns. @item +(@var{pattern-list}) Matches one or more occurrences of the given patterns. @item @@(@var{pattern-list}) Matches exactly one of the given patterns. @item !(@var{pattern-list}) Matches anything except one of the given patterns. @end table @node Quote Removal @subsection Quote Removal After the preceding expansions, all unquoted occurrences of the characters @samp{\}, @samp{'}, and @samp{"} that did not result from one of the above expansions are removed. @node Redirections @section Redirections @cindex redirection Before a command is executed, its input and output may be @var{redirected} using a special notation interpreted by the shell. Redirection may also be used to open and close files for the current shell execution environment. The following redirection operators may precede or appear anywhere within a simple command or may follow a command. Redirections are processed in the order they appear, from left to right. In the following descriptions, if the file descriptor number is omitted, and the first character of the redirection operator is @samp{<}, the redirection refers to the standard input (file descriptor 0). If the first character of the redirection operator is @samp{>}, the redirection refers to the standard output (file descriptor 1). The word following the redirection operator in the following descriptions, unless otherwise noted, is subjected to brace expansion, tilde expansion, parameter expansion, command substitution, arithmetic expansion, quote removal, filename expansion, and word splitting. If it expands to more than one word, Bash reports an error. Note that the order of redirections is significant. For example, the command @example ls > @var{dirlist} 2>&1 @end example @noindent directs both standard output (file descriptor 1) and standard error (file descriptor 2) to the file @var{dirlist}, while the command @example ls 2>&1 > @var{dirlist} @end example @noindent directs only the standard output to file @var{dirlist}, because the standard error was duplicated as standard output before the standard output was redirected to @var{dirlist}. Bash handles several filenames specially when they are used in redirections, as described in the following table: @table @code @item /dev/fd/@var{fd} If @var{fd} is a valid integer, file descriptor @var{fd} is duplicated. @item /dev/stdin File descriptor 0 is duplicated. @item /dev/stdout File descriptor 1 is duplicated. @item /dev/stderr File descriptor 2 is duplicated. @item /dev/tcp/@var{host}/@var{port} If @var{host} is a valid hostname or Internet address, and @var{port} is an integer port number or service name, Bash attempts to open a TCP connection to the corresponding socket. @item /dev/udp/@var{host}/@var{port} If @var{host} is a valid hostname or Internet address, and @var{port} is an integer port number or service name, Bash attempts to open a UDP connection to the corresponding socket. @end table A failure to open or create a file causes the redirection to fail. @subsection Redirecting Input Redirection of input causes the file whose name results from the expansion of @var{word} to be opened for reading on file descriptor @code{n}, or the standard input (file descriptor 0) if @code{n} is not specified. The general format for redirecting input is: @example [n]<@var{word} @end example @subsection Redirecting Output Redirection of output causes the file whose name results from the expansion of @var{word} to be opened for writing on file descriptor @code{n}, or the standard output (file descriptor 1) if @code{n} is not specified. If the file does not exist it is created; if it does exist it is truncated to zero size. The general format for redirecting output is: @example [n]>[|]@var{word} @end example If the redirection operator is @samp{>}, and the @code{noclobber} option to the @code{set} builtin has been enabled, the redirection will fail if the file whose name results from the expansion of @var{word} exists and is a regular file. If the redirection operator is @samp{>|}, or the redirection operator is @samp{>} and the @code{noclobber} option is not enabled, the redirection is attempted even if the file named by @var{word} exists. @subsection Appending Redirected Output Redirection of output in this fashion causes the file whose name results from the expansion of @var{word} to be opened for appending on file descriptor @code{n}, or the standard output (file descriptor 1) if @code{n} is not specified. If the file does not exist it is created. The general format for appending output is: @example [n]>>@var{word} @end example @subsection Redirecting Standard Output and Standard Error Bash allows both the standard output (file descriptor 1) and the standard error output (file descriptor 2) to be redirected to the file whose name is the expansion of @var{word} with this construct. There are two formats for redirecting standard output and standard error: @example &>@var{word} @end example @noindent and @example >&@var{word} @end example @noindent Of the two forms, the first is preferred. This is semantically equivalent to @example >@var{word} 2>&1 @end example @subsection Here Documents This type of redirection instructs the shell to read input from the current source until a line containing only @var{word} (with no trailing blanks) is seen. All of the lines read up to that point are then used as the standard input for a command. The format of here-documents is as follows: @example <<[@minus{}]@var{word} @var{here-document} @var{delimiter} @end example No parameter expansion, command substitution, arithmetic expansion, or filename expansion is performed on @var{word}. If any characters in @var{word} are quoted, the @var{delimiter} is the result of quote removal on @var{word}, and the lines in the here-document are not expanded. If @var{word} is unquoted, all lines of the here-document are subjected to parameter expansion, command substitution, and arithmetic expansion. In the latter case, the character sequence @code{\newline} is ignored, and @samp{\} must be used to quote the characters @samp{\}, @samp{$}, and @samp{`}. If the redirection operator is @samp{<<-}, then all leading tab characters are stripped from input lines and the line containing @var{delimiter}. This allows here-documents within shell scripts to be indented in a natural fashion. @subsection Duplicating File Descriptors The redirection operator @example [n]<&@var{word} @end example @noindent is used to duplicate input file descriptors. If @var{word} expands to one or more digits, the file descriptor denoted by @code{n} is made to be a copy of that file descriptor. If the digits in @var{word} do not specify a file descriptor open for input, a redirection error occurs. If @var{word} evaluates to @samp{-}, file descriptor @code{n} is closed. If @code{n} is not specified, the standard input (file descriptor 0) is used. The operator @example [n]>&@var{word} @end example @noindent is used similarly to duplicate output file descriptors. If @code{n} is not specified, the standard output (file descriptor 1) is used. If the digits in @var{word} do not specify a file descriptor open for output, a redirection error occurs. As a special case, if @code{n} is omitted, and @var{word} does not expand to one or more digits, the standard output and standard error are redirected as described previously. @subsection Opening File Descriptors for Reading and Writing The redirection operator @example [n]<>@var{word} @end example @noindent causes the file whose name is the expansion of @var{word} to be opened for both reading and writing on file descriptor @code{n}, or on file descriptor 0 if @code{n} is not specified. If the file does not exist, it is created. @node Executing Commands @section Executing Commands @menu * Simple Command Expansion:: How Bash expands simple commands before executing them. * Command Search and Execution:: How Bash finds commands and runs them. * Command Execution Environment:: The environment in which Bash executes commands that are not shell builtins. * Environment:: The environment given to a command. * Exit Status:: The status returned by commands and how Bash interprets it. * Signals:: What happens when Bash or a command it runs receives a signal. @end menu @node Simple Command Expansion @subsection Simple Command Expansion @cindex command expansion When a simple command is executed, the shell performs the following expansions, assignments, and redirections, from left to right. @enumerate @item The words that the parser has marked as variable assignments (those preceding the command name) and redirections are saved for later processing. @item The words that are not variable assignments or redirections are expanded (@pxref{Shell Expansions}). If any words remain after expansion, the first word is taken to be the name of the command and the remaining words are the arguments. @item Redirections are performed as described above (@pxref{Redirections}). @item The text after the @samp{=} in each variable assignment undergoes tilde expansion, parameter expansion, command substitution, arithmetic expansion, and quote removal before being assigned to the variable. @end enumerate If no command name results, the variable assignments affect the current shell environment. Otherwise, the variables are added to the environment of the executed command and do not affect the current shell environment. If any of the assignments attempts to assign a value to a readonly variable, an error occurs, and the command exits with a non-zero status. If no command name results, redirections are performed, but do not affect the current shell environment. A redirection error causes the command to exit with a non-zero status. If there is a command name left after expansion, execution proceeds as described below. Otherwise, the command exits. If one of the expansions contained a command substitution, the exit status of the command is the exit status of the last command substitution performed. If there were no command substitutions, the command exits with a status of zero. @node Command Search and Execution @subsection Command Search and Execution @cindex command execution @cindex command search After a command has been split into words, if it results in a simple command and an optional list of arguments, the following actions are taken. @enumerate @item If the command name contains no slashes, the shell attempts to locate it. If there exists a shell function by that name, that function is invoked as described in @ref{Shell Functions}. @item If the name does not match a function, the shell searches for it in the list of shell builtins. If a match is found, that builtin is invoked. @item If the name is neither a shell function nor a builtin, and contains no slashes, Bash searches each element of @env{$PATH} for a directory containing an executable file by that name. Bash uses a hash table to remember the full pathnames of executable files to avoid multiple @env{PATH} searches (see the description of @code{hash} in @ref{Bourne Shell Builtins}). A full search of the directories in @env{$PATH} is performed only if the command is not found in the hash table. If the search is unsuccessful, the shell prints an error message and returns an exit status of 127. @item If the search is successful, or if the command name contains one or more slashes, the shell executes the named program in a separate execution environment. Argument 0 is set to the name given, and the remaining arguments to the command are set to the arguments supplied, if any. @item If this execution fails because the file is not in executable format, and the file is not a directory, it is assumed to be a @var{shell script} and the shell executes it as described in @ref{Shell Scripts}. @item If the command was not begun asynchronously, the shell waits for the command to complete and collects its exit status. @end enumerate @node Command Execution Environment @subsection Command Execution Environment @cindex execution environment The shell has an @var{execution environment}, which consists of the following: @itemize @bullet @item open files inherited by the shell at invocation, as modified by redirections supplied to the @code{exec} builtin @item the current working directory as set by @code{cd}, @code{pushd}, or @code{popd}, or inherited by the shell at invocation @item the file creation mode mask as set by @code{umask} or inherited from the shell's parent @item current traps set by @code{trap} @item shell parameters that are set by variable assignment or with @code{set} or inherited from the shell's parent in the environment @item shell functions defined during execution or inherited from the shell's parent in the environment @item options enabled at invocation (either by default or with command-line arguments) or by @code{set} @item options enabled by @code{shopt} @item shell aliases defined with @code{alias} (@pxref{Aliases}) @item various process @sc{id}s, including those of background jobs (@pxref{Lists}), the value of @code{$$}, and the value of @env{$PPID} @end itemize When a simple command other than a builtin or shell function is to be executed, it is invoked in a separate execution environment that consists of the following. Unless otherwise noted, the values are inherited from the shell. @itemize @bullet @item the shell's open files, plus any modifications and additions specified by redirections to the command @item the current working directory @item the file creation mode mask @item shell variables marked for export, along with variables exported for the command, passed in the environment (@pxref{Environment}) @item traps caught by the shell are reset to the values inherited from the shell's parent, and traps ignored by the shell are ignored @end itemize A command invoked in this separate environment cannot affect the shell's execution environment. Command substitution and asynchronous commands are invoked in a subshell environment that is a duplicate of the shell environment, except that traps caught by the shell are reset to the values that the shell inherited from its parent at invocation. Builtin commands that are invoked as part of a pipeline are also executed in a subshell environment. Changes made to the subshell environment cannot affect the shell's execution environment. If a command is followed by a @samp{&} and job control is not active, the default standard input for the command is the empty file @file{/dev/null}. Otherwise, the invoked command inherits the file descriptors of the calling shell as modified by redirections. @node Environment @subsection Environment @cindex environment When a program is invoked it is given an array of strings called the @var{environment}. This is a list of name-value pairs, of the form @code{name=value}. Bash provides several ways to manipulate the environment. On invocation, the shell scans its own environment and creates a parameter for each name found, automatically marking it for @var{export} to child processes. Executed commands inherit the environment. The @code{export} and @samp{declare -x} commands allow parameters and functions to be added to and deleted from the environment. If the value of a parameter in the environment is modified, the new value becomes part of the environment, replacing the old. The environment inherited by any executed command consists of the shell's initial environment, whose values may be modified in the shell, less any pairs removed by the @code{unset} and @samp{export -n} commands, plus any additions via the @code{export} and @samp{declare -x} commands. The environment for any simple command or function may be augmented temporarily by prefixing it with parameter assignments, as described in @ref{Shell Parameters}. These assignment statements affect only the environment seen by that command. If the @option{-k} option is set (@pxref{The Set Builtin}), then all parameter assignments are placed in the environment for a command, not just those that precede the command name. When Bash invokes an external command, the variable @samp{$_} is set to the full path name of the command and passed to that command in its environment. @node Exit Status @subsection Exit Status @cindex exit status For the shell's purposes, a command which exits with a zero exit status has succeeded. A non-zero exit status indicates failure. This seemingly counter-intuitive scheme is used so there is one well-defined way to indicate success and a variety of ways to indicate various failure modes. When a command terminates on a fatal signal whose number is @var{N}, Bash uses the value 128+@var{N} as the exit status. If a command is not found, the child process created to execute it returns a status of 127. If a command is found but is not executable, the return status is 126. If a command fails because of an error during expansion or redirection, the exit status is greater than zero. The exit status is used by the Bash conditional commands (@pxref{Conditional Constructs}) and some of the list constructs (@pxref{Lists}). All of the Bash builtins return an exit status of zero if they succeed and a non-zero status on failure, so they may be used by the conditional and list constructs. All builtins return an exit status of 2 to indicate incorrect usage. @node Signals @subsection Signals @cindex signal handling When Bash is interactive, in the absence of any traps, it ignores @code{SIGTERM} (so that @samp{kill 0} does not kill an interactive shell), and @code{SIGINT} is caught and handled (so that the @code{wait} builtin is interruptible). When Bash receives a @code{SIGINT}, it breaks out of any executing loops. In all cases, Bash ignores @code{SIGQUIT}. If job control is in effect (@pxref{Job Control}), Bash ignores @code{SIGTTIN}, @code{SIGTTOU}, and @code{SIGTSTP}. Commands started by Bash have signal handlers set to the values inherited by the shell from its parent. When job control is not in effect, asynchronous commands ignore @code{SIGINT} and @code{SIGQUIT} as well. Commands run as a result of command substitution ignore the keyboard-generated job control signals @code{SIGTTIN}, @code{SIGTTOU}, and @code{SIGTSTP}. The shell exits by default upon receipt of a @code{SIGHUP}. Before exiting, an interactive shell resends the @code{SIGHUP} to all jobs, running or stopped. Stopped jobs are sent @code{SIGCONT} to ensure that they receive the @code{SIGHUP}. To prevent the shell from sending the @code{SIGHUP} signal to a particular job, it should be removed from the jobs table with the @code{disown} builtin (@pxref{Job Control Builtins}) or marked to not receive @code{SIGHUP} using @code{disown -h}. If the @code{huponexit} shell option has been set with @code{shopt} (@pxref{Bash Builtins}), Bash sends a @code{SIGHUP} to all jobs when an interactive login shell exits. When Bash receives a signal for which a trap has been set while waiting for a command to complete, the trap will not be executed until the command completes. When Bash is waiting for an asynchronous command via the @code{wait} builtin, the reception of a signal for which a trap has been set will cause the @code{wait} builtin to return immediately with an exit status greater than 128, immediately after which the trap is executed. @node Shell Scripts @section Shell Scripts @cindex shell script A shell script is a text file containing shell commands. When such a file is used as the first non-option argument when invoking Bash, and neither the @option{-c} nor @option{-s} option is supplied (@pxref{Invoking Bash}), Bash reads and executes commands from the file, then exits. This mode of operation creates a non-interactive shell. The shell first searches for the file in the current directory, and looks in the directories in @env{$PATH} if not found there. When Bash runs a shell script, it sets the special parameter @code{0} to the name of the file, rather than the name of the shell, and the positional parameters are set to the remaining arguments, if any are given. If no additional arguments are supplied, the positional parameters are unset. A shell script may be made executable by using the @code{chmod} command to turn on the execute bit. When Bash finds such a file while searching the @env{$PATH} for a command, it spawns a subshell to execute it. In other words, executing @example filename @var{arguments} @end example @noindent is equivalent to executing @example bash filename @var{arguments} @end example @noindent if @code{filename} is an executable shell script. This subshell reinitializes itself, so that the effect is as if a new shell had been invoked to interpret the script, with the exception that the locations of commands remembered by the parent (see the description of @code{hash} in @ref{Bourne Shell Builtins}) are retained by the child. Most versions of Unix make this a part of the operating system's command execution mechanism. If the first line of a script begins with the two characters @samp{#!}, the remainder of the line specifies an interpreter for the program. Thus, you can specify Bash, @code{awk}, Perl, or some other interpreter and write the rest of the script file in that language. The arguments to the interpreter consist of a single optional argument following the interpreter name on the first line of the script file, followed by the name of the script file, followed by the rest of the arguments. Bash will perform this action on operating systems that do not handle it themselves. Note that some older versions of Unix limit the interpreter name and argument to a maximum of 32 characters. Bash scripts often begin with @code{#! /bin/bash} (assuming that Bash has been installed in @file{/bin}), since this ensures that Bash will be used to interpret the script, even if it is executed under another shell. @node Shell Builtin Commands @chapter Shell Builtin Commands @menu * Bourne Shell Builtins:: Builtin commands inherited from the Bourne Shell. * Bash Builtins:: Table of builtins specific to Bash. * The Set Builtin:: This builtin is so overloaded it deserves its own section. * Special Builtins:: Builtin commands classified specially by POSIX.2. @end menu Builtin commands are contained within the shell itself. When the name of a builtin command is used as the first word of a simple command (@pxref{Simple Commands}), the shell executes the command directly, without invoking another program. Builtin commands are necessary to implement functionality impossible or inconvenient to obtain with separate utilities. This section briefly the builtins which Bash inherits from the Bourne Shell, as well as the builtin commands which are unique to or have been extended in Bash. Several builtin commands are described in other chapters: builtin commands which provide the Bash interface to the job control facilities (@pxref{Job Control Builtins}), the directory stack (@pxref{Directory Stack Builtins}), the command history (@pxref{Bash History Builtins}), and the programmable completion facilities (@pxref{Programmable Completion Builtins}). Many of the builtins have been extended by @sc{posix} or Bash. @node Bourne Shell Builtins @section Bourne Shell Builtins The following shell builtin commands are inherited from the Bourne Shell. These commands are implemented as specified by the @sc{posix} 1003.2 standard. @table @code @item : @r{(a colon)} @btindex : @example : [@var{arguments}] @end example Do nothing beyond expanding @var{arguments} and performing redirections. The return status is zero. @item . @r{(a period)} @btindex . @example . @var{filename} [@var{arguments}] @end example Read and execute commands from the @var{filename} argument in the current shell context. If @var{filename} does not contain a slash, the @env{PATH} variable is used to find @var{filename}. When Bash is not in @sc{posix} mode, the current directory is searched if @var{filename} is not found in @env{$PATH}. If any @var{arguments} are supplied, they become the positional parameters when @var{filename} is executed. Otherwise the positional parameters are unchanged. The return status is the exit status of the last command executed, or zero if no commands are executed. If @var{filename} is not found, or cannot be read, the return status is non-zero. This builtin is equivalent to @code{source}. @item break @btindex break @example break [@var{n}] @end example Exit from a @code{for}, @code{while}, @code{until}, or @code{select} loop. If @var{n} is supplied, the @var{n}th enclosing loop is exited. @var{n} must be greater than or equal to 1. The return status is zero unless @var{n} is not greater than or equal to 1. @item cd @btindex cd @example cd [-LP] [@var{directory}] @end example Change the current working directory to @var{directory}. If @var{directory} is not given, the value of the @env{HOME} shell variable is used. If the shell variable @env{CDPATH} exists, it is used as a search path. If @var{directory} begins with a slash, @env{CDPATH} is not used. The @option{-P} option means to not follow symbolic links; symbolic links are followed by default or with the @option{-L} option. If @var{directory} is @samp{-}, it is equivalent to @env{$OLDPWD}. The return status is zero if the directory is successfully changed, non-zero otherwise. @item continue @btindex continue @example continue [@var{n}] @end example Resume the next iteration of an enclosing @code{for}, @code{while}, @code{until}, or @code{select} loop. If @var{n} is supplied, the execution of the @var{n}th enclosing loop is resumed. @var{n} must be greater than or equal to 1. The return status is zero unless @var{n} is not greater than or equal to 1. @item eval @btindex eval @example eval [@var{arguments}] @end example The arguments are concatenated together into a single command, which is then read and executed, and its exit status returned as the exit status of @code{eval}. If there are no arguments or only empty arguments, the return status is zero. @item exec @btindex exec @example exec [-cl] [-a @var{name}] [@var{command} [@var{arguments}]] @end example If @var{command} is supplied, it replaces the shell without creating a new process. If the @option{-l} option is supplied, the shell places a dash at the beginning of the zeroth arg passed to @var{command}. This is what the @code{login} program does. The @option{-c} option causes @var{command} to be executed with an empty environment. If @option{-a} is supplied, the shell passes @var{name} as the zeroth argument to @var{command}. If no @var{command} is specified, redirections may be used to affect the current shell environment. If there are no redirection errors, the return status is zero; otherwise the return status is non-zero. @item exit @btindex exit @example exit [@var{n}] @end example Exit the shell, returning a status of @var{n} to the shell's parent. If @var{n} is omitted, the exit status is that of the last command executed. Any trap on @code{EXIT} is executed before the shell terminates. @item export @btindex export @example export [-fn] [-p] [@var{name}[=@var{value}]] @end example Mark each @var{name} to be passed to child processes in the environment. If the @option{-f} option is supplied, the @var{name}s refer to shell functions; otherwise the names refer to shell variables. The @option{-n} option means to no longer mark each @var{name} for export. If no @var{names} are supplied, or if the @option{-p} option is given, a list of exported names is displayed. The @option{-p} option displays output in a form that may be reused as input. The return status is zero unless an invalid option is supplied, one of the names is not a valid shell variable name, or @option{-f} is supplied with a name that is not a shell function. @item getopts @btindex getopts @example getopts @var{optstring} @var{name} [@var{args}] @end example @code{getopts} is used by shell scripts to parse positional parameters. @var{optstring} contains the option characters to be recognized; if a character is followed by a colon, the option is expected to have an argument, which should be separated from it by white space. The colon (@samp{:}) and question mark (@samp{?}) may not be used as option characters. Each time it is invoked, @code{getopts} places the next option in the shell variable @var{name}, initializing @var{name} if it does not exist, and the index of the next argument to be processed into the variable @env{OPTIND}. @env{OPTIND} is initialized to 1 each time the shell or a shell script is invoked. When an option requires an argument, @code{getopts} places that argument into the variable @env{OPTARG}. The shell does not reset @env{OPTIND} automatically; it must be manually reset between multiple calls to @code{getopts} within the same shell invocation if a new set of parameters is to be used. When the end of options is encountered, @code{getopts} exits with a return value greater than zero. @env{OPTIND} is set to the index of the first non-option argument, and @code{name} is set to @samp{?}. @code{getopts} normally parses the positional parameters, but if more arguments are given in @var{args}, @code{getopts} parses those instead. @code{getopts} can report errors in two ways. If the first character of @var{optstring} is a colon, @var{silent} error reporting is used. In normal operation diagnostic messages are printed when invalid options or missing option arguments are encountered. If the variable @env{OPTERR} is set to 0, no error messages will be displayed, even if the first character of @code{optstring} is not a colon. If an invalid option is seen, @code{getopts} places @samp{?} into @var{name} and, if not silent, prints an error message and unsets @env{OPTARG}. If @code{getopts} is silent, the option character found is placed in @env{OPTARG} and no diagnostic message is printed. If a required argument is not found, and @code{getopts} is not silent, a question mark (@samp{?}) is placed in @var{name}, @code{OPTARG} is unset, and a diagnostic message is printed. If @code{getopts} is silent, then a colon (@samp{:}) is placed in @var{name} and @env{OPTARG} is set to the option character found. @item hash @btindex hash @example hash [-r] [-p @var{filename}] [-t] [@var{name}] @end example Remember the full pathnames of commands specified as @var{name} arguments, so they need not be searched for on subsequent invocations. The commands are found by searching through the directories listed in @env{$PATH}. The @option{-p} option inhibits the path search, and @var{filename} is used as the location of @var{name}. The @option{-r} option causes the shell to forget all remembered locations. If the @option{-t} option is supplied, the full pathname to which each @var{name} corresponds is printed. If multiple @var{name} arguments are supplied with @option{-t} the @var{name} is printed before the hashed full pathname. If no arguments are given, information about remembered commands is printed. The return status is zero unless a @var{name} is not found or an invalid option is supplied. @item pwd @btindex pwd @example pwd [-LP] @end example Print the absolute pathname of the current working directory. If the @option{-P} option is supplied, the pathname printed will not contain symbolic links. If the @option{-L} option is supplied, the pathname printed may contain symbolic links. The return status is zero unless an error is encountered while determining the name of the current directory or an invalid option is supplied. @item readonly @btindex readonly @example readonly [-apf] [@var{name}] @dots{} @end example Mark each @var{name} as readonly. The values of these names may not be changed by subsequent assignment. If the @option{-f} option is supplied, each @var{name} refers to a shell function. The @option{-a} option means each @var{name} refers to an array variable. If no @var{name} arguments are given, or if the @option{-p} option is supplied, a list of all readonly names is printed. The @option{-p} option causes output to be displayed in a format that may be reused as input. The return status is zero unless an invalid option is supplied, one of the @var{name} arguments is not a valid shell variable or function name, or the @option{-f} option is supplied with a name that is not a shell function. @item return @btindex return @example return [@var{n}] @end example Cause a shell function to exit with the return value @var{n}. If @var{n} is not supplied, the return value is the exit status of the last command executed in the function. This may also be used to terminate execution of a script being executed with the @code{.} (or @code{source}) builtin, returning either @var{n} or the exit status of the last command executed within the script as the exit status of the script. The return status is non-zero if @code{return} is used outside a function and not during the execution of a script by @code{.} or @code{source}. @item shift @btindex shift @example shift [@var{n}] @end example Shift the positional parameters to the left by @var{n}. The positional parameters from @var{n}+1 @dots{} @code{$#} are renamed to @code{$1} @dots{} @code{$#}-@var{n}+1. Parameters represented by the numbers @code{$#} to @var{n}+1 are unset. @var{n} must be a non-negative number less than or equal to @code{$#}. If @var{n} is zero or greater than @code{$#}, the positional parameters are not changed. If @var{n} is not supplied, it is assumed to be 1. The return status is zero unless @var{n} is greater than @code{$#} or less than zero, non-zero otherwise. @item test @itemx [ @btindex test @btindex [ Evaluate a conditional expression @var{expr}. Each operator and operand must be a separate argument. Expressions are composed of the primaries described below in @ref{Bash Conditional Expressions}. When the @code{[} form is used, the last argument to the command must be a @code{]}. Expressions may be combined using the following operators, listed in decreasing order of precedence. @table @code @item ! @var{expr} True if @var{expr} is false. @item ( @var{expr} ) Returns the value of @var{expr}. This may be used to override the normal precedence of operators. @item @var{expr1} -a @var{expr2} True if both @var{expr1} and @var{expr2} are true. @item @var{expr1} -o @var{expr2} True if either @var{expr1} or @var{expr2} is true. @end table The @code{test} and @code{[} builtins evaluate conditional expressions using a set of rules based on the number of arguments. @table @asis @item 0 arguments The expression is false. @item 1 argument The expression is true if and only if the argument is not null. @item 2 arguments If the first argument is @samp{!}, the expression is true if and only if the second argument is null. If the first argument is one of the unary conditional operators (@pxref{Bash Conditional Expressions}), the expression is true if the unary test is true. If the first argument is not a valid unary operator, the expression is false. @item 3 arguments If the second argument is one of the binary conditional operators (@pxref{Bash Conditional Expressions}), the result of the expression is the result of the binary test using the first and third arguments as operands. If the first argument is @samp{!}, the value is the negation of the two-argument test using the second and third arguments. If the first argument is exactly @samp{(} and the third argument is exactly @samp{)}, the result is the one-argument test of the second argument. Otherwise, the expression is false. The @samp{-a} and @samp{-o} operators are considered binary operators in this case. @item 4 arguments If the first argument is @samp{!}, the result is the negation of the three-argument expression composed of the remaining arguments. Otherwise, the expression is parsed and evaluated according to precedence using the rules listed above. @item 5 or more arguments The expression is parsed and evaluated according to precedence using the rules listed above. @end table @item times @btindex times @example times @end example Print out the user and system times used by the shell and its children. The return status is zero. @item trap @btindex trap @example trap [-lp] [@var{arg}] [@var{sigspec} @dots{}] @end example The commands in @var{arg} are to be read and executed when the shell receives signal @var{sigspec}. If @var{arg} is absent or equal to @samp{-}, all specified signals are reset to the values they had when the shell was started. If @var{arg} is the null string, then the signal specified by each @var{sigspec} is ignored by the shell and commands it invokes. If @var{arg} is not present and @option{-p} has been supplied, the shell displays the trap commands associated with each @var{sigspec}. If no arguments are supplied, or only @option{-p} is given, @code{trap} prints the list of commands associated with each signal number in a form that may be reused as shell input. Each @var{sigspec} is either a signal name such as @code{SIGINT} (with or without the @code{SIG} prefix) or a signal number. If a @var{sigspec} is @code{0} or @code{EXIT}, @var{arg} is executed when the shell exits. If a @var{sigspec} is @code{DEBUG}, the command @var{arg} is executed after every simple command. If a @var{sigspec} is @code{ERR}, the command @var{arg} is executed whenever a simple command has a non-zero exit status. The @code{ERR} trap is not executed if the failed command is part of an @code{until} or @code{while} loop, part of an @code{if} statement, part of a @code{&&} or @code{||} list, or if the command's return status is being inverted using @code{!}. The @option{-l} option causes the shell to print a list of signal names and their corresponding numbers. Signals ignored upon entry to the shell cannot be trapped or reset. Trapped signals are reset to their original values in a child process when it is created. The return status is zero unless a @var{sigspec} does not specify a valid signal. @item umask @btindex umask @example umask [-p] [-S] [@var{mode}] @end example Set the shell process's file creation mask to @var{mode}. If @var{mode} begins with a digit, it is interpreted as an octal number; if not, it is interpreted as a symbolic mode mask similar to that accepted by the @code{chmod} command. If @var{mode} is omitted, the current value of the mask is printed. If the @option{-S} option is supplied without a @var{mode} argument, the mask is printed in a symbolic format. If the @option{-p} option is supplied, and @var{mode} is omitted, the output is in a form that may be reused as input. The return status is zero if the mode is successfully changed or if no @var{mode} argument is supplied, and non-zero otherwise. Note that when the mode is interpreted as an octal number, each number of the umask is subtracted from @code{7}. Thus, a umask of @code{022} results in permissions of @code{755}. @item unset @btindex unset @example unset [-fv] [@var{name}] @end example Each variable or function @var{name} is removed. If no options are supplied, or the @option{-v} option is given, each @var{name} refers to a shell variable. If the @option{-f} option is given, the @var{name}s refer to shell functions, and the function definition is removed. Readonly variables and functions may not be unset. The return status is zero unless a @var{name} does not exist or is readonly. @end table @node Bash Builtins @section Bash Builtin Commands This section describes builtin commands which are unique to or have been extended in Bash. Some of these commands are specified in the @sc{posix} 1003.2 standard. @table @code @item alias @btindex alias @example alias [@code{-p}] [@var{name}[=@var{value}] @dots{}] @end example Without arguments or with the @option{-p} option, @code{alias} prints the list of aliases on the standard output in a form that allows them to be reused as input. If arguments are supplied, an alias is defined for each @var{name} whose @var{value} is given. If no @var{value} is given, the name and value of the alias is printed. Aliases are described in @ref{Aliases}. @item bind @btindex bind @example bind [-m @var{keymap}] [-lpsvPSV] bind [-m @var{keymap}] [-q @var{function}] [-u @var{function}] [-r @var{keyseq}] bind [-m @var{keymap}] -f @var{filename} bind [-m @var{keymap}] -x @var{keyseq:shell-command} bind [-m @var{keymap}] @var{keyseq:function-name} @end example Display current Readline (@pxref{Command Line Editing}) key and function bindings, or bind a key sequence to a Readline function or macro. The binding syntax accepted is identical to that of a Readline initialization file (@pxref{Readline Init File}), but each binding must be passed as a separate argument: e.g., @samp{"\C-x\C-r":re-read-init-file}. Options, if supplied, have the following meanings: @table @code @item -m @var{keymap} Use @var{keymap} as the keymap to be affected by the subsequent bindings. Acceptable @var{keymap} names are @code{emacs}, @code{emacs-standard}, @code{emacs-meta}, @code{emacs-ctlx}, @code{vi}, @code{vi-move}, @code{vi-command}, and @code{vi-insert}. @code{vi} is equivalent to @code{vi-command}; @code{emacs} is equivalent to @code{emacs-standard}. @item -l List the names of all Readline functions. @item -p Display Readline function names and bindings in such a way that they can be used as input or in a Readline initialization file. @item -P List current Readline function names and bindings. @item -v Display Readline variable names and values in such a way that they can be used as input or in a Readline initialization file. @item -V List current Readline variable names and values. @item -s Display Readline key sequences bound to macros and the strings they output in such a way that they can be used as input or in a Readline initialization file. @item -S Display Readline key sequences bound to macros and the strings they output. @item -f @var{filename} Read key bindings from @var{filename}. @item -q @var{function} Query about which keys invoke the named @var{function}. @item -u @var{function} Unbind all keys bound to the named @var{function}. @item -r @var{keyseq} Remove any current binding for @var{keyseq}. @item -x @var{keyseq:shell-command} Cause @var{shell-command} to be executed whenever @var{keyseq} is entered. @end table @noindent The return status is zero unless an invalid option is supplied or an error occurs. @item builtin @btindex builtin @example builtin [@var{shell-builtin} [@var{args}]] @end example Run a shell builtin, passing it @var{args}, and return its exit status. This is useful when defining a shell function with the same name as a shell builtin, retaining the functionality of the builtin within the function. The return status is non-zero if @var{shell-builtin} is not a shell builtin command. @item command @btindex command @example command [-pVv] @var{command} [@var{arguments} @dots{}] @end example Runs @var{command} with @var{arguments} ignoring any shell function named @var{command}. Only shell builtin commands or commands found by searching the @env{PATH} are executed. If there is a shell function named @code{ls}, running @samp{command ls} within the function will execute the external command @code{ls} instead of calling the function recursively. The @option{-p} option means to use a default value for @env{PATH} that is guaranteed to find all of the standard utilities. The return status in this case is 127 if @var{command} cannot be found or an error occurred, and the exit status of @var{command} otherwise. If either the @option{-V} or @option{-v} option is supplied, a description of @var{command} is printed. The @option{-v} option causes a single word indicating the command or file name used to invoke @var{command} to be displayed; the @option{-V} option produces a more verbose description. In this case, the return status is zero if @var{command} is found, and non-zero if not. @item declare @btindex declare @example declare [-afFrxi] [-p] [@var{name}[=@var{value}]] @end example Declare variables and give them attributes. If no @var{name}s are given, then display the values of variables instead. The @option{-p} option will display the attributes and values of each @var{name}. When @option{-p} is used, additional options are ignored. The @option{-F} option inhibits the display of function definitions; only the function name and attributes are printed. @option{-F} implies @option{-f}. The following options can be used to restrict output to variables with the specified attributes or to give variables attributes: @table @code @item -a Each @var{name} is an array variable (@pxref{Arrays}). @item -f Use function names only. @item -i The variable is to be treated as an integer; arithmetic evaluation (@pxref{Shell Arithmetic}) is performed when the variable is assigned a value. @item -r Make @var{name}s readonly. These names cannot then be assigned values by subsequent assignment statements or unset. @item -x Mark each @var{name} for export to subsequent commands via the environment. @end table Using @samp{+} instead of @samp{-} turns off the attribute instead. When used in a function, @code{declare} makes each @var{name} local, as with the @code{local} command. The return status is zero unless an invalid option is encountered, an attempt is made to define a function using @samp{-f foo=bar}, an attempt is made to assign a value to a readonly variable, an attempt is made to assign a value to an array variable without using the compound assignment syntax (@pxref{Arrays}), one of the @var{names} is not a valid shell variable name, an attempt is made to turn off readonly status for a readonly variable, an attempt is made to turn off array status for an array variable, or an attempt is made to display a non-existent function with @option{-f}. @item echo @btindex echo @example echo [-neE] [@var{arg} @dots{}] @end example Output the @var{arg}s, separated by spaces, terminated with a newline. The return status is always 0. If @option{-n} is specified, the trailing newline is suppressed. If the @option{-e} option is given, interpretation of the following backslash-escaped characters is enabled. The @option{-E} option disables the interpretation of these escape characters, even on systems where they are interpreted by default. The @code{xpg_echo} shell option may be used to dynamically determine whether or not @code{echo} expands these escape characters by default. @code{echo} interprets the following escape sequences: @table @code @item \a alert (bell) @item \b backspace @item \c suppress trailing newline @item \e escape @item \f form feed @item \n new line @item \r carriage return @item \t horizontal tab @item \v vertical tab @item \\ backslash @item \@var{nnn} the eight-bit character whose value is the octal value @var{nnn} (one to three digits) @item \x@var{HH} the eight-bit character whose value is the hexadecimal value @var{HH} (one or two hex digits) @end table @item enable @btindex enable @example enable [-n] [-p] [-f @var{filename}] [-ads] [@var{name} @dots{}] @end example Enable and disable builtin shell commands. Disabling a builtin allows a disk command which has the same name as a shell builtin to be executed without specifying a full pathname, even though the shell normally searches for builtins before disk commands. If @option{-n} is used, the @var{name}s become disabled. Otherwise @var{name}s are enabled. For example, to use the @code{test} binary found via @env{$PATH} instead of the shell builtin version, type @samp{enable -n test}. If the @option{-p} option is supplied, or no @var{name} arguments appear, a list of shell builtins is printed. With no other arguments, the list consists of all enabled shell builtins. The @option{-a} option means to list each builtin with an indication of whether or not it is enabled. The @option{-f} option means to load the new builtin command @var{name} from shared object @var{filename}, on systems that support dynamic loading. The @option{-d} option will delete a builtin loaded with @option{-f}. If there are no options, a list of the shell builtins is displayed. The @option{-s} option restricts @code{enable} to the @sc{posix} special builtins. If @option{-s} is used with @option{-f}, the new builtin becomes a special builtin (@pxref{Special Builtins}). The return status is zero unless a @var{name} is not a shell builtin or there is an error loading a new builtin from a shared object. @item help @btindex help @example help [-s] [@var{pattern}] @end example Display helpful information about builtin commands. If @var{pattern} is specified, @code{help} gives detailed help on all commands matching @var{pattern}, otherwise a list of the builtins is printed. The @option{-s} option restricts the information displayed to a short usage synopsis. The return status is zero unless no command matches @var{pattern}. @item let @btindex let @example let @var{expression} [@var{expression}] @end example The @code{let} builtin allows arithmetic to be performed on shell variables. Each @var{expression} is evaluated according to the rules given below in @ref{Shell Arithmetic}. If the last @var{expression} evaluates to 0, @code{let} returns 1; otherwise 0 is returned. @item local @btindex local @example local [@var{option}] @var{name}[=@var{value}] @end example For each argument, a local variable named @var{name} is created, and assigned @var{value}. The @var{option} can be any of the options accepted by @code{declare}. @code{local} can only be used within a function; it makes the variable @var{name} have a visible scope restricted to that function and its children. The return status is zero unless @code{local} is used outside a function, an invalid @var{name} is supplied, or @var{name} is a readonly variable. @item logout @btindex logout @example logout [@var{n}] @end example Exit a login shell, returning a status of @var{n} to the shell's parent. @item printf @btindex printf @example @code{printf} @var{format} [@var{arguments}] @end example Write the formatted @var{arguments} to the standard output under the control of the @var{format}. The @var{format} is a character string which contains three types of objects: plain characters, which are simply copied to standard output, character escape sequences, which are converted and copied to the standard output, and format specifications, each of which causes printing of the next successive @var{argument}. In addition to the standard @code{printf(1)} formats, @samp{%b} causes @code{printf} to expand backslash escape sequences in the corresponding @var{argument}, and @samp{%q} causes @code{printf} to output the corresponding @var{argument} in a format that can be reused as shell input. The @var{format} is reused as necessary to consume all of the @var{arguments}. If the @var{format} requires more @var{arguments} than are supplied, the extra format specifications behave as if a zero value or null string, as appropriate, had been supplied. The return value is zero on success, non-zero on failure. @item read @btindex read @example read [-ers] [-a @var{aname}] [-p @var{prompt}] [-t @var{timeout}] [-n @var{nchars}] [-d @var{delim}] [@var{name} @dots{}] @end example One line is read from the standard input, and the first word is assigned to the first @var{name}, the second word to the second @var{name}, and so on, with leftover words and their intervening separators assigned to the last @var{name}. If there are fewer words read from the standard input than names, the remaining names are assigned empty values. The characters in the value of the @env{IFS} variable are used to split the line into words. The backslash character @samp{\} may be used to remove any special meaning for the next character read and for line continuation. If no names are supplied, the line read is assigned to the variable @env{REPLY}. The return code is zero, unless end-of-file is encountered or @code{read} times out. Options, if supplied, have the following meanings: @table @code @item -a @var{aname} The words are assigned to sequential indices of the array variable @var{aname}, starting at 0. All elements are removed from @var{aname} before the assignment. Other @var{name} arguments are ignored. @item -d @var{delim} The first character of @var{delim} is used to terminate the input line, rather than newline. @item -e Readline (@pxref{Command Line Editing}) is used to obtain the line. @item -n @var{nchars} @code{read} returns after reading @var{nchars} characters rather than waiting for a complete line of input. @item -p @var{prompt} Display @var{prompt}, without a trailing newline, before attempting to read any input. The prompt is displayed only if input is coming from a terminal. @item -r If this option is given, backslash does not act as an escape character. The backslash is considered to be part of the line. In particular, a backslash-newline pair may not be used as a line continuation. @item -s Silent mode. If input is coming from a terminal, characters are not echoed. @item -t @var{timeout} Cause @code{read} to time out and return failure if a complete line of input is not read within @var{timeout} seconds. This option has no effect if @code{read} is not reading input from the terminal or a pipe. @end table @item shopt @btindex shopt @example shopt [-pqsu] [-o] [@var{optname} @dots{}] @end example Toggle the values of variables controlling optional shell behavior. With no options, or with the @option{-p} option, a list of all settable options is displayed, with an indication of whether or not each is set. The @option{-p} option causes output to be displayed in a form that may be reused as input. Other options have the following meanings: @table @code @item -s Enable (set) each @var{optname}. @item -u Disable (unset) each @var{optname}. @item -q Suppresses normal output; the return status indicates whether the @var{optname} is set or unset. If multiple @var{optname} arguments are given with @option{-q}, the return status is zero if all @var{optnames} are enabled; non-zero otherwise. @item -o Restricts the values of @var{optname} to be those defined for the @option{-o} option to the @code{set} builtin (@pxref{The Set Builtin}). @end table If either @option{-s} or @option{-u} is used with no @var{optname} arguments, the display is limited to those options which are set or unset, respectively. Unless otherwise noted, the @code{shopt} options are disabled (off) by default. The return status when listing options is zero if all @var{optnames} are enabled, non-zero otherwise. When setting or unsetting options, the return status is zero unless an @var{optname} is not a valid shell option. The list of @code{shopt} options is: @table @code @item cdable_vars If this is set, an argument to the @code{cd} builtin command that is not a directory is assumed to be the name of a variable whose value is the directory to change to. @item cdspell If set, minor errors in the spelling of a directory component in a @code{cd} command will be corrected. The errors checked for are transposed characters, a missing character, and a character too many. If a correction is found, the corrected path is printed, and the command proceeds. This option is only used by interactive shells. @item checkhash If this is set, Bash checks that a command found in the hash table exists before trying to execute it. If a hashed command no longer exists, a normal path search is performed. @item checkwinsize If set, Bash checks the window size after each command and, if necessary, updates the values of @env{LINES} and @env{COLUMNS}. @item cmdhist If set, Bash attempts to save all lines of a multiple-line command in the same history entry. This allows easy re-editing of multi-line commands. @item dotglob If set, Bash includes filenames beginning with a `.' in the results of filename expansion. @item execfail If this is set, a non-interactive shell will not exit if it cannot execute the file specified as an argument to the @code{exec} builtin command. An interactive shell does not exit if @code{exec} fails. @item expand_aliases If set, aliases are expanded as described below under Aliases, @ref{Aliases}. This option is enabled by default for interactive shells. @item extglob If set, the extended pattern matching features described above (@pxref{Pattern Matching}) are enabled. @item histappend If set, the history list is appended to the file named by the value of the @env{HISTFILE} variable when the shell exits, rather than overwriting the file. @item histreedit If set, and Readline is being used, a user is given the opportunity to re-edit a failed history substitution. @item histverify If set, and Readline is being used, the results of history substitution are not immediately passed to the shell parser. Instead, the resulting line is loaded into the Readline editing buffer, allowing further modification. @item hostcomplete If set, and Readline is being used, Bash will attempt to perform hostname completion when a word containing a @samp{@@} is being completed (@pxref{Commands For Completion}). This option is enabled by default. @item huponexit If set, Bash will send @code{SIGHUP} to all jobs when an interactive login shell exits (@pxref{Signals}). @item interactive_comments Allow a word beginning with @samp{#} to cause that word and all remaining characters on that line to be ignored in an interactive shell. This option is enabled by default. @item lithist If enabled, and the @code{cmdhist} option is enabled, multi-line commands are saved to the history with embedded newlines rather than using semicolon separators where possible. @item login_shell The shell sets this option if it is started as a login shell (@pxref{Invoking Bash}). The value may not be changed. @item mailwarn If set, and a file that Bash is checking for mail has been accessed since the last time it was checked, the message @code{"The mail in @var{mailfile} has been read"} is displayed. @item no_empty_cmd_completion If set, and Readline is being used, Bash will not attempt to search the @env{PATH} for possible completions when completion is attempted on an empty line. @item nocaseglob If set, Bash matches filenames in a case-insensitive fashion when performing filename expansion. @item nullglob If set, Bash allows filename patterns which match no files to expand to a null string, rather than themselves. @item progcomp If set, the programmable completion facilities (@pxref{Programmable Completion}) are enabled. This option is enabled by default. @item promptvars If set, prompt strings undergo variable and parameter expansion after being expanded (@pxref{Printing a Prompt}). This option is enabled by default. @item restricted_shell The shell sets this option if it is started in restricted mode (@pxref{The Restricted Shell}). The value may not be changed. This is not reset when the startup files are executed, allowing the startup files to discover whether or not a shell is restricted. @item shift_verbose If this is set, the @code{shift} builtin prints an error message when the shift count exceeds the number of positional parameters. @item sourcepath If set, the @code{source} builtin uses the value of @env{PATH} to find the directory containing the file supplied as an argument. This option is enabled by default. @item xpg_echo If set, the @code{echo} builtin expands backslash-escape sequences by default. @end table @noindent The return status when listing options is zero if all @var{optnames} are enabled, non-zero otherwise. When setting or unsetting options, the return status is zero unless an @var{optname} is not a valid shell option. @item source @btindex source @example source @var{filename} @end example A synonym for @code{.} (@pxref{Bourne Shell Builtins}). @item type @btindex type @example type [-atp] [@var{name} @dots{}] @end example For each @var{name}, indicate how it would be interpreted if used as a command name. If the @option{-t} option is used, @code{type} prints a single word which is one of @samp{alias}, @samp{function}, @samp{builtin}, @samp{file} or @samp{keyword}, if @var{name} is an alias, shell function, shell builtin, disk file, or shell reserved word, respectively. If the @var{name} is not found, then nothing is printed, and @code{type} returns a failure status. If the @option{-p} option is used, @code{type} either returns the name of the disk file that would be executed, or nothing if @option{-t} would not return @samp{file}. If the @option{-a} option is used, @code{type} returns all of the places that contain an executable named @var{file}. This includes aliases and functions, if and only if the @option{-p} option is not also used. The return status is zero if any of the @var{names} are found, non-zero if none are found. @item typeset @btindex typeset @example typeset [-afFrxi] [-p] [@var{name}[=@var{value}]] @end example The @code{typeset} command is supplied for compatibility with the Korn shell; however, it has been deprecated in favor of the @code{declare} builtin command. @item ulimit @btindex ulimit @example ulimit [-acdflmnpstuvSH] [@var{limit}] @end example @code{ulimit} provides control over the resources available to processes started by the shell, on systems that allow such control. If an option is given, it is interpreted as follows: @table @code @item -S Change and report the soft limit associated with a resource. @item -H Change and report the hard limit associated with a resource. @item -a All current limits are reported. @item -c The maximum size of core files created. @item -d The maximum size of a process's data segment. @item -f The maximum size of files created by the shell. @item -l The maximum size that may be locked into memory. @item -m The maximum resident set size. @item -n The maximum number of open file descriptors. @item -p The pipe buffer size. @item -s The maximum stack size. @item -t The maximum amount of cpu time in seconds. @item -u The maximum number of processes available to a single user. @item -v The maximum amount of virtual memory available to the process. @end table If @var{limit} is given, it is the new value of the specified resource; the special @var{limit} values @code{hard}, @code{soft}, and @code{unlimited} stand for the current hard limit, the current soft limit, and no limit, respectively. Otherwise, the current value of the soft limit for the specified resource is printed, unless the @option{-H} option is supplied. When setting new limits, if neither @option{-H} nor @option{-S} is supplied, both the hard and soft limits are set. If no option is given, then @option{-f} is assumed. Values are in 1024-byte increments, except for @option{-t}, which is in seconds, @option{-p}, which is in units of 512-byte blocks, and @option{-n} and @option{-u}, which are unscaled values. The return status is zero unless an invalid option or argument is supplied, or an error occurs while setting a new limit. @item unalias @btindex unalias @example unalias [-a] [@var{name} @dots{} ] @end example Remove each @var{name} from the list of aliases. If @option{-a} is supplied, all aliases are removed. Aliases are described in @ref{Aliases}. @end table @node The Set Builtin @section The Set Builtin This builtin is so complicated that it deserves its own section. @table @code @item set @btindex set @example set [--abefhkmnptuvxBCHP] [-o @var{option}] [@var{argument} @dots{}] @end example If no options or arguments are supplied, @code{set} displays the names and values of all shell variables and functions, sorted according to the current locale, in a format that may be reused as input. When options are supplied, they set or unset shell attributes. Options, if specified, have the following meanings: @table @code @item -a Mark variables and function which are modified or created for export to the environment of subsequent commands. @item -b Cause the status of terminated background jobs to be reported immediately, rather than before printing the next primary prompt. @item -e Exit immediately if a simple command (@pxref{Simple Commands}) exits with a non-zero status, unless the command that fails is part of an @code{until} or @code{while} loop, part of an @code{if} statement, part of a @code{&&} or @code{||} list, or if the command's return status is being inverted using @code{!}. A trap on @code{ERR}, if set, is executed before the shell exits. @item -f Disable file name generation (globbing). @item -h Locate and remember (hash) commands as they are looked up for execution. This option is enabled by default. @item -k All arguments in the form of assignment statements are placed in the environment for a command, not just those that precede the command name. @item -m Job control is enabled (@pxref{Job Control}). @item -n Read commands but do not execute them; this may be used to check a script for syntax errors. This option is ignored by interactive shells. @item -o @var{option-name} Set the option corresponding to @var{option-name}: @table @code @item allexport Same as @code{-a}. @item braceexpand Same as @code{-B}. @item emacs Use an @code{emacs}-style line editing interface (@pxref{Command Line Editing}). @item errexit Same as @code{-e}. @item hashall Same as @code{-h}. @item histexpand Same as @code{-H}. @item history Enable command history, as described in @ref{Bash History Facilities}. This option is on by default in interactive shells. @item ignoreeof An interactive shell will not exit upon reading EOF. @item keyword Same as @code{-k}. @item monitor Same as @code{-m}. @item noclobber Same as @code{-C}. @item noexec Same as @code{-n}. @item noglob Same as @code{-f}. @item nolog Currently ignored. @item notify Same as @code{-b}. @item nounset Same as @code{-u}. @item onecmd Same as @code{-t}. @item physical Same as @code{-P}. @item posix Change the behavior of Bash where the default operation differs from the @sc{posix} 1003.2 standard to match the standard (@pxref{Bash POSIX Mode}). This is intended to make Bash behave as a strict superset of that standard. @item privileged Same as @code{-p}. @item verbose Same as @code{-v}. @item vi Use a @code{vi}-style line editing interface. @item xtrace Same as @code{-x}. @end table @item -p Turn on privileged mode. In this mode, the @env{$BASH_ENV} and @env{$ENV} files are not processed, shell functions are not inherited from the environment, and the @env{SHELLOPTS} variable, if it appears in the environment, is ignored. If the shell is started with the effective user (group) id not equal to the real user (group) id, and the @code{-p} option is not supplied, these actions are taken and the effective user id is set to the real user id. If the @code{-p} option is supplied at startup, the effective user id is not reset. Turning this option off causes the effective user and group ids to be set to the real user and group ids. @item -t Exit after reading and executing one command. @item -u Treat unset variables as an error when performing parameter expansion. An error message will be written to the standard error, and a non-interactive shell will exit. @item -v Print shell input lines as they are read. @item -x Print a trace of simple commands and their arguments after they are expanded and before they are executed. @item -B The shell will perform brace expansion (@pxref{Brace Expansion}). This option is on by default. @item -C Prevent output redirection using @samp{>}, @samp{>&}, and @samp{<>} from overwriting existing files. @item -H Enable @samp{!} style history substitution (@pxref{History Interaction}). This option is on by default for interactive shells. @item -P If set, do not follow symbolic links when performing commands such as @code{cd} which change the current directory. The physical directory is used instead. By default, Bash follows the logical chain of directories when performing commands which change the current directory. For example, if @file{/usr/sys} is a symbolic link to @file{/usr/local/sys} then: @example $ cd /usr/sys; echo $PWD /usr/sys $ cd ..; pwd /usr @end example @noindent If @code{set -P} is on, then: @example $ cd /usr/sys; echo $PWD /usr/local/sys $ cd ..; pwd /usr/local @end example @item -- If no arguments follow this option, then the positional parameters are unset. Otherwise, the positional parameters are set to the @var{arguments}, even if some of them begin with a @samp{-}. @item - Signal the end of options, cause all remaining @var{arguments} to be assigned to the positional parameters. The @option{-x} and @option{-v} options are turned off. If there are no arguments, the positional parameters remain unchanged. @end table Using @samp{+} rather than @samp{-} causes these options to be turned off. The options can also be used upon invocation of the shell. The current set of options may be found in @code{$-}. The remaining N @var{arguments} are positional parameters and are assigned, in order, to @code{$1}, @code{$2}, @dots{} @code{$N}. The special parameter @code{#} is set to N. The return status is always zero unless an invalid option is supplied. @end table @node Special Builtins @section Special Builtins @cindex special builtin For historical reasons, the @sc{posix} 1003.2 standard has classified several builtin commands as @emph{special}. When Bash is executing in @sc{posix} mode, the special builtins differ from other builtin commands in three respects: @enumerate @item Special builtins are found before shell functions during command lookup. @item If a special builtin returns an error status, a non-interactive shell exits. @item Assignment statements preceding the command stay in effect in the shell environment after the command completes. @end enumerate When Bash is not executing in @sc{posix} mode, these builtins behave no differently than the rest of the Bash builtin commands. The Bash @sc{posix} mode is described in @ref{Bash POSIX Mode}. These are the @sc{posix} special builtins: @example @w{break : . continue eval exec exit export readonly return set} @w{shift trap unset} @end example @node Shell Variables @chapter Shell Variables @menu * Bourne Shell Variables:: Variables which Bash uses in the same way as the Bourne Shell. * Bash Variables:: List of variables that exist in Bash. @end menu This chapter describes the shell variables that Bash uses. Bash automatically assigns default values to a number of variables. @node Bourne Shell Variables @section Bourne Shell Variables Bash uses certain shell variables in the same way as the Bourne shell. In some cases, Bash assigns a default value to the variable. @vtable @code @item CDPATH A colon-separated list of directories used as a search path for the @code{cd} builtin command. @item HOME The current user's home directory; the default for the @code{cd} builtin command. The value of this variable is also used by tilde expansion (@pxref{Tilde Expansion}). @item IFS A list of characters that separate fields; used when the shell splits words as part of expansion. @item MAIL If this parameter is set to a filename and the @env{MAILPATH} variable is not set, Bash informs the user of the arrival of mail in the specified file. @item MAILPATH A colon-separated list of filenames which the shell periodically checks for new mail. Each list entry can specify the message that is printed when new mail arrives in the mail file by separating the file name from the message with a @samp{?}. When used in the text of the message, @code{$_} expands to the name of the current mail file. @item OPTARG The value of the last option argument processed by the @code{getopts} builtin. @item OPTIND The index of the last option argument processed by the @code{getopts} builtin. @item PATH A colon-separated list of directories in which the shell looks for commands. @item PS1 The primary prompt string. The default value is @samp{\s-\v\$ }. @xref{Printing a Prompt}, for the complete list of escape sequences that are expanded before @env{PS1} is displayed. @item PS2 The secondary prompt string. The default value is @samp{> }. @end vtable @node Bash Variables @section Bash Variables These variables are set or used by Bash, but other shells do not normally treat them specially. A few variables used by Bash are described in different chapters: variables for controlling the job control facilities (@pxref{Job Control Variables}). @vtable @code @item BASH The full pathname used to execute the current instance of Bash. @item BASH_ENV If this variable is set when Bash is invoked to execute a shell script, its value is expanded and used as the name of a startup file to read before executing the script. @xref{Bash Startup Files}. @item BASH_VERSION The version number of the current instance of Bash. @item BASH_VERSINFO A readonly array variable (@pxref{Arrays}) whose members hold version information for this instance of Bash. The values assigned to the array members are as follows: @table @code @item BASH_VERSINFO[0] The major version number (the @var{release}). @item BASH_VERSINFO[1] The minor version number (the @var{version}). @item BASH_VERSINFO[2] The patch level. @item BASH_VERSINFO[3] The build version. @item BASH_VERSINFO[4] The release status (e.g., @var{beta1}). @item BASH_VERSINFO[5] The value of @env{MACHTYPE}. @end table @item COLUMNS Used by the @code{select} builtin command to determine the terminal width when printing selection lists. Automatically set upon receipt of a @code{SIGWINCH}. @item COMP_CWORD An index into @env{$@{COMP_WORDS@}} of the word containing the current cursor position. This variable is available only in shell functions invoked by the programmable completion facilities (@pxref{Programmable Completion}). @item COMP_LINE The current command line. This variable is available only in shell functions and external commands invoked by the programmable completion facilities (@pxref{Programmable Completion}). @item COMP_POINT The index of the current cursor position relative to the beginning of the current command. If the current cursor position is at the end of the current command, the value of this variable is equal to @code{$@{#COMP_LINE@}}. This variable is available only in shell functions and external commands invoked by the programmable completion facilities (@pxref{Programmable Completion}). @item COMP_WORDS An array variable consisting of the individual words in the current command line. This variable is available only in shell functions invoked by the programmable completion facilities (@pxref{Programmable Completion}). @item COMPREPLY An array variable from which Bash reads the possible completions generated by a shell function invoked by the programmable completion facility (@pxref{Programmable Completion}). @item DIRSTACK An array variable containing the current contents of the directory stack. Directories appear in the stack in the order they are displayed by the @code{dirs} builtin. Assigning to members of this array variable may be used to modify directories already in the stack, but the @code{pushd} and @code{popd} builtins must be used to add and remove directories. Assignment to this variable will not change the current directory. If @env{DIRSTACK} is unset, it loses its special properties, even if it is subsequently reset. @item EUID The numeric effective user id of the current user. This variable is readonly. @item FCEDIT The editor used as a default by the @option{-e} option to the @code{fc} builtin command. @item FIGNORE A colon-separated list of suffixes to ignore when performing filename completion. A file name whose suffix matches one of the entries in @env{FIGNORE} is excluded from the list of matched file names. A sample value is @samp{.o:~} @item FUNCNAME The name of any currently-executing shell function. This variable exists only when a shell function is executing. Assignments to @env{FUNCNAME} have no effect and return an error status. If @env{FUNCNAME} is unset, it loses its special properties, even if it is subsequently reset. @item GLOBIGNORE A colon-separated list of patterns defining the set of filenames to be ignored by filename expansion. If a filename matched by a filename expansion pattern also matches one of the patterns in @env{GLOBIGNORE}, it is removed from the list of matches. @item GROUPS An array variable containing the list of groups of which the current user is a member. Assignments to @env{GROUPS} have no effect and return an error status. If @env{GROUPS} is unset, it loses its special properties, even if it is subsequently reset. @item histchars Up to three characters which control history expansion, quick substitution, and tokenization (@pxref{History Interaction}). The first character is the @var{history expansion} character, that is, the character which signifies the start of a history expansion, normally @samp{!}. The second character is the character which signifies `quick substitution' when seen as the first character on a line, normally @samp{^}. The optional third character is the character which indicates that the remainder of the line is a comment when found as the first character of a word, usually @samp{#}. The history comment character causes history substitution to be skipped for the remaining words on the line. It does not necessarily cause the shell parser to treat the rest of the line as a comment. @item HISTCMD The history number, or index in the history list, of the current command. If @env{HISTCMD} is unset, it loses its special properties, even if it is subsequently reset. @item HISTCONTROL A value of @samp{ignorespace} means to not enter lines which begin with a space or tab into the history list. A value of @samp{ignoredups} means to not enter lines which match the last entered line. A value of @samp{ignoreboth} combines the two options. Unset, or set to any other value than those above, means to save all lines on the history list. The second and subsequent lines of a multi-line compound command are not tested, and are added to the history regardless of the value of @env{HISTCONTROL}. @item HISTFILE The name of the file to which the command history is saved. The default value is @file{~/.bash_history}. @item HISTFILESIZE The maximum number of lines contained in the history file. When this variable is assigned a value, the history file is truncated, if necessary, to contain no more than that number of lines. The history file is also truncated to this size after writing it when an interactive shell exits. The default value is 500. @item HISTIGNORE A colon-separated list of patterns used to decide which command lines should be saved on the history list. Each pattern is anchored at the beginning of the line and must match the complete line (no implicit @samp{*} is appended). Each pattern is tested against the line after the checks specified by @env{HISTCONTROL} are applied. In addition to the normal shell pattern matching characters, @samp{&} matches the previous history line. @samp{&} may be escaped using a backslash; the backslash is removed before attempting a match. The second and subsequent lines of a multi-line compound command are not tested, and are added to the history regardless of the value of @env{HISTIGNORE}. @env{HISTIGNORE} subsumes the function of @env{HISTCONTROL}. A pattern of @samp{&} is identical to @code{ignoredups}, and a pattern of @samp{[ ]*} is identical to @code{ignorespace}. Combining these two patterns, separating them with a colon, provides the functionality of @code{ignoreboth}. @item HISTSIZE The maximum number of commands to remember on the history list. The default value is 500. @item HOSTFILE Contains the name of a file in the same format as @file{/etc/hosts} that should be read when the shell needs to complete a hostname. The list of possible hostname completions may be changed while the shell is running; the next time hostname completion is attempted after the value is changed, Bash adds the contents of the new file to the existing list. If @env{HOSTFILE} is set, but has no value, Bash attempts to read @file{/etc/hosts} to obtain the list of possible hostname completions. When @env{HOSTFILE} is unset, the hostname list is cleared. @item HOSTNAME The name of the current host. @item HOSTTYPE A string describing the machine Bash is running on. @item IGNOREEOF Controls the action of the shell on receipt of an @code{EOF} character as the sole input. If set, the value denotes the number of consecutive @code{EOF} characters that can be read as the first character on an input line before the shell will exit. If the variable exists but does not have a numeric value (or has no value) then the default is 10. If the variable does not exist, then @code{EOF} signifies the end of input to the shell. This is only in effect for interactive shells. @item INPUTRC The name of the Readline initialization file, overriding the default of @file{~/.inputrc}. @item LANG Used to determine the locale category for any category not specifically selected with a variable starting with @code{LC_}. @item LC_ALL This variable overrides the value of @env{LANG} and any other @code{LC_} variable specifying a locale category. @item LC_COLLATE This variable determines the collation order used when sorting the results of filename expansion, and determines the behavior of range expressions, equivalence classes, and collating sequences within filename expansion and pattern matching (@pxref{Filename Expansion}). @item LC_CTYPE This variable determines the interpretation of characters and the behavior of character classes within filename expansion and pattern matching (@pxref{Filename Expansion}). @item LC_MESSAGES This variable determines the locale used to translate double-quoted strings preceded by a @samp{$} (@pxref{Locale Translation}). @item LC_NUMERIC This variable determines the locale category used for number formatting. @item LINENO The line number in the script or shell function currently executing. @item LINES Used by the @code{select} builtin command to determine the column length for printing selection lists. Automatically set upon receipt of a @code{SIGWINCH}. @item MACHTYPE A string that fully describes the system type on which Bash is executing, in the standard @sc{gnu} @var{cpu-company-system} format. @item MAILCHECK How often (in seconds) that the shell should check for mail in the files specified in the @env{MAILPATH} or @env{MAIL} variables. The default is 60 seconds. When it is time to check for mail, the shell does so before displaying the primary prompt. If this variable is unset, or set to a value that is not a number greater than or equal to zero, the shell disables mail checking. @item OLDPWD The previous working directory as set by the @code{cd} builtin. @item OPTERR If set to the value 1, Bash displays error messages generated by the @code{getopts} builtin command. @item OSTYPE A string describing the operating system Bash is running on. @item PIPESTATUS An array variable (@pxref{Arrays}) containing a list of exit status values from the processes in the most-recently-executed foreground pipeline (which may contain only a single command). @item POSIXLY_CORRECT If this variable is in the environment when @code{bash} starts, the shell enters @sc{posix} mode (@pxref{Bash POSIX Mode}) before reading the startup files, as if the @option{--posix} invocation option had been supplied. If it is set while the shell is running, @code{bash} enables @sc{posix} mode, as if the command @example @code{set -o posix} @end example @noindent had been executed. @item PPID The process @sc{id} of the shell's parent process. This variable is readonly. @item PROMPT_COMMAND If set, the value is interpreted as a command to execute before the printing of each primary prompt (@env{$PS1}). @item PS3 The value of this variable is used as the prompt for the @code{select} command. If this variable is not set, the @code{select} command prompts with @samp{#? } @item PS4 The value is the prompt printed before the command line is echoed when the @option{-x} option is set (@pxref{The Set Builtin}). The first character of @env{PS4} is replicated multiple times, as necessary, to indicate multiple levels of indirection. The default is @samp{+ }. @item PWD The current working directory as set by the @code{cd} builtin. @item RANDOM Each time this parameter is referenced, a random integer between 0 and 32767 is generated. Assigning a value to this variable seeds the random number generator. @item REPLY The default variable for the @code{read} builtin. @item SECONDS This variable expands to the number of seconds since the shell was started. Assignment to this variable resets the count to the value assigned, and the expanded value becomes the value assigned plus the number of seconds since the assignment. @item SHELLOPTS A colon-separated list of enabled shell options. Each word in the list is a valid argument for the @option{-o} option to the @code{set} builtin command (@pxref{The Set Builtin}). The options appearing in @env{SHELLOPTS} are those reported as @samp{on} by @samp{set -o}. If this variable is in the environment when Bash starts up, each shell option in the list will be enabled before reading any startup files. This variable is readonly. @item SHLVL Incremented by one each time a new instance of Bash is started. This is intended to be a count of how deeply your Bash shells are nested. @item TIMEFORMAT The value of this parameter is used as a format string specifying how the timing information for pipelines prefixed with the @code{time} reserved word should be displayed. The @samp{%} character introduces an escape sequence that is expanded to a time value or other information. The escape sequences and their meanings are as follows; the braces denote optional portions. @table @code @item %% A literal @samp{%}. @item %[@var{p}][l]R The elapsed time in seconds. @item %[@var{p}][l]U The number of CPU seconds spent in user mode. @item %[@var{p}][l]S The number of CPU seconds spent in system mode. @item %P The CPU percentage, computed as (%U + %S) / %R. @end table The optional @var{p} is a digit specifying the precision, the number of fractional digits after a decimal point. A value of 0 causes no decimal point or fraction to be output. At most three places after the decimal point may be specified; values of @var{p} greater than 3 are changed to 3. If @var{p} is not specified, the value 3 is used. The optional @code{l} specifies a longer format, including minutes, of the form @var{MM}m@var{SS}.@var{FF}s. The value of @var{p} determines whether or not the fraction is included. If this variable is not set, Bash acts as if it had the value @example @code{$'\nreal\t%3lR\nuser\t%3lU\nsys\t%3lS'} @end example If the value is null, no timing information is displayed. A trailing newline is added when the format string is displayed. @item TMOUT If set to a value greater than zero, the value is interpreted as the number of seconds to wait for input after issuing the primary prompt when the shell is interactive. Bash terminates after that number of seconds if input does not arrive. @item UID The numeric real user id of the current user. This variable is readonly. @end vtable @node Bash Features @chapter Bash Features This section describes features unique to Bash. @menu * Invoking Bash:: Command line options that you can give to Bash. * Bash Startup Files:: When and how Bash executes scripts. * Interactive Shells:: What an interactive shell is. * Bash Conditional Expressions:: Primitives used in composing expressions for the @code{test} builtin. * Shell Arithmetic:: Arithmetic on shell variables. * Aliases:: Substituting one command for another. * Arrays:: Array Variables. * The Directory Stack:: History of visited directories. * Printing a Prompt:: Controlling the PS1 string. * The Restricted Shell:: A more controlled mode of shell execution. * Bash POSIX Mode:: Making Bash behave more closely to what the POSIX standard specifies. @end menu @node Invoking Bash @section Invoking Bash @example bash [long-opt] [-ir] [-abefhkmnptuvxdBCDHP] [-o @var{option}] [-O @var{shopt_option}] [@var{argument} @dots{}] bash [long-opt] [-abefhkmnptuvxdBCDHP] [-o @var{option}] [-O @var{shopt_option}] -c @var{string} [@var{argument} @dots{}] bash [long-opt] -s [-abefhkmnptuvxdBCDHP] [-o @var{option}] [-O @var{shopt_option}] [@var{argument} @dots{}] @end example In addition to the single-character shell command-line options (@pxref{The Set Builtin}), there are several multi-character options that you can use. These options must appear on the command line before the single-character options in order for them to be recognized. @table @code @item --dump-po-strings A list of all double-quoted strings preceded by @samp{$} is printed on the standard ouput in the @sc{gnu} @code{gettext} PO (portable object) file format. Equivalent to @option{-D} except for the output format. @item --dump-strings Equivalent to @option{-D}. @item --help Display a usage message on standard output and exit sucessfully. @item --init-file @var{filename} @itemx --rcfile @var{filename} Execute commands from @var{filename} (instead of @file{~/.bashrc}) in an interactive shell. @item --login Make this shell act as if it had been directly invoked by login. When the shell is interactive, this is equivalent to starting a login shell with @samp{exec -l bash}. When the shell is not interactive, the login shell startup files will be executed. @samp{exec bash --login} will replace the current shell with a Bash login shell. @xref{Bash Startup Files}, for a description of the special behavior of a login shell. @item --noediting Do not use the @sc{gnu} Readline library (@pxref{Command Line Editing}) to read command lines when the shell is interactive. @item --noprofile Don't load the system-wide startup file @file{/etc/profile} or any of the personal initialization files @file{~/.bash_profile}, @file{~/.bash_login}, or @file{~/.profile} when Bash is invoked as a login shell. @item --norc Don't read the @file{~/.bashrc} initialization file in an interactive shell. This is on by default if the shell is invoked as @code{sh}. @item --posix Change the behavior of Bash where the default operation differs from the @sc{posix} 1003.2 standard to match the standard. This is intended to make Bash behave as a strict superset of that standard. @xref{Bash POSIX Mode}, for a description of the Bash @sc{posix} mode. @item --restricted Make the shell a restricted shell (@pxref{The Restricted Shell}). @item --verbose Equivalent to @option{-v}. Print shell input lines as they're read. @item --version Show version information for this instance of Bash on the standard output and exit successfully. @end table There are several single-character options that may be supplied at invocation which are not available with the @code{set} builtin. @table @code @item -c @var{string} Read and execute commands from @var{string} after processing the options, then exit. Any remaining arguments are assigned to the positional parameters, starting with @code{$0}. @item -i Force the shell to run interactively. Interactive shells are described in @ref{Interactive Shells}. @item -r Make the shell a restricted shell (@pxref{The Restricted Shell}). @item -s If this option is present, or if no arguments remain after option processing, then commands are read from the standard input. This option allows the positional parameters to be set when invoking an interactive shell. @item -D A list of all double-quoted strings preceded by @samp{$} is printed on the standard ouput. These are the strings that are subject to language translation when the current locale is not @code{C} or @code{POSIX} (@pxref{Locale Translation}). This implies the @option{-n} option; no commands will be executed. @item [-+]O [@var{shopt_option}] @var{shopt_option} is one of the shell options accepted by the @code{shopt} builtin (@pxref{Shell Builtin Commands}). If @var{shopt_option} is present, @option{-O} sets the value of that option; @option{+O} unsets it. If @var{shopt_option} is not supplied, the names and values of the shell options accepted by @code{shopt} are printed on the standard output. If the invocation option is @option{+O}, the output is displayed in a format that may be reused as input. @item -- A @code{--} signals the end of options and disables further option processing. Any arguments after the @code{--} are treated as filenames and arguments. @end table @cindex login shell A @emph{login} shell is one whose first character of argument zero is @samp{-}, or one invoked with the @option{--login} option. @cindex interactive shell An @emph{interactive} shell is one started without non-option arguments, unless @option{-s} is specified, without specifying the @option{-c} option, and whose input and output are both connected to terminals (as determined by @code{isatty(3)}), or one started with the @option{-i} option. @xref{Interactive Shells}, for more information. If arguments remain after option processing, and neither the @option{-c} nor the @option{-s} option has been supplied, the first argument is assumed to be the name of a file containing shell commands (@pxref{Shell Scripts}). When Bash is invoked in this fashion, @code{$0} is set to the name of the file, and the positional parameters are set to the remaining arguments. Bash reads and executes commands from this file, then exits. Bash's exit status is the exit status of the last command executed in the script. If no commands are executed, the exit status is 0. @node Bash Startup Files @section Bash Startup Files @cindex startup files This section describs how Bash executes its startup files. If any of the files exist but cannot be read, Bash reports an error. Tildes are expanded in file names as described above under Tilde Expansion (@pxref{Tilde Expansion}). Interactive shells are described in @ref{Interactive Shells}. @subsubheading Invoked as an interactive login shell, or with @option{--login} When Bash is invoked as an interactive login shell, or as a non-interactive shell with the @option{--login} option, it first reads and executes commands from the file @file{/etc/profile}, if that file exists. After reading that file, it looks for @file{~/.bash_profile}, @file{~/.bash_login}, and @file{~/.profile}, in that order, and reads and executes commands from the first one that exists and is readable. The @option{--noprofile} option may be used when the shell is started to inhibit this behavior. When a login shell exits, Bash reads and executes commands from the file @file{~/.bash_logout}, if it exists. @subsubheading Invoked as an interactive non-login shell When an interactive shell that is not a login shell is started, Bash reads and executes commands from @file{~/.bashrc}, if that file exists. This may be inhibited by using the @option{--norc} option. The @option{--rcfile @var{file}} option will force Bash to read and execute commands from @var{file} instead of @file{~/.bashrc}. So, typically, your @file{~/.bash_profile} contains the line @example @code{if [ -f ~/.bashrc ]; then . ~/.bashrc; fi} @end example @noindent after (or before) any login-specific initializations. @subsubheading Invoked non-interactively When Bash is started non-interactively, to run a shell script, for example, it looks for the variable @env{BASH_ENV} in the environment, expands its value if it appears there, and uses the expanded value as the name of a file to read and execute. Bash behaves as if the following command were executed: @example @code{if [ -n "$BASH_ENV" ]; then . "$BASH_ENV"; fi} @end example @noindent but the value of the @env{PATH} variable is not used to search for the file name. As noted above, if a non-interactive shell is invoked with the @option{--login} option, Bash attempts to read and execute commands from the login shell startup files. @subsubheading Invoked with name @code{sh} If Bash is invoked with the name @code{sh}, it tries to mimic the startup behavior of historical versions of @code{sh} as closely as possible, while conforming to the @sc{posix} standard as well. When invoked as an interactive login shell, or as a non-interactive shell with the @option{--login} option, it first attempts to read and execute commands from @file{/etc/profile} and @file{~/.profile}, in that order. The @option{--noprofile} option may be used to inhibit this behavior. When invoked as an interactive shell with the name @code{sh}, Bash looks for the variable @env{ENV}, expands its value if it is defined, and uses the expanded value as the name of a file to read and execute. Since a shell invoked as @code{sh} does not attempt to read and execute commands from any other startup files, the @option{--rcfile} option has no effect. A non-interactive shell invoked with the name @code{sh} does not attempt to read any other startup files. When invoked as @code{sh}, Bash enters @sc{posix} mode after the startup files are read. @subsubheading Invoked in @sc{posix} mode When Bash is started in @sc{posix} mode, as with the @option{--posix} command line option, it follows the @sc{posix} standard for startup files. In this mode, interactive shells expand the @env{ENV} variable and commands are read and executed from the file whose name is the expanded value. No other startup files are read. @subsubheading Invoked by remote shell daemon Bash attempts to determine when it is being run by the remote shell daemon, usually @code{rshd}. If Bash determines it is being run by rshd, it reads and executes commands from @file{~/.bashrc}, if that file exists and is readable. It will not do this if invoked as @code{sh}. The @option{--norc} option may be used to inhibit this behavior, and the @option{--rcfile} option may be used to force another file to be read, but @code{rshd} does not generally invoke the shell with those options or allow them to be specified. @subsubheading Invoked with unequal effective and real @sc{uid/gid}s If Bash is started with the effective user (group) id not equal to the real user (group) id, and the @code{-p} option is not supplied, no startup files are read, shell functions are not inherited from the environment, the @env{SHELLOPTS} variable, if it appears in the environment, is ignored, and the effective user id is set to the real user id. If the @code{-p} option is supplied at invocation, the startup behavior is the same, but the effective user id is not reset. @node Interactive Shells @section Interactive Shells @cindex interactive shell @cindex shell, interactive @menu * What is an Interactive Shell?:: What determines whether a shell is Interactive. * Is this Shell Interactive?:: How to tell if a shell is interactive. * Interactive Shell Behavior:: What changes in a interactive shell? @end menu @node What is an Interactive Shell? @subsection What is an Interactive Shell? An interactive shell is one started without non-option arguments, unless @option{-s} is specified, without specifiying the @option{-c} option, and whose input and output are both connected to terminals (as determined by @code{isatty(3)}), or one started with the @option{-i} option. An interactive shell generally reads from and writes to a user's terminal. The @option{-s} invocation option may be used to set the positional parameters when an interactive shell is started. @node Is this Shell Interactive? @subsection Is this Shell Interactive? To determine within a startup script whether or not Bash is running interactively, test the value of the @samp{-} special parameter. It contains @code{i} when the shell is interactive. For example: @example case "$-" in *i*) echo This shell is interactive ;; *) echo This shell is not interactive ;; esac @end example Alternatively, startup scripts may examine the variable @env{PS1}; it is unset in non-interactive shells, and set in interactive shells. Thus: @example if [ -z "$PS1" ]; then echo This shell is not interactive else echo This shell is interactive fi @end example @node Interactive Shell Behavior @subsection Interactive Shell Behavior When the shell is running interactively, it changes its behavior in several ways. @enumerate @item Startup files are read and executed as described in @ref{Bash Startup Files}. @item Job Control (@pxref{Job Control}) is enabled by default. When job control is in effect, Bash ignores the keyboard-generated job control signals @code{SIGTTIN}, @code{SIGTTOU}, and @code{SIGTSTP}. @item Bash expands and displays @env{PS1} before reading the first line of a command, and expands and displays @env{PS2} before reading the second and subsequent lines of a multi-line command. @item Bash executes the value of the @env{PROMPT_COMMAND} variable as a command before printing the primary prompt, @env{$PS1} (@pxref{Bash Variables}). @item Readline (@pxref{Command Line Editing}) is used to read commands from the user's terminal. @item Bash inspects the value of the @code{ignoreeof} option to @code{set -o} instead of exiting immediately when it receives an @code{EOF} on its standard input when reading a command (@pxref{The Set Builtin}). @item Command history (@pxref{Bash History Facilities}) and history expansion (@pxref{History Interaction}) are enabled by default. Bash will save the command history to the file named by @env{$HISTFILE} when an interactive shell exits. @item Alias expansion (@pxref{Aliases}) is performed by default. @item In the absence of any traps, Bash ignores @code{SIGTERM} (@pxref{Signals}). @item In the absence of any traps, @code{SIGINT} is caught and handled ((@pxref{Signals}). @code{SIGINT} will interrupt some shell builtins. @item An interactive login shell sends a @code{SIGHUP} to all jobs on exit if the @code{hupoxexit} shell option has been enabled (@pxref{Signals}). @item The @option{-n} invocation option is ignored, and @samp{set -n} has no effect (@pxref{The Set Builtin}). @item Bash will check for mail periodically, depending on the values of the @env{MAIL}, @env{MAILPATH}, and @env{MAILCHECK} shell variables (@pxref{Bash Variables}). @item Expansion errors due to references to unbound shell variables after @samp{set -u} has been enabled will not cause the shell to exit (@pxref{The Set Builtin}). @item The shell will not exit on expansion errors caused by @var{var} being unset or null in @code{$@{@var{var}:?@var{word}@}} expansions (@pxref{Shell Parameter Expansion}). @item Redirection errors encountered by shell builtins will not cause the shell to exit. @item When running in @sc{posix} mode, a special builtin returning an error status will not cause the shell to exit (@pxref{Bash POSIX Mode}). @item A failed @code{exec} will not cause the shell to exit (@pxref{Bourne Shell Builtins}). @item Parser syntax errors will not cause the shell to exit. @item Simple spelling correction for directory arguments to the @code{cd} builtin is enabled by default (see the description of the @code{cdspell} option to the @code{shopt} builtin in @ref{Bash Builtins}). @item The shell will check the value of the @env{TMOUT} variable and exit if a command is not read within the specified number of seconds after printing @env{$PS1} (@pxref{Bash Variables}). @end enumerate @node Bash Conditional Expressions @section Bash Conditional Expressions @cindex expressions, conditional Conditional expressions are used by the @code{[[} compound command and the @code{test} and @code{[} builtin commands. Expressions may be unary or binary. Unary expressions are often used to examine the status of a file. There are string operators and numeric comparison operators as well. If the @var{file} argument to one of the primaries is of the form @file{/dev/fd/@var{N}}, then file descriptor @var{N} is checked. If the @var{file} argument to one of the primaries is one of @file{/dev/stdin}, @file{/dev/stdout}, or @file{/dev/stderr}, file descriptor 0, 1, or 2, respectively, is checked. @table @code @item -a @var{file} True if @var{file} exists. @item -b @var{file} True if @var{file} exists and is a block special file. @item -c @var{file} True if @var{file} exists and is a character special file. @item -d @var{file} True if @var{file} exists and is a directory. @item -e @var{file} True if @var{file} exists. @item -f @var{file} True if @var{file} exists and is a regular file. @item -g @var{file} True if @var{file} exists and its set-group-id bit is set. @item -h @var{file} True if @var{file} exists and is a symbolic link. @item -k @var{file} True if @var{file} exists and its "sticky" bit is set. @item -p @var{file} True if @var{file} exists and is a named pipe (FIFO). @item -r @var{file} True if @var{file} exists and is readable. @item -s @var{file} True if @var{file} exists and has a size greater than zero. @item -t @var{fd} True if file descriptor @var{fd} is open and refers to a terminal. @item -u @var{file} True if @var{file} exists and its set-user-id bit is set. @item -w @var{file} True if @var{file} exists and is writable. @item -x @var{file} True if @var{file} exists and is executable. @item -O @var{file} True if @var{file} exists and is owned by the effective user id. @item -G @var{file} True if @var{file} exists and is owned by the effective group id. @item -L @var{file} True if @var{file} exists and is a symbolic link. @item -S @var{file} True if @var{file} exists and is a socket. @item -N @var{file} True if @var{file} exists and has been modified since it was last read. @item @var{file1} -nt @var{file2} True if @var{file1} is newer (according to modification date) than @var{file2}. @item @var{file1} -ot @var{file2} True if @var{file1} is older than @var{file2}. @item @var{file1} -ef @var{file2} True if @var{file1} and @var{file2} have the same device and inode numbers. @item -o @var{optname} True if shell option @var{optname} is enabled. The list of options appears in the description of the @option{-o} option to the @code{set} builtin (@pxref{The Set Builtin}). @item -z @var{string} True if the length of @var{string} is zero. @item -n @var{string} @itemx @var{string} True if the length of @var{string} is non-zero. @item @var{string1} == @var{string2} True if the strings are equal. @samp{=} may be used in place of @samp{==}. @item @var{string1} != @var{string2} True if the strings are not equal. @item @var{string1} < @var{string2} True if @var{string1} sorts before @var{string2} lexicographically in the current locale. @item @var{string1} > @var{string2} True if @var{string1} sorts after @var{string2} lexicographically in the current locale. @item @var{arg1} OP @var{arg2} @code{OP} is one of @samp{-eq}, @samp{-ne}, @samp{-lt}, @samp{-le}, @samp{-gt}, or @samp{-ge}. These arithmetic binary operators return true if @var{arg1} is equal to, not equal to, less than, less than or equal to, greater than, or greater than or equal to @var{arg2}, respectively. @var{Arg1} and @var{arg2} may be positive or negative integers. @end table @node Shell Arithmetic @section Shell Arithmetic @cindex arithmetic, shell @cindex shell arithmetic @cindex expressions, arithmetic @cindex evaluation, arithmetic @cindex arithmetic evaluation The shell allows arithmetic expressions to be evaluated, as one of the shell expansions or by the @code{let} builtin. Evaluation is done in long integers with no check for overflow, though division by 0 is trapped and flagged as an error. The operators and their precedence and associativity are the same as in the C language. The following list of operators is grouped into levels of equal-precedence operators. The levels are listed in order of decreasing precedence. @table @code @item @var{id}++ @var{id}-- variable post-increment and post-decrement @item ++@var{id} --@var{id} variable pre-increment and pre-decrement @item - + unary minus and plus @item ! ~ logical and bitwise negation @item ** exponentiation @item * / % multiplication, division, remainder @item + - addition, subtraction @item << >> left and right bitwise shifts @item <= >= < > comparison @item == != equality and inequality @item & bitwise AND @item ^ bitwise exclusive OR @item | bitwise OR @item && logical AND @item || logical OR @item expr ? expr : expr conditional evaluation @item = *= /= %= += -= <<= >>= &= ^= |= assignment @item expr1 , expr2 comma @end table Shell variables are allowed as operands; parameter expansion is performed before the expression is evaluated. Within an expression, shell variables may also be referenced by name without using the parameter expansion syntax. The value of a variable is evaluated as an arithmetic expression when it is referenced. A shell variable need not have its integer attribute turned on to be used in an expression. Constants with a leading 0 are interpreted as octal numbers. A leading @samp{0x} or @samp{0X} denotes hexadecimal. Otherwise, numbers take the form [@var{base}@code{#}]@var{n}, where @var{base} is a decimal number between 2 and 64 representing the arithmetic base, and @var{n} is a number in that base. If @var{base}@code{#} is omitted, then base 10 is used. The digits greater than 9 are represented by the lowercase letters, the uppercase letters, @samp{@@}, and @samp{_}, in that order. If @var{base} is less than or equal to 36, lowercase and uppercase letters may be used interchangably to represent numbers between 10 and 35. Operators are evaluated in order of precedence. Sub-expressions in parentheses are evaluated first and may override the precedence rules above. @node Aliases @section Aliases @cindex alias expansion @var{Aliases} allow a string to be substituted for a word when it is used as the first word of a simple command. The shell maintains a list of aliases that may be set and unset with the @code{alias} and @code{unalias} builtin commands. The first word of each simple command, if unquoted, is checked to see if it has an alias. If so, that word is replaced by the text of the alias. The alias name and the replacement text may contain any valid shell input, including shell metacharacters, with the exception that the alias name may not contain @samp{=}. The first word of the replacement text is tested for aliases, but a word that is identical to an alias being expanded is not expanded a second time. This means that one may alias @code{ls} to @code{"ls -F"}, for instance, and Bash does not try to recursively expand the replacement text. If the last character of the alias value is a space or tab character, then the next command word following the alias is also checked for alias expansion. Aliases are created and listed with the @code{alias} command, and removed with the @code{unalias} command. There is no mechanism for using arguments in the replacement text, as in @code{csh}. If arguments are needed, a shell function should be used (@pxref{Shell Functions}). Aliases are not expanded when the shell is not interactive, unless the @code{expand_aliases} shell option is set using @code{shopt} (@pxref{Bash Builtins}). The rules concerning the definition and use of aliases are somewhat confusing. Bash always reads at least one complete line of input before executing any of the commands on that line. Aliases are expanded when a command is read, not when it is executed. Therefore, an alias definition appearing on the same line as another command does not take effect until the next line of input is read. The commands following the alias definition on that line are not affected by the new alias. This behavior is also an issue when functions are executed. Aliases are expanded when a function definition is read, not when the function is executed, because a function definition is itself a compound command. As a consequence, aliases defined in a function are not available until after that function is executed. To be safe, always put alias definitions on a separate line, and do not use @code{alias} in compound commands. For almost every purpose, shell functions are preferred over aliases. @node Arrays @section Arrays @cindex arrays Bash provides one-dimensional array variables. Any variable may be used as an array; the @code{declare} builtin will explicitly declare an array. There is no maximum limit on the size of an array, nor any requirement that members be indexed or assigned contiguously. Arrays are zero-based. An array is created automatically if any variable is assigned to using the syntax @example name[@var{subscript}]=@var{value} @end example @noindent The @var{subscript} is treated as an arithmetic expression that must evaluate to a number greater than or equal to zero. To explicitly declare an array, use @example declare -a @var{name} @end example @noindent The syntax @example declare -a @var{name}[@var{subscript}] @end example @noindent is also accepted; the @var{subscript} is ignored. Attributes may be specified for an array variable using the @code{declare} and @code{readonly} builtins. Each attribute applies to all members of an array. Arrays are assigned to using compound assignments of the form @example name=(value@var{1} @dots{} value@var{n}) @end example @noindent where each @var{value} is of the form @code{[[@var{subscript}]=]}@var{string}. If the optional subscript is supplied, that index is assigned to; otherwise the index of the element assigned is the last index assigned to by the statement plus one. Indexing starts at zero. This syntax is also accepted by the @code{declare} builtin. Individual array elements may be assigned to using the @code{name[}@var{subscript}@code{]=}@var{value} syntax introduced above. Any element of an array may be referenced using @code{$@{name[}@var{subscript}@code{]@}}. The braces are required to avoid conflicts with the shell's filename expansion operators. If the @var{subscript} is @samp{@@} or @samp{*}, the word expands to all members of the array @var{name}. These subscripts differ only when the word appears within double quotes. If the word is double-quoted, @code{$@{name[*]@}} expands to a single word with the value of each array member separated by the first character of the @env{IFS} variable, and @code{$@{name[@@]@}} expands each element of @var{name} to a separate word. When there are no array members, @code{$@{name[@@]@}} expands to nothing. This is analogous to the expansion of the special parameters @samp{@@} and @samp{*}. @code{$@{#name[}@var{subscript}@code{]@}} expands to the length of @code{$@{name[}@var{subscript}@code{]@}}. If @var{subscript} is @samp{@@} or @samp{*}, the expansion is the number of elements in the array. Referencing an array variable without a subscript is equivalent to referencing element zero. The @code{unset} builtin is used to destroy arrays. @code{unset} @var{name}[@var{subscript}] destroys the array element at index @var{subscript}. @code{unset} @var{name}, where @var{name} is an array, removes the entire array. A subscript of @samp{*} or @samp{@@} also removes the entire array. The @code{declare}, @code{local}, and @code{readonly} builtins each accept a @option{-a} option to specify an array. The @code{read} builtin accepts a @option{-a} option to assign a list of words read from the standard input to an array, and can read values from the standard input into individual array elements. The @code{set} and @code{declare} builtins display array values in a way that allows them to be reused as input. @node The Directory Stack @section The Directory Stack @cindex directory stack @menu * Directory Stack Builtins:: Bash builtin commands to manipulate the directory stack. @end menu The directory stack is a list of recently-visited directories. The @code{pushd} builtin adds directories to the stack as it changes the current directory, and the @code{popd} builtin removes specified directories from the stack and changes the current directory to the directory removed. The @code{dirs} builtin displays the contents of the directory stack. The contents of the directory stack are also visible as the value of the @env{DIRSTACK} shell variable. @node Directory Stack Builtins @subsection Directory Stack Builtins @table @code @item dirs @btindex dirs @example dirs [+@var{N} | -@var{N}] [-clpv] @end example Display the list of currently remembered directories. Directories are added to the list with the @code{pushd} command; the @code{popd} command removes directories from the list. @table @code @item +@var{N} Displays the @var{N}th directory (counting from the left of the list printed by @code{dirs} when invoked without options), starting with zero. @item -@var{N} Displays the @var{N}th directory (counting from the right of the list printed by @code{dirs} when invoked without options), starting with zero. @item -c Clears the directory stack by deleting all of the elements. @item -l Produces a longer listing; the default listing format uses a tilde to denote the home directory. @item -p Causes @code{dirs} to print the directory stack with one entry per line. @item -v Causes @code{dirs} to print the directory stack with one entry per line, prefixing each entry with its index in the stack. @end table @item popd @btindex popd @example popd [+@var{N} | -@var{N}] [-n] @end example Remove the top entry from the directory stack, and @code{cd} to the new top directory. When no arguments are given, @code{popd} removes the top directory from the stack and performs a @code{cd} to the new top directory. The elements are numbered from 0 starting at the first directory listed with @code{dirs}; i.e., @code{popd} is equivalent to @code{popd +0}. @table @code @item +@var{N} Removes the @var{N}th directory (counting from the left of the list printed by @code{dirs}), starting with zero. @item -@var{N} Removes the @var{N}th directory (counting from the right of the list printed by @code{dirs}), starting with zero. @item -n Suppresses the normal change of directory when removing directories from the stack, so that only the stack is manipulated. @end table @btindex pushd @item pushd @example pushd [@var{dir} | @var{+N} | @var{-N}] [-n] @end example Save the current directory on the top of the directory stack and then @code{cd} to @var{dir}. With no arguments, @code{pushd} exchanges the top two directories. @table @code @item +@var{N} Brings the @var{N}th directory (counting from the left of the list printed by @code{dirs}, starting with zero) to the top of the list by rotating the stack. @item -@var{N} Brings the @var{N}th directory (counting from the right of the list printed by @code{dirs}, starting with zero) to the top of the list by rotating the stack. @item -n Suppresses the normal change of directory when adding directories to the stack, so that only the stack is manipulated. @item @var{dir} Makes the current working directory be the top of the stack, and then executes the equivalent of `@code{cd} @var{dir}'. @code{cd}s to @var{dir}. @end table @end table @node Printing a Prompt @section Controlling the Prompt @cindex prompting The value of the variable @env{PROMPT_COMMAND} is examined just before Bash prints each primary prompt. If @env{PROMPT_COMMAND} is set and has a non-null value, then the value is executed just as if it had been typed on the command line. In addition, the following table describes the special characters which can appear in the prompt variables: @table @code @item \a A bell character. @item \d The date, in "Weekday Month Date" format (e.g., "Tue May 26"). @item \e An escape character. @item \h The hostname, up to the first `.'. @item \H The hostname. @item \j The number of jobs currently managed by the shell. @item \l The basename of the shell's terminal device name. @item \n A newline. @item \r A carriage return. @item \s The name of the shell, the basename of @code{$0} (the portion following the final slash). @item \t The time, in 24-hour HH:MM:SS format. @item \T The time, in 12-hour HH:MM:SS format. @item \@@ The time, in 12-hour am/pm format. @item \A The time, in 24-hour HH:MM format. @item \u The username of the current user. @item \v The version of Bash (e.g., 2.00) @item \V The release of Bash, version + patchlevel (e.g., 2.00.0) @item \w The current working directory. @item \W The basename of @env{$PWD}. @item \! The history number of this command. @item \# The command number of this command. @item \$ If the effective uid is 0, @code{#}, otherwise @code{$}. @item \@var{nnn} The character whose ASCII code is the octal value @var{nnn}. @item \\ A backslash. @item \[ Begin a sequence of non-printing characters. This could be used to embed a terminal control sequence into the prompt. @item \] End a sequence of non-printing characters. @end table The command number and the history number are usually different: the history number of a command is its position in the history list, which may include commands restored from the history file (@pxref{Bash History Facilities}), while the command number is the position in the sequence of commands executed during the current shell session. After the string is decoded, it is expanded via parameter expansion, command substitution, arithmetic expansion, and quote removal, subject to the value of the @code{promptvars} shell option (@pxref{Bash Builtins}). @node The Restricted Shell @section The Restricted Shell @cindex restricted shell If Bash is started with the name @code{rbash}, or the @option{--restricted} option is supplied at invocation, the shell becomes restricted. A restricted shell is used to set up an environment more controlled than the standard shell. A restricted shell behaves identically to @code{bash} with the exception that the following are disallowed: @itemize @bullet @item Changing directories with the @code{cd} builtin. @item Setting or unsetting the values of the @env{SHELL}, @env{PATH}, @env{ENV}, or @env{BASH_ENV} variables. @item Specifying command names containing slashes. @item Specifying a filename containing a slash as an argument to the @code{.} builtin command. @item Specifying a filename containing a slash as an argument to the @option{-p} option to the @code{hash} builtin command. @item Importing function definitions from the shell environment at startup. @item Parsing the value of @env{SHELLOPTS} from the shell environment at startup. @item Redirecting output using the @samp{>}, @samp{>|}, @samp{<>}, @samp{>&}, @samp{&>}, and @samp{>>} redirection operators. @item Using the @code{exec} builtin to replace the shell with another command. @item Adding or deleting builtin commands with the @option{-f} and @option{-d} options to the @code{enable} builtin. @item Specifying the @option{-p} option to the @code{command} builtin. @item Turning off restricted mode with @samp{set +r} or @samp{set +o restricted}. @end itemize @node Bash POSIX Mode @section Bash POSIX Mode @cindex POSIX Mode Starting Bash with the @option{--posix} command-line option or executing @samp{set -o posix} while Bash is running will cause Bash to conform more closely to the @sc{posix} 1003.2 standard by changing the behavior to match that specified by @sc{posix} in areas where the Bash default differs. The following list is what's changed when `@sc{posix} mode' is in effect: @enumerate @item When a command in the hash table no longer exists, Bash will re-search @env{$PATH} to find the new location. This is also available with @samp{shopt -s checkhash}. @item The message printed by the job control code and builtins when a job exits with a non-zero status is `Done(status)'. @item The message printed by the job control code and builtins when a job is stopped is `Stopped(@var{signame})', where @var{signame} is, for example, @code{SIGTSTP}. @item Reserved words may not be aliased. @item The @sc{posix} 1003.2 @env{PS1} and @env{PS2} expansions of @samp{!} to the history number and @samp{!!} to @samp{!} are enabled, and parameter expansion is performed on the values of @env{PS1} and @env{PS2} regardless of the setting of the @code{promptvars} option. @item Interactive comments are enabled by default. (Bash has them on by default anyway.) @item The @sc{posix} 1003.2 startup files are executed (@env{$ENV}) rather than the normal Bash files. @item Tilde expansion is only performed on assignments preceding a command name, rather than on all assignment statements on the line. @item The default history file is @file{~/.sh_history} (this is the default value of @env{$HISTFILE}). @item The output of @samp{kill -l} prints all the signal names on a single line, separated by spaces. @item Non-interactive shells exit if @var{filename} in @code{.} @var{filename} is not found. @item Non-interactive shells exit if a syntax error in an arithmetic expansion results in an invalid expression. @item Redirection operators do not perform filename expansion on the word in the redirection unless the shell is interactive. @item Redirection operators do not perform word splitting on the word in the redirection. @item Function names must be valid shell @code{name}s. That is, they may not contain characters other than letters, digits, and underscores, and may not start with a digit. Declaring a function with an invalid name causes a fatal syntax error in non-interactive shells. @item @sc{posix} 1003.2 `special' builtins are found before shell functions during command lookup. @item If a @sc{posix} 1003.2 special builtin returns an error status, a non-interactive shell exits. The fatal errors are those listed in the POSIX.2 standard, and include things like passing incorrect options, redirection errors, variable assignment errors for assignments preceding the command name, and so on. @item If the @code{cd} builtin finds a directory to change to using @env{$CDPATH}, the value it assigns to the @env{PWD} variable does not contain any symbolic links, as if @samp{cd -P} had been executed. @item If @env{CDPATH} is set, the @code{cd} builtin will not implicitly append the current directory to it. This means that @code{cd} will fail if no valid directory name can be constructed from any of the entries in @env{$CDPATH}, even if the a directory with the same name as the name given as an argument to @code{cd} exists in the current directory. @item A non-interactive shell exits with an error status if a variable assignment error occurs when no command name follows the assignment statements. A variable assignment error occurs, for example, when trying to assign a value to a readonly variable. @item A non-interactive shell exits with an error status if the iteration variable in a @code{for} statement or the selection variable in a @code{select} statement is a readonly variable. @item Process substitution is not available. @item Assignment statements preceding @sc{posix} 1003.2 special builtins persist in the shell environment after the builtin completes. @item Assignment statements preceding shell function calls persist in the shell environment after the function returns, as if a @sc{posix} special builtin command had been executed. @item The @code{export} and @code{readonly} builtin commands display their output in the format required by @sc{posix} 1003.2. @item The @code{trap} builtin displays signal names without the leading @code{SIG}. @item The @code{.} and @code{source} builtins do not search the current directory for the filename argument if it is not found by searching @env{PATH}. @item Subshells spawned to execute command substitutions inherit the value of the @option{-e} option from the parent shell. When not in @sc{posix} mode, Bash clears the @option{-e} option in such subshells. @item Alias expansion is always enabled, even in non-interactive shells. @item When the @code{set} builtin is invoked without options, it does not display shell function names and definitions. @item When the @code{set} builtin is invoked without options, it displays variable values without quotes, unless they contain shell metacharacters, even if the result contains nonprinting characters. @end enumerate There is other @sc{posix} 1003.2 behavior that Bash does not implement. Specifically: @enumerate @item Assignment statements affect the execution environment of all builtins, not just special ones. @item When a subshell is created to execute a shell script with execute permission, but without a leading @samp{#!}, Bash sets @code{$0} to the full pathname of the script as found by searching @code{$PATH}, rather than the command as typed by the user. @item When using @samp{.} to source a shell script found in @code{$PATH}, bash checks execute permission bits rather than read permission bits, just as if it were searching for a command. @end enumerate @node Job Control @chapter Job Control This chapter discusses what job control is, how it works, and how Bash allows you to access its facilities. @menu * Job Control Basics:: How job control works. * Job Control Builtins:: Bash builtin commands used to interact with job control. * Job Control Variables:: Variables Bash uses to customize job control. @end menu @node Job Control Basics @section Job Control Basics @cindex job control @cindex foreground @cindex background @cindex suspending jobs Job control refers to the ability to selectively stop (suspend) the execution of processes and continue (resume) their execution at a later point. A user typically employs this facility via an interactive interface supplied jointly by the system's terminal driver and Bash. The shell associates a @var{job} with each pipeline. It keeps a table of currently executing jobs, which may be listed with the @code{jobs} command. When Bash starts a job asynchronously, it prints a line that looks like: @example [1] 25647 @end example @noindent indicating that this job is job number 1 and that the process @sc{id} of the last process in the pipeline associated with this job is 25647. All of the processes in a single pipeline are members of the same job. Bash uses the @var{job} abstraction as the basis for job control. To facilitate the implementation of the user interface to job control, the operating system maintains the notion of a current terminal process group @sc{id}. Members of this process group (processes whose process group @sc{id} is equal to the current terminal process group @sc{id}) receive keyboard-generated signals such as @code{SIGINT}. These processes are said to be in the foreground. Background processes are those whose process group @sc{id} differs from the terminal's; such processes are immune to keyboard-generated signals. Only foreground processes are allowed to read from or write to the terminal. Background processes which attempt to read from (write to) the terminal are sent a @code{SIGTTIN} (@code{SIGTTOU}) signal by the terminal driver, which, unless caught, suspends the process. If the operating system on which Bash is running supports job control, Bash contains facilities to use it. Typing the @var{suspend} character (typically @samp{^Z}, Control-Z) while a process is running causes that process to be stopped and returns control to Bash. Typing the @var{delayed suspend} character (typically @samp{^Y}, Control-Y) causes the process to be stopped when it attempts to read input from the terminal, and control to be returned to Bash. The user then manipulates the state of this job, using the @code{bg} command to continue it in the background, the @code{fg} command to continue it in the foreground, or the @code{kill} command to kill it. A @samp{^Z} takes effect immediately, and has the additional side effect of causing pending output and typeahead to be discarded. There are a number of ways to refer to a job in the shell. The character @samp{%} introduces a job name. Job number @code{n} may be referred to as @samp{%n}. The symbols @samp{%%} and @samp{%+} refer to the shell's notion of the current job, which is the last job stopped while it was in the foreground or started in the background. The previous job may be referenced using @samp{%-}. In output pertaining to jobs (e.g., the output of the @code{jobs} command), the current job is always flagged with a @samp{+}, and the previous job with a @samp{-}. A job may also be referred to using a prefix of the name used to start it, or using a substring that appears in its command line. For example, @samp{%ce} refers to a stopped @code{ce} job. Using @samp{%?ce}, on the other hand, refers to any job containing the string @samp{ce} in its command line. If the prefix or substring matches more than one job, Bash reports an error. Simply naming a job can be used to bring it into the foreground: @samp{%1} is a synonym for @samp{fg %1}, bringing job 1 from the background into the foreground. Similarly, @samp{%1 &} resumes job 1 in the background, equivalent to @samp{bg %1} The shell learns immediately whenever a job changes state. Normally, Bash waits until it is about to print a prompt before reporting changes in a job's status so as to not interrupt any other output. If the @option{-b} option to the @code{set} builtin is enabled, Bash reports such changes immediately (@pxref{The Set Builtin}). Any trap on @code{SIGCHLD} is executed for each child process that exits. If an attempt to exit Bash is while jobs are stopped, the shell prints a message warning that there are stopped jobs. The @code{jobs} command may then be used to inspect their status. If a second attempt to exit is made without an intervening command, Bash does not print another warning, and the stopped jobs are terminated. @node Job Control Builtins @section Job Control Builtins @table @code @item bg @btindex bg @example bg [@var{jobspec}] @end example Resume the suspended job @var{jobspec} in the background, as if it had been started with @samp{&}. If @var{jobspec} is not supplied, the current job is used. The return status is zero unless it is run when job control is not enabled, or, when run with job control enabled, if @var{jobspec} was not found or @var{jobspec} specifies a job that was started without job control. @item fg @btindex fg @example fg [@var{jobspec}] @end example Resume the job @var{jobspec} in the foreground and make it the current job. If @var{jobspec} is not supplied, the current job is used. The return status is that of the command placed into the foreground, or non-zero if run when job control is disabled or, when run with job control enabled, @var{jobspec} does not specify a valid job or @var{jobspec} specifies a job that was started without job control. @item jobs @btindex jobs @example jobs [-lnprs] [@var{jobspec}] jobs -x @var{command} [@var{arguments}] @end example The first form lists the active jobs. The options have the following meanings: @table @code @item -l List process @sc{id}s in addition to the normal information. @item -n Display information only about jobs that have changed status since the user was last notified of their status. @item -p List only the process @sc{id} of the job's process group leader. @item -r Restrict output to running jobs. @item -s Restrict output to stopped jobs. @end table If @var{jobspec} is given, output is restricted to information about that job. If @var{jobspec} is not supplied, the status of all jobs is listed. If the @option{-x} option is supplied, @code{jobs} replaces any @var{jobspec} found in @var{command} or @var{arguments} with the corresponding process group @sc{id}, and executes @var{command}, passing it @var{argument}s, returning its exit status. @item kill @btindex kill @example kill [-s @var{sigspec}] [-n @var{signum}] [-@var{sigspec}] @var{jobspec} or @var{pid} kill -l [@var{exit_status}] @end example Send a signal specified by @var{sigspec} or @var{signum} to the process named by job specification @var{jobspec} or process @sc{id} @var{pid}. @var{sigspec} is either a signal name such as @code{SIGINT} (with or without the @code{SIG} prefix) or a signal number; @var{signum} is a signal number. If @var{sigspec} and @var{signum} are not present, @code{SIGTERM} is used. The @option{-l} option lists the signal names. If any arguments are supplied when @option{-l} is given, the names of the signals corresponding to the arguments are listed, and the return status is zero. @var{exit_status} is a number specifying a signal number or the exit status of a process terminated by a signal. The return status is zero if at least one signal was successfully sent, or non-zero if an error occurs or an invalid option is encountered. @item wait @btindex wait @example wait [@var{jobspec} or @var{pid}] @end example Wait until the child process specified by process @sc{id} @var{pid} or job specification @var{jobspec} exits and return the exit status of the last command waited for. If a job spec is given, all processes in the job are waited for. If no arguments are given, all currently active child processes are waited for, and the return status is zero. If neither @var{jobspec} nor @var{pid} specifies an active child process of the shell, the return status is 127. @item disown @btindex disown @example disown [-ar] [-h] [@var{jobspec} @dots{}] @end example Without options, each @var{jobspec} is removed from the table of active jobs. If the @option{-h} option is given, the job is not removed from the table, but is marked so that @code{SIGHUP} is not sent to the job if the shell receives a @code{SIGHUP}. If @var{jobspec} is not present, and neither the @option{-a} nor @option{-r} option is supplied, the current job is used. If no @var{jobspec} is supplied, the @option{-a} option means to remove or mark all jobs; the @option{-r} option without a @var{jobspec} argument restricts operation to running jobs. @item suspend @btindex suspend @example suspend [-f] @end example Suspend the execution of this shell until it receives a @code{SIGCONT} signal. The @option{-f} option means to suspend even if the shell is a login shell. @end table When job control is not active, the @code{kill} and @code{wait} builtins do not accept @var{jobspec} arguments. They must be supplied process @sc{id}s. @node Job Control Variables @section Job Control Variables @vtable @code @item auto_resume This variable controls how the shell interacts with the user and job control. If this variable exists then single word simple commands without redirections are treated as candidates for resumption of an existing job. There is no ambiguity allowed; if there is more than one job beginning with the string typed, then the most recently accessed job will be selected. The name of a stopped job, in this context, is the command line used to start it. If this variable is set to the value @samp{exact}, the string supplied must match the name of a stopped job exactly; if set to @samp{substring}, the string supplied needs to match a substring of the name of a stopped job. The @samp{substring} value provides functionality analogous to the @samp{%?} job @sc{id} (@pxref{Job Control Basics}). If set to any other value, the supplied string must be a prefix of a stopped job's name; this provides functionality analogous to the @samp{%} job @sc{id}. @end vtable @set readline-appendix @set history-appendix @cindex Readline, how to use @include rluser.texinfo @cindex History, how to use @include hsuser.texinfo @clear readline-appendix @clear history-appendix @node Installing Bash @chapter Installing Bash This chapter provides basic instructions for installing Bash on the various supported platforms. The distribution supports the @sc{gnu} operating systems, nearly every version of Unix, and several non-Unix systems such as BeOS and Interix. Other independent ports exist for @sc{ms-dos}, @sc{os/2}, Windows @sc{95/98}, and Windows @sc{nt}. @menu * Basic Installation:: Installation instructions. * Compilers and Options:: How to set special options for various systems. * Compiling For Multiple Architectures:: How to compile Bash for more than one kind of system from the same source tree. * Installation Names:: How to set the various paths used by the installation. * Specifying the System Type:: How to configure Bash for a particular system. * Sharing Defaults:: How to share default configuration values among GNU programs. * Operation Controls:: Options recognized by the configuration program. * Optional Features:: How to enable and disable optional features when building Bash. @end menu @node Basic Installation @section Basic Installation @cindex installation @cindex configuration @cindex Bash installation @cindex Bash configuration These are installation instructions for Bash. The simplest way to compile Bash is: @enumerate @item @code{cd} to the directory containing the source code and type @samp{./configure} to configure Bash for your system. If you're using @code{csh} on an old version of System V, you might need to type @samp{sh ./configure} instead to prevent @code{csh} from trying to execute @code{configure} itself. Running @code{configure} takes some time. While running, it prints messages telling which features it is checking for. @item Type @samp{make} to compile Bash and build the @code{bashbug} bug reporting script. @item Optionally, type @samp{make tests} to run the Bash test suite. @item Type @samp{make install} to install @code{bash} and @code{bashbug}. This will also install the manual pages and Info file. @end enumerate The @code{configure} shell script attempts to guess correct values for various system-dependent variables used during compilation. It uses those values to create a @file{Makefile} in each directory of the package (the top directory, the @file{builtins}, @file{doc}, and @file{support} directories, each directory under @file{lib}, and several others). It also creates a @file{config.h} file containing system-dependent definitions. Finally, it creates a shell script named @code{config.status} that you can run in the future to recreate the current configuration, a file @file{config.cache} that saves the results of its tests to speed up reconfiguring, and a file @file{config.log} containing compiler output (useful mainly for debugging @code{configure}). If at some point @file{config.cache} contains results you don't want to keep, you may remove or edit it. To find out more about the options and arguments that the @code{configure} script understands, type @example bash-2.04$ ./configure --help @end example @noindent at the Bash prompt in your Bash source directory. If you need to do unusual things to compile Bash, please try to figure out how @code{configure} could check whether or not to do them, and mail diffs or instructions to @email{bash-maintainers@@gnu.org} so they can be considered for the next release. The file @file{configure.in} is used to create @code{configure} by a program called Autoconf. You only need @file{configure.in} if you want to change it or regenerate @code{configure} using a newer version of Autoconf. If you do this, make sure you are using Autoconf version 2.50 or newer. You can remove the program binaries and object files from the source code directory by typing @samp{make clean}. To also remove the files that @code{configure} created (so you can compile Bash for a different kind of computer), type @samp{make distclean}. @node Compilers and Options @section Compilers and Options Some systems require unusual options for compilation or linking that the @code{configure} script does not know about. You can give @code{configure} initial values for variables by setting them in the environment. Using a Bourne-compatible shell, you can do that on the command line like this: @example CC=c89 CFLAGS=-O2 LIBS=-lposix ./configure @end example On systems that have the @code{env} program, you can do it like this: @example env CPPFLAGS=-I/usr/local/include LDFLAGS=-s ./configure @end example The configuration process uses GCC to build Bash if it is available. @node Compiling For Multiple Architectures @section Compiling For Multiple Architectures You can compile Bash for more than one kind of computer at the same time, by placing the object files for each architecture in their own directory. To do this, you must use a version of @code{make} that supports the @code{VPATH} variable, such as GNU @code{make}. @code{cd} to the directory where you want the object files and executables to go and run the @code{configure} script from the source directory. You may need to supply the @option{--srcdir=PATH} argument to tell @code{configure} where the source files are. @code{configure} automatically checks for the source code in the directory that @code{configure} is in and in `..'. If you have to use a @code{make} that does not supports the @code{VPATH} variable, you can compile Bash for one architecture at a time in the source code directory. After you have installed Bash for one architecture, use @samp{make distclean} before reconfiguring for another architecture. Alternatively, if your system supports symbolic links, you can use the @file{support/mkclone} script to create a build tree which has symbolic links back to each file in the source directory. Here's an example that creates a build directory in the current directory from a source directory @file{/usr/gnu/src/bash-2.0}: @example bash /usr/gnu/src/bash-2.0/support/mkclone -s /usr/gnu/src/bash-2.0 . @end example @noindent The @code{mkclone} script requires Bash, so you must have already built Bash for at least one architecture before you can create build directories for other architectures. @node Installation Names @section Installation Names By default, @samp{make install} will install into @file{/usr/local/bin}, @file{/usr/local/man}, etc. You can specify an installation prefix other than @file{/usr/local} by giving @code{configure} the option @option{--prefix=@var{PATH}}, or by specifying a value for the @code{DESTDIR} @samp{make} variable when running @samp{make install}. You can specify separate installation prefixes for architecture-specific files and architecture-independent files. If you give @code{configure} the option @option{--exec-prefix=@var{PATH}}, @samp{make install} will use @var{PATH} as the prefix for installing programs and libraries. Documentation and other data files will still use the regular prefix. @node Specifying the System Type @section Specifying the System Type There may be some features @code{configure} can not figure out automatically, but need to determine by the type of host Bash will run on. Usually @code{configure} can figure that out, but if it prints a message saying it can not guess the host type, give it the @option{--host=TYPE} option. @samp{TYPE} can either be a short name for the system type, such as @samp{sun4}, or a canonical name with three fields: @samp{CPU-COMPANY-SYSTEM} (e.g., @samp{i386-unknown-freebsd4.2}). See the file @file{support/config.sub} for the possible values of each field. @node Sharing Defaults @section Sharing Defaults If you want to set default values for @code{configure} scripts to share, you can create a site shell script called @code{config.site} that gives default values for variables like @code{CC}, @code{cache_file}, and @code{prefix}. @code{configure} looks for @file{PREFIX/share/config.site} if it exists, then @file{PREFIX/etc/config.site} if it exists. Or, you can set the @code{CONFIG_SITE} environment variable to the location of the site script. A warning: the Bash @code{configure} looks for a site script, but not all @code{configure} scripts do. @node Operation Controls @section Operation Controls @code{configure} recognizes the following options to control how it operates. @table @code @item --cache-file=@var{file} Use and save the results of the tests in @var{file} instead of @file{./config.cache}. Set @var{file} to @file{/dev/null} to disable caching, for debugging @code{configure}. @item --help Print a summary of the options to @code{configure}, and exit. @item --quiet @itemx --silent @itemx -q Do not print messages saying which checks are being made. @item --srcdir=@var{dir} Look for the Bash source code in directory @var{dir}. Usually @code{configure} can determine that directory automatically. @item --version Print the version of Autoconf used to generate the @code{configure} script, and exit. @end table @code{configure} also accepts some other, not widely used, boilerplate options. @samp{configure --help} prints the complete list. @node Optional Features @section Optional Features The Bash @code{configure} has a number of @option{--enable-@var{feature}} options, where @var{feature} indicates an optional part of Bash. There are also several @option{--with-@var{package}} options, where @var{package} is something like @samp{bash-malloc} or @samp{purify}. To turn off the default use of a package, use @option{--without-@var{package}}. To configure Bash without a feature that is enabled by default, use @option{--disable-@var{feature}}. Here is a complete list of the @option{--enable-} and @option{--with-} options that the Bash @code{configure} recognizes. @table @code @item --with-afs Define if you are using the Andrew File System from Transarc. @item --with-bash-malloc Use the Bash version of @code{malloc} in @file{lib/malloc/malloc.c}. This is not the same @code{malloc} that appears in @sc{gnu} libc, but an older version derived from the 4.2 @sc{bsd} @code{malloc}. This @code{malloc} is very fast, but wastes some space on each allocation. This option is enabled by default. The @file{NOTES} file contains a list of systems for which this should be turned off, and @code{configure} disables this option automatically for a number of systems. @item --with-curses Use the curses library instead of the termcap library. This should be supplied if your system has an inadequate or incomplete termcap database. @item --with-gnu-malloc A synonym for @code{--with-bash-malloc}. @item --with-installed-readline[=@var{PREFIX}] Define this to make Bash link with a locally-installed version of Readline rather than the version in @file{lib/readline}. This works only with Readline 4.2 and later versions. If @var{PREFIX} is @code{yes} or not supplied, @code{configure} uses the values of the make variables @code{includedir} and @code{libdir}, which are subdirectories of @code{prefix} by default, to find the installed version of Readline if it is not in the standard system include and library directories. If @var{PREFIX} is @code{no}, Bash links with the version in @file{lib/readline}. If @var{PREFIX} is set to any other value, @code{configure} treats it as a directory pathname and looks for the installed version of Readline in subdirectories of that directory (include files in @var{PREFIX}/@code{include} and the library in @var{PREFIX}/@code{lib}). @item --with-purify Define this to use the Purify memory allocation checker from Rational Software. @item --enable-minimal-config This produces a shell with minimal features, close to the historical Bourne shell. @end table There are several @option{--enable-} options that alter how Bash is compiled and linked, rather than changing run-time features. @table @code @item --enable-largefile Enable support for @uref{http://www.sas.com/standards/large_file/x_open.20Mar96.html, large files} if the operating system requires special compiler options to build programs which can access large files. @item --enable-profiling This builds a Bash binary that produces profiling information to be processed by @code{gprof} each time it is executed. @item --enable-static-link This causes Bash to be linked statically, if @code{gcc} is being used. This could be used to build a version to use as root's shell. @end table The @samp{minimal-config} option can be used to disable all of the following options, but it is processed first, so individual options may be enabled using @samp{enable-@var{feature}}. All of the following options except for @samp{disabled-builtins} and @samp{xpg-echo-default} are enabled by default, unless the operating system does not provide the necessary support. @table @code @item --enable-alias Allow alias expansion and include the @code{alias} and @code{unalias} builtins (@pxref{Aliases}). @item --enable-arith-for-command Include support for the alternate form of the @code{for} command that behaves like the C language @code{for} statement (@pxref{Looping Constructs}). @item --enable-array-variables Include support for one-dimensional array shell variables (@pxref{Arrays}). @item --enable-bang-history Include support for @code{csh}-like history substitution (@pxref{History Interaction}). @item --enable-brace-expansion Include @code{csh}-like brace expansion ( @code{b@{a,b@}c} @expansion{} @code{bac bbc} ). See @ref{Brace Expansion}, for a complete description. @item --enable-command-timing Include support for recognizing @code{time} as a reserved word and for displaying timing statistics for the pipeline following @code{time} (@pxref{Pipelines}). This allows pipelines as well as shell builtins and functions to be timed. @item --enable-cond-command Include support for the @code{[[} conditional command (@pxref{Conditional Constructs}). @item --enable-directory-stack Include support for a @code{csh}-like directory stack and the @code{pushd}, @code{popd}, and @code{dirs} builtins (@pxref{The Directory Stack}). @item --enable-disabled-builtins Allow builtin commands to be invoked via @samp{builtin xxx} even after @code{xxx} has been disabled using @samp{enable -n xxx}. See @ref{Bash Builtins}, for details of the @code{builtin} and @code{enable} builtin commands. @item --enable-dparen-arithmetic Include support for the @code{((@dots{}))} command (@pxref{Conditional Constructs}). @item --enable-extended-glob Include support for the extended pattern matching features described above under @ref{Pattern Matching}. @item --enable-help-builtin Include the @code{help} builtin, which displays help on shell builtins and variables (@pxref{Bash Builtins}). @item --enable-history Include command history and the @code{fc} and @code{history} builtin commands (@pxref{Bash History Facilities}). @item --enable-job-control This enables the job control features (@pxref{Job Control}), if the operating system supports them. @item --enable-net-redirections This enables the special handling of filenames of the form @code{/dev/tcp/@var{host}/@var{port}} and @code{/dev/udp/@var{host}/@var{port}} when used in redirections (@pxref{Redirections}). @item --enable-process-substitution This enables process substitution (@pxref{Process Substitution}) if the operating system provides the necessary support. @item --enable-prompt-string-decoding Turn on the interpretation of a number of backslash-escaped characters in the @env{$PS1}, @env{$PS2}, @env{$PS3}, and @env{$PS4} prompt strings. See @ref{Printing a Prompt}, for a complete list of prompt string escape sequences. @item --enable-progcomp Enable the programmable completion facilities (@pxref{Programmable Completion}). If Readline is not enabled, this option has no effect. @item --enable-readline Include support for command-line editing and history with the Bash version of the Readline library (@pxref{Command Line Editing}). @item --enable-restricted Include support for a @dfn{restricted shell}. If this is enabled, Bash, when called as @code{rbash}, enters a restricted mode. See @ref{The Restricted Shell}, for a description of restricted mode. @item --enable-select Include the @code{select} builtin, which allows the generation of simple menus (@pxref{Conditional Constructs}). @item --enable-usg-echo-default A synonym for @code{--enable-xpg-echo-default}. @item --enable-xpg-echo-default Make the @code{echo} builtin expand backslash-escaped characters by default, without requiring the @option{-e} option. This sets the default value of the @code{xpg_echo} shell option to @code{on}, which makes the Bash @code{echo} behave more like the version specified in the Single Unix Specification, version 2. @xref{Bash Builtins}, for a description of the escape sequences that @code{echo} recognizes. @end table The file @file{config-top.h} contains C Preprocessor @samp{#define} statements for options which are not settable from @code{configure}. Some of these are not meant to be changed; beware of the consequences if you do. Read the comments associated with each definition for more information about its effect. @node Reporting Bugs @appendix Reporting Bugs Please report all bugs you find in Bash. But first, you should make sure that it really is a bug, and that it appears in the latest version of Bash that you have. Once you have determined that a bug actually exists, use the @code{bashbug} command to submit a bug report. If you have a fix, you are encouraged to mail that as well! Suggestions and `philosophical' bug reports may be mailed to @email{bug-bash@@gnu.org} or posted to the Usenet newsgroup @code{gnu.bash.bug}. All bug reports should include: @itemize @bullet @item The version number of Bash. @item The hardware and operating system. @item The compiler used to compile Bash. @item A description of the bug behaviour. @item A short script or `recipe' which exercises the bug and may be used to reproduce it. @end itemize @noindent @code{bashbug} inserts the first three items automatically into the template it provides for filing a bug report. Please send all reports concerning this manual to @email{chet@@po.CWRU.Edu}. @node Major Differences From The Bourne Shell @appendix Major Differences From The Bourne Shell Bash implements essentially the same grammar, parameter and variable expansion, redirection, and quoting as the Bourne Shell. Bash uses the @sc{posix} 1003.2 standard as the specification of how these features are to be implemented. There are some differences between the traditional Bourne shell and Bash; this section quickly details the differences of significance. A number of these differences are explained in greater depth in previous sections. This section uses the version of @code{sh} included in SVR4.2 as the baseline reference. @itemize @bullet @item Bash is @sc{posix}-conformant, even where the @sc{posix} specification differs from traditional @code{sh} behavior (@pxref{Bash POSIX Mode}). @item Bash has multi-character invocation options (@pxref{Invoking Bash}). @item Bash has command-line editing (@pxref{Command Line Editing}) and the @code{bind} builtin. @item Bash provides a programmable word completion mechanism (@pxref{Programmable Completion}), and two builtin commands, @code{complete} and @code{compgen}, to manipulate it. @item Bash has command history (@pxref{Bash History Facilities}) and the @code{history} and @code{fc} builtins to manipulate it. @item Bash implements @code{csh}-like history expansion (@pxref{History Interaction}). @item Bash has one-dimensional array variables (@pxref{Arrays}), and the appropriate variable expansions and assignment syntax to use them. Several of the Bash builtins take options to act on arrays. Bash provides a number of built-in array variables. @item The @code{$'@dots{}'} quoting syntax, which expands ANSI-C backslash-escaped characters in the text between the single quotes, is supported (@pxref{ANSI-C Quoting}). @item Bash supports the @code{$"@dots{}"} quoting syntax to do locale-specific translation of the characters between the double quotes. The @option{-D}, @option{--dump-strings}, and @option{--dump-po-strings} invocation options list the translatable strings found in a script (@pxref{Locale Translation}). @item Bash implements the @code{!} keyword to negate the return value of a pipeline (@pxref{Pipelines}). Very useful when an @code{if} statement needs to act only if a test fails. @item Bash has the @code{time} reserved word and command timing (@pxref{Pipelines}). The display of the timing statistics may be controlled with the @env{TIMEFORMAT} variable. @item Bash implements the @code{for (( @var{expr1} ; @var{expr2} ; @var{expr3} ))} arithmetic for command, similar to the C language (@pxref{Looping Constructs}). @item Bash includes the @code{select} compound command, which allows the generation of simple menus (@pxref{Conditional Constructs}). @item Bash includes the @code{[[} compound command, which makes conditional testing part of the shell grammar (@pxref{Conditional Constructs}). @item Bash includes brace expansion (@pxref{Brace Expansion}) and tilde expansion (@pxref{Tilde Expansion}). @item Bash implements command aliases and the @code{alias} and @code{unalias} builtins (@pxref{Aliases}). @item Bash provides shell arithmetic, the @code{((} compound command (@pxref{Conditional Constructs}), and arithmetic expansion (@pxref{Shell Arithmetic}). @item Variables present in the shell's initial environment are automatically exported to child processes. The Bourne shell does not normally do this unless the variables are explicitly marked using the @code{export} command. @item Bash includes the @sc{posix} pattern removal @samp{%}, @samp{#}, @samp{%%} and @samp{##} expansions to remove leading or trailing substrings from variable values (@pxref{Shell Parameter Expansion}). @item The expansion @code{$@{#xx@}}, which returns the length of @code{$@{xx@}}, is supported (@pxref{Shell Parameter Expansion}). @item The expansion @code{$@{var:}@var{offset}@code{[:}@var{length}@code{]@}}, which expands to the substring of @code{var}'s value of length @var{length}, beginning at @var{offset}, is present (@pxref{Shell Parameter Expansion}). @item The expansion @code{$@{var/[/]}@var{pattern}@code{[/}@var{replacement}@code{]@}}, which matches @var{pattern} and replaces it with @var{replacement} in the value of @code{var}, is available (@pxref{Shell Parameter Expansion}). @item The expansion @code{$@{!@var{prefix@}*}} expansion, which expands to the names of all shell variables whose names begin with @var{prefix}, is available (@pxref{Shell Parameter Expansion}). @item Bash has @var{indirect} variable expansion using @code{$@{!word@}} (@pxref{Shell Parameter Expansion}). @item Bash can expand positional parameters beyond @code{$9} using @code{$@{@var{num}@}}. @item The @sc{posix} @code{$()} form of command substitution is implemented (@pxref{Command Substitution}), and preferred to the Bourne shell's @code{``} (which is also implemented for backwards compatibility). @item Bash has process substitution (@pxref{Process Substitution}). @item Bash automatically assigns variables that provide information about the current user (@env{UID}, @env{EUID}, and @env{GROUPS}), the current host (@env{HOSTTYPE}, @env{OSTYPE}, @env{MACHTYPE}, and @env{HOSTNAME}), and the instance of Bash that is running (@env{BASH}, @env{BASH_VERSION}, and @env{BASH_VERSINFO}). @xref{Bash Variables}, for details. @item The @env{IFS} variable is used to split only the results of expansion, not all words (@pxref{Word Splitting}). This closes a longstanding shell security hole. @item Bash implements the full set of @sc{posix} 1003.2 filename expansion operators, including @var{character classes}, @var{equivalence classes}, and @var{collating symbols} (@pxref{Filename Expansion}). @item Bash implements extended pattern matching features when the @code{extglob} shell option is enabled (@pxref{Pattern Matching}). @item It is possible to have a variable and a function with the same name; @code{sh} does not separate the two name spaces. @item Bash functions are permitted to have local variables using the @code{local} builtin, and thus useful recursive functions may be written (@pxref{Bash Builtins}). @item Variable assignments preceding commands affect only that command, even builtins and functions (@pxref{Environment}). In @code{sh}, all variable assignments preceding commands are global unless the command is executed from the file system. @item Bash performs filename expansion on filenames specified as operands to input and output redirection operators (@pxref{Redirections}). @item Bash contains the @samp{<>} redirection operator, allowing a file to be opened for both reading and writing, and the @samp{&>} redirection operator, for directing standard output and standard error to the same file (@pxref{Redirections}). @item Bash treats a number of filenames specially when they are used in redirection operators (@pxref{Redirections}). @item Bash can open network connections to arbitrary machines and services with the redirection operators (@pxref{Redirections}). @item The @code{noclobber} option is available to avoid overwriting existing files with output redirection (@pxref{The Set Builtin}). The @samp{>|} redirection operator may be used to override @code{noclobber}. @item The Bash @code{cd} and @code{pwd} builtins (@pxref{Bourne Shell Builtins}) each take @option{-L} and @option{-P} options to switch between logical and physical modes. @item Bash allows a function to override a builtin with the same name, and provides access to that builtin's functionality within the function via the @code{builtin} and @code{command} builtins (@pxref{Bash Builtins}). @item The @code{command} builtin allows selective disabling of functions when command lookup is performed (@pxref{Bash Builtins}). @item Individual builtins may be enabled or disabled using the @code{enable} builtin (@pxref{Bash Builtins}). @item The Bash @code{exec} builtin takes additional options that allow users to control the contents of the environment passed to the executed command, and what the zeroth argument to the command is to be (@pxref{Bourne Shell Builtins}). @item Shell functions may be exported to children via the environment using @code{export -f} (@pxref{Shell Functions}). @item The Bash @code{export}, @code{readonly}, and @code{declare} builtins can take a @option{-f} option to act on shell functions, a @option{-p} option to display variables with various attributes set in a format that can be used as shell input, a @option{-n} option to remove various variable attributes, and @samp{name=value} arguments to set variable attributes and values simultaneously. @item The Bash @code{hash} builtin allows a name to be associated with an arbitrary filename, even when that filename cannot be found by searching the @env{$PATH}, using @samp{hash -p} (@pxref{Bourne Shell Builtins}). @item Bash includes a @code{help} builtin for quick reference to shell facilities (@pxref{Bash Builtins}). @item The @code{printf} builtin is available to display formatted output (@pxref{Bash Builtins}). @item The Bash @code{read} builtin (@pxref{Bash Builtins}) will read a line ending in @samp{\} with the @option{-r} option, and will use the @env{REPLY} variable as a default if no non-option arguments are supplied. The Bash @code{read} builtin also accepts a prompt string with the @option{-p} option and will use Readline to obtain the line when given the @option{-e} option. The @code{read} builtin also has additional options to control input: the @option{-s} option will turn off echoing of input characters as they are read, the @option{-t} option will allow @code{read} to time out if input does not arrive within a specified number of seconds, the @option{-n} option will allow reading only a specified number of characters rather than a full line, and the @option{-d} option will read until a particular character rather than newline. @item The @code{return} builtin may be used to abort execution of scripts executed with the @code{.} or @code{source} builtins (@pxref{Bourne Shell Builtins}). @item Bash includes the @code{shopt} builtin, for finer control of shell optional capabilities (@pxref{Bash Builtins}), and allows these options to be set and unset at shell invocation (@pxref{Invoking Bash}). @item Bash has much more optional behavior controllable with the @code{set} builtin (@pxref{The Set Builtin}). @item The @code{test} builtin (@pxref{Bourne Shell Builtins}) is slightly different, as it implements the @sc{posix} algorithm, which specifies the behavior based on the number of arguments. @item The @code{trap} builtin (@pxref{Bourne Shell Builtins}) allows a @code{DEBUG} pseudo-signal specification, similar to @code{EXIT}. Commands specified with a @code{DEBUG} trap are executed after every simple command. The @code{DEBUG} trap is not inherited by shell functions. The @code{trap} builtin (@pxref{Bourne Shell Builtins}) allows an @code{ERR} pseudo-signal specification, similar to @code{EXIT} and @code{DEBUG}. Commands specified with an @code{ERR} trap are executed after a simple command fails, with a few exceptions. The @code{ERR} trap is not inherited by shell functions. @item The Bash @code{type} builtin is more extensive and gives more information about the names it finds (@pxref{Bash Builtins}). @item The Bash @code{umask} builtin permits a @option{-p} option to cause the output to be displayed in the form of a @code{umask} command that may be reused as input (@pxref{Bourne Shell Builtins}). @item Bash implements a @code{csh}-like directory stack, and provides the @code{pushd}, @code{popd}, and @code{dirs} builtins to manipulate it (@pxref{The Directory Stack}). Bash also makes the directory stack visible as the value of the @env{DIRSTACK} shell variable. @item Bash interprets special backslash-escaped characters in the prompt strings when interactive (@pxref{Printing a Prompt}). @item The Bash restricted mode is more useful (@pxref{The Restricted Shell}); the SVR4.2 shell restricted mode is too limited. @item The @code{disown} builtin can remove a job from the internal shell job table (@pxref{Job Control Builtins}) or suppress the sending of @code{SIGHUP} to a job when the shell exits as the result of a @code{SIGHUP}. @item The SVR4.2 shell has two privilege-related builtins (@code{mldmode} and @code{priv}) not present in Bash. @item Bash does not have the @code{stop} or @code{newgrp} builtins. @item Bash does not use the @env{SHACCT} variable or perform shell accounting. @item The SVR4.2 @code{sh} uses a @env{TIMEOUT} variable like Bash uses @env{TMOUT}. @end itemize @noindent More features unique to Bash may be found in @ref{Bash Features}. @appendixsec Implementation Differences From The SVR4.2 Shell Since Bash is a completely new implementation, it does not suffer from many of the limitations of the SVR4.2 shell. For instance: @itemize @bullet @item Bash does not fork a subshell when redirecting into or out of a shell control structure such as an @code{if} or @code{while} statement. @item Bash does not allow unbalanced quotes. The SVR4.2 shell will silently insert a needed closing quote at @code{EOF} under certain circumstances. This can be the cause of some hard-to-find errors. @item The SVR4.2 shell uses a baroque memory management scheme based on trapping @code{SIGSEGV}. If the shell is started from a process with @code{SIGSEGV} blocked (e.g., by using the @code{system()} C library function call), it misbehaves badly. @item In a questionable attempt at security, the SVR4.2 shell, when invoked without the @option{-p} option, will alter its real and effective @sc{uid} and @sc{gid} if they are less than some magic threshold value, commonly 100. This can lead to unexpected results. @item The SVR4.2 shell does not allow users to trap @code{SIGSEGV}, @code{SIGALRM}, or @code{SIGCHLD}. @item The SVR4.2 shell does not allow the @env{IFS}, @env{MAILCHECK}, @env{PATH}, @env{PS1}, or @env{PS2} variables to be unset. @item The SVR4.2 shell treats @samp{^} as the undocumented equivalent of @samp{|}. @item Bash allows multiple option arguments when it is invoked (@code{-x -v}); the SVR4.2 shell allows only one option argument (@code{-xv}). In fact, some versions of the shell dump core if the second argument begins with a @samp{-}. @item The SVR4.2 shell exits a script if any builtin fails; Bash exits a script only if one of the @sc{posix} 1003.2 special builtins fails, and only for certain failures, as enumerated in the @sc{posix} 1003.2 standard. @item The SVR4.2 shell behaves differently when invoked as @code{jsh} (it turns on job control). @end itemize @node Builtin Index @unnumbered Index of Shell Builtin Commands @printindex bt @node Reserved Word Index @unnumbered Index of Shell Reserved Words @printindex rw @node Variable Index @unnumbered Parameter and Variable Index @printindex vr @node Function Index @unnumbered Function Index @printindex fn @node Concept Index @unnumbered Concept Index @printindex cp @contents @bye bash-2.05a/doc/bashref.info100664 436 0 1220141 7374257266 14074 0ustar chetwheelThis is bashref.info, produced by makeinfo version 4.0 from /usr/homes/chet/src/bash/src/doc/bashref.texi. INFO-DIR-SECTION Utilities START-INFO-DIR-ENTRY * Bash: (bash). The GNU Bourne-Again SHell. END-INFO-DIR-ENTRY This text is a brief description of the features that are present in the Bash shell. This is Edition 2.5a, last updated 13 November 2001, of `The GNU Bash Reference Manual', for `Bash', Version 2.05a. Copyright (C) 1991-2001 Free Software Foundation, Inc. Permission is granted to make and distribute verbatim copies of this manual provided the copyright notice and this permission notice are preserved on all copies. Permission is granted to copy and distribute modified versions of this manual under the conditions for verbatim copying, provided that the entire resulting derived work is distributed under the terms of a permission notice identical to this one. Permission is granted to copy and distribute translations of this manual into another language, under the above conditions for modified versions, except that this permission notice may be stated in a translation approved by the Free Software Foundation.  File: bashref.info, Node: Top, Next: Introduction, Prev: (dir), Up: (dir) Bash Features ************* This text is a brief description of the features that are present in the Bash shell. This is Edition 2.5a, last updated 13 November 2001, of `The GNU Bash Reference Manual', for `Bash', Version 2.05a. Copyright (C) 1991, 1993, 1996 Free Software Foundation, Inc. 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 based upon which one of these other shells inspired the feature. This manual is meant as a brief introduction to features found in Bash. The Bash manual page should be used as the definitive reference on shell behavior. * Menu: * Introduction:: An introduction to the shell. * Definitions:: Some definitions used in the rest of this manual. * Basic Shell Features:: The shell "building blocks". * Shell Builtin Commands:: Commands that are a part of the shell. * Shell Variables:: Variables used or set by Bash. * Bash Features:: Features found only in Bash. * Job Control:: A chapter describing what job control is and how Bash allows you to use it. * Using History Interactively:: Chapter dealing with history expansion rules. * Command Line Editing:: Chapter describing the command line editing features. * Installing Bash:: How to build and install Bash on your system. * Reporting Bugs:: How to report bugs in Bash. * Major Differences From The Bourne Shell:: A terse list of the differences between Bash and historical versions of /bin/sh. * Builtin Index:: Index of Bash builtin commands. * Reserved Word Index:: Index of Bash reserved words. * Variable Index:: Quick reference helps you find the variable you want. * Function Index:: Index of bindable Readline functions. * Concept Index:: General index for concepts described in this manual.  File: bashref.info, Node: Introduction, Next: Definitions, Prev: Top, Up: Top Introduction ************ * Menu: * What is Bash?:: A short description of Bash. * What is a shell?:: A brief introduction to shells.  File: bashref.info, Node: What is Bash?, Next: What is a shell?, Up: Introduction What is Bash? ============= Bash is the shell, or command language interpreter, for the GNU operating system. The name is an acronym for the `Bourne-Again SHell', a pun on Stephen Bourne, the author of the direct ancestor of the current Unix shell `/bin/sh', which appeared in the Seventh Edition Bell Labs Research version of Unix. Bash is largely compatible with `sh' and incorporates useful features from the Korn shell `ksh' and the C shell `csh'. It is intended to be a conformant implementation of the IEEE POSIX Shell and Tools specification (IEEE Working Group 1003.2). It offers functional improvements over `sh' for both interactive and programming use. While the GNU operating system provides other shells, including a version of `csh', Bash is the default shell. Like other GNU software, Bash is quite portable. It currently runs on nearly every version of Unix and a few other operating systems - independently-supported ports exist for MS-DOS, OS/2, Windows 95/98, and Windows NT.  File: bashref.info, Node: What is a shell?, Prev: What is Bash?, Up: Introduction What is a shell? ================ At its base, a shell is simply a macro processor that executes commands. A Unix shell is both a command interpreter, which provides the user interface to the rich set of GNU utilities, and a programming language, allowing these utilitites to be combined. Files containing commands can be created, and become commands themselves. These new commands have the same status as system commands in directories such as `/bin', allowing users or groups to establish custom environments. A shell allows execution of GNU commands, both synchronously and asynchronously. The shell waits for synchronous commands to complete before accepting more input; asynchronous commands continue to execute in parallel with the shell while it reads and executes additional commands. The "redirection" constructs permit fine-grained control of the input and output of those commands. Moreover, the shell allows control over the contents of commands' environments. Shells may be used interactively or non-interactively: they accept input typed from the keyboard or from a file. Shells also provide a small set of built-in commands ("builtins") implementing functionality impossible or inconvenient to obtain via separate utilities. For example, `cd', `break', `continue', and `exec') cannot be implemented outside of the shell because they directly manipulate the shell itself. The `history', `getopts', `kill', or `pwd' builtins, among others, could be implemented in separate utilities, but they are more convenient to use as builtin commands. All of the shell builtins are described in subsequent sections. While executing commands is essential, most of the power (and complexity) of shells is due to their embedded programming languages. Like any high-level language, the shell provides variables, flow control constructs, quoting, and functions. Shells offer features geared specifically for interactive use rather than to augment the programming language. These interactive features include job control, command line editing, history and aliases. Each of these features is described in this manual.  File: bashref.info, Node: Definitions, Next: Basic Shell Features, Prev: Introduction, Up: Top Definitions *********** These definitions are used throughout the remainder of this manual. `POSIX' A family of open system standards based on Unix. Bash is concerned with POSIX 1003.2, the Shell and Tools Standard. `blank' A space or tab character. `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 `word' 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 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 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. `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 (resume) execution of processes. `metacharacter' A character that, when unquoted, separates words. A metacharacter is a `blank' or one of the following characters: `|', `&', `;', `(', `)', `<', or `>'. `name' A `word' consisting solely of letters, numbers, and underscores, and beginning with a letter or underscore. `Name's are used as shell variable and function names. Also referred to as an `identifier'. `operator' A `control operator' or a `redirection operator'. *Note Redirections::, for a list of redirection operators. `process group' A collection of related processes each having the same process group ID. `process group ID' A unique identifer that represents a `process group' during its lifetime. `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'. `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 POSIX 1003.2 standard. `token' A sequence of characters considered a single unit by the shell. It is either a `word' or an `operator'. `word' A `token' that is not an `operator'.  File: bashref.info, Node: Basic Shell Features, Next: Shell Builtin Commands, Prev: Definitions, Up: Top Basic Shell Features ******************** Bash is an acronym for `Bourne-Again SHell'. The Bourne shell is the traditional Unix shell originally written by Stephen Bourne. All of the Bourne shell builtin commands are available in Bash, and the rules for evaluation and quoting are taken from the POSIX 1003.2 specification for the `standard' Unix shell. This chapter briefly summarizes the shell's `building blocks': commands, control structures, shell functions, shell parameters, shell expansions, redirections, which are a way to direct input and output from and to named files, and how the shell executes commands. * Menu: * Shell Syntax:: What your input means to the shell. * Shell Commands:: The types of commands you can use. * Shell Functions:: Grouping commands by name. * Shell Parameters:: Special shell variables. * Shell Expansions:: How Bash expands variables and the various expansions available. * Redirections:: A way to control where input and output go. * Executing Commands:: What happens when you run a command. * Shell Scripts:: Executing files of shell commands.  File: bashref.info, Node: Shell Syntax, Next: Shell Commands, Up: Basic Shell Features Shell Syntax ============ * Menu: * Shell Operation:: The basic operation of the shell. * Quoting:: How to remove the special meaning from characters. * Comments:: How to specify comments. When the shell reads input, it proceeds through a sequence of operations. If the input indicates the beginning of a comment, the shell ignores the comment symbol (`#'), and the rest of that line. Otherwise, roughly speaking, the shell reads its input and divides the input into words and operators, employing the quoting rules to select which meanings to assign various words and characters. The shell then parses these tokens into commands and other constructs, removes the special meaning of certain words or characters, expands others, redirects input and output as needed, executes the specified command, waits for the command's exit status, and makes that exit status available for further inspection or processing.  File: bashref.info, Node: Shell Operation, Next: Quoting, Up: Shell Syntax Shell Operation --------------- The following is a brief description of the shell's operation when it reads and executes a command. Basically, the shell does the following: 1. Reads its input from a file (*note Shell Scripts::), from a string supplied as an argument to the `-c' invocation option (*note Invoking Bash::), or from the user's terminal. 2. Breaks the input into words and operators, obeying the quoting rules described in *Note Quoting::. These tokens are separated by `metacharacters'. Alias expansion is performed by this step (*note Aliases::). 3. Parses the tokens into simple and compound commands (*note Shell Commands::). 4. Performs the various shell expansions (*note Shell Expansions::), breaking the expanded tokens into lists of filenames (*note Filename Expansion::) and commands and arguments. 5. Performs any necessary redirections (*note Redirections::) and removes the redirection operators and their operands from the argument list. 6. Executes the command (*note Executing Commands::). 7. Optionally waits for the command to complete and collects its exit status (*note Exit Status::).  File: bashref.info, Node: Quoting, Next: Comments, Prev: Shell Operation, Up: Shell Syntax Quoting ------- * Menu: * Escape Character:: How to remove the special meaning from a single character. * Single Quotes:: How to inhibit all interpretation of a sequence of characters. * Double Quotes:: How to suppress most of the interpretation of a sequence of characters. * ANSI-C Quoting:: How to expand ANSI-C sequences in quoted strings. * Locale Translation:: How to translate strings into different languages. Quoting is used to remove the special meaning of certain characters or words to the shell. Quoting can be used to disable special treatment for special characters, to prevent reserved words from being recognized as such, and to prevent parameter expansion. Each of the shell metacharacters (*note Definitions::) has special meaning to the shell and must be quoted if it is to represent itself. When the command history expansion facilities are being used, the HISTORY EXPANSION character, usually `!', must be quoted to prevent history expansion. *Note Bash History Facilities::, for more details concerning history expansion. There are three quoting mechanisms: the ESCAPE CHARACTER, single quotes, and double quotes.  File: bashref.info, Node: Escape Character, Next: Single Quotes, Up: Quoting Escape Character ................ A non-quoted backslash `\' is the Bash escape character. It preserves the literal value of the next character that follows, with the exception of `newline'. If a `\newline' pair appears, and the backslash itself is not quoted, the `\newline' is treated as a line continuation (that is, it is removed from the input stream and effectively ignored).  File: bashref.info, Node: Single Quotes, Next: Double Quotes, Prev: Escape Character, Up: Quoting Single Quotes ............. Enclosing characters in single quotes (`'') preserves the literal value of each character within the quotes. A single quote may not occur between single quotes, even when preceded by a backslash.  File: bashref.info, Node: Double Quotes, Next: ANSI-C Quoting, Prev: Single Quotes, Up: Quoting Double Quotes ............. Enclosing characters in double quotes (`"') preserves the literal value of all characters within the quotes, with the exception of `$', ``', and `\'. The characters `$' and ``' retain their special meaning within double quotes (*note Shell Expansions::). The backslash retains its special meaning only when followed by one of the following characters: `$', ``', `"', `\', or `newline'. Within double quotes, backslashes that are followed by one of these characters are removed. Backslashes preceding characters without a special meaning are left unmodified. A double quote may be quoted within double quotes by preceding it with a backslash. The special parameters `*' and `@' have special meaning when in double quotes (*note Shell Parameter Expansion::).  File: bashref.info, Node: ANSI-C Quoting, Next: Locale Translation, Prev: Double Quotes, Up: Quoting ANSI-C Quoting .............. Words of the form `$'STRING'' are treated specially. The word expands to STRING, with backslash-escaped characters replaced as specified by the ANSI C standard. Backslash escape sequences, if present, are decoded as follows: `\a' alert (bell) `\b' backspace `\e' an escape character (not ANSI C) `\f' form feed `\n' newline `\r' carriage return `\t' horizontal tab `\v' vertical tab `\\' backslash `\'' single quote `\NNN' the eight-bit character whose value is the octal value NNN (one to three digits) `\xHH' the eight-bit character whose value is the hexadecimal value HH (one or two hex digits) The expanded result is single-quoted, as if the dollar sign had not been present.  File: bashref.info, Node: Locale Translation, Prev: ANSI-C Quoting, Up: Quoting Locale-Specific Translation ........................... A double-quoted string preceded by a dollar sign (`$') will cause the string to be translated according to the current locale. If the current locale is `C' or `POSIX', the dollar sign is ignored. If the string is translated and replaced, the replacement is double-quoted. Some systems use the message catalog selected by the `LC_MESSAGES' shell variable. Others create the name of the message catalog from the value of the `TEXTDOMAIN' shell variable, possibly adding a suffix of `.mo'. If you use the `TEXTDOMAIN' variable, you may need to set the `TEXTDOMAINDIR' variable to the location of the message catalog files. Still others use both variables in this fashion: `TEXTDOMAINDIR'/`LC_MESSAGES'/LC_MESSAGES/`TEXTDOMAIN'.mo.  File: bashref.info, Node: Comments, Prev: Quoting, Up: Shell Syntax Comments -------- In a non-interactive shell, or an interactive shell in which the `interactive_comments' option to the `shopt' builtin is enabled (*note Bash Builtins::), a word beginning with `#' causes that word and all remaining characters on that line to be ignored. An interactive shell without the `interactive_comments' option enabled does not allow comments. The `interactive_comments' option is on by default in interactive shells. *Note Interactive Shells::, for a description of what makes a shell interactive.  File: bashref.info, Node: Shell Commands, Next: Shell Functions, Prev: Shell Syntax, Up: Basic Shell Features Shell Commands ============== A simple shell command such as `echo a b c' consists of the command itself followed by arguments, separated by spaces. More complex shell commands are composed of simple commands arranged together in a variety of ways: in a pipeline in which the output of one command becomes the input of a second, in a loop or conditional construct, or in some other grouping. * Menu: * Simple Commands:: The most common type of command. * Pipelines:: Connecting the input and output of several commands. * Lists:: How to execute commands sequentially. * Looping Constructs:: Shell commands for iterative action. * Conditional Constructs:: Shell commands for conditional execution. * Command Grouping:: Ways to group commands.  File: bashref.info, Node: Simple Commands, Next: Pipelines, Up: Shell Commands Simple Commands --------------- A simple command is the kind of command encountered most often. It's just a sequence of words separated by `blank's, terminated by one of the shell's control operators (*note Definitions::). The first word generally specifies a command to be executed, with the rest of the words being that command's arguments. The return status (*note Exit Status::) of a simple command is its exit status as provided by the POSIX 1003.1 `waitpid' function, or 128+N if the command was terminated by signal N.  File: bashref.info, Node: Pipelines, Next: Lists, Prev: Simple Commands, Up: Shell Commands Pipelines --------- A `pipeline' is a sequence of simple commands separated by `|'. The format for a pipeline is [`time' [`-p']] [`!'] COMMAND1 [`|' COMMAND2 ...] The output of each command in the pipeline is connected via a pipe to the input of the next command. That is, each command reads the previous command's output. The reserved word `time' causes timing statistics to be printed for the pipeline once it finishes. The statistics currently consist of elapsed (wall-clock) time and user and system time consumed by the command's execution. The `-p' option changes the output format to that specified by POSIX. The `TIMEFORMAT' variable may be set to a format string that specifies how the timing information should be displayed. *Note Bash Variables::, for a description of the available formats. The use of `time' as a reserved word permits the timing of shell builtins, shell functions, and pipelines. An external `time' command cannot time these easily. If the pipeline is not executed asynchronously (*note Lists::), the shell waits for all commands in the pipeline to complete. Each command in a pipeline is executed in its own subshell (*note Command Execution Environment::). The exit status of a pipeline is the exit status of the last command in the pipeline. If the reserved word `!' precedes the pipeline, the exit status is the logical negation of the exit status of the last command.  File: bashref.info, Node: Lists, Next: Looping Constructs, Prev: Pipelines, Up: Shell Commands Lists of Commands ----------------- A `list' is a sequence of one or more pipelines separated by one of the operators `;', `&', `&&', or `||', and optionally terminated by one of `;', `&', or a `newline'. Of these list operators, `&&' and `||' have equal precedence, followed by `;' and `&', which have equal precedence. If a command is terminated by the control operator `&', the shell executes the command asynchronously in a subshell. This is known as executing the command in the BACKGROUND. The shell does not wait for the command to finish, and the return status is 0 (true). When job control is not active (*note Job Control::), the standard input for asynchronous commands, in the absence of any explicit redirections, is redirected from `/dev/null'. Commands separated by a `;' are executed sequentially; the shell waits for each command to terminate in turn. The return status is the exit status of the last command executed. The control operators `&&' and `||' denote AND lists and OR lists, respectively. An AND list has the form COMMAND1 && COMMAND2 COMMAND2 is executed if, and only if, COMMAND1 returns an exit status of zero. An OR list has the form COMMAND1 || COMMAND2 COMMAND2 is executed if, and only if, COMMAND1 returns a non-zero exit status. The return status of AND and OR lists is the exit status of the last command executed in the list.  File: bashref.info, Node: Looping Constructs, Next: Conditional Constructs, Prev: Lists, Up: Shell Commands Looping Constructs ------------------ Bash supports the following looping constructs. Note that wherever a `;' appears in the description of a command's syntax, it may be replaced with one or more newlines. `until' The syntax of the `until' command is: until TEST-COMMANDS; do CONSEQUENT-COMMANDS; done Execute CONSEQUENT-COMMANDS as long as TEST-COMMANDS has an exit status which is not zero. 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 TEST-COMMANDS; do CONSEQUENT-COMMANDS; done Execute CONSEQUENT-COMMANDS as long as TEST-COMMANDS has an exit status of zero. 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 NAME [in WORDS ...]; do COMMANDS; done Expand WORDS, and execute COMMANDS once for each member in the resultant list, with NAME bound to the current member. If `in WORDS' is not present, the `for' command executes the COMMANDS once for each positional parameter that is set, as if `in "$@"' had been specified (*note Special Parameters::). The return status is the exit status of the last command that executes. If there are no items in the expansion of WORDS, no commands are executed, and the return status is zero. An alternate form of the `for' command is also supported: for (( EXPR1 ; EXPR2 ; EXPR3 )) ; do COMMANDS ; done First, the arithmetic expression EXPR1 is evaluated according to the rules described below (*note Shell Arithmetic::). The arithmetic expression EXPR2 is then evaluated repeatedly until it evaluates to zero. Each time EXPR2 evaluates to a non-zero value, COMMANDS are executed and the arithmetic expression EXPR3 is evaluated. If any expression is omitted, it behaves as if it evaluates to 1. The return value is the exit status of the last command in LIST that is executed, or false if any of the expressions is invalid. The `break' and `continue' builtins (*note Bourne Shell Builtins::) may be used to control loop execution.  File: bashref.info, Node: Conditional Constructs, Next: Command Grouping, Prev: Looping Constructs, Up: Shell Commands Conditional Constructs ---------------------- `if' The syntax of the `if' command is: if TEST-COMMANDS; then CONSEQUENT-COMMANDS; [elif MORE-TEST-COMMANDS; then MORE-CONSEQUENTS;] [else ALTERNATE-CONSEQUENTS;] fi The TEST-COMMANDS list is executed, and if its return status is zero, the CONSEQUENT-COMMANDS list is executed. If TEST-COMMANDS returns a non-zero status, each `elif' list is executed in turn, and if its exit status is zero, the corresponding MORE-CONSEQUENTS is executed and the command completes. If `else ALTERNATE-CONSEQUENTS' is present, and the final command in the final `if' or `elif' clause has a non-zero exit status, then ALTERNATE-CONSEQUENTS is executed. The return status is the exit status of the last command executed, or zero if no condition tested true. `case' The syntax of the `case' command is: `case WORD in [ [(] PATTERN [| PATTERN]...) COMMAND-LIST ;;]... esac' `case' will selectively execute the COMMAND-LIST corresponding to the first PATTERN that matches WORD. The `|' is used to separate multiple patterns, and the `)' operator terminates a pattern list. A list of patterns and an associated command-list is known as a CLAUSE. Each clause must be terminated with `;;'. The WORD undergoes tilde expansion, parameter expansion, command substitution, arithmetic expansion, and quote removal before matching is attempted. Each PATTERN undergoes tilde expansion, parameter expansion, command substitution, and arithmetic expansion. There may be an arbitrary number of `case' clauses, each terminated by a `;;'. The first pattern that matches determines the command-list that is executed. Here is an example using `case' in a script that could be used to describe one interesting feature of an animal: echo -n "Enter the name of an animal: " read ANIMAL echo -n "The $ANIMAL has " case $ANIMAL in horse | dog | cat) echo -n "four";; man | kangaroo ) echo -n "two";; *) echo -n "an unknown number of";; esac echo " legs." The return status is zero if no PATTERN is matched. Otherwise, the return status is the exit status of the COMMAND-LIST executed. `select' The `select' construct allows the easy generation of menus. It has almost the same syntax as the `for' command: select NAME [in WORDS ...]; do COMMANDS; done The list of words following `in' is expanded, generating a list of items. The set of expanded words is printed on the standard error output stream, each preceded by a number. If the `in WORDS' is omitted, the positional parameters are printed, as if `in "$@"' had been specifed. The `PS3' prompt is then displayed and a line is read from the standard input. If the line consists of a number corresponding to one of the displayed words, then the value of NAME is set to that word. If the line is empty, the words and prompt are displayed again. If `EOF' is read, the `select' command completes. Any other value read causes NAME to be set to null. The line read is saved in the variable `REPLY'. The COMMANDS are executed after each selection until a `break' command is executed, at which point the `select' command completes. Here is an example that allows the user to pick a filename from the current directory, and displays the name and index of the file selected. select fname in *; do echo you picked $fname \($REPLY\) break; done `((...))' (( EXPRESSION )) The arithmetic EXPRESSION is evaluated according to the rules described below (*note Shell Arithmetic::). If the value of the expression is non-zero, the return status is 0; otherwise the return status is 1. This is exactly equivalent to let "EXPRESSION" *Note Bash Builtins::, for a full description of the `let' builtin. `[[...]]' [[ EXPRESSION ]] Return a status of 0 or 1 depending on the evaluation of the conditional expression EXPRESSION. Expressions are composed of the primaries described below in *Note Bash Conditional Expressions::. Word splitting and filename expansion are not performed on the words between the `[[' and `]]'; tilde expansion, parameter and variable expansion, arithmetic expansion, command substitution, process substitution, and quote removal are performed. When the `==' and `!=' operators are used, the string to the right of the operator is considered a pattern and matched according to the rules described below in *Note Pattern Matching::. The return value is 0 if the string matches or does not match the pattern, respectively, and 1 otherwise. Any part of the pattern may be quoted to force it to be matched as a string. Expressions may be combined using the following operators, listed in decreasing order of precedence: `( EXPRESSION )' Returns the value of EXPRESSION. This may be used to override the normal precedence of operators. `! EXPRESSION' True if EXPRESSION is false. `EXPRESSION1 && EXPRESSION2' True if both EXPRESSION1 and EXPRESSION2 are true. `EXPRESSION1 || EXPRESSION2' True if either EXPRESSION1 or EXPRESSION2 is true. The `&&' and `||' commands do not execute EXPRESSION2 if the value of EXPRESSION1 is sufficient to determine the return value of the entire conditional expression.  File: bashref.info, Node: Command Grouping, Prev: Conditional Constructs, Up: Shell Commands Grouping Commands ----------------- Bash provides two ways to group a list of commands to be executed as a unit. When commands are grouped, redirections may be applied to the entire command list. For example, the output of all the commands in the list may be redirected to a single stream. `()' ( LIST ) Placing a list of commands between parentheses causes a subshell to be created, and each of the commands in LIST to be executed in that subshell. Since the LIST is executed in a subshell, variable assignments do not remain in effect after the subshell completes. `{}' { LIST; } Placing a list of commands between curly braces causes the list to be executed in the current shell context. No subshell is created. The semicolon (or newline) following LIST is required. In addition to the creation of a subshell, there is a subtle difference between these two constructs due to historical reasons. The braces are `reserved words', so they must be separated from the LIST by `blank's. The parentheses are `operators', and are recognized as separate tokens by the shell even if they are not separated from the LIST by whitespace. The exit status of both of these constructs is the exit status of LIST.  File: bashref.info, Node: Shell Functions, Next: Shell Parameters, Prev: Shell Commands, Up: Basic Shell Features Shell Functions =============== Shell functions are a way to group commands for later execution using a single name for the group. They are executed just like a "regular" command. When the name of a shell function is used as a simple command name, the list of commands associated with that function name is executed. Shell functions are executed in the current shell context; no new process is created to interpret them. Functions are declared using this syntax: [ `function' ] NAME () { COMMAND-LIST; } This defines a shell function named NAME. The reserved word `function' is optional. If the `function' reserved word is supplied, the parentheses are optional. The BODY of the function is the COMMAND-LIST between { and }. This list is executed whenever NAME is specified as the name of a command. The exit status of a function is the exit status of the last command executed in the body. Note that for historical reasons, the curly braces that surround the body of the function must be separated from the body by `blank's or newlines. This is because the braces are reserved words and are only recognized as such when they are separated by whitespace. Also, the COMMAND-LIST must be terminated with a semicolon or a newline. When a function is executed, the arguments to the function become the positional parameters during its execution (*note Positional Parameters::). The special parameter `#' that expands to the number of positional parameters is updated to reflect the change. Positional parameter `0' is unchanged. The `FUNCNAME' variable is set to the name of the function while the function is executing. If the builtin command `return' is executed in a function, the function completes and execution resumes with the next command after the function call. When a function completes, the values of the positional parameters and the special parameter `#' are restored to the values they had prior to the function's execution. If a numeric argument is given to `return', that is the function's return status; otherwise the function's return status is the exit status of the last command executed before the `return'. Variables local to the function may be declared with the `local' builtin. These variables are visible only to the function and the commands it invokes. Functions may be recursive. No limit is placed on the number of recursive calls.  File: bashref.info, Node: Shell Parameters, Next: Shell Expansions, Prev: Shell Functions, Up: Basic Shell Features Shell Parameters ================ * Menu: * Positional Parameters:: The shell's command-line arguments. * Special Parameters:: Parameters with special meanings. A PARAMETER is an entity that stores values. It can be a `name', a number, or one of the special characters listed below. For the shell's purposes, 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 *Note Bash Builtins::). A parameter is set if it has been assigned a value. The null string is a valid value. Once a variable is set, it may be unset only by using the `unset' builtin command. A variable may be assigned to by a statement of the form NAME=[VALUE] If VALUE is not given, the variable is assigned the null string. All VALUEs undergo tilde expansion, parameter and variable expansion, command substitution, arithmetic expansion, and quote removal (detailed below). If the variable has its `integer' attribute set, then VALUE is subject to arithmetic expansion even if the `$((...))' expansion is not used (*note Arithmetic Expansion::). Word splitting is not performed, with the exception of `"$@"' as explained below. Filename expansion is not performed. Assignment statements may also appear as arguments to the `declare', `typeset', `export', `readonly', and `local' builtin commands.  File: bashref.info, Node: Positional Parameters, Next: Special Parameters, Up: Shell Parameters Positional Parameters --------------------- A POSITIONAL PARAMETER is a parameter denoted by one or more digits, other than the single digit `0'. Positional parameters are assigned from the shell's arguments when it is invoked, and may be reassigned using the `set' builtin command. Positional parameter `N' may be referenced as `${N}', or as `$N' when `N' consists of a single digit. Positional parameters may not be assigned to with assignment statements. The `set' and `shift' builtins are used to set and unset them (*note Shell Builtin Commands::). The positional parameters are temporarily replaced when a shell function is executed (*note Shell Functions::). When a positional parameter consisting of more than a single digit is expanded, it must be enclosed in braces.  File: bashref.info, Node: Special Parameters, Prev: Positional Parameters, Up: Shell Parameters Special Parameters ------------------ The shell treats several parameters specially. These parameters may only be referenced; assignment to them is not allowed. `*' Expands to the positional parameters, starting from one. When the expansion occurs within double quotes, it expands to a single word with the value of each parameter separated by the first character of the `IFS' special variable. That is, `"$*"' is equivalent to `"$1C$2C..."', where C is the first character of the value of the `IFS' variable. If `IFS' is unset, the parameters are separated by spaces. If `IFS' is null, the parameters are joined without intervening separators. `@' Expands to the positional parameters, starting from one. When the expansion occurs within double quotes, each parameter expands to a separate word. That is, `"$@"' is equivalent to `"$1" "$2" ...'. 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' 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 most recently executed background (asynchronous) command. `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 (*note Shell Scripts::), `$0' is set to the name of that file. If Bash is started with the `-c' option (*note Invoking Bash::), then `$0' is set to the first argument after the string to be executed, if one is present. Otherwise, it is set to the filename used to invoke Bash, as given by argument zero. `_' (An underscore.) At shell startup, set to the absolute filename of the shell or shell script being executed as passed in the argument list. Subsequently, expands to the last argument to the previous command, after expansion. Also set to the full pathname of each command executed and placed in the environment exported to that command. When checking mail, this parameter holds the name of the mail file.  File: bashref.info, Node: Shell Expansions, Next: Redirections, Prev: Shell Parameters, Up: Basic Shell Features Shell Expansions ================ Expansion is performed on the command line after it has been split into `token's. There are seven kinds of expansion performed: * brace expansion * tilde expansion * parameter and variable expansion * command substitution * arithmetic expansion * word splitting * filename expansion * Menu: * Brace Expansion:: Expansion of expressions within braces. * Tilde Expansion:: Expansion of the ~ character. * Shell Parameter Expansion:: How Bash expands variables to their values. * Command Substitution:: Using the output of a command as an argument. * Arithmetic Expansion:: How to use arithmetic in shell expansions. * Process Substitution:: A way to write and read to and from a command. * Word Splitting:: How the results of expansion are split into separate arguments. * Filename Expansion:: A shorthand for specifying filenames matching patterns. * Quote Removal:: How and when quote characters are removed from words. The order of expansions is: brace expansion, tilde expansion, parameter, variable, and arithmetic expansion and command substitution (done in a left-to-right fashion), word splitting, and filename expansion. On systems that can support it, there is an additional expansion available: PROCESS SUBSTITUTION. This is performed at the same time as parameter, variable, and arithmetic expansion and command substitution. Only brace expansion, word splitting, and filename expansion can change the number of words of the expansion; other expansions expand a single word to a single word. The only exceptions to this are the expansions of `"$@"' (*note Special Parameters::) and `"${NAME[@]}"' (*note Arrays::). After all expansions, `quote removal' (*note Quote Removal::) is performed.  File: bashref.info, Node: Brace Expansion, Next: Tilde Expansion, Up: Shell Expansions Brace Expansion --------------- Brace expansion is a mechanism by which arbitrary strings may be generated. This mechanism is similar to FILENAME EXPANSION (*note Filename Expansion::), but the file names generated need not exist. Patterns to be brace expanded take the form of an optional PREAMBLE, followed by a series of comma-separated strings between a pair of braces, followed by an optional POSTSCRIPT. The preamble is prefixed to each string contained within the braces, and the postscript is then appended to each resulting string, expanding left to right. Brace expansions may be nested. The results of each expanded string are not sorted; left to right order is preserved. For example, bash$ echo a{d,c,b}e ade ace abe Brace expansion is performed before any other expansions, and any characters special to other expansions are preserved in the result. It is strictly textual. Bash does not apply any syntactic interpretation to the context of the expansion or the text between the braces. To avoid conflicts with parameter expansion, the string `${' is not considered eligible for brace expansion. A correctly-formed brace expansion must contain unquoted opening and closing braces, and at least one unquoted comma. Any incorrectly formed brace expansion is left unchanged. This construct is typically used as shorthand when the common prefix of the strings to be generated is longer than in the above example: mkdir /usr/local/src/bash/{old,new,dist,bugs} or chown root /usr/{ucb/{ex,edit},lib/{ex?.?*,how_ex}}  File: bashref.info, Node: Tilde Expansion, Next: Shell Parameter Expansion, Prev: Brace Expansion, Up: Shell Expansions Tilde Expansion --------------- If a word begins with an unquoted tilde character (`~'), all of the characters up to the first unquoted slash (or all characters, if there is no unquoted slash) are considered a TILDE-PREFIX. If none of the characters in the tilde-prefix are quoted, the characters in the tilde-prefix following the tilde are treated as a possible LOGIN NAME. If this login name is the null string, the tilde is replaced with the value of the `HOME' shell variable. If `HOME' is unset, the home directory of the user executing the shell is substituted instead. Otherwise, the tilde-prefix is replaced with the home directory associated with the specified login name. If the tilde-prefix is `~+', the value of the shell variable `PWD' replaces the tilde-prefix. If the tilde-prefix is `~-', the value of the shell variable `OLDPWD', if it is set, is substituted. If the characters following the tilde in the tilde-prefix consist of a number N, optionally prefixed by a `+' or a `-', the tilde-prefix is replaced with the corresponding element from the directory stack, as it would be displayed by the `dirs' builtin invoked with the characters following tilde in the tilde-prefix as an argument (*note The Directory Stack::). If the tilde-prefix, sans the tilde, consists of a number without a leading `+' or `-', `+' is assumed. If the login name is invalid, or the tilde expansion fails, the word is left unchanged. Each variable assignment is checked for unquoted tilde-prefixes immediately following a `:' or `='. In these cases, tilde expansion is also performed. Consequently, one may use file names with tildes in assignments to `PATH', `MAILPATH', and `CDPATH', and the shell assigns the expanded value. The following table shows how Bash treats unquoted tilde-prefixes: `~' The value of `$HOME' `~/foo' `$HOME/foo' `~fred/foo' The subdirectory `foo' of the home directory of the user `fred' `~+/foo' `$PWD/foo' `~-/foo' `${OLDPWD-'~-'}/foo' `~N' The string that would be displayed by `dirs +N' `~+N' The string that would be displayed by `dirs +N' `~-N' The string that would be displayed by `dirs -N'  File: bashref.info, Node: Shell Parameter Expansion, Next: Command Substitution, Prev: Tilde Expansion, Up: Shell Expansions Shell Parameter Expansion ------------------------- The `$' character introduces parameter expansion, command substitution, or arithmetic expansion. The parameter name or symbol to be expanded may be enclosed in braces, which are optional but serve to protect the variable to be expanded from characters immediately following it which could be interpreted as part of the name. When braces are used, the matching ending brace is the first `}' not escaped by a backslash or within a quoted string, and not within an embedded arithmetic expansion, command substitution, or parameter expansion. The basic form of parameter expansion is ${PARAMETER}. The value of PARAMETER is substituted. The braces are required when PARAMETER is a positional parameter with more than one digit, or when PARAMETER is followed by a character that is not to be interpreted as part of its name. If the first character of PARAMETER is an exclamation point, a level of variable indirection is introduced. Bash uses the value of the variable formed from the rest of PARAMETER as the name of the variable; this variable is then expanded and that value is used in the rest of the substitution, rather than the value of PARAMETER itself. This is known as `indirect expansion'. The exception to this is the expansion of ${!PREFIX*} described below. In each of the cases below, WORD is subject to tilde expansion, parameter expansion, command substitution, and arithmetic expansion. When not performing substring expansion, Bash tests for a parameter that is unset or null; omitting the colon results in a test only for a parameter that is unset. Put another way, if the colon is included, the operator tests for both existence and that the value is not null; if the colon is omitted, the operator tests only for existence. `${PARAMETER:-WORD}' If PARAMETER is unset or null, the expansion of WORD is substituted. Otherwise, the value of PARAMETER is substituted. `${PARAMETER:=WORD}' If PARAMETER is unset or null, the expansion of WORD is assigned to PARAMETER. The value of PARAMETER is then substituted. Positional parameters and special parameters may not be assigned to in this way. `${PARAMETER:?WORD}' If PARAMETER is null or unset, the expansion of WORD (or a message to that effect if WORD is not present) is written to the standard error and the shell, if it is not interactive, exits. Otherwise, the value of PARAMETER is substituted. `${PARAMETER:+WORD}' If PARAMETER is null or unset, nothing is substituted, otherwise the expansion of WORD is substituted. `${PARAMETER:OFFSET}' `${PARAMETER:OFFSET:LENGTH}' Expands to up to LENGTH characters of PARAMETER starting at the character specified by OFFSET. If LENGTH is omitted, expands to the substring of PARAMETER starting at the character specified by OFFSET. LENGTH and OFFSET are arithmetic expressions (*note Shell Arithmetic::). This is referred to as Substring Expansion. LENGTH must evaluate to a number greater than or equal to zero. If OFFSET evaluates to a number less than zero, the value is used as an offset from the end of the value of PARAMETER. If PARAMETER is `@', the result is LENGTH positional parameters beginning at OFFSET. If PARAMETER is an array name indexed by `@' or `*', the result is the LENGTH members of the array beginning with `${PARAMETER[OFFSET]}'. Substring indexing is zero-based unless the positional parameters are used, in which case the indexing starts at 1. `${!PREFIX*}' Expands to the names of variables whose names begin with PREFIX, separated by the first character of the `IFS' special variable. `${#PARAMETER}' The length in characters of the expanded value of PARAMETER is substituted. If PARAMETER is `*' or `@', the value substituted is the number of positional parameters. If PARAMETER is an array name subscripted by `*' or `@', the value substituted is the number of elements in the array. `${PARAMETER#WORD}' `${PARAMETER##WORD}' The WORD is expanded to produce a pattern just as in filename expansion (*note Filename Expansion::). If the pattern matches the beginning of the expanded value of PARAMETER, then the result of the expansion is the expanded value of PARAMETER with the shortest matching pattern (the `#' case) or the longest matching pattern (the `##' case) deleted. If PARAMETER is `@' or `*', the pattern removal operation is applied to each positional parameter in turn, and the expansion is the resultant list. If PARAMETER is an array variable subscripted with `@' or `*', 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}' The WORD is expanded to produce a pattern just as in filename expansion. If the pattern matches a trailing portion of the expanded value of PARAMETER, then the result of the expansion is the value of PARAMETER with the shortest matching pattern (the `%' case) or the longest matching pattern (the `%%' case) deleted. If PARAMETER is `@' or `*', the pattern removal operation is applied to each positional parameter in turn, and the expansion is the resultant list. If PARAMETER is an array variable subscripted with `@' or `*', 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. PARAMETER is expanded and the longest match of PATTERN against its value is replaced with STRING. In the first form, only the first match is replaced. The second form causes all matches of PATTERN to be replaced with STRING. If PATTERN begins with `#', it must match at the beginning of the expanded value of PARAMETER. If PATTERN begins with `%', it must match at the end of the expanded value of PARAMETER. If STRING is null, matches of PATTERN are deleted and the `/' following PATTERN may be omitted. If PARAMETER is `@' or `*', the substitution operation is applied to each positional parameter in turn, and the expansion is the resultant list. If PARAMETER is an array variable subscripted with `@' or `*', the substitution operation is applied to each member of the array in turn, and the expansion is the resultant list.  File: bashref.info, Node: Command Substitution, Next: Arithmetic Expansion, Prev: Shell Parameter Expansion, Up: Shell Expansions Command Substitution -------------------- Command substitution allows the output of a command to replace the command itself. Command substitution occurs when a command is enclosed as follows: $(COMMAND) or `COMMAND` Bash performs the expansion by executing COMMAND and replacing the command substitution with the standard output of the command, with any trailing newlines deleted. Embedded newlines are not deleted, but they may be removed during word splitting. The command substitution `$(cat FILE)' can be replaced by the equivalent but faster `$(< FILE)'. When the old-style backquote form of substitution is used, backslash retains its literal meaning except when followed by `$', ``', or `\'. The first backquote not preceded by a backslash terminates the command substitution. When using the `$(COMMAND)' form, all characters between the parentheses make up the command; none are treated specially. Command substitutions may be nested. To nest when using the backquoted form, escape the inner backquotes with backslashes. If the substitution appears within double quotes, word splitting and filename expansion are not performed on the results.  File: bashref.info, Node: Arithmetic Expansion, Next: Process Substitution, Prev: Command Substitution, Up: Shell Expansions Arithmetic Expansion -------------------- Arithmetic expansion allows the evaluation of an arithmetic expression and the substitution of the result. The format for arithmetic expansion is: $(( EXPRESSION )) The expression is treated as if it were within double quotes, but a double quote inside the parentheses is not treated specially. All tokens in the expression undergo parameter expansion, command substitution, and quote removal. Arithmetic substitutions may be nested. The evaluation is performed according to the rules listed below (*note Shell Arithmetic::). If the expression is invalid, Bash prints a message indicating failure to the standard error and no substitution occurs.  File: bashref.info, Node: Process Substitution, Next: Word Splitting, Prev: Arithmetic Expansion, Up: Shell Expansions Process Substitution -------------------- Process substitution is supported on systems that support named pipes (FIFOs) or the `/dev/fd' method of naming open files. It takes the form of <(LIST) or >(LIST) The process LIST is run with its input or output connected to a FIFO or some file in `/dev/fd'. The name of this file is passed as an argument to the current command as the result of the expansion. If the `>(LIST)' form is used, writing to the file will provide input for LIST. If the `<(LIST)' form is used, the file passed as an argument should be read to obtain the output of LIST. Note that no space may appear between the `<' or `>' and the left parenthesis, otherwise the construct would be interpreted as a redirection. When available, process substitution is performed simultaneously with parameter and variable expansion, command substitution, and arithmetic expansion.  File: bashref.info, Node: Word Splitting, Next: Filename Expansion, Prev: Process Substitution, Up: Shell Expansions Word Splitting -------------- The shell scans the results of parameter expansion, command substitution, and arithmetic expansion that did not occur within double quotes for word splitting. The shell treats each character of `$IFS' as a delimiter, and splits the results of the other expansions into words on these characters. If `IFS' is unset, or its value is exactly `', the default, then any sequence of `IFS' characters serves to delimit words. If `IFS' has a value other than the default, then sequences of the whitespace characters `space' and `tab' are ignored at the beginning and end of the word, as long as the whitespace character is in the value of `IFS' (an `IFS' whitespace character). Any character in `IFS' that is not `IFS' whitespace, along with any adjacent `IFS' whitespace characters, delimits a field. A sequence of `IFS' whitespace characters is also treated as a delimiter. If the value of `IFS' is null, no word splitting occurs. Explicit null arguments (`""' or `''') are retained. Unquoted implicit null arguments, resulting from the expansion of parameters that have no values, are removed. If a parameter with no value is expanded within double quotes, a null argument results and is retained. Note that if no expansion occurs, no splitting is performed.  File: bashref.info, Node: Filename Expansion, Next: Quote Removal, Prev: Word Splitting, Up: Shell Expansions Filename Expansion ------------------ * Menu: * Pattern Matching:: How the shell matches patterns. After word splitting, unless the `-f' option has been set (*note The Set Builtin::), Bash scans each word for the characters `*', `?', and `['. If one of these characters appears, then the word is regarded as a PATTERN, and replaced with an alphabetically sorted list of file names matching the pattern. If no matching file names are found, and the shell option `nullglob' is disabled, the word is left unchanged. If the `nullglob' option is set, and no matches are found, the word is removed. If the shell option `nocaseglob' is enabled, the match is performed without regard to the case of alphabetic characters. When a pattern is used for filename generation, the character `.' at the start of a filename or immediately following a slash must be matched explicitly, unless the shell option `dotglob' is set. When matching a file name, the slash character must always be matched explicitly. In other cases, the `.' character is not treated specially. See the description of `shopt' in *Note Bash Builtins::, for a description of the `nocaseglob', `nullglob', and `dotglob' options. The `GLOBIGNORE' shell variable may be used to restrict the set of filenames matching a pattern. If `GLOBIGNORE' is set, each matching filename that also matches one of the patterns in `GLOBIGNORE' is removed from the list of matches. The filenames `.' and `..' are always ignored, even when `GLOBIGNORE' is set. However, setting `GLOBIGNORE' has the effect of enabling the `dotglob' shell option, so all other filenames beginning with a `.' will match. To get the old behavior of ignoring filenames beginning with a `.', make `.*' one of the patterns in `GLOBIGNORE'. The `dotglob' option is disabled when `GLOBIGNORE' is unset.  File: bashref.info, Node: Pattern Matching, Up: Filename Expansion Pattern Matching ................ Any character that appears in a pattern, other than the special pattern characters described below, matches itself. The NUL character may not occur in a pattern. The special pattern characters must be quoted if they are to be matched literally. The special pattern characters have the following meanings: `*' Matches any string, including the null string. `?' 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 sorts between those two characters, inclusive, using the current locale's collating sequence and character set, is matched. If the first character following the `[' is a `!' or a `^' then any character not enclosed is matched. A `-' may be matched by including it as the first or last character in the set. A `]' may be matched by including it as the first character in the set. The sorting order of characters in range expressions is determined by the current locale and the value of the `LC_COLLATE' shell variable, if set. For example, in the default C locale, `[a-dx-z]' is equivalent to `[abcdxyz]'. Many locales sort characters in dictionary order, and in these locales `[a-dx-z]' is typically not equivalent to `[abcdxyz]'; it might be equivalent to `[aBbCcDdxXyYz]', for example. To obtain the traditional interpretation of ranges in bracket expressions, you can force the use of the C locale by setting the `LC_COLLATE' or `LC_ALL' environment variable to the value `C'. Within `[' and `]', CHARACTER CLASSES can be specified using the syntax `[:'CLASS`:]', where CLASS is one of the following classes defined in the POSIX 1003.2 standard: alnum alpha ascii blank cntrl digit graph lower print punct space upper xdigit A character class matches any character belonging to that class. Within `[' and `]', an EQUIVALENCE CLASS can be specified using the syntax `[='C`=]', which matches all characters with the same collation weight (as defined by the current locale) as the character C. Within `[' and `]', the syntax `[.'SYMBOL`.]' matches the collating symbol SYMBOL. If the `extglob' shell option is enabled using the `shopt' builtin, several extended pattern matching operators are recognized. In the following description, a PATTERN-LIST is a list of one or more patterns separated by a `|'. Composite patterns may be formed using one or more of the following sub-patterns: `?(PATTERN-LIST)' Matches zero or one occurrence of the given patterns. `*(PATTERN-LIST)' Matches zero or more occurrences of the given patterns. `+(PATTERN-LIST)' Matches one or more occurrences of the given patterns. `@(PATTERN-LIST)' Matches exactly one of the given patterns. `!(PATTERN-LIST)' Matches anything except one of the given patterns.  File: bashref.info, Node: Quote Removal, Prev: Filename Expansion, Up: Shell Expansions Quote Removal ------------- After the preceding expansions, all unquoted occurrences of the characters `\', `'', and `"' that did not result from one of the above expansions are removed.  File: bashref.info, Node: Redirections, Next: Executing Commands, Prev: Shell Expansions, Up: Basic Shell Features Redirections ============ Before a command is executed, its input and output may be REDIRECTED using a special notation interpreted by the shell. Redirection may also be used to open and close files for the current shell execution environment. The following redirection operators may precede or appear anywhere within a simple command or may follow a command. Redirections are processed in the order they appear, from left to right. In the following descriptions, if the file descriptor number is omitted, and the first character of the redirection operator is `<', the redirection refers to the standard input (file descriptor 0). If the first character of the redirection operator is `>', the redirection refers to the standard output (file descriptor 1). The word following the redirection operator in the following descriptions, unless otherwise noted, is subjected to brace expansion, tilde expansion, parameter expansion, command substitution, arithmetic expansion, quote removal, filename expansion, and word splitting. If it expands to more than one word, Bash reports an error. Note that the order of redirections is significant. For example, the command ls > DIRLIST 2>&1 directs both standard output (file descriptor 1) and standard error (file descriptor 2) to the file DIRLIST, while the command ls 2>&1 > DIRLIST directs only the standard output to file DIRLIST, because the standard error was duplicated as standard output before the standard output was redirected to DIRLIST. Bash handles several filenames specially when they are used in redirections, as described in the following table: `/dev/fd/FD' If FD is a valid integer, file descriptor FD is duplicated. `/dev/stdin' File descriptor 0 is duplicated. `/dev/stdout' File descriptor 1 is duplicated. `/dev/stderr' File descriptor 2 is duplicated. `/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 a TCP connection to the corresponding socket. `/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 a UDP connection to the corresponding socket. A failure to open or create a file causes the redirection to fail. 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', or the standard input (file descriptor 0) if `n' is not specified. The general format for redirecting input is: [n][|]WORD If the redirection operator is `>', and the `noclobber' option to the `set' builtin has been enabled, the redirection will fail if the file whose name results from the expansion of WORD exists and is a regular file. If the redirection operator is `>|', or the redirection operator is `>' and the `noclobber' option is not enabled, the redirection is attempted even if the file named by WORD exists. Appending Redirected Output --------------------------- Redirection of output in this fashion causes the file whose name results from the expansion of WORD to be opened for appending on file descriptor `n', or the standard output (file descriptor 1) if `n' is not specified. If the file does not exist it is created. The general format for appending output is: [n]>>WORD Redirecting Standard Output and Standard Error ---------------------------------------------- Bash allows both the standard output (file descriptor 1) and the standard error output (file descriptor 2) to be redirected to the file whose name is the expansion of WORD with this construct. There are two formats for redirecting standard output and standard error: &>WORD and >&WORD Of the two forms, the first is preferred. This is semantically equivalent to >WORD 2>&1 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 the lines read up to that point are then used as the standard input for a command. The format of here-documents is as follows: <<[-]WORD HERE-DOCUMENT DELIMITER No parameter expansion, command substitution, arithmetic expansion, or filename expansion is performed on WORD. If any characters in WORD are quoted, the DELIMITER is the result of quote removal on WORD, and the lines in the here-document are not expanded. If WORD is unquoted, all lines of the here-document are subjected to parameter expansion, command substitution, and arithmetic expansion. In the latter case, the character sequence `\newline' is ignored, and `\' must be used to quote the characters `\', `$', and ``'. If the redirection operator is `<<-', then all leading tab characters are stripped from input lines and the line containing DELIMITER. This allows here-documents within shell scripts to be indented in a natural fashion. Duplicating File Descriptors ---------------------------- The redirection operator [n]<&WORD is used to duplicate input file descriptors. If WORD expands to one or more digits, the file descriptor denoted by `n' is made to be a copy of that file descriptor. If the digits in WORD do not specify a file descriptor open for input, a redirection error occurs. If WORD evaluates to `-', file descriptor `n' is closed. If `n' is not specified, the standard input (file descriptor 0) is used. The operator [n]>&WORD is used similarly to duplicate output file descriptors. If `n' is not specified, the standard output (file descriptor 1) is used. If the digits in WORD do not specify a file descriptor open for output, a redirection error occurs. As a special case, if `n' is omitted, and WORD does not expand to one or more digits, the standard output and standard error are redirected as described previously. Opening File Descriptors for Reading and Writing ------------------------------------------------ The redirection operator [n]<>WORD causes the file whose name is the expansion of WORD to be opened for both reading and writing on file descriptor `n', or on file descriptor 0 if `n' is not specified. If the file does not exist, it is created.  File: bashref.info, Node: Executing Commands, Next: Shell Scripts, Prev: Redirections, Up: Basic Shell Features Executing Commands ================== * Menu: * Simple Command Expansion:: How Bash expands simple commands before executing them. * Command Search and Execution:: How Bash finds commands and runs them. * Command Execution Environment:: The environment in which Bash executes commands that are not shell builtins. * Environment:: The environment given to a command. * Exit Status:: The status returned by commands and how Bash interprets it. * Signals:: What happens when Bash or a command it runs receives a signal.  File: bashref.info, Node: Simple Command Expansion, Next: Command Search and Execution, Up: Executing Commands Simple Command Expansion ------------------------ When a simple command is executed, the shell performs the following expansions, assignments, and redirections, from left to right. 1. The words that the parser has marked as variable assignments (those preceding the command name) and redirections are saved for later processing. 2. The words that are not variable assignments or redirections are expanded (*note Shell Expansions::). If any words remain after expansion, the first word is taken to be the name of the command and the remaining words are the arguments. 3. Redirections are performed as described above (*note Redirections::). 4. The text after the `=' in each variable assignment undergoes tilde expansion, parameter expansion, command substitution, arithmetic expansion, and quote removal before being assigned to the variable. If no command name results, the variable assignments affect the current shell environment. Otherwise, the variables are added to the environment of the executed command and do not affect the current shell environment. If any of the assignments attempts to assign a value to a readonly variable, an error occurs, and the command exits with a non-zero status. If no command name results, redirections are performed, but do not affect the current shell environment. A redirection error causes the command to exit with a non-zero status. If there is a command name left after expansion, execution proceeds as described below. Otherwise, the command exits. If one of the expansions contained a command substitution, the exit status of the command is the exit status of the last command substitution performed. If there were no command substitutions, the command exits with a status of zero.  File: bashref.info, Node: Command Search and Execution, Next: Command Execution Environment, Prev: Simple Command Expansion, Up: Executing Commands Command Search and Execution ---------------------------- After a command has been split into words, if it results in a simple command and an optional list of arguments, the following actions are taken. 1. If the command name contains no slashes, the shell attempts to locate it. If there exists a shell function by that name, that function is invoked as described in *Note Shell Functions::. 2. If the name does not match a function, the shell searches for it in the list of shell builtins. If a match is found, that builtin is invoked. 3. If the name is neither a shell function nor a builtin, and contains no slashes, Bash searches each element of `$PATH' for a directory containing an executable file by that name. Bash uses a hash table to remember the full pathnames of executable files to avoid multiple `PATH' searches (see the description of `hash' in *Note Bourne Shell Builtins::). A full search of the directories in `$PATH' is performed only if the command is not found in the hash table. If the search is unsuccessful, the shell prints an error message and returns an exit status of 127. 4. If the search is successful, or if the command name contains one or more slashes, the shell executes the named program in a separate execution environment. Argument 0 is set to the name given, and the remaining arguments to the command are set to the arguments supplied, if any. 5. If this execution fails because the file is not in executable format, and the file is not a directory, it is assumed to be a SHELL SCRIPT and the shell executes it as described in *Note Shell Scripts::. 6. If the command was not begun asynchronously, the shell waits for the command to complete and collects its exit status.  File: bashref.info, Node: Command Execution Environment, Next: Environment, Prev: Command Search and Execution, Up: Executing Commands Command Execution Environment ----------------------------- The shell has an EXECUTION ENVIRONMENT, which consists of the following: * open files inherited by the shell at invocation, as modified by redirections supplied to the `exec' builtin * the current working directory as set by `cd', `pushd', or `popd', or inherited by the shell at invocation * the file creation mode mask as set by `umask' or inherited from the shell's parent * current traps set by `trap' * shell parameters that are set by variable assignment or with `set' or inherited from the shell's parent in the environment * shell functions defined during execution or inherited from the shell's parent in the environment * options enabled at invocation (either by default or with command-line arguments) or by `set' * options enabled by `shopt' * shell aliases defined with `alias' (*note Aliases::) * various process IDs, including those of background jobs (*note Lists::), the value of `$$', and the value of `$PPID' When a simple command other than a builtin or shell function is to be executed, it is invoked in a separate execution environment that consists of the following. Unless otherwise noted, the values are inherited from the shell. * the shell's open files, plus any modifications and additions specified by redirections to the command * the current working directory * the file creation mode mask * shell variables marked for export, along with variables exported for the command, passed in the environment (*note Environment::) * traps caught by the shell are reset to the values inherited from the shell's parent, and traps ignored by the shell are ignored A command invoked in this separate environment cannot affect the shell's execution environment. Command substitution and asynchronous commands are invoked in a subshell environment that is a duplicate of the shell environment, except that traps caught by the shell are reset to the values that the shell inherited from its parent at invocation. Builtin commands that are invoked as part of a pipeline are also executed in a subshell environment. Changes made to the subshell environment cannot affect the shell's execution environment. If a command is followed by a `&' and job control is not active, the default standard input for the command is the empty file `/dev/null'. Otherwise, the invoked command inherits the file descriptors of the calling shell as modified by redirections.  File: bashref.info, Node: Environment, Next: Exit Status, Prev: Command Execution Environment, Up: Executing Commands Environment ----------- When a program is invoked it is given an array of strings called the ENVIRONMENT. This is a list of name-value pairs, of the form `name=value'. Bash provides several ways to manipulate the environment. On invocation, the shell scans its own environment and creates a parameter for each name found, automatically marking it for EXPORT to child processes. Executed commands inherit the environment. The `export' and `declare -x' commands allow parameters and functions to be added to and deleted from the environment. If the value of a parameter in the environment is modified, the new value becomes part of the environment, replacing the old. The environment inherited by any executed command consists of the shell's initial environment, whose values may be modified in the shell, less any pairs removed by the `unset' and `export -n' commands, plus any additions via the `export' and `declare -x' commands. The environment for any simple command or function may be augmented temporarily by prefixing it with parameter assignments, as described in *Note Shell Parameters::. These assignment statements affect only the environment seen by that command. If the `-k' option is set (*note The Set Builtin::), then all parameter assignments are placed in the environment for a command, not just those that precede the command name. When Bash invokes an external command, the variable `$_' is set to the full path name of the command and passed to that command in its environment.  File: bashref.info, Node: Exit Status, Next: Signals, Prev: Environment, Up: Executing Commands Exit Status ----------- For the shell's purposes, a command which exits with a zero exit status has succeeded. A non-zero exit status indicates failure. This seemingly counter-intuitive scheme is used so there is one well-defined way to indicate success and a variety of ways to indicate various failure modes. When a command terminates on a fatal signal whose number is N, Bash uses the value 128+N as the exit status. If a command is not found, the child process created to execute it returns a status of 127. If a command is found but is not executable, the return status is 126. If a command fails because of an error during expansion or redirection, the exit status is greater than zero. The exit status is used by the Bash conditional commands (*note Conditional Constructs::) and some of the list constructs (*note Lists::). All of the Bash builtins return an exit status of zero if they succeed and a non-zero status on failure, so they may be used by the conditional and list constructs. All builtins return an exit status of 2 to indicate incorrect usage.  File: bashref.info, Node: Signals, Prev: Exit Status, Up: Executing Commands Signals ------- When Bash is interactive, in the absence of any traps, it ignores `SIGTERM' (so that `kill 0' does not kill an interactive shell), and `SIGINT' is caught and handled (so that the `wait' builtin is interruptible). When Bash receives a `SIGINT', it breaks out of any executing loops. In all cases, Bash ignores `SIGQUIT'. If job control is in effect (*note Job Control::), Bash ignores `SIGTTIN', `SIGTTOU', and `SIGTSTP'. Commands started by Bash have signal handlers set to the values inherited by the shell from its parent. When job control is not in effect, asynchronous commands ignore `SIGINT' and `SIGQUIT' as well. Commands run as a result of command substitution ignore the keyboard-generated job control signals `SIGTTIN', `SIGTTOU', and `SIGTSTP'. The shell exits by default upon receipt of a `SIGHUP'. Before exiting, an interactive shell resends the `SIGHUP' to all jobs, running or stopped. Stopped jobs are sent `SIGCONT' to ensure that they receive the `SIGHUP'. To prevent the shell from sending the `SIGHUP' signal to a particular job, it should be removed from the jobs table with the `disown' builtin (*note Job Control Builtins::) or marked to not receive `SIGHUP' using `disown -h'. If the `huponexit' shell option has been set with `shopt' (*note Bash Builtins::), Bash sends a `SIGHUP' to all jobs when an interactive login shell exits. When Bash receives a signal for which a trap has been set while waiting for a command to complete, the trap will not be executed until the command completes. When Bash is waiting for an asynchronous command via the `wait' builtin, the reception of a signal for which a trap has been set will cause the `wait' builtin to return immediately with an exit status greater than 128, immediately after which the trap is executed.  File: bashref.info, Node: Shell Scripts, Prev: Executing Commands, Up: Basic Shell Features Shell Scripts ============= A shell script is a text file containing shell commands. When such a file is used as the first non-option argument when invoking Bash, and neither the `-c' nor `-s' option is supplied (*note Invoking Bash::), Bash reads and executes commands from the file, then exits. This mode of operation creates a non-interactive shell. The shell first searches for the file in the current directory, and looks in the directories in `$PATH' if not found there. When Bash runs a shell script, it sets the special parameter `0' to the name of the file, rather than the name of the shell, and the positional parameters are set to the remaining arguments, if any are given. If no additional arguments are supplied, the positional parameters are unset. A shell script may be made executable by using the `chmod' command to turn on the execute bit. When Bash finds such a file while searching the `$PATH' for a command, it spawns a subshell to execute it. In other words, executing filename ARGUMENTS is equivalent to executing bash filename ARGUMENTS if `filename' is an executable shell script. This subshell reinitializes itself, so that the effect is as if a new shell had been invoked to interpret the script, with the exception that the locations of commands remembered by the parent (see the description of `hash' in *Note Bourne Shell Builtins::) are retained by the child. Most versions of Unix make this a part of the operating system's command execution mechanism. If the first line of a script begins with the two characters `#!', the remainder of the line specifies an interpreter for the program. Thus, you can specify Bash, `awk', Perl, or some other interpreter and write the rest of the script file in that language. The arguments to the interpreter consist of a single optional argument following the interpreter name on the first line of the script file, followed by the name of the script file, followed by the rest of the arguments. Bash will perform this action on operating systems that do not handle it themselves. Note that some older versions of Unix limit the interpreter name and argument to a maximum of 32 characters. Bash scripts often begin with `#! /bin/bash' (assuming that Bash has been installed in `/bin'), since this ensures that Bash will be used to interpret the script, even if it is executed under another shell.  File: bashref.info, Node: Shell Builtin Commands, Next: Shell Variables, Prev: Basic Shell Features, Up: Top Shell Builtin Commands ********************** * Menu: * Bourne Shell Builtins:: Builtin commands inherited from the Bourne Shell. * Bash Builtins:: Table of builtins specific to Bash. * The Set Builtin:: This builtin is so overloaded it deserves its own section. * Special Builtins:: Builtin commands classified specially by POSIX.2. Builtin commands are contained within the shell itself. When the name of a builtin command is used as the first word of a simple command (*note Simple Commands::), the shell executes the command directly, without invoking another program. Builtin commands are necessary to implement functionality impossible or inconvenient to obtain with separate utilities. This section briefly the builtins which Bash inherits from the Bourne Shell, as well as the builtin commands which are unique to or have been extended in Bash. Several builtin commands are described in other chapters: builtin commands which provide the Bash interface to the job control facilities (*note Job Control Builtins::), the directory stack (*note Directory Stack Builtins::), the command history (*note Bash History Builtins::), and the programmable completion facilities (*note Programmable Completion Builtins::). Many of the builtins have been extended by POSIX or Bash.  File: bashref.info, Node: Bourne Shell Builtins, Next: Bash Builtins, Up: Shell Builtin Commands Bourne Shell Builtins ===================== The following shell builtin commands are inherited from the Bourne Shell. These commands are implemented as specified by the POSIX 1003.2 standard. `: (a colon)' : [ARGUMENTS] Do nothing beyond expanding ARGUMENTS and performing redirections. The return status is zero. `. (a period)' . FILENAME [ARGUMENTS] Read and execute commands from the FILENAME argument in the current shell context. If FILENAME does not contain a slash, the `PATH' variable is used to find FILENAME. When Bash is not in POSIX mode, the current directory is searched if FILENAME is not found in `$PATH'. If any ARGUMENTS are supplied, they become the positional parameters when FILENAME is executed. Otherwise the positional parameters are unchanged. The return status is the exit status of the last command executed, or zero if no commands are executed. If FILENAME is not found, or cannot be read, the return status is non-zero. This builtin is equivalent to `source'. `break' break [N] Exit from a `for', `while', `until', or `select' loop. If N is supplied, the Nth enclosing loop is exited. N must be greater than or equal to 1. The return status is zero unless N is not greater than or equal to 1. `cd' cd [-LP] [DIRECTORY] Change the current working directory to DIRECTORY. If DIRECTORY is not given, the value of the `HOME' shell variable is used. If the shell variable `CDPATH' exists, it is used as a search path. If DIRECTORY begins with a slash, `CDPATH' is not used. The `-P' option means to not follow symbolic links; symbolic links are followed by default or with the `-L' option. If DIRECTORY is `-', it is equivalent to `$OLDPWD'. The return status is zero if the directory is successfully changed, non-zero otherwise. `continue' continue [N] Resume the next iteration of an enclosing `for', `while', `until', or `select' loop. If N is supplied, the execution of the Nth enclosing loop is resumed. N must be greater than or equal to 1. The return status is zero unless N is not greater than or equal to 1. `eval' eval [ARGUMENTS] The arguments are concatenated together into a single command, which is then read and executed, and its exit status returned as the exit status of `eval'. If there are no arguments or only empty arguments, the return status is zero. `exec' exec [-cl] [-a NAME] [COMMAND [ARGUMENTS]] If COMMAND is supplied, it replaces the shell without creating a new process. If the `-l' option is supplied, the shell places a dash at the beginning of the zeroth arg passed to COMMAND. This is what the `login' program does. The `-c' option causes COMMAND to be executed with an empty environment. If `-a' is supplied, the shell passes NAME as the zeroth argument to COMMAND. If no COMMAND is specified, redirections may be used to affect the current shell environment. If there are no redirection errors, the return status is zero; otherwise the return status is non-zero. `exit' exit [N] Exit the shell, returning a status of N to the shell's parent. 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 [-fn] [-p] [NAME[=VALUE]] Mark each NAME to be passed to child processes in the environment. If the `-f' option is supplied, the NAMEs refer to shell functions; otherwise the names refer to shell variables. The `-n' option means to no longer mark each NAME for export. If no NAMES are supplied, or if the `-p' option is given, a list of exported names is displayed. The `-p' option displays output in a form that may be reused as input. The return status is zero unless an invalid option is supplied, one of the names is not a valid shell variable name, or `-f' is supplied with a name that is not a shell function. `getopts' getopts OPTSTRING NAME [ARGS] `getopts' is used by shell scripts to parse positional parameters. OPTSTRING contains the option characters to be recognized; if a character is followed by a colon, the option is expected to have an argument, which should be separated from it by white space. The colon (`:') and question mark (`?') may not be used as option characters. Each time it is invoked, `getopts' places the next option in the shell variable NAME, initializing NAME if it does not exist, and the index of the next argument to be processed into the variable `OPTIND'. `OPTIND' is initialized to 1 each time the shell or a shell script is invoked. When an option requires an argument, `getopts' places that argument into the variable `OPTARG'. The shell does not reset `OPTIND' automatically; it must be manually reset between multiple calls to `getopts' within the same shell invocation if a new set of parameters is to be used. When the end of options is encountered, `getopts' exits with a return value greater than zero. `OPTIND' is set to the index of the first non-option argument, and `name' is set to `?'. `getopts' normally parses the positional parameters, but if more arguments are given in ARGS, `getopts' parses those instead. `getopts' can report errors in two ways. If the first character of OPTSTRING is a colon, SILENT error reporting is used. In normal operation diagnostic messages are printed when invalid options or missing option arguments are encountered. If the variable `OPTERR' is set to 0, no error messages will be displayed, even if the first character of `optstring' is not a colon. If an invalid option is seen, `getopts' places `?' into NAME and, if not silent, prints an error message and unsets `OPTARG'. If `getopts' is silent, the option character found is placed in `OPTARG' and no diagnostic message is printed. If a required argument is not found, and `getopts' is not silent, a question mark (`?') is placed in NAME, `OPTARG' is unset, and a diagnostic message is printed. If `getopts' is silent, then a colon (`:') is placed in NAME and `OPTARG' is set to the option character found. `hash' hash [-r] [-p FILENAME] [-t] [NAME] Remember the full pathnames of commands specified as NAME arguments, so they need not be searched for on subsequent invocations. The commands are found by searching through the directories listed in `$PATH'. The `-p' option inhibits the path search, and FILENAME is used as the location of NAME. The `-r' option causes the shell to forget all remembered locations. If the `-t' option is supplied, the full pathname to which each NAME corresponds is printed. If multiple NAME arguments are supplied with `-t' the NAME is printed before the hashed full pathname. If no arguments are given, information about remembered commands is printed. The return status is zero unless a NAME is not found or an invalid option is supplied. `pwd' pwd [-LP] Print the absolute pathname of the current working directory. If the `-P' option is supplied, the pathname printed will not contain symbolic links. If the `-L' option is supplied, the pathname printed may contain symbolic links. The return status is zero unless an error is encountered while determining the name of the current directory or an invalid option is supplied. `readonly' readonly [-apf] [NAME] ... Mark each NAME as readonly. The values of these names may not be changed by subsequent assignment. If the `-f' option is supplied, each NAME refers to a shell function. The `-a' option means each NAME refers to an array variable. If no NAME arguments are given, or if the `-p' option is supplied, a list of all readonly names is printed. The `-p' option causes output to be displayed in a format that may be reused as input. The return status is zero unless an invalid option is supplied, one of 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 [N] Cause a shell function to exit with the return value N. If N is not supplied, the return value is the exit status of the last command executed in the function. This may also be used to terminate execution of a script being executed with the `.' (or `source') builtin, returning either N or the exit status of the last command executed within the script as the exit status of the script. The return status is non-zero if `return' is used outside a function and not during the execution of a script by `.' or `source'. `shift' shift [N] Shift the positional parameters to the left by N. The positional parameters from N+1 ... `$#' are renamed to `$1' ... `$#'-N+1. Parameters represented by the numbers `$#' to N+1 are unset. N must be a non-negative number less than or equal to `$#'. If N is zero or greater than `$#', the positional parameters are not changed. If N is not supplied, it is assumed to be 1. The return status is zero unless N is greater than `$#' or less than zero, non-zero otherwise. `test' `[' Evaluate a conditional expression EXPR. Each operator and operand must be a separate argument. Expressions are composed of the primaries described below in *Note Bash Conditional Expressions::. When the `[' form is used, the last argument to the command must be a `]'. Expressions may be combined using the following operators, listed in decreasing order of precedence. `! EXPR' True if EXPR is false. `( EXPR )' Returns the value of EXPR. This may be used to override the normal precedence of operators. `EXPR1 -a EXPR2' True if both EXPR1 and EXPR2 are true. `EXPR1 -o EXPR2' True if either EXPR1 or EXPR2 is true. The `test' and `[' builtins evaluate conditional expressions using a set of rules based on the number of arguments. 0 arguments The expression is false. 1 argument The expression is true if and only if the argument is not null. 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 (*note Bash Conditional Expressions::), the expression is true if the unary test is true. If the first argument is not a valid unary operator, the expression is false. 3 arguments If the second argument is one of the binary conditional operators (*note Bash Conditional Expressions::), the result of the expression is the result of the binary test using the first and third arguments as operands. If the first argument is `!', the value is the negation of the two-argument test using the second and third arguments. If the first argument is exactly `(' and the third argument is exactly `)', the result is the one-argument test of the second argument. Otherwise, the expression is false. The `-a' and `-o' operators are considered binary operators in this case. 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 The expression is parsed and evaluated according to precedence using the rules listed above. `times' times Print out the user and system times used by the shell and its children. The return status is zero. `trap' trap [-lp] [ARG] [SIGSPEC ...] The commands in ARG are to be read and executed when the shell receives signal SIGSPEC. If ARG is absent or equal to `-', all specified signals are reset to the values they had when the shell was started. If ARG is the null string, then the signal specified by each SIGSPEC is ignored by the shell and commands it invokes. If ARG is not present and `-p' has been supplied, the shell displays the trap commands associated with each SIGSPEC. If no arguments are supplied, or only `-p' is given, `trap' prints the list of commands associated with each signal number in a form that may be reused as shell input. Each SIGSPEC is either a signal name such as `SIGINT' (with or without the `SIG' prefix) or a signal number. If a SIGSPEC is `0' or `EXIT', ARG is executed when the shell exits. If a SIGSPEC is `DEBUG', the command ARG is executed after every simple command. If a SIGSPEC is `ERR', the command ARG is executed whenever a simple command has a non-zero exit status. The `ERR' trap is not executed if the failed command is part of an `until' or `while' loop, part of an `if' statement, part of a `&&' or `||' list, or if the command's return status is being inverted using `!'. The `-l' option causes the shell to print a list of signal names and their corresponding numbers. Signals ignored upon entry to the shell cannot be trapped or reset. Trapped signals are reset to their original values in a child process when it is created. The return status is zero unless a SIGSPEC does not specify a valid signal. `umask' umask [-p] [-S] [MODE] Set the shell process's file creation mask to MODE. If MODE begins with a digit, it is interpreted as an octal number; if not, it is interpreted as a symbolic mode mask similar to that accepted by the `chmod' command. If MODE is omitted, the current value of the mask is printed. If the `-S' option is supplied without a MODE argument, the mask is printed in a symbolic format. If the `-p' option is supplied, and MODE is omitted, the output is in a form that may be reused as input. The return status is zero if the mode is successfully changed or if no MODE argument is supplied, and non-zero otherwise. Note that when the mode is interpreted as an octal number, each number of the umask is subtracted from `7'. Thus, a umask of `022' results in permissions of `755'. `unset' unset [-fv] [NAME] Each variable or function NAME is removed. If no options are supplied, or the `-v' option is given, each NAME refers to a shell variable. If the `-f' option is given, the NAMEs refer to shell functions, and the function definition is removed. Readonly variables and functions may not be unset. The return status is zero unless a NAME does not exist or is readonly.  File: bashref.info, Node: Bash Builtins, Next: The Set Builtin, Prev: Bourne Shell Builtins, Up: Shell Builtin Commands Bash Builtin Commands ===================== This section describes builtin commands which are unique to or have been extended in Bash. Some of these commands are specified in the POSIX 1003.2 standard. `alias' alias [`-p'] [NAME[=VALUE] ...] Without arguments or with the `-p' option, `alias' prints the list of aliases on the standard output in a form that allows them to be reused as input. If arguments are supplied, an alias is defined for each NAME whose VALUE is given. If no VALUE is given, the name and value of the alias is printed. Aliases are described in *Note Aliases::. `bind' bind [-m KEYMAP] [-lpsvPSV] bind [-m KEYMAP] [-q FUNCTION] [-u FUNCTION] [-r KEYSEQ] bind [-m KEYMAP] -f FILENAME bind [-m KEYMAP] -x KEYSEQ:SHELL-COMMAND bind [-m KEYMAP] KEYSEQ:FUNCTION-NAME Display current Readline (*note Command Line Editing::) key and function bindings, or bind a key sequence to a Readline function or macro. The binding syntax accepted is identical to that of a Readline initialization file (*note Readline Init File::), but each binding must be passed as a separate argument: e.g., `"\C-x\C-r":re-read-init-file'. Options, if supplied, have the following meanings: `-m KEYMAP' Use KEYMAP as the keymap to be affected by the subsequent bindings. Acceptable KEYMAP names are `emacs', `emacs-standard', `emacs-meta', `emacs-ctlx', `vi', `vi-move', `vi-command', and `vi-insert'. `vi' is equivalent to `vi-command'; `emacs' is equivalent to `emacs-standard'. `-l' List the names of all Readline functions. `-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' List current Readline function names and bindings. `-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' List current Readline variable names and values. `-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' Display Readline key sequences bound to macros and the strings they output. `-f FILENAME' Read key bindings from FILENAME. `-q FUNCTION' Query about which keys invoke the named FUNCTION. `-u FUNCTION' Unbind all keys bound to the named FUNCTION. `-r KEYSEQ' Remove any current binding for KEYSEQ. `-x KEYSEQ:SHELL-COMMAND' Cause SHELL-COMMAND to be executed whenever KEYSEQ is entered. The return status is zero unless an invalid option is supplied or an error occurs. `builtin' builtin [SHELL-BUILTIN [ARGS]] Run a shell builtin, passing it ARGS, and return its exit status. This is useful when defining a shell function with the same name as a shell builtin, retaining the functionality of the builtin within the function. The return status is non-zero if SHELL-BUILTIN is not a shell builtin command. `command' command [-pVv] COMMAND [ARGUMENTS ...] Runs COMMAND with ARGUMENTS ignoring any shell function named COMMAND. Only shell builtin commands or commands found by searching the `PATH' are executed. If there is a shell function named `ls', running `command ls' within the function will execute the external command `ls' instead of calling the function recursively. The `-p' option means to use a default value for `PATH' that is guaranteed to find all of the standard utilities. The return status in this case is 127 if COMMAND cannot be found or an error occurred, and the exit status of COMMAND otherwise. If either the `-V' or `-v' option is supplied, a description of COMMAND is printed. The `-v' option causes a single word indicating the command or file name used to invoke COMMAND to be displayed; the `-V' option produces a more verbose description. In this case, the return status is zero if COMMAND is found, and non-zero if not. `declare' declare [-afFrxi] [-p] [NAME[=VALUE]] Declare variables and give them attributes. If no NAMEs are given, then display the values of variables instead. The `-p' option will display the attributes and values of each NAME. When `-p' is used, additional options are ignored. The `-F' option inhibits the display of function definitions; only the function name and attributes are printed. `-F' implies `-f'. The following options can be used to restrict output to variables with the specified attributes or to give variables attributes: `-a' Each NAME is an array variable (*note Arrays::). `-f' Use function names only. `-i' The variable is to be treated as an integer; arithmetic evaluation (*note Shell Arithmetic::) is performed when the variable is assigned a value. `-r' Make NAMEs readonly. These names cannot then be assigned values by subsequent assignment statements or unset. `-x' Mark each NAME for export to subsequent commands via the environment. Using `+' instead of `-' turns off the attribute instead. When used in a function, `declare' makes each NAME local, as with the `local' command. The return status is zero unless an invalid option is encountered, an attempt is made to define a function using `-f foo=bar', an attempt is made to assign a value to a readonly variable, an attempt is made to assign a value to an array variable without using the compound assignment syntax (*note Arrays::), one of the NAMES is not a valid shell variable name, an attempt is made to turn off readonly status for a readonly variable, an attempt is made to turn off array status for an array variable, or an attempt is made to display a non-existent function with `-f'. `echo' echo [-neE] [ARG ...] Output the ARGs, separated by spaces, terminated with a newline. The return status is always 0. If `-n' is specified, the trailing newline is suppressed. If the `-e' option is given, interpretation of the following backslash-escaped characters is enabled. The `-E' option disables the interpretation of these escape characters, even on systems where they are interpreted by default. The `xpg_echo' shell option may be used to dynamically determine whether or not `echo' expands these escape characters by default. `echo' interprets the following escape sequences: `\a' alert (bell) `\b' backspace `\c' suppress trailing newline `\e' escape `\f' form feed `\n' new line `\r' carriage return `\t' horizontal tab `\v' vertical tab `\\' backslash `\NNN' the eight-bit character whose value is the octal value NNN (one to three digits) `\xHH' the eight-bit character whose value is the hexadecimal value HH (one or two hex digits) `enable' enable [-n] [-p] [-f FILENAME] [-ads] [NAME ...] Enable and disable builtin shell commands. Disabling a builtin allows a disk command which has the same name as a shell builtin to be executed without specifying a full pathname, even though the shell normally searches for builtins before disk commands. If `-n' is used, the NAMEs become disabled. Otherwise NAMEs are enabled. For example, to use the `test' binary found via `$PATH' instead of the shell builtin version, type `enable -n test'. If the `-p' option is supplied, or no NAME arguments appear, a list of shell builtins is printed. With no other arguments, the list consists of all enabled shell builtins. The `-a' option means to list each builtin with an indication of whether or not it is enabled. The `-f' option means to load the new builtin command NAME from shared object FILENAME, on systems that support dynamic loading. The `-d' option will delete a builtin loaded with `-f'. If there are no options, a list of the shell builtins is displayed. The `-s' option restricts `enable' to the POSIX special builtins. If `-s' is used with `-f', the new builtin becomes a special builtin (*note Special Builtins::). The return status is zero unless a NAME is not a shell builtin or there is an error loading a new builtin from a shared object. `help' help [-s] [PATTERN] Display helpful information about builtin commands. If PATTERN is specified, `help' gives detailed help on all commands matching PATTERN, otherwise a list of the builtins is printed. The `-s' option restricts the information displayed to a short usage synopsis. The return status is zero unless no command matches PATTERN. `let' let EXPRESSION [EXPRESSION] The `let' builtin allows arithmetic to be performed on shell variables. Each EXPRESSION is evaluated according to the rules given below in *Note Shell Arithmetic::. If the last EXPRESSION evaluates to 0, `let' returns 1; otherwise 0 is returned. `local' local [OPTION] NAME[=VALUE] For each argument, a local variable named NAME is created, and assigned VALUE. The OPTION can be any of the options accepted by `declare'. `local' can only be used within a function; it makes the variable NAME have a visible scope restricted to that function and its children. The return status is zero unless `local' is used outside a function, an invalid NAME is supplied, or NAME is a readonly variable. `logout' logout [N] Exit a login shell, returning a status of N to the shell's parent. `printf' `printf' FORMAT [ARGUMENTS] Write the formatted ARGUMENTS to the standard output under the control of the FORMAT. The FORMAT is a character string which contains three types of objects: plain characters, which are simply copied to standard output, character escape sequences, which are converted and copied to the standard output, and format specifications, each of which causes printing of the next successive ARGUMENT. In addition to the standard `printf(1)' formats, `%b' causes `printf' to expand backslash escape sequences in the corresponding ARGUMENT, and `%q' causes `printf' to output the corresponding ARGUMENT in a format that can be reused as shell input. The FORMAT is reused as necessary to consume all of the ARGUMENTS. If the FORMAT requires more ARGUMENTS than are supplied, the extra format specifications behave as if a zero value or null string, as appropriate, had been supplied. The return value is zero on success, non-zero on failure. `read' read [-ers] [-a ANAME] [-p PROMPT] [-t TIMEOUT] [-n NCHARS] [-d DELIM] [NAME ...] One line is read from the standard input, and the first word is assigned to the first NAME, the second word to the second NAME, and so on, with leftover words and their intervening separators assigned to the last NAME. If there are fewer words read from the standard input than names, the remaining names are assigned empty values. The characters in the value of the `IFS' variable are used to split the line into words. The backslash character `\' may be used to remove any special meaning for the next character read and for line continuation. If no names are supplied, the line read is assigned to the variable `REPLY'. The return code is zero, unless end-of-file is encountered or `read' times out. Options, if supplied, have the following meanings: `-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' The first character of DELIM is used to terminate the input line, rather than newline. `-e' Readline (*note Command Line Editing::) is used to obtain the line. `-n NCHARS' `read' returns after reading NCHARS characters rather than waiting for a complete line of input. `-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' If this option is given, backslash does not act as an escape character. The backslash is considered to be part of the line. In particular, a backslash-newline pair may not be used as a line continuation. `-s' Silent mode. If input is coming from a terminal, characters are not echoed. `-t TIMEOUT' Cause `read' to time out and return failure if a complete line of input is not read within TIMEOUT seconds. This option has no effect if `read' is not reading input from the terminal or a pipe. `shopt' shopt [-pqsu] [-o] [OPTNAME ...] Toggle the values of variables controlling optional shell behavior. With no options, or with the `-p' option, a list of all settable options is displayed, with an indication of whether or not each is set. The `-p' option causes output to be displayed in a form that may be reused as input. Other options have the following meanings: `-s' Enable (set) each OPTNAME. `-u' Disable (unset) each OPTNAME. `-q' Suppresses normal output; the return status indicates whether the OPTNAME is set or unset. If multiple OPTNAME arguments are given with `-q', the return status is zero if all OPTNAMES are enabled; non-zero otherwise. `-o' Restricts the values of OPTNAME to be those defined for the `-o' option to the `set' builtin (*note The Set Builtin::). If either `-s' or `-u' is used with no OPTNAME arguments, the display is limited to those options which are set or unset, respectively. Unless otherwise noted, the `shopt' options are disabled (off) by default. The return status when listing options is zero if all OPTNAMES are enabled, non-zero otherwise. When setting or unsetting options, the return status is zero unless an OPTNAME is not a valid shell option. The list of `shopt' options is: `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' 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, a missing character, and a character too many. If a correction is found, the corrected path is printed, and the command proceeds. This option is only used by interactive shells. `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. `checkwinsize' If set, Bash checks the window size after each command and, if necessary, updates the values of `LINES' and `COLUMNS'. `cmdhist' If set, Bash attempts to save all lines of a multiple-line command in the same history entry. This allows easy re-editing of multi-line commands. `dotglob' If set, Bash includes filenames beginning with a `.' in the results of filename expansion. `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' If set, aliases are expanded as described below under Aliases, *Note Aliases::. This option is enabled by default for interactive shells. `extglob' If set, the extended pattern matching features described above (*note Pattern Matching::) are enabled. `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' If set, and Readline is being used, a user is given the opportunity to re-edit a failed history substitution. `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' If set, and Readline is being used, Bash will attempt to perform hostname completion when a word containing a `@' is being completed (*note Commands For Completion::). This option is enabled by default. `huponexit' If set, Bash will send `SIGHUP' to all jobs when an interactive login shell exits (*note Signals::). `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. `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. `login_shell' The shell sets this option if it is started as a login shell (*note Invoking Bash::). The value may not be changed. `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' 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' If set, Bash matches filenames in a case-insensitive fashion when performing filename expansion. `nullglob' If set, Bash allows filename patterns which match no files to expand to a null string, rather than themselves. `progcomp' If set, the programmable completion facilities (*note Programmable Completion::) are enabled. This option is enabled by default. `promptvars' If set, prompt strings undergo variable and parameter expansion after being expanded (*note Printing a Prompt::). This option is enabled by default. `restricted_shell' The shell sets this option if it is started in restricted mode (*note The Restricted Shell::). The value may not be changed. This is not reset when the startup files are executed, allowing the startup files to discover whether or not a shell is restricted. `shift_verbose' If this is set, the `shift' builtin prints an error message when the shift count exceeds the number of positional parameters. `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' If set, the `echo' builtin expands backslash-escape sequences by default. The return status when listing options is zero if all OPTNAMES are enabled, non-zero otherwise. When setting or unsetting options, the return status is zero unless an OPTNAME is not a valid shell option. `source' source FILENAME A synonym for `.' (*note Bourne Shell Builtins::). `type' type [-atp] [NAME ...] For each NAME, indicate how it would be interpreted if used as a command name. If the `-t' option is used, `type' prints a single word which is one of `alias', `function', `builtin', `file' or `keyword', if NAME is an alias, shell function, shell builtin, disk file, or shell reserved word, respectively. If the NAME is not found, then nothing is printed, and `type' returns a failure status. If the `-p' option is used, `type' either returns the name of the disk file that would be executed, or nothing if `-t' would not return `file'. If the `-a' option is used, `type' returns all of the places that contain an executable named FILE. This includes aliases and functions, if and only if the `-p' option is not also used. The return status is zero if any of the NAMES are found, non-zero if none are found. `typeset' typeset [-afFrxi] [-p] [NAME[=VALUE]] The `typeset' command is supplied for compatibility with the Korn shell; however, it has been deprecated in favor of the `declare' builtin command. `ulimit' ulimit [-acdflmnpstuvSH] [LIMIT] `ulimit' provides control over the resources available to processes started by the shell, on systems that allow such control. If an option is given, it is interpreted as follows: `-S' Change and report the soft limit associated with a resource. `-H' Change and report the hard limit associated with a resource. `-a' All current limits are reported. `-c' The maximum size of core files created. `-d' The maximum size of a process's data segment. `-f' The maximum size of files created by the shell. `-l' The maximum size that may be locked into memory. `-m' The maximum resident set size. `-n' The maximum number of open file descriptors. `-p' The pipe buffer size. `-s' The maximum stack size. `-t' The maximum amount of cpu time in seconds. `-u' The maximum number of processes available to a single user. `-v' The maximum amount of virtual memory available to the process. If LIMIT is given, it is the new value of the specified resource; the special LIMIT values `hard', `soft', and `unlimited' stand for the current hard limit, the current soft limit, and no limit, respectively. Otherwise, the current value of the soft limit for the specified resource is printed, unless the `-H' option is supplied. When setting new limits, if neither `-H' nor `-S' is supplied, both the hard and soft limits are set. If no option is given, then `-f' is assumed. Values are in 1024-byte increments, except for `-t', which is in seconds, `-p', which is in units of 512-byte blocks, and `-n' and `-u', which are unscaled values. The return status is zero unless an invalid option or argument is supplied, or an error occurs while setting a new limit. `unalias' unalias [-a] [NAME ... ] Remove each NAME from the list of aliases. If `-a' is supplied, all aliases are removed. Aliases are described in *Note Aliases::.  File: bashref.info, Node: The Set Builtin, Next: Special Builtins, Prev: Bash Builtins, Up: Shell Builtin Commands The Set Builtin =============== This builtin is so complicated that it deserves its own section. `set' set [--abefhkmnptuvxBCHP] [-o OPTION] [ARGUMENT ...] If no options or arguments are supplied, `set' displays the names and values of all shell variables and functions, sorted according to the current locale, in a format that may be reused as input. When options are supplied, they set or unset shell attributes. Options, if specified, have the following meanings: `-a' Mark variables and function which are modified or created for export to the environment of subsequent commands. `-b' Cause the status of terminated background jobs to be reported immediately, rather than before printing the next primary prompt. `-e' Exit immediately if a simple command (*note Simple Commands::) exits with a non-zero status, unless the command that fails is part of an `until' or `while' loop, part of an `if' statement, part of a `&&' or `||' list, or if the command's return status is being inverted using `!'. A trap on `ERR', if set, is executed before the shell exits. `-f' Disable file name generation (globbing). `-h' Locate and remember (hash) commands as they are looked up for execution. This option is enabled by default. `-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' Job control is enabled (*note Job Control::). `-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' Set the option corresponding to OPTION-NAME: `allexport' Same as `-a'. `braceexpand' Same as `-B'. `emacs' Use an `emacs'-style line editing interface (*note Command Line Editing::). `errexit' Same as `-e'. `hashall' Same as `-h'. `histexpand' Same as `-H'. `history' Enable command history, as described in *Note Bash History Facilities::. This option is on by default in interactive shells. `ignoreeof' An interactive shell will not exit upon reading EOF. `keyword' Same as `-k'. `monitor' Same as `-m'. `noclobber' Same as `-C'. `noexec' Same as `-n'. `noglob' Same as `-f'. `nolog' Currently ignored. `notify' Same as `-b'. `nounset' Same as `-u'. `onecmd' Same as `-t'. `physical' Same as `-P'. `posix' Change the behavior of Bash where the default operation differs from the POSIX 1003.2 standard to match the standard (*note Bash POSIX Mode::). This is intended to make Bash behave as a strict superset of that standard. `privileged' Same as `-p'. `verbose' Same as `-v'. `vi' Use a `vi'-style line editing interface. `xtrace' Same as `-x'. `-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, and the `SHELLOPTS' variable, if it appears in the environment, is ignored. If the shell is started with the effective user (group) id not equal to the real user (group) id, and the `-p' option is not supplied, these actions are taken and the effective user id is set to the real user id. If the `-p' option is supplied at startup, the effective user id is not reset. Turning this option off causes the effective user and group ids to be set to the real user and group ids. `-t' Exit after reading and executing one command. `-u' Treat unset variables as an error when performing parameter expansion. An error message will be written to the standard error, and a non-interactive shell will exit. `-v' Print shell input lines as they are read. `-x' Print a trace of simple commands and their arguments after they are expanded and before they are executed. `-B' The shell will perform brace expansion (*note Brace Expansion::). This option is on by default. `-C' Prevent output redirection using `>', `>&', and `<>' from overwriting existing files. `-H' Enable `!' style history substitution (*note History Interaction::). This option is on by default for interactive shells. `-P' If set, do not follow symbolic links when performing commands such as `cd' which change the current directory. The physical directory is used instead. By default, Bash follows the logical chain of directories when performing commands which change the current directory. For example, if `/usr/sys' is a symbolic link to `/usr/local/sys' then: $ cd /usr/sys; echo $PWD /usr/sys $ cd ..; pwd /usr If `set -P' is on, then: $ cd /usr/sys; echo $PWD /usr/local/sys $ cd ..; pwd /usr/local `--' 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. If there are no arguments, the positional parameters remain unchanged. Using `+' rather than `-' causes these options to be turned off. The options can also be used upon invocation of the shell. The current set of options may be found in `$-'. The remaining N ARGUMENTS are positional parameters and are assigned, in order, to `$1', `$2', ... `$N'. The special parameter `#' is set to N. The return status is always zero unless an invalid option is supplied.  File: bashref.info, Node: Special Builtins, Prev: The Set Builtin, Up: Shell Builtin Commands Special Builtins ================ For historical reasons, the POSIX 1003.2 standard has classified several builtin commands as _special_. When Bash is executing in POSIX mode, the special builtins differ from other builtin commands in three respects: 1. Special builtins are found before shell functions during command lookup. 2. If a special builtin returns an error status, a non-interactive shell exits. 3. Assignment statements preceding the command stay in effect in the shell environment after the command completes. When Bash is not executing in POSIX mode, these builtins behave no differently than the rest of the Bash builtin commands. The Bash POSIX mode is described in *Note Bash POSIX Mode::. These are the POSIX special builtins: break : . continue eval exec exit export readonly return set shift trap unset  File: bashref.info, Node: Shell Variables, Next: Bash Features, Prev: Shell Builtin Commands, Up: Top Shell Variables *************** * Menu: * Bourne Shell Variables:: Variables which Bash uses in the same way as the Bourne Shell. * Bash Variables:: List of variables that exist in Bash. This chapter describes the shell variables that Bash uses. Bash automatically assigns default values to a number of variables.  File: bashref.info, Node: Bourne Shell Variables, Next: Bash Variables, Up: Shell Variables Bourne Shell Variables ====================== Bash uses certain shell variables in the same way as the Bourne shell. In some cases, Bash assigns a default value to the variable. `CDPATH' A colon-separated list of directories used as a search path for the `cd' builtin command. `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 (*note Tilde Expansion::). `IFS' A list of characters that separate fields; used when the shell splits words as part of expansion. `MAIL' If this parameter is set to a filename and the `MAILPATH' variable is not set, Bash informs the user of the arrival of mail in the specified file. `MAILPATH' A colon-separated list of filenames which the shell periodically checks for new mail. Each list entry can specify the message that is printed when new mail arrives in the mail file by separating the file name from the message with a `?'. When used in the text of the message, `$_' expands to the name of the current mail file. `OPTARG' The value of the last option argument processed by the `getopts' builtin. `OPTIND' The index of the last option argument processed by the `getopts' builtin. `PATH' A colon-separated list of directories in which the shell looks for commands. `PS1' The primary prompt string. The default value is `\s-\v\$ '. *Note Printing a Prompt::, for the complete list of escape sequences that are expanded before `PS1' is displayed. `PS2' The secondary prompt string. The default value is `> '.  File: bashref.info, Node: Bash Variables, Prev: Bourne Shell Variables, Up: Shell Variables Bash Variables ============== These variables are set or used by Bash, but other shells do not normally treat them specially. A few variables used by Bash are described in different chapters: variables for controlling the job control facilities (*note Job Control Variables::). `BASH' The full pathname used to execute the current instance of Bash. `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. *Note Bash Startup Files::. `BASH_VERSION' The version number of the current instance of Bash. `BASH_VERSINFO' A readonly array variable (*note Arrays::) whose members hold version information for this instance of Bash. The values assigned to the array members are as follows: `BASH_VERSINFO[0]' The major version number (the RELEASE). `BASH_VERSINFO[1]' The minor version number (the VERSION). `BASH_VERSINFO[2]' The patch level. `BASH_VERSINFO[3]' The build version. `BASH_VERSINFO[4]' The release status (e.g., BETA1). `BASH_VERSINFO[5]' The value of `MACHTYPE'. `COLUMNS' Used by the `select' builtin command to determine the terminal width when printing selection lists. Automatically set upon receipt of a `SIGWINCH'. `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 (*note Programmable Completion::). `COMP_LINE' The current command line. This variable is available only in shell functions and external commands invoked by the programmable completion facilities (*note Programmable Completion::). `COMP_POINT' The index of the current cursor position relative to the beginning of the current command. If the current cursor position is at the end of the current command, the value of this variable is equal to `${#COMP_LINE}'. This variable is available only in shell functions and external commands invoked by the programmable completion facilities (*note Programmable Completion::). `COMP_WORDS' An array variable consisting of the individual words in the current command line. This variable is available only in shell functions invoked by the programmable completion facilities (*note Programmable Completion::). `COMPREPLY' An array variable from which Bash reads the possible completions generated by a shell function invoked by the programmable completion facility (*note Programmable Completion::). `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. Assigning to members of this array variable may be used to modify directories already in the stack, but the `pushd' and `popd' builtins must be used to add and remove directories. Assignment to this variable will not change the current directory. If `DIRSTACK' is unset, it loses its special properties, even if it is subsequently reset. `EUID' The numeric effective user id of the current user. This variable is readonly. `FCEDIT' The editor used as a default by the `-e' option to the `fc' builtin command. `FIGNORE' A colon-separated list of suffixes to ignore when performing filename completion. A file name whose suffix matches one of the entries in `FIGNORE' is excluded from the list of matched file names. A sample value is `.o:~' `FUNCNAME' The name of any currently-executing shell function. This variable exists only when a shell function is executing. Assignments to `FUNCNAME' have no effect and return an error status. If `FUNCNAME' is unset, it loses its special properties, even if it is subsequently reset. `GLOBIGNORE' A colon-separated list of patterns defining the set of filenames to be ignored by filename expansion. If a filename matched by a filename expansion pattern also matches one of the patterns in `GLOBIGNORE', it is removed from the list of matches. `GROUPS' An array variable containing the list of groups of which the current user is a member. Assignments to `GROUPS' have no effect and return an error status. If `GROUPS' is unset, it loses its special properties, even if it is subsequently reset. `histchars' Up to three characters which control history expansion, quick substitution, and tokenization (*note History Interaction::). 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 character which signifies `quick substitution' when seen as the first character on a line, normally `^'. The optional third character is the character which indicates that the remainder of the line is a comment when found as the first character of a word, usually `#'. The history comment character causes history substitution to be skipped for the remaining words on the line. It does not necessarily cause the shell parser to treat the rest of the line as a comment. `HISTCMD' The history number, or index in the history list, of the current command. If `HISTCMD' is unset, it loses its special properties, even if it is subsequently reset. `HISTCONTROL' A value of `ignorespace' means to not enter lines which begin with a space or tab into the history list. A value of `ignoredups' means to not enter lines which match the last entered line. A value of `ignoreboth' combines the two options. Unset, or set to any other value than those above, means to save all lines on the history list. The second and subsequent lines of a multi-line compound command are not tested, and are added to the history regardless of the value of `HISTCONTROL'. `HISTFILE' The name of the file to which the command history is saved. The default value is `~/.bash_history'. `HISTFILESIZE' The maximum number of lines contained in the history file. When this variable is assigned a value, the history file is truncated, if necessary, to contain no more than that number of lines. The history file is also truncated to this size after writing it when an interactive shell exits. The default value is 500. `HISTIGNORE' A colon-separated list of patterns used to decide which command lines should be saved on the history list. Each pattern is anchored at the beginning of the line and must match the complete line (no implicit `*' is appended). Each pattern is tested against the line after the checks specified by `HISTCONTROL' are applied. In addition to the normal shell pattern matching characters, `&' matches the previous history line. `&' may be escaped using a backslash; the backslash is removed before attempting a match. The second and subsequent lines of a multi-line compound command are not tested, and are added to the history regardless of the value of `HISTIGNORE'. `HISTIGNORE' subsumes the function of `HISTCONTROL'. A pattern of `&' is identical to `ignoredups', and a pattern of `[ ]*' is identical to `ignorespace'. Combining these two patterns, separating them with a colon, provides the functionality of `ignoreboth'. `HISTSIZE' The maximum number of commands to remember on the history list. The default value is 500. `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 is running; the next time hostname completion is attempted after the value is changed, Bash adds the contents of the new file to the existing list. If `HOSTFILE' is set, but has no value, Bash attempts to read `/etc/hosts' to obtain the list of possible hostname completions. When `HOSTFILE' is unset, the hostname list is cleared. `HOSTNAME' The name of the current host. `HOSTTYPE' A string describing the machine Bash is running on. `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 first character on an input line before the shell will exit. If the variable exists but does not have a numeric value (or has no value) then the default is 10. If the variable does not exist, then `EOF' signifies the end of input to the shell. This is only in effect for interactive shells. `INPUTRC' The name of the Readline initialization file, overriding the default of `~/.inputrc'. `LANG' Used to determine the locale category for any category not specifically selected with a variable starting with `LC_'. `LC_ALL' This variable overrides the value of `LANG' and any other `LC_' variable specifying a locale category. `LC_COLLATE' This variable determines the collation order used when sorting the results of filename expansion, and determines the behavior of range expressions, equivalence classes, and collating sequences within filename expansion and pattern matching (*note Filename Expansion::). `LC_CTYPE' This variable determines the interpretation of characters and the behavior of character classes within filename expansion and pattern matching (*note Filename Expansion::). `LC_MESSAGES' This variable determines the locale used to translate double-quoted strings preceded by a `$' (*note Locale Translation::). `LC_NUMERIC' This variable determines the locale category used for number formatting. `LINENO' The line number in the script or shell function currently executing. `LINES' Used by the `select' builtin command to determine the column length for printing selection lists. Automatically set upon receipt of a `SIGWINCH'. `MACHTYPE' A string that fully describes the system type on which Bash is executing, in the standard GNU CPU-COMPANY-SYSTEM format. `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 for mail, the shell does so before displaying the primary prompt. If this variable is unset, or set to a value that is not a number greater than or equal to zero, the shell disables mail checking. `OLDPWD' The previous working directory as set by the `cd' builtin. `OPTERR' If set to the value 1, Bash displays error messages generated by the `getopts' builtin command. `OSTYPE' A string describing the operating system Bash is running on. `PIPESTATUS' An array variable (*note 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' If this variable is in the environment when `bash' starts, the shell enters POSIX mode (*note Bash POSIX Mode::) before reading the startup files, as if the `--posix' invocation option had been supplied. If it is set while the shell is running, `bash' enables POSIX mode, as if the command `set -o posix' had been executed. `PPID' The process ID of the shell's parent process. This variable is readonly. `PROMPT_COMMAND' If set, the value is interpreted as a command to execute before the printing of each primary prompt (`$PS1'). `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' The value is the prompt printed before the command line is echoed when the `-x' option is set (*note The Set Builtin::). The first character of `PS4' is replicated multiple times, as necessary, to indicate multiple levels of indirection. The default is `+ '. `PWD' The current working directory as set by the `cd' builtin. `RANDOM' Each time this parameter is referenced, a random integer between 0 and 32767 is generated. Assigning a value to this variable seeds the random number generator. `REPLY' The default variable for the `read' builtin. `SECONDS' This variable expands to the number of seconds since the shell was started. Assignment to this variable resets the count to the value assigned, and the expanded value becomes the value assigned plus the number of seconds since the assignment. `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 (*note The Set Builtin::). The options appearing in `SHELLOPTS' are those reported as `on' by `set -o'. If this variable is in the environment when Bash starts up, each shell option in the list will be enabled before reading any startup files. This variable is readonly. `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. `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. The `%' character introduces an escape sequence that is expanded to a time value or other information. The escape sequences and their meanings are as follows; the braces denote optional portions. `%%' A literal `%'. `%[P][l]R' The elapsed time in seconds. `%[P][l]U' The number of CPU seconds spent in user mode. `%[P][l]S' The number of CPU seconds spent in system mode. `%P' The CPU percentage, computed as (%U + %S) / %R. The optional P is a digit specifying the precision, the number of fractional digits after a decimal point. A value of 0 causes no decimal point or fraction to be output. At most three places after the decimal point may be specified; values of P greater than 3 are changed to 3. If P is not specified, the value 3 is used. The optional `l' specifies a longer format, including minutes, of the form MMmSS.FFs. The value of P determines whether or not the fraction is included. If this variable is not set, Bash acts as if it had the value `$'\nreal\t%3lR\nuser\t%3lU\nsys\t%3lS'' If the value is null, no timing information is displayed. A trailing newline is added when the format string is displayed. `TMOUT' If set to a value greater than zero, the value is interpreted as the number of seconds to wait for input after issuing the primary prompt when the shell is interactive. Bash terminates after that number of seconds if input does not arrive. `UID' The numeric real user id of the current user. This variable is readonly.  File: bashref.info, Node: Bash Features, Next: Job Control, Prev: Shell Variables, Up: Top Bash Features ************* This section describes features unique to Bash. * Menu: * Invoking Bash:: Command line options that you can give to Bash. * Bash Startup Files:: When and how Bash executes scripts. * Interactive Shells:: What an interactive shell is. * Bash Conditional Expressions:: Primitives used in composing expressions for the `test' builtin. * Shell Arithmetic:: Arithmetic on shell variables. * Aliases:: Substituting one command for another. * Arrays:: Array Variables. * The Directory Stack:: History of visited directories. * Printing a Prompt:: Controlling the PS1 string. * The Restricted Shell:: A more controlled mode of shell execution. * Bash POSIX Mode:: Making Bash behave more closely to what the POSIX standard specifies.  File: bashref.info, Node: Invoking Bash, Next: Bash Startup Files, Up: Bash Features Invoking Bash ============= bash [long-opt] [-ir] [-abefhkmnptuvxdBCDHP] [-o OPTION] [-O SHOPT_OPTION] [ARGUMENT ...] bash [long-opt] [-abefhkmnptuvxdBCDHP] [-o OPTION] [-O SHOPT_OPTION] -c STRING [ARGUMENT ...] bash [long-opt] -s [-abefhkmnptuvxdBCDHP] [-o OPTION] [-O SHOPT_OPTION] [ARGUMENT ...] In addition to the single-character shell command-line options (*note The Set Builtin::), there are several multi-character options that you can use. These options must appear on the command line before the single-character options in order for them to be recognized. `--dump-po-strings' A list of all double-quoted strings preceded by `$' is printed on the standard ouput in the GNU `gettext' PO (portable object) file format. Equivalent to `-D' except for the output format. `--dump-strings' Equivalent to `-D'. `--help' Display a usage message on standard output and exit sucessfully. `--init-file FILENAME' `--rcfile FILENAME' Execute commands from FILENAME (instead of `~/.bashrc') in an interactive shell. `--login' 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'. When the shell is not interactive, the login shell startup files will be executed. `exec bash --login' will replace the current shell with a Bash login shell. *Note Bash Startup Files::, for a description of the special behavior of a login shell. `--noediting' Do not use the GNU Readline library (*note Command Line Editing::) to read command lines when the shell is interactive. `--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' Don't read the `~/.bashrc' initialization file in an interactive shell. This is on by default if the shell is invoked as `sh'. `--posix' Change the behavior of Bash where the default operation differs from the POSIX 1003.2 standard to match the standard. This is intended to make Bash behave as a strict superset of that standard. *Note Bash POSIX Mode::, for a description of the Bash POSIX mode. `--restricted' Make the shell a restricted shell (*note The Restricted Shell::). `--verbose' Equivalent to `-v'. Print shell input lines as they're read. `--version' Show version information for this instance of Bash on the standard output and exit successfully. There are several single-character options that may be supplied at invocation which are not available with the `set' builtin. `-c STRING' Read and execute commands from STRING after processing the options, then exit. Any remaining arguments are assigned to the positional parameters, starting with `$0'. `-i' Force the shell to run interactively. Interactive shells are described in *Note Interactive Shells::. `-r' Make the shell a restricted shell (*note The Restricted Shell::). `-s' If this option is present, or if no arguments remain after option processing, then commands are read from the standard input. This option allows the positional parameters to be set when invoking an interactive shell. `-D' A list of all double-quoted strings preceded by `$' is printed on the standard ouput. These are the strings that are subject to language translation when the current locale is not `C' or `POSIX' (*note Locale Translation::). This implies the `-n' option; no commands will be executed. `[-+]O [SHOPT_OPTION]' SHOPT_OPTION is one of the shell options accepted by the `shopt' builtin (*note Shell Builtin Commands::). If SHOPT_OPTION is present, `-O' sets the value of that option; `+O' unsets it. If SHOPT_OPTION is not supplied, the names and values of the shell options accepted by `shopt' are printed on the standard output. 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. A _login_ shell is one whose first character of argument zero is `-', or one invoked with the `--login' option. An _interactive_ shell is one started without non-option arguments, unless `-s' is specified, without specifying the `-c' option, and whose input and output are both connected to terminals (as determined by `isatty(3)'), or one started with the `-i' option. *Note Interactive Shells::, for more information. If arguments remain after option processing, and neither the `-c' nor the `-s' option has been supplied, the first argument is assumed to be the name of a file containing shell commands (*note Shell Scripts::). When Bash is invoked in this fashion, `$0' is set to the name of the file, and the positional parameters are set to the remaining arguments. Bash reads and executes commands from this file, then exits. Bash's exit status is the exit status of the last command executed in the script. If no commands are executed, the exit status is 0.  File: bashref.info, Node: Bash Startup Files, Next: Interactive Shells, Prev: Invoking Bash, Up: Bash Features Bash Startup Files ================== This section describs how Bash executes its startup files. If any of the files exist but cannot be read, Bash reports an error. Tildes are expanded in file names as described above under Tilde Expansion (*note Tilde Expansion::). Interactive shells are described in *Note Interactive Shells::. Invoked as an interactive login shell, or with `--login' ........................................................ When Bash is invoked as an interactive login shell, or as a non-interactive shell with the `--login' option, it first reads and executes commands from the file `/etc/profile', if that file exists. After reading that file, it looks for `~/.bash_profile', `~/.bash_login', and `~/.profile', in that order, and reads and executes commands from the first one that exists and is readable. The `--noprofile' option may be used when the shell is started to inhibit this behavior. When a login shell exits, Bash reads and executes commands from the file `~/.bash_logout', if it exists. Invoked as an interactive non-login shell ......................................... When an interactive shell that is not a login shell is started, Bash reads and executes commands from `~/.bashrc', if that file exists. This may be inhibited by using the `--norc' option. The `--rcfile FILE' option will force Bash to read and execute commands from FILE instead of `~/.bashrc'. So, typically, your `~/.bash_profile' contains the line `if [ -f ~/.bashrc ]; then . ~/.bashrc; fi' after (or before) any login-specific initializations. Invoked non-interactively ......................... When Bash is started non-interactively, to run a shell script, for example, it looks for the variable `BASH_ENV' in the environment, expands its value if it appears there, and uses the expanded value as the name of a file to read and execute. Bash behaves as if the following command were executed: `if [ -n "$BASH_ENV" ]; then . "$BASH_ENV"; fi' but the value of the `PATH' variable is not used to search for the file name. As noted above, if a non-interactive shell is invoked with the `--login' option, Bash attempts to read and execute commands from the login shell startup files. Invoked with name `sh' ...................... If Bash is invoked with the name `sh', it tries to mimic the startup behavior of historical versions of `sh' as closely as possible, while conforming to the POSIX standard as well. When invoked as an interactive login shell, or as a non-interactive shell with the `--login' option, it first attempts to read and execute commands from `/etc/profile' and `~/.profile', in that order. The `--noprofile' option may be used to inhibit this behavior. When invoked as an interactive shell with the name `sh', Bash looks for the variable `ENV', expands its value if it is defined, and uses the expanded value as the name of a file to read and execute. Since a shell invoked as `sh' does not attempt to read and execute commands from any other startup files, the `--rcfile' option has no effect. A non-interactive shell invoked with the name `sh' does not attempt to read any other startup files. When invoked as `sh', Bash enters POSIX mode after the startup files are read. Invoked in POSIX mode ..................... When Bash is started in POSIX mode, as with the `--posix' command line option, it follows the POSIX standard for startup files. In this mode, interactive shells expand the `ENV' variable and commands are read and executed from the file whose name is the expanded value. No other startup files are read. Invoked by remote shell daemon .............................. Bash attempts to determine when it is being run by the remote shell daemon, usually `rshd'. If Bash determines it is being run by rshd, it reads and executes commands from `~/.bashrc', if that file exists and is readable. It will not do this if invoked as `sh'. The `--norc' option may be used to inhibit this behavior, and the `--rcfile' option may be used to force another file to be read, but `rshd' does not generally invoke the shell with those options or allow them to be specified. Invoked with unequal effective and real UID/GIDs ................................................ If Bash is started with the effective user (group) id not equal to the real user (group) id, and the `-p' option is not supplied, no startup files are read, shell functions are not inherited from the environment, the `SHELLOPTS' variable, if it appears in the environment, is ignored, and the effective user id is set to the real user id. If the `-p' option is supplied at invocation, the startup behavior is the same, but the effective user id is not reset.  File: bashref.info, Node: Interactive Shells, Next: Bash Conditional Expressions, Prev: Bash Startup Files, Up: Bash Features Interactive Shells ================== * Menu: * What is an Interactive Shell?:: What determines whether a shell is Interactive. * Is this Shell Interactive?:: How to tell if a shell is interactive. * Interactive Shell Behavior:: What changes in a interactive shell?  File: bashref.info, Node: What is an Interactive Shell?, Next: Is this Shell Interactive?, Up: Interactive Shells What is an Interactive Shell? ----------------------------- An interactive shell is one started without non-option arguments, unless `-s' is specified, without specifiying the `-c' option, and whose input and output are both connected to terminals (as determined by `isatty(3)'), or one started with the `-i' option. An interactive shell generally reads from and writes to a user's terminal. The `-s' invocation option may be used to set the positional parameters when an interactive shell is started.  File: bashref.info, Node: Is this Shell Interactive?, Next: Interactive Shell Behavior, Prev: What is an Interactive Shell?, Up: Interactive Shells Is this Shell Interactive? -------------------------- To determine within a startup script whether or not Bash is running interactively, test the value of the `-' special parameter. It contains `i' when the shell is interactive. For example: case "$-" in *i*) echo This shell is interactive ;; *) echo This shell is not interactive ;; esac Alternatively, startup scripts may examine the variable `PS1'; it is unset in non-interactive shells, and set in interactive shells. Thus: if [ -z "$PS1" ]; then echo This shell is not interactive else echo This shell is interactive fi  File: bashref.info, Node: Interactive Shell Behavior, Prev: Is this Shell Interactive?, Up: Interactive Shells Interactive Shell Behavior -------------------------- When the shell is running interactively, it changes its behavior in several ways. 1. Startup files are read and executed as described in *Note Bash Startup Files::. 2. Job Control (*note Job Control::) is enabled by default. When job control is in effect, Bash ignores the keyboard-generated job control signals `SIGTTIN', `SIGTTOU', and `SIGTSTP'. 3. Bash expands and displays `PS1' before reading the first line of a command, and expands and displays `PS2' before reading the second and subsequent lines of a multi-line command. 4. Bash executes the value of the `PROMPT_COMMAND' variable as a command before printing the primary prompt, `$PS1' (*note Bash Variables::). 5. Readline (*note Command Line Editing::) is used to read commands from the user's terminal. 6. Bash inspects the value of the `ignoreeof' option to `set -o' instead of exiting immediately when it receives an `EOF' on its standard input when reading a command (*note The Set Builtin::). 7. Command history (*note Bash History Facilities::) and history expansion (*note History Interaction::) are enabled by default. Bash will save the command history to the file named by `$HISTFILE' when an interactive shell exits. 8. Alias expansion (*note Aliases::) is performed by default. 9. In the absence of any traps, Bash ignores `SIGTERM' (*note Signals::). 10. In the absence of any traps, `SIGINT' is caught and handled ((*note Signals::). `SIGINT' will interrupt some shell builtins. 11. An interactive login shell sends a `SIGHUP' to all jobs on exit if the `hupoxexit' shell option has been enabled (*note Signals::). 12. The `-n' invocation option is ignored, and `set -n' has no effect (*note The Set Builtin::). 13. Bash will check for mail periodically, depending on the values of the `MAIL', `MAILPATH', and `MAILCHECK' shell variables (*note Bash Variables::). 14. Expansion errors due to references to unbound shell variables after `set -u' has been enabled will not cause the shell to exit (*note The Set Builtin::). 15. The shell will not exit on expansion errors caused by VAR being unset or null in `${VAR:?WORD}' expansions (*note Shell Parameter Expansion::). 16. Redirection errors encountered by shell builtins will not cause the shell to exit. 17. When running in POSIX mode, a special builtin returning an error status will not cause the shell to exit (*note Bash POSIX Mode::). 18. A failed `exec' will not cause the shell to exit (*note Bourne Shell Builtins::). 19. Parser syntax errors will not cause the shell to exit. 20. Simple spelling correction for directory arguments to the `cd' builtin is enabled by default (see the description of the `cdspell' option to the `shopt' builtin in *Note Bash Builtins::). 21. The shell will check the value of the `TMOUT' variable and exit if a command is not read within the specified number of seconds after printing `$PS1' (*note Bash Variables::).  File: bashref.info, Node: Bash Conditional Expressions, Next: Shell Arithmetic, Prev: Interactive Shells, Up: Bash Features Bash Conditional Expressions ============================ Conditional expressions are used by the `[[' compound command and the `test' and `[' builtin commands. Expressions may be unary or binary. Unary expressions are often used to examine the status of a file. There are string operators and numeric comparison operators as well. If the FILE argument to one of the primaries is of the form `/dev/fd/N', then file descriptor N is checked. If the FILE argument to one of the primaries is one of `/dev/stdin', `/dev/stdout', or `/dev/stderr', file descriptor 0, 1, or 2, respectively, is checked. `-a FILE' True if FILE exists. `-b FILE' True if FILE exists and is a block special file. `-c FILE' True if FILE exists and is a character special file. `-d FILE' True if FILE exists and is a directory. `-e FILE' True if FILE exists. `-f FILE' True if FILE exists and is a regular file. `-g FILE' True if FILE exists and its set-group-id bit is set. `-h FILE' True if FILE exists and is a symbolic link. `-k FILE' True if FILE exists and its "sticky" bit is set. `-p FILE' True if FILE exists and is a named pipe (FIFO). `-r FILE' True if FILE exists and is readable. `-s FILE' True if FILE exists and has a size greater than zero. `-t FD' True if file descriptor FD is open and refers to a terminal. `-u FILE' True if FILE exists and its set-user-id bit is set. `-w FILE' True if FILE exists and is writable. `-x FILE' True if FILE exists and is executable. `-O FILE' True if FILE exists and is owned by the effective user id. `-G FILE' True if FILE exists and is owned by the effective group id. `-L FILE' True if FILE exists and is a symbolic link. `-S FILE' True if FILE exists and is a socket. `-N FILE' True if FILE exists and has been modified since it was last read. `FILE1 -nt FILE2' True if FILE1 is newer (according to modification date) than FILE2. `FILE1 -ot FILE2' True if FILE1 is older than FILE2. `FILE1 -ef FILE2' True if FILE1 and FILE2 have the same device and inode numbers. `-o OPTNAME' True if shell option OPTNAME is enabled. The list of options appears in the description of the `-o' option to the `set' builtin (*note The Set Builtin::). `-z STRING' True if the length of STRING is zero. `-n STRING' `STRING' True if the length of STRING is non-zero. `STRING1 == STRING2' True if the strings are equal. `=' may be used in place of `=='. `STRING1 != STRING2' True if the strings are not equal. `STRING1 < STRING2' True if STRING1 sorts before STRING2 lexicographically in the current locale. `STRING1 > STRING2' True if STRING1 sorts after STRING2 lexicographically in the current locale. `ARG1 OP ARG2' `OP' is one of `-eq', `-ne', `-lt', `-le', `-gt', or `-ge'. These arithmetic binary operators return true if ARG1 is equal to, not equal to, less than, less than or equal to, greater than, or greater than or equal to ARG2, respectively. ARG1 and ARG2 may be positive or negative integers.  File: bashref.info, Node: Shell Arithmetic, Next: Aliases, Prev: Bash Conditional Expressions, Up: Bash Features Shell Arithmetic ================ The shell allows arithmetic expressions to be evaluated, as one of the shell expansions or by the `let' builtin. Evaluation is done in long integers with no check for overflow, though division by 0 is trapped and flagged as an error. The operators and their precedence and associativity are the same as in the C language. The following list of operators is grouped into levels of equal-precedence operators. The levels are listed in order of decreasing precedence. `ID++ ID--' variable post-increment and post-decrement `++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' conditional evaluation `= *= /= %= += -= <<= >>= &= ^= |=' assignment `expr1 , expr2' comma Shell variables are allowed as operands; parameter expansion is performed before the expression is evaluated. Within an expression, shell variables may also be referenced by name without using the parameter expansion syntax. The value of a variable is evaluated as an arithmetic expression when it is referenced. A shell variable need not have its integer attribute turned on to be used in an expression. Constants with a leading 0 are interpreted as octal numbers. A leading `0x' or `0X' denotes hexadecimal. Otherwise, numbers take the form [BASE`#']N, where BASE is a decimal number between 2 and 64 representing the arithmetic base, and N is a number in that base. If BASE`#' is omitted, then base 10 is used. The digits greater than 9 are represented by the lowercase letters, the uppercase letters, `@', and `_', in that order. If BASE is less than or equal to 36, lowercase and uppercase letters may be used interchangably to represent numbers between 10 and 35. Operators are evaluated in order of precedence. Sub-expressions in parentheses are evaluated first and may override the precedence rules above.  File: bashref.info, Node: Aliases, Next: Arrays, Prev: Shell Arithmetic, Up: Bash Features Aliases ======= ALIASES allow a string to be substituted for a word when it is used as the first word of a simple command. The shell maintains a list of aliases that may be set and unset with the `alias' and `unalias' builtin commands. The first word of each simple command, if unquoted, is checked to see if it has an alias. If so, that word is replaced by the text of the alias. The alias name and the replacement text may contain any valid shell input, including shell metacharacters, with the exception that the alias name may not contain `='. The first word of the replacement text is tested for aliases, but a word that is identical to an alias being expanded is not expanded a second time. This means that one may alias `ls' to `"ls -F"', for instance, and Bash does not try to recursively expand the replacement text. If the last character of the alias value is a space or tab character, then the next command word following the alias is also checked for alias expansion. Aliases are created and listed with the `alias' command, and removed with the `unalias' command. There is no mechanism for using arguments in the replacement text, as in `csh'. If arguments are needed, a shell function should be used (*note Shell Functions::). Aliases are not expanded when the shell is not interactive, unless the `expand_aliases' shell option is set using `shopt' (*note Bash Builtins::). The rules concerning the definition and use of aliases are somewhat confusing. Bash always reads at least one complete line of input before executing any of the commands on that line. Aliases are expanded when a command is read, not when it is executed. Therefore, an alias definition appearing on the same line as another command does not take effect until the next line of input is read. The commands following the alias definition on that line are not affected by the new alias. This behavior is also an issue when functions are executed. Aliases are expanded when a function definition is read, not when the function is executed, because a function definition is itself a compound command. As a consequence, aliases defined in a function are not available until after that function is executed. To be safe, always put alias definitions on a separate line, and do not use `alias' in compound commands. For almost every purpose, shell functions are preferred over aliases.  File: bashref.info, Node: Arrays, Next: The Directory Stack, Prev: Aliases, Up: Bash Features Arrays ====== Bash provides one-dimensional array variables. Any variable may be used as an array; the `declare' builtin will explicitly declare an array. There is no maximum limit on the size of an array, nor any requirement that members be indexed or assigned contiguously. Arrays are zero-based. An array is created automatically if any variable is assigned to using the syntax name[SUBSCRIPT]=VALUE The SUBSCRIPT is treated as an arithmetic expression that must evaluate to a number greater than or equal to zero. To explicitly declare an array, use declare -a NAME The syntax declare -a NAME[SUBSCRIPT] is also accepted; the SUBSCRIPT is ignored. Attributes may be specified for an array variable using the `declare' and `readonly' builtins. Each attribute applies to all members of an array. Arrays are assigned to using compound assignments of the form name=(value1 ... valueN) where each VALUE is of the form `[[SUBSCRIPT]=]'STRING. If the optional subscript is supplied, that index is assigned to; otherwise the index of the element assigned is the last index assigned to by the statement plus one. Indexing starts at zero. This syntax is also accepted by the `declare' builtin. Individual array elements may be assigned to using the `name['SUBSCRIPT`]='VALUE syntax introduced above. Any element of an array may be referenced using `${name['SUBSCRIPT`]}'. The braces are required to avoid conflicts with the shell's filename expansion operators. If the SUBSCRIPT is `@' or `*', the word expands to all members of the array NAME. These subscripts differ only when the word appears within double quotes. If the word is double-quoted, `${name[*]}' expands to a single word with the value of each array member separated by the first character of the `IFS' variable, and `${name[@]}' expands each element of NAME to a separate word. When there are no array members, `${name[@]}' expands to nothing. This is analogous to the expansion of the special parameters `@' and `*'. `${#name['SUBSCRIPT`]}' expands to the length of `${name['SUBSCRIPT`]}'. If SUBSCRIPT is `@' or `*', the expansion is the number of elements in the array. Referencing an array variable without a subscript is equivalent to referencing element zero. The `unset' builtin is used to destroy arrays. `unset' NAME[SUBSCRIPT] destroys the array element at index SUBSCRIPT. `unset' NAME, where NAME is an array, removes the entire array. A subscript of `*' or `@' also removes the entire array. The `declare', `local', and `readonly' builtins each accept a `-a' option to specify an array. The `read' builtin accepts a `-a' option to assign a list of words read from the standard input to an array, and can read values from the standard input into individual array elements. The `set' and `declare' builtins display array values in a way that allows them to be reused as input.  File: bashref.info, Node: The Directory Stack, Next: Printing a Prompt, Prev: Arrays, Up: Bash Features The Directory Stack =================== * Menu: * Directory Stack Builtins:: Bash builtin commands to manipulate the directory stack. The directory stack is a list of recently-visited directories. The `pushd' builtin adds directories to the stack as it changes the current directory, and the `popd' builtin removes specified directories from the stack and changes the current directory to the directory removed. The `dirs' builtin displays the contents of the directory stack. The contents of the directory stack are also visible as the value of the `DIRSTACK' shell variable.  File: bashref.info, Node: Directory Stack Builtins, Up: The Directory Stack Directory Stack Builtins ------------------------ `dirs' dirs [+N | -N] [-clpv] Display the list of currently remembered directories. Directories are added to the list with the `pushd' command; the `popd' command removes directories from the list. `+N' Displays the Nth directory (counting from the left of the list printed by `dirs' when invoked without options), starting with zero. `-N' Displays the Nth directory (counting from the right of the list printed by `dirs' when invoked without options), starting with zero. `-c' Clears the directory stack by deleting all of the elements. `-l' Produces a longer listing; the default listing format uses a tilde to denote the home directory. `-p' Causes `dirs' to print the directory stack with one entry per line. `-v' Causes `dirs' to print the directory stack with one entry per line, prefixing each entry with its index in the stack. `popd' popd [+N | -N] [-n] Remove the top entry from the directory stack, and `cd' to the new top directory. When no arguments are given, `popd' removes the top directory from the stack and performs a `cd' to the new top directory. The elements are numbered from 0 starting at the first directory listed with `dirs'; i.e., `popd' is equivalent to `popd +0'. `+N' Removes the Nth directory (counting from the left of the list printed by `dirs'), starting with zero. `-N' Removes the Nth directory (counting from the right of the list printed by `dirs'), starting with zero. `-n' Suppresses the normal change of directory when removing directories from the stack, so that only the stack is manipulated. `pushd' pushd [DIR | +N | -N] [-n] Save the current directory on the top of the directory stack and then `cd' to DIR. With no arguments, `pushd' exchanges the top two directories. `+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' 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. `-n' Suppresses the normal change of directory when adding directories to the stack, so that only the stack is manipulated. `DIR' Makes the current working directory be the top of the stack, and then executes the equivalent of ``cd' DIR'. `cd's to DIR.  File: bashref.info, Node: Printing a Prompt, Next: The Restricted Shell, Prev: The Directory Stack, Up: Bash Features Controlling the Prompt ====================== The value of the variable `PROMPT_COMMAND' is examined just before Bash prints each primary prompt. If `PROMPT_COMMAND' is set and has a non-null value, then the value is executed just as if it had been typed on the command line. In addition, the following table describes the special characters which can appear in the prompt variables: `\a' A bell character. `\d' The date, in "Weekday Month Date" format (e.g., "Tue May 26"). `\e' An escape character. `\h' The hostname, up to the first `.'. `\H' The hostname. `\j' The number of jobs currently managed by the shell. `\l' The basename of the shell's terminal device name. `\n' A newline. `\r' A carriage return. `\s' The name of the shell, the basename of `$0' (the portion following the final slash). `\t' The time, in 24-hour HH:MM:SS format. `\T' The time, in 12-hour HH:MM:SS format. `\@' The time, in 12-hour am/pm format. `\A' The time, in 24-hour HH:MM format. `\u' The username of the current user. `\v' The version of Bash (e.g., 2.00) `\V' The release of Bash, version + patchlevel (e.g., 2.00.0) `\w' The current working directory. `\W' The basename of `$PWD'. `\!' The history number of this command. `\#' The command number of this command. `\$' If the effective uid is 0, `#', otherwise `$'. `\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. The command number and the history number are usually different: the history number of a command is its position in the history list, which may include commands restored from the history file (*note Bash History Facilities::), while the command number is the position in the sequence of commands executed during the current shell session. After the string is decoded, it is expanded via parameter expansion, command substitution, arithmetic expansion, and quote removal, subject to the value of the `promptvars' shell option (*note Bash Builtins::).  File: bashref.info, Node: The Restricted Shell, Next: Bash POSIX Mode, Prev: Printing a Prompt, Up: Bash Features The Restricted Shell ==================== If Bash is started with the name `rbash', or the `--restricted' option is supplied at invocation, the shell becomes restricted. A restricted shell is used to set up an environment more controlled than the standard shell. A restricted shell behaves identically to `bash' with the exception that the following are disallowed: * Changing directories with the `cd' builtin. * Setting or unsetting the values of the `SHELL', `PATH', `ENV', or `BASH_ENV' variables. * Specifying command names containing slashes. * Specifying a filename containing a slash as an argument to the `.' builtin command. * Specifying a filename containing a slash as an argument to the `-p' option to the `hash' builtin command. * Importing function definitions from the shell environment at startup. * Parsing the value of `SHELLOPTS' from the shell environment at startup. * Redirecting output using the `>', `>|', `<>', `>&', `&>', and `>>' redirection operators. * Using the `exec' builtin to replace the shell with another command. * Adding or deleting builtin commands with the `-f' and `-d' options to the `enable' builtin. * Specifying the `-p' option to the `command' builtin. * Turning off restricted mode with `set +r' or `set +o restricted'.  File: bashref.info, Node: Bash POSIX Mode, Prev: The Restricted Shell, Up: Bash Features Bash POSIX Mode =============== Starting Bash with the `--posix' command-line option or executing `set -o posix' while Bash is running will cause Bash to conform more closely to the POSIX 1003.2 standard by changing the behavior to match that specified by POSIX in areas where the Bash default differs. The following list is what's changed when `POSIX mode' is in effect: 1. When a command in the hash table no longer exists, Bash will re-search `$PATH' to find the new location. This is also available with `shopt -s checkhash'. 2. The message printed by the job control code and builtins when a job exits with a non-zero status is `Done(status)'. 3. The message printed by the job control code and builtins when a job is stopped is `Stopped(SIGNAME)', where SIGNAME is, for example, `SIGTSTP'. 4. Reserved words may not be aliased. 5. The POSIX 1003.2 `PS1' and `PS2' expansions of `!' to the history number and `!!' to `!' are enabled, and parameter expansion is performed on the values of `PS1' and `PS2' regardless of the setting of the `promptvars' option. 6. Interactive comments are enabled by default. (Bash has them on by default anyway.) 7. The POSIX 1003.2 startup files are executed (`$ENV') rather than the normal Bash files. 8. Tilde expansion is only performed on assignments preceding a command name, rather than on all assignment statements on the line. 9. The default history file is `~/.sh_history' (this is the default value of `$HISTFILE'). 10. The output of `kill -l' prints all the signal names on a single line, separated by spaces. 11. Non-interactive shells exit if FILENAME in `.' FILENAME is not found. 12. Non-interactive shells exit if a syntax error in an arithmetic expansion results in an invalid expression. 13. Redirection operators do not perform filename expansion on the word in the redirection unless the shell is interactive. 14. Redirection operators do not perform word splitting on the word in the redirection. 15. Function names must be valid shell `name's. That is, they may not contain characters other than letters, digits, and underscores, and may not start with a digit. Declaring a function with an invalid name causes a fatal syntax error in non-interactive shells. 16. POSIX 1003.2 `special' builtins are found before shell functions during command lookup. 17. If a POSIX 1003.2 special builtin returns an error status, a non-interactive shell exits. The fatal errors are those listed in the POSIX.2 standard, and include things like passing incorrect options, redirection errors, variable assignment errors for assignments preceding the command name, and so on. 18. If the `cd' builtin finds a directory to change to using `$CDPATH', the value it assigns to the `PWD' variable does not contain any symbolic links, as if `cd -P' had been executed. 19. If `CDPATH' is set, the `cd' builtin will not implicitly append the current directory to it. This means that `cd' will fail if no valid directory name can be constructed from any of the entries in `$CDPATH', even if the a directory with the same name as the name given as an argument to `cd' exists in the current directory. 20. A non-interactive shell exits with an error status if a variable assignment error occurs when no command name follows the assignment statements. A variable assignment error occurs, for example, when trying to assign a value to a readonly variable. 21. A non-interactive shell exits with an error status if the iteration variable in a `for' statement or the selection variable in a `select' statement is a readonly variable. 22. Process substitution is not available. 23. Assignment statements preceding POSIX 1003.2 special builtins persist in the shell environment after the builtin completes. 24. Assignment statements preceding shell function calls persist in the shell environment after the function returns, as if a POSIX special builtin command had been executed. 25. The `export' and `readonly' builtin commands display their output in the format required by POSIX 1003.2. 26. The `trap' builtin displays signal names without the leading `SIG'. 27. The `.' and `source' builtins do not search the current directory for the filename argument if it is not found by searching `PATH'. 28. Subshells spawned to execute command substitutions inherit the value of the `-e' option from the parent shell. When not in POSIX mode, Bash clears the `-e' option in such subshells. 29. Alias expansion is always enabled, even in non-interactive shells. 30. When the `set' builtin is invoked without options, it does not display shell function names and definitions. 31. When the `set' builtin is invoked without options, it displays variable values without quotes, unless they contain shell metacharacters, even if the result contains nonprinting characters. There is other POSIX 1003.2 behavior that Bash does not implement. Specifically: 1. Assignment statements affect the execution environment of all builtins, not just special ones. 2. When a subshell is created to execute a shell script with execute permission, but without a leading `#!', Bash sets `$0' to the full pathname of the script as found by searching `$PATH', rather than the command as typed by the user. 3. When using `.' to source a shell script found in `$PATH', bash checks execute permission bits rather than read permission bits, just as if it were searching for a command.  File: bashref.info, Node: Job Control, Next: Using History Interactively, Prev: Bash Features, Up: Top Job Control *********** This chapter discusses what job control is, how it works, and how Bash allows you to access its facilities. * Menu: * Job Control Basics:: How job control works. * Job Control Builtins:: Bash builtin commands used to interact with job control. * Job Control Variables:: Variables Bash uses to customize job control.  File: bashref.info, Node: Job Control Basics, Next: Job Control Builtins, Up: Job Control Job Control Basics ================== Job control refers to the ability to selectively stop (suspend) the execution of processes and continue (resume) their execution at a later point. A user typically employs this facility via an interactive interface supplied jointly by the system's terminal driver and Bash. The shell associates a JOB with each pipeline. It keeps a table of currently executing jobs, which may be listed with the `jobs' command. When Bash starts a job asynchronously, it prints a line that looks like: [1] 25647 indicating that this job is job number 1 and that the process ID of the last process in the pipeline associated with this job is 25647. All of the processes in a single pipeline are members of the same job. Bash uses the JOB abstraction as the basis for job control. To facilitate the implementation of the user interface to job control, the operating system maintains the notion of a current terminal process group ID. Members of this process group (processes whose process group ID is equal to the current terminal process group ID) receive keyboard-generated signals such as `SIGINT'. These processes are said to be in the foreground. Background processes are those whose process group ID differs from the terminal's; such processes are immune to keyboard-generated signals. Only foreground processes are allowed to read from or write to the terminal. Background processes which attempt to read from (write to) the terminal are sent a `SIGTTIN' (`SIGTTOU') signal by the terminal driver, which, unless caught, suspends the process. If the operating system on which Bash is running supports job control, Bash contains facilities to use it. Typing the SUSPEND character (typically `^Z', Control-Z) while a process is running causes that process to be stopped and returns control to Bash. Typing the DELAYED SUSPEND character (typically `^Y', Control-Y) causes the process to be stopped when it attempts to read input from the terminal, and control to be returned to Bash. The user then manipulates the state of this job, using the `bg' command to continue it in the background, the `fg' command to continue it in the foreground, or the `kill' command to kill it. A `^Z' takes effect immediately, and has the additional side effect of causing pending output and typeahead to be discarded. There are a number of ways to refer to a job in the shell. The character `%' introduces a job name. Job number `n' may be referred to as `%n'. The symbols `%%' and `%+' refer to the shell's notion of the current job, which is the last job stopped while it was in the foreground or started in the background. The previous job may be referenced using `%-'. In output pertaining to jobs (e.g., the output of the `jobs' command), the current job is always flagged with a `+', and the previous job with a `-'. A job may also be referred to using a prefix of the name used to start it, or using a substring that appears in its command line. For example, `%ce' refers to a stopped `ce' job. Using `%?ce', on the other hand, refers to any job containing the string `ce' in its command line. If the prefix or substring matches more than one job, Bash reports an error. Simply naming a job can be used to bring it into the foreground: `%1' is a synonym for `fg %1', bringing job 1 from the background into the foreground. Similarly, `%1 &' resumes job 1 in the background, equivalent to `bg %1' The shell learns immediately whenever a job changes state. Normally, Bash waits until it is about to print a prompt before reporting changes in a job's status so as to not interrupt any other output. If the `-b' option to the `set' builtin is enabled, Bash reports such changes immediately (*note The Set Builtin::). Any trap on `SIGCHLD' is executed for each child process that exits. If an attempt to exit Bash is while jobs are stopped, the shell prints a message warning that there are stopped jobs. The `jobs' command may then be used to inspect their status. If a second attempt to exit is made without an intervening command, Bash does not print another warning, and the stopped jobs are terminated.  File: bashref.info, Node: Job Control Builtins, Next: Job Control Variables, Prev: Job Control Basics, Up: Job Control Job Control Builtins ==================== `bg' bg [JOBSPEC] Resume the suspended job JOBSPEC in the background, as if it had been started with `&'. If JOBSPEC is not supplied, the current job is used. The return status is zero unless it is run when job control is not enabled, or, when run with job control enabled, if JOBSPEC was not found or JOBSPEC specifies a job that was started without job control. `fg' fg [JOBSPEC] Resume the job JOBSPEC in the foreground and make it the current job. If JOBSPEC is not supplied, the current job is used. The return status is that of the command placed into the foreground, or non-zero if run when job control is disabled or, when run with job control enabled, JOBSPEC does not specify a valid job or JOBSPEC specifies a job that was started without job control. `jobs' jobs [-lnprs] [JOBSPEC] jobs -x COMMAND [ARGUMENTS] The first form lists the active jobs. The options have the following meanings: `-l' List process IDs in addition to the normal information. `-n' Display information only about jobs that have changed status since the user was last notified of their status. `-p' List only the process ID of the job's process group leader. `-r' Restrict output to running jobs. `-s' Restrict output to stopped jobs. If JOBSPEC is given, output is restricted to information about that job. If JOBSPEC is not supplied, the status of all jobs is listed. If the `-x' option is supplied, `jobs' replaces any JOBSPEC found in COMMAND or ARGUMENTS with the corresponding process group ID, and executes COMMAND, passing it ARGUMENTs, returning its exit status. `kill' kill [-s SIGSPEC] [-n SIGNUM] [-SIGSPEC] JOBSPEC or PID kill -l [EXIT_STATUS] Send a signal specified by SIGSPEC or SIGNUM to the process named by job specification JOBSPEC or process ID PID. SIGSPEC is either a signal name such as `SIGINT' (with or without the `SIG' prefix) or a signal number; SIGNUM is a signal number. If SIGSPEC and SIGNUM are not present, `SIGTERM' is used. The `-l' option lists the signal names. If any arguments are supplied when `-l' is given, the names of the signals corresponding to the arguments are listed, and the return status is zero. EXIT_STATUS is a number specifying a signal number or the exit status of a process terminated by a signal. The return status is zero if at least one signal was successfully sent, or non-zero if an error occurs or an invalid option is encountered. `wait' wait [JOBSPEC or PID] Wait until the child process specified by process ID PID or job specification JOBSPEC exits and return the exit status of the last command waited for. If a job spec is given, all processes in the job are waited for. If no arguments are given, all currently active child processes are waited for, and the return status is zero. If neither JOBSPEC nor PID specifies an active child process of the shell, the return status is 127. `disown' disown [-ar] [-h] [JOBSPEC ...] Without options, each JOBSPEC is removed from the table of active jobs. If the `-h' option is given, the job is not removed from the table, but is marked so that `SIGHUP' is not sent to the job if the shell receives a `SIGHUP'. If JOBSPEC is not present, and neither the `-a' nor `-r' option is supplied, the current job is used. If no JOBSPEC is supplied, the `-a' option means to remove or mark all jobs; the `-r' option without a JOBSPEC argument restricts operation to running jobs. `suspend' suspend [-f] Suspend the execution of this shell until it receives a `SIGCONT' signal. The `-f' option means to suspend even if the shell is a login shell. When job control is not active, the `kill' and `wait' builtins do not accept JOBSPEC arguments. They must be supplied process IDs.  File: bashref.info, Node: Job Control Variables, Prev: Job Control Builtins, Up: Job Control Job Control Variables ===================== `auto_resume' This variable controls how the shell interacts with the user and job control. If this variable exists then single word simple commands without redirections are treated as candidates for resumption of an existing job. There is no ambiguity allowed; if there is more than one job beginning with the string typed, then the most recently accessed job will be selected. The name of a stopped job, in this context, is the command line used to start it. If this variable is set to the value `exact', the string supplied must match the name of a stopped job exactly; if set to `substring', the string supplied needs to match a substring of the name of a stopped job. The `substring' value provides functionality analogous to the `%?' job ID (*note Job Control Basics::). If set to any other value, the supplied string must be a prefix of a stopped job's name; this provides functionality analogous to the `%' job ID.  File: bashref.info, Node: Command Line Editing, Next: Installing Bash, Prev: Using History Interactively, Up: Top Command Line Editing ******************** This chapter describes the basic features of the GNU command line editing interface. Command line editing is provided by the Readline library, which is used by several different programs, including Bash. * Menu: * Introduction and Notation:: Notation used in this text. * Readline Interaction:: The minimum set of commands for editing a line. * Readline Init File:: Customizing Readline from a user's view. * Bindable Readline Commands:: A description of most of the Readline commands available for binding * Readline vi Mode:: A short description of how to make Readline behave like the vi editor. * Programmable Completion:: How to specify the possible completions for a specific command. * Programmable Completion Builtins:: Builtin commands to specify how to complete arguments for a particular command.  File: bashref.info, Node: Introduction and Notation, Next: Readline Interaction, Up: Command Line Editing Introduction to Line Editing ============================ The following paragraphs describe the notation used to represent keystrokes. The text `C-k' is read as `Control-K' and describes the character produced when the key is pressed while the Control key is depressed. The text `M-k' is read as `Meta-K' and describes the character produced when the Meta key (if you have one) is depressed, and the key is pressed. The Meta key is labeled on many keyboards. On keyboards with two keys labeled (usually to either side of the space bar), the on the left side is generally set to work as a Meta key. The key on the right may also be configured to work as a Meta key or may be configured as some other modifier, such as a Compose key for typing accented characters. If you do not have a Meta or key, or another key working as a Meta key, the identical keystroke can be generated by typing _first_, and then typing . Either process is known as "metafying" the key. The text `M-C-k' is read as `Meta-Control-k' and describes the character produced by "metafying" `C-k'. In addition, several keys have their own names. Specifically, , , , , , and all stand for themselves when seen in this text, or in an init file (*note Readline Init File::). If your keyboard lacks a key, typing will produce the desired character. The key may be labeled or on some keyboards.  File: bashref.info, Node: Readline Interaction, Next: Readline Init File, Prev: Introduction and Notation, Up: Command Line Editing Readline Interaction ==================== Often during an interactive session you type in a long line of text, only to notice that the first word on the line is misspelled. The Readline library gives you a set of commands for manipulating the text as you type it in, allowing you to just fix your typo, and not forcing you to retype the majority of the line. Using these editing commands, you move the cursor to the place that needs correction, and delete or insert the text of the corrections. Then, when you are satisfied with the line, you simply press . You do not have to be at the end of the line to press ; the entire line is accepted regardless of the location of the cursor within the line. * Menu: * Readline Bare Essentials:: The least you need to know about Readline. * Readline Movement Commands:: Moving about the input line. * Readline Killing Commands:: How to delete text, and how to get it back! * Readline Arguments:: Giving numeric arguments to commands. * Searching:: Searching through previous lines.  File: bashref.info, Node: Readline Bare Essentials, Next: Readline Movement Commands, Up: Readline Interaction Readline Bare Essentials ------------------------ In order to enter characters into the line, simply type them. The typed character appears where the cursor was, and then the cursor moves one space to the right. If you mistype a character, you can use your erase character to back up and delete the mistyped character. Sometimes you may mistype a character, and not notice the error until you have typed several other characters. In that case, you can type `C-b' to move the cursor to the left, and then correct your mistake. Afterwards, you can move the cursor to the right with `C-f'. When you add text in the middle of a line, you will notice that characters to the right of the cursor are `pushed over' to make room for the text that you have inserted. Likewise, when you delete text behind the cursor, characters to the right of the cursor are `pulled back' to fill in the 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' Move back one character. `C-f' Move forward one character. or Delete the character to the left of the cursor. `C-d' Delete the character underneath the cursor. Printing characters Insert the character into the line at the cursor. `C-_' or `C-x C-u' Undo the last editing command. You can undo all the way back to an empty line. (Depending on your configuration, the key be set to delete the character to the left of the cursor and the key set to delete the character underneath the cursor, like `C-d', rather than the character to the left of the cursor.)  File: bashref.info, Node: Readline Movement Commands, Next: Readline Killing Commands, Prev: Readline Bare Essentials, Up: Readline Interaction Readline Movement Commands -------------------------- The above table describes the most basic keystrokes that you need in order to do editing of the input line. For your convenience, many other commands have been added in addition to `C-b', `C-f', `C-d', and . Here are some commands for moving more rapidly about the line. `C-a' Move to the start of the line. `C-e' Move to the end of the line. `M-f' Move forward a word, where a word is composed of letters and digits. `M-b' Move backward a word. `C-l' Clear the screen, reprinting the current line at the top. Notice how `C-f' moves forward a character, while `M-f' moves forward a word. It is a loose convention that control keystrokes operate on characters while meta keystrokes operate on words.  File: bashref.info, Node: Readline Killing Commands, Next: Readline Arguments, Prev: Readline Movement Commands, Up: Readline Interaction Readline Killing Commands ------------------------- "Killing" text means to delete the text from the line, but to save it away for later use, usually by "yanking" (re-inserting) it back into the line. (`Cut' and `paste' are more recent jargon for `kill' and `yank'.) If the description for a command says that it `kills' text, then you can be sure that you can get the text back in a different (or the same) place later. When you use a kill command, the text is saved in a "kill-ring". Any number of consecutive kills save all of the killed text together, so that when you yank it back, you get it all. The kill ring is not line specific; the text that you killed on a previously typed line is available to be yanked back later, when you are typing another line. Here is the list of commands for killing text. `C-k' Kill the text from the current cursor position to the end of the line. `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-' 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' Kill from the cursor to the previous whitespace. This is different than `M-' because the word boundaries differ. Here is how to "yank" the text back into the line. Yanking means to copy the most-recently-killed text from the kill buffer. `C-y' Yank the most recently killed text back into the buffer at the cursor. `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'.  File: bashref.info, Node: Readline Arguments, Next: Searching, Prev: Readline Killing Commands, Up: Readline Interaction Readline Arguments ------------------ You can pass numeric arguments to Readline commands. Sometimes the argument acts as a repeat count, other times it is the sign of the argument that is significant. If you pass a negative argument to a command which normally acts in a forward direction, that command will act in a backward direction. For example, to kill text back to the start of the line, you might type `M-- C-k'. The general way to pass numeric arguments to a command is to type meta digits before the command. If the first `digit' typed is a minus sign (`-'), then the sign of the argument will be negative. Once you have typed one meta digit to get the argument started, you can type the remainder of the digits, and then the command. For example, to give the `C-d' command an argument of 10, you could type `M-1 0 C-d', which will delete the next ten characters on the input line.  File: bashref.info, Node: Searching, Prev: Readline Arguments, Up: Readline Interaction Searching for Commands in the History ------------------------------------- Readline provides commands for searching through the command history (*note Bash History Facilities::) for lines containing a specified string. There are two search modes: "incremental" and "non-incremental". Incremental searches begin before the user has finished typing the search string. As each character of the search string is typed, Readline displays the next entry from the history matching the string typed so far. An incremental search requires only as many characters as needed to find the desired history entry. To search backward in the history for a particular string, type `C-r'. Typing `C-s' searches forward through the history. The characters present in the value of the `isearch-terminators' variable are used to terminate an incremental search. If that variable has not been assigned a value, the and `C-J' characters will terminate an incremental search. `C-g' will abort an incremental search and restore the original line. When the search is terminated, the history entry containing the search string becomes the current line. To find other matching entries in the history list, type `C-r' or `C-s' as appropriate. This will search backward or forward in the history for the next entry matching the search string typed so far. Any other key sequence bound to a Readline command will terminate the search and execute that command. For instance, a will terminate the search and accept the line, thereby executing the command from the history list. A movement command will terminate the search, make the last line found the current line, and begin editing. Readline remembers the last incremental search string. If two `C-r's are typed without any intervening characters defining a new search string, any remembered search string is used. Non-incremental searches read the entire search string before starting to search for matching history lines. The search string may be typed by the user or be part of the contents of the current line.  File: bashref.info, Node: Readline Init File, Next: Bindable Readline Commands, Prev: Readline Interaction, Up: Command Line Editing Readline Init File ================== Although the Readline library comes with a set of Emacs-like keybindings installed by default, it is possible to use a different set of keybindings. Any user can customize programs that use Readline by putting commands in an "inputrc" file, conventionally in his home directory. The name of this file is taken from the value of the shell variable `INPUTRC'. If that variable is unset, the default is `~/.inputrc'. When a program which uses the Readline library starts up, the 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. * Menu: * Readline Init File Syntax:: Syntax for the commands in the inputrc file. * Conditional Init Constructs:: Conditional key bindings in the inputrc file. * Sample Init File:: An example inputrc file.  File: bashref.info, Node: Readline Init File Syntax, Next: Conditional Init Constructs, Up: Readline Init File Readline Init File Syntax ------------------------- There are only a few basic constructs allowed in the Readline init file. Blank lines are ignored. Lines beginning with a `#' are comments. Lines beginning with a `$' indicate conditional constructs (*note Conditional Init Constructs::). Other lines denote variable settings and key bindings. 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. The syntax is simple: set VARIABLE VALUE Here, for example, is how to change from the default Emacs-like key binding to use `vi' line editing commands: set editing-mode vi Variable names and values, where appropriate, are recognized without regard to case. The `bind -V' command lists the current Readline variable names and values. *Note Bash Builtins::. 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. 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. `comment-begin' The string to insert at the beginning of the line when the `insert-comment' command is executed. The default value is `"#"'. `completion-ignore-case' If set to `on', Readline performs filename matching and completion in a case-insensitive fashion. The default value is `off'. `completion-query-items' The number of possible completions that determines when the user is asked whether he wants to see the list of possibilities. If the number of possible completions is greater than this value, Readline will ask the user whether or not he wishes to view them; otherwise, they are simply listed. This variable must be set to an integer value greater than or equal to 0. The default limit is `100'. `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 character, converting them to a meta-prefixed key sequence. The default value is `on'. `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'. `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'. `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'. `expand-tilde' If set to `on', tilde expansion is performed when Readline attempts word completion. The default is `off'. If set to `on', the history code attempts to place point at the same location on each history line retrived with `previous-history' or `next-history'. `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. By default, this variable is set to `off'. `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 default value is `off'. 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 (*note Searching::). If this variable has not been given a value, the characters and `C-J' will terminate an incremental search. `keymap' Sets Readline's idea of the current keymap for key binding commands. Acceptable `keymap' names are `emacs', `emacs-standard', `emacs-meta', `emacs-ctlx', `vi', `vi-move', `vi-command', and `vi-insert'. `vi' is equivalent to `vi-command'; `emacs' is equivalent to `emacs-standard'. The default value is `emacs'. The value of the `editing-mode' variable also affects the default keymap. `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 asterisk (`*') at the start of history lines which have been modified. This variable is `off' by default. `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, unless the leading `.' is supplied by the user in the filename to be completed. This variable is `on' by default. `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'. `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'. `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'. `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'. 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 name, the default keybinding, if any, and a short description of what the command does. Once you know the name of the command, simply place on a line in the init file the name of the key you wish to bind the command to, a colon, and then the name of the command. The name of the key can be expressed in different ways, depending on what you find most comfortable. In addition to command names, readline allows keys to be bound 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. *Note Bash Builtins::. KEYNAME: FUNCTION-NAME or MACRO KEYNAME is the name of a key spelled out in English. For example: Control-u: universal-argument Meta-Rubout: backward-kill-word Control-o: "> output" In the above example, `C-u' is bound to the function `universal-argument', `M-DEL' is bound to the function `backward-kill-word', and `C-o' is bound to run the macro expressed on the right hand side (that is, to insert the text `> output' into the line). A number of symbolic character names are recognized while processing this key binding syntax: DEL, ESC, ESCAPE, LFD, NEWLINE, RET, RETURN, RUBOUT, SPACE, SPC, and TAB. "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 escapes can be used, as in the following example, but the special character names are not recognized. "\C-u": universal-argument "\C-x\C-r": re-read-init-file "\e[11~": "Function Key 1" In the above example, `C-u' is again bound to the function `universal-argument' (just as it was in the first example), `C-x C-r' is bound to the function `re-read-init-file', and ` <[> <1> <1> <~>' is bound to insert the text `Function Key 1'. The following GNU Emacs style escape sequences are available when specifying key sequences: `\C-' control prefix `\M-' meta prefix `\e' an escape character `\\' backslash `\"' <">, a double quotation mark `\'' <'>, a single quote or apostrophe In addition to the GNU Emacs style escape sequences, a second set of backslash escapes is available: `\a' alert (bell) `\b' backspace `\d' delete `\f' form feed `\n' newline `\r' carriage return `\t' horizontal tab `\v' vertical tab `\NNN' the eight-bit character whose value is the octal value NNN (one to three digits) `\xHH' the eight-bit character whose value is the hexadecimal value HH (one or two hex digits) When entering the text of a macro, single or double quotes must be used to indicate a macro definition. Unquoted text is assumed to be a function name. In the macro body, the backslash escapes described above are expanded. Backslash will quote any other character in the macro text, including `"' and `''. For example, the following binding will make `C-x \' insert a single `\' into the line: "\C-x\\": "\\"  File: bashref.info, Node: Conditional Init Constructs, Next: Sample Init File, Prev: Readline Init File Syntax, Up: Readline Init File Conditional Init Constructs --------------------------- Readline implements a facility similar in spirit to the conditional compilation features of the C preprocessor which allows key bindings and variable settings to be performed as the result of tests. There are four parser directives used. `$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 extends to the end of the line; no characters are required to isolate it. `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 with the `set keymap' command, for instance, to set bindings in the `emacs-standard' and `emacs-ctlx' keymaps only if Readline is starting out in `emacs' mode. `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 `=' is tested against both the full name of the terminal and the portion of the terminal name before the first `-'. This allows `sun' to match both `sun' and `sun-cmd', for instance. `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 a particular value. This could be used to bind key sequences to functions useful for a specific program. For instance, the following command adds a key sequence that quotes the current or previous word in Bash: $if Bash # Quote the current or previous word "\C-xq": "\eb\"\ef\"" $endif `$endif' This command, as seen in the previous example, terminates an `$if' command. `$else' Commands in this branch of the `$if' directive are executed if the test fails. `$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': $include /etc/inputrc  File: bashref.info, Node: Sample Init File, Prev: Conditional Init Constructs, Up: Readline Init File Sample Init File ---------------- Here is an example of an INPUTRC file. This illustrates key binding, variable assignment, and conditional syntax. # This file controls the behaviour of line input editing for # programs that use the Gnu Readline library. Existing programs # include FTP, Bash, and Gdb. # # You can re-read the inputrc file with C-x C-r. # Lines beginning with '#' are comments. # # First, include any systemwide bindings and variable assignments from # /etc/Inputrc $include /etc/Inputrc # # Set various bindings for emacs mode. set editing-mode emacs $if mode=emacs Meta-Control-h: backward-kill-word Text after the function name is ignored # # Arrow keys in keypad mode # #"\M-OD": backward-char #"\M-OC": forward-char #"\M-OA": previous-history #"\M-OB": next-history # # Arrow keys in ANSI mode # "\M-[D": backward-char "\M-[C": forward-char "\M-[A": previous-history "\M-[B": next-history # # Arrow keys in 8 bit keypad mode # #"\M-\C-OD": backward-char #"\M-\C-OC": forward-char #"\M-\C-OA": previous-history #"\M-\C-OB": next-history # # Arrow keys in 8 bit ANSI mode # #"\M-\C-[D": backward-char #"\M-\C-[C": forward-char #"\M-\C-[A": previous-history #"\M-\C-[B": next-history C-q: quoted-insert $endif # An old-style binding. This happens to be the default. TAB: complete # Macros that are convenient for shell interaction $if Bash # edit the path "\C-xp": "PATH=${PATH}\e\C-e\C-a\ef\C-f" # prepare to type a quoted word -- insert open and close double quotes # and move to just after the open quote "\C-x\"": "\"\"\C-b" # insert a backslash (testing backslash escapes in sequences and macros) "\C-x\\": "\\" # Quote the current or previous word "\C-xq": "\eb\"\ef\"" # Add a binding to refresh the line, which is unbound "\C-xr": redraw-current-line # Edit variable on current line. "\M-\C-v": "\C-a\C-k$\C-y\M-\C-e\C-a\C-y=" $endif # use a visible bell if one is available set bell-style visible # don't strip characters to 7 bits when reading set input-meta on # allow iso-latin1 characters to be inserted rather than converted to # prefix-meta sequences set convert-meta off # display characters with the eighth bit set directly rather than # as meta-prefixed characters set output-meta on # if there are more than 150 possible completions for a word, ask the # user if he wants to see all of them set completion-query-items 150 # For FTP $if Ftp "\C-xg": "get \M-?" "\C-xt": "put \M-?" "\M-.": yank-last-arg $endif  File: bashref.info, Node: Bindable Readline Commands, Next: Readline vi Mode, Prev: Readline Init File, Up: Command Line Editing Bindable Readline Commands ========================== * Menu: * Commands For Moving:: Moving about the line. * Commands For History:: Getting at previous lines. * Commands For Text:: Commands for changing text. * Commands For Killing:: Commands for killing and yanking. * Numeric Arguments:: Specifying numeric arguments, repeat counts. * Commands For Completion:: Getting Readline to do the typing for you. * Keyboard Macros:: Saving and re-executing typed characters * Miscellaneous Commands:: Other miscellaneous 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'. (*Note Bash Builtins::.) Command names without an accompanying key sequence are unbound by default. In the following descriptions, "point" refers to the current cursor 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".  File: bashref.info, Node: Commands For Moving, Next: Commands For History, Up: Bindable Readline Commands Commands For Moving ------------------- `beginning-of-line (C-a)' Move to the start of the current line. `end-of-line (C-e)' Move to the end of the line. `forward-char (C-f)' Move forward a character. `backward-char (C-b)' Move back a character. `forward-word (M-f)' Move forward to the end of the next word. Words are composed of letters and digits. `backward-word (M-b)' Move back to the start of the current or previous word. Words are composed of letters and digits. `clear-screen (C-l)' Clear the screen and redraw the current line, leaving the current line at the top of the screen. `redraw-current-line ()' Refresh the current line. By default, this is unbound.  File: bashref.info, Node: Commands For History, Next: Commands For Text, Prev: Commands For Moving, Up: Bindable Readline Commands Commands For Manipulating The History ------------------------------------- `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 the `HISTCONTROL' and `HISTIGNORE' variables. If this line is a modified history line, then restore the history line to its original state. `previous-history (C-p)' Move `back' through the history list, fetching the previous command. `next-history (C-n)' Move `forward' through the history list, fetching the next command. `beginning-of-history (M-<)' Move to the first line in the history. `end-of-history (M->)' Move to the end of the input history, i.e., the line currently being entered. `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. `forward-search-history (C-s)' Search forward starting at the current line and moving `down' through the the history as necessary. This is an incremental search. `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. `non-incremental-forward-search-history (M-n)' Search forward starting at the current line and moving `down' through the the history as necessary using a non-incremental search for a string supplied by the user. `history-search-forward ()' Search forward through the history for the string of characters between the start of the current line and the point. This is a non-incremental search. By default, this command is unbound. `history-search-backward ()' Search backward through the history for the string of characters between the start of the current line and the point. This is a non-incremental search. By default, this command is unbound. `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, insert the Nth word from the previous command (the words in the previous command begin with word 0). A negative argument inserts the Nth word from the end of the previous command. `yank-last-arg (M-. or M-_)' Insert last argument to the previous command (the last word of the previous history entry). With an argument, behave exactly like `yank-nth-arg'. Successive calls to `yank-last-arg' move back through the history list, inserting the last argument of each line in turn.  File: bashref.info, Node: Commands For Text, Next: Commands For Killing, Prev: Commands For History, Up: Bindable Readline Commands Commands For Changing Text -------------------------- `delete-char (C-d)' Delete the character at point. If point is at the beginning of the line, there are no characters in the line, and the last character typed was not bound to `delete-char', then return EOF. `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 ()' 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)' 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, !, ...)' Insert yourself. `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 is at the end of the line, then this transposes the last two characters of the line. Negative arguments have no effect. `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)' Uppercase the current (or following) word. With a negative argument, uppercase the previous word, but do not move the cursor. `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 the current (or following) word. With a negative argument, capitalize the previous word, but do not move the cursor.  File: bashref.info, Node: Commands For Killing, Next: Numeric Arguments, Prev: Commands For Text, Up: Bindable Readline Commands Killing And Yanking ------------------- `kill-line (C-k)' Kill the text from point to the end of the line. `backward-kill-line (C-x Rubout)' Kill backward to the beginning of the line. `unix-line-discard (C-u)' Kill backward from the cursor to the beginning of the current 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 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-)' Kill the word behind point. Word boundaries are the same as `backward-word'. `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. `delete-horizontal-space ()' Delete all spaces and tabs around point. By default, this is unbound. `kill-region ()' Kill the text in the current region. By default, this command is unbound. `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 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 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 the top of the kill ring into the buffer at point. `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'.  File: bashref.info, Node: Numeric Arguments, Next: Commands For Completion, Prev: Commands For Killing, Up: Bindable Readline Commands Specifying Numeric Arguments ---------------------------- `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 ()' This is another way to specify an argument. If this command is followed by one or more digits, optionally with a leading minus sign, those digits define the argument. If the command is followed by digits, executing `universal-argument' again ends the numeric argument, but is otherwise ignored. As a special case, if this command is immediately followed by a character that is neither a digit or minus sign, the argument count for the next command is multiplied by four. The argument count is initially one, so executing this function the first time makes the argument count four, a second time makes the argument count sixteen, and so on. By default, this is not bound to a key.  File: bashref.info, Node: Commands For Completion, Next: Keyboard Macros, Prev: Numeric Arguments, Up: Bindable Readline Commands Letting Readline Type For You ----------------------------- `complete ()' 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 text begins with `$'), username (if the text begins with `~'), hostname (if the text begins with `@'), or command (including aliases and functions) in turn. If none of these produces a match, filename completion is attempted. `possible-completions (M-?)' List the possible completions of the text before point. `insert-completions (M-*)' Insert all completions of the text before point that would have been generated by `possible-completions'. `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 of possible completions, inserting each match in turn. At the end of the list of completions, the bell is rung (subject to the setting of `bell-style') and the original text is restored. An argument of N moves N positions forward in the list of matches; a negative argument may be used to move backward through the list. This command is intended to be bound to , but is unbound by default. `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 `possible-completions'. This command is unbound by default. `complete-filename (M-/)' Attempt filename completion on the text before point. `possible-filename-completions (C-x /)' List the possible completions of the text before point, treating it as a filename. `complete-username (M-~)' Attempt completion on the text before point, treating it as a username. `possible-username-completions (C-x ~)' List the possible completions of the text before point, treating it as a username. `complete-variable (M-$)' Attempt completion on the text before point, treating it as a shell variable. `possible-variable-completions (C-x $)' List the possible completions of the text before point, treating it as a shell variable. `complete-hostname (M-@)' Attempt completion on the text before point, treating it as a hostname. `possible-hostname-completions (C-x @)' List the possible completions of the text before point, treating it as a hostname. `complete-command (M-!)' Attempt completion on the text before point, treating it as a command name. Command completion attempts to match the text against aliases, reserved words, shell functions, shell builtins, and finally executable filenames, in that order. `possible-command-completions (C-x !)' List the possible completions of the text before point, treating it as a command name. `dynamic-complete-history (M-)' Attempt completion on the text before point, comparing the text against lines from the history list for possible completion matches. `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 (*note Brace Expansion::).  File: bashref.info, Node: Keyboard Macros, Next: Miscellaneous Commands, Prev: Commands For Completion, Up: Bindable Readline Commands Keyboard Macros --------------- `start-kbd-macro (C-x ()' Begin saving the characters typed into the current keyboard macro. `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)' Re-execute the last keyboard macro defined, by making the characters in the macro appear as if typed at the keyboard.  File: bashref.info, Node: Miscellaneous Commands, Prev: Keyboard Macros, Up: Bindable Readline Commands Some Miscellaneous Commands --------------------------- `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 the current editing command and ring the terminal's bell (subject to the setting of `bell-style'). `do-uppercase-version (M-a, M-b, M-X, ...)' If the metafied character X is lowercase, run the command that is bound to the corresponding uppercase character. `prefix-meta ()' Metafy the next character typed. This is for keyboards without a meta key. Typing ` f' is equivalent to typing `M-f'. `undo (C-_ or C-x C-u)' Incremental undo, separately remembered for each line. `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-&)' Perform tilde expansion on the current word. `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)' 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-])' 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-])' A character is read and point is moved to the previous occurrence of that character. A negative count searches for subsequent occurrences. `insert-comment (M-#)' The value of the `comment-begin' variable is inserted at the beginning of the current line, and the line is accepted as if a newline had been typed. The default value of `comment-begin' causes this command to make the current line a shell comment. `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 ()' 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 ()' 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-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. `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. `display-shell-version (C-x C-v)' Display version information about the current instance of Bash. `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 (*note Shell Expansions::). `history-expand-line (M-^)' Perform history expansion on the current line. `magic-space ()' Perform history expansion on the current line and insert a space (*note History Interaction::). `alias-expand-line ()' Perform alias expansion on the current line (*note Aliases::). `history-and-alias-expand-line ()' Perform history and alias expansion on the current line. `insert-last-argument (M-. or M-_)' A synonym for `yank-last-arg'. `operate-and-get-next (C-o)' Accept the current line for execution and fetch the next line relative to the current line from the history for editing. Any argument is ignored. `emacs-editing-mode (C-e)' When in `vi' editing mode, this causes a switch back to `emacs' editing mode, as if the command `set -o emacs' had been executed.  File: bashref.info, Node: Readline vi Mode, Next: Programmable Completion, Prev: Bindable Readline Commands, Up: Command Line Editing Readline vi Mode ================ While the Readline library does not have a full set of `vi' editing functions, it does contain enough to allow simple editing of the line. The Readline `vi' mode behaves as specified in the POSIX 1003.2 standard. In order to switch interactively between `emacs' and `vi' editing modes, use the `set -o emacs' and `set -o vi' commands (*note The Set Builtin::). The Readline default is `emacs' mode. When you enter a line in `vi' mode, you are already placed in `insertion' mode, as if you had typed an `i'. Pressing switches you into `command' mode, where you can edit the text of the line with the standard `vi' movement keys, move to previous history lines with `k' and subsequent lines with `j', and so forth.  File: bashref.info, Node: Programmable Completion, Next: Programmable Completion Builtins, Prev: Readline vi Mode, Up: Command Line Editing Programmable Completion ======================= When word completion is attempted for an argument to a command for which a completion specification (a COMPSPEC) has been defined using the `complete' builtin (*note Programmable Completion Builtins::), the programmable completion facilities are invoked. First, the command name is identified. If a compspec has been defined for that command, the compspec is used to generate the list of possible completions for the word. If the command word is a full pathname, a compspec for the full pathname is searched for first. If no compspec is found for the full pathname, an attempt is made to find a compspec for the portion following the final slash. 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 (*note Commands For Completion::) is performed. First, the actions specified by the compspec are used. Only matches which are prefixed by the word being completed are returned. When the `-f' or `-d' option is used for filename or directory name completion, the shell variable `FIGNORE' is used to filter the matches. *Note Bash Variables::, for a description of `FIGNORE'. Any completions specified by a filename expansion pattern to the `-G' option are generated next. The words generated by the pattern need not match the word being completed. The `GLOBIGNORE' shell variable is not used to filter the matches, but the `FIGNORE' shell variable is used. Next, the string specified as the argument to the `-W' option is considered. The string is first split using the characters in the `IFS' special variable as delimiters. Shell quoting is honored. Each word is then expanded using brace expansion, tilde expansion, parameter and variable expansion, command substitution, arithmetic expansion, and pathname expansion, as described above (*note Shell Expansions::). The results are split using the rules described above (*note Word Splitting::). The results of the expansion are prefix-matched against the word being completed, and the matching words become the possible completions. After these matches have been generated, any shell function or command specified with the `-F' and `-C' options is invoked. When the command or function is invoked, the `COMP_LINE' and `COMP_POINT' variables are assigned values as described above (*note Bash Variables::). If a shell function is being invoked, the `COMP_WORDS' and `COMP_CWORD' variables are also set. When the function or command is invoked, the first argument is the name of the command whose arguments are being completed, the second argument is the word being completed, and the third argument is the word preceding the word being completed on the current command line. No filtering of the generated completions against the word being completed is performed; the function or command has complete freedom in generating the matches. Any function specified with `-F' is invoked first. The function may use any of the shell facilities, including the `compgen' builtin described below (*note Programmable Completion Builtins::), to generate the matches. It must put the possible completions in the `COMPREPLY' array variable. Next, any command specified with the `-C' option is invoked in an environment equivalent to command substitution. It should print a list of completions, one per line, to the standard output. Backslash may be used to escape a newline, if necessary. After all of the possible completions are generated, any filter specified with the `-X' option is applied to the list. The filter is a pattern as used for pathname expansion; a `&' in the pattern is replaced with the text of the word being completed. A literal `&' may be escaped with a backslash; the backslash is removed before attempting a match. Any completion that matches the pattern will be removed from the list. A leading `!' negates the pattern; in this case any completion not matching the pattern will be removed. Finally, any prefix and suffix specified with the `-P' and `-S' options are added to each member of the completion list, and the result is returned to the Readline completion code as the list of possible completions. If the previously-applied actions do not generate any matches, and the `-o dirnames' option was supplied to `complete' when the compspec was defined, directory name completion is attempted. By default, if a compspec is found, whatever it generates is returned to the completion code as the full set of possible completions. The default Bash completions are not attempted, and the Readline default of filename completion is disabled. If the `-o default' option was supplied to `complete' when the compspec was defined, Readline's default completion will be performed if the compspec generates no matches.  File: bashref.info, Node: Programmable Completion Builtins, Prev: Programmable Completion, Up: Command Line Editing Programmable Completion Builtins ================================ Two builtin commands are available to manipulate the programmable completion facilities. `compgen' `compgen [OPTION] [WORD]' Generate possible completion matches for WORD according to the OPTIONs, which may be any option accepted by the `complete' builtin with the exception of `-p' and `-r', and write the matches to the standard output. When using the `-F' or `-C' options, the various shell variables set by the programmable completion facilities, while available, will not have useful values. The matches will be generated in the same way as if the programmable completion code had generated them directly from a completion specification with the same flags. If WORD is specified, only those completions matching WORD will be displayed. The return value is true unless an invalid option is supplied, or no matches were generated. `complete' `complete [-abcdefgjkvu] [-o COMP-OPTION] [-A ACTION] [-G GLOBPAT] [-W WORDLIST] [-P PREFIX] [-S SUFFIX] [-X FILTERPAT] [-F FUNCTION] [-C COMMAND] NAME [NAME ...]' `complete -pr [NAME ...]' Specify how arguments to each NAME should be completed. If the `-p' option is supplied, or if no options are supplied, existing completion specifications are printed in a way that allows them to be reused as input. The `-r' option removes a completion specification for each NAME, or, if no NAMEs are supplied, all completion specifications. The process of applying these completion specifications when word completion is attempted is described above (*note Programmable Completion::). Other options, if specified, have the following meanings. The arguments to the `-G', `-W', and `-X' options (and, if necessary, the `-P' and `-S' options) should be quoted to protect them from expansion before the `complete' builtin is invoked. `-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: `default' Use readline's default completion if the compspec generates no matches. `dirnames' Perform directory name completion if the compspec generates no matches. `filenames' Tell Readline that the compspec generates filenames, so it can perform any filename\-specific processing (like adding a slash to directory names or suppressing trailing spaces). This option is intended to be used with shell functions specified with `-F'. `-A ACTION' The ACTION may be one of the following to generate a list of possible completions: `alias' Alias names. May also be specified as `-a'. `arrayvar' Array variable names. `binding' Readline key binding names (*note Bindable Readline Commands::). `builtin' Names of shell builtin commands. May also be specified as `-b'. `command' Command names. May also be specified as `-c'. `directory' Directory names. May also be specified as `-d'. `disabled' Names of disabled shell builtins. `enabled' Names of enabled shell builtins. `export' Names of exported shell variables. May also be specified as `-e'. `file' File names. May also be specified as `-f'. `function' Names of shell functions. `group' Group names. May also be specified as `-g'. `helptopic' Help topics as accepted by the `help' builtin (*note Bash Builtins::). `hostname' Hostnames, as taken from the file specified by the `HOSTFILE' shell variable (*note Bash Variables::). `job' Job names, if job control is active. May also be specified as `-j'. `keyword' Shell reserved words. May also be specified as `-k'. `running' Names of running jobs, if job control is active. `setopt' Valid arguments for the `-o' option to the `set' builtin (*note The Set Builtin::). `shopt' Shell option names as accepted by the `shopt' builtin (*note Bash Builtins::). `signal' Signal names. `stopped' Names of stopped jobs, if job control is active. `user' User names. May also be specified as `-u'. `variable' Names of all shell variables. May also be specified as `-v'. `-G GLOBPAT' The filename expansion pattern GLOBPAT is expanded to generate the possible completions. `-W WORDLIST' The WORDLIST is split using the characters in the `IFS' special variable as delimiters, and each resultant word is expanded. The possible completions are the members of the resultant list which match the word being completed. `-C COMMAND' COMMAND is executed in a subshell environment, and its output is used as the possible completions. `-F FUNCTION' The shell function FUNCTION is executed in the current shell environment. When it finishes, the possible completions are retrieved from the value of the `COMPREPLY' array variable. `-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 FILTERPAT is removed from the list. A leading `!' in FILTERPAT negates the pattern; in this case, any completion not matching FILTERPAT is removed. `-P PREFIX' PREFIX is added at the beginning of each possible completion after all other options have been applied. `-S SUFFIX' SUFFIX is appended to each possible completion after all other options have been applied. The return value is true unless an invalid option is supplied, an option other than `-p' or `-r' is supplied without a NAME argument, an attempt is made to remove a completion specification for a NAME for which no specification exists, or an error occurs adding a completion specification.  File: bashref.info, Node: Using History Interactively, Next: Command Line Editing, Prev: Job Control, Up: Top Using History Interactively *************************** This chapter describes how to use the GNU History Library interactively, from a user's standpoint. 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. * Menu: * Bash History Facilities:: How Bash lets you manipulate your command history. * Bash History Builtins:: The Bash builtin commands that manipulate the command history. * History Interaction:: What it feels like using History as a user.  File: bashref.info, Node: Bash History Facilities, Next: Bash History Builtins, Up: Using History Interactively Bash History Facilities ======================= When the `-o history' option to the `set' builtin is enabled (*note The Set Builtin::), the shell provides access to the "command history", the list of commands previously typed. The value of the `HISTSIZE' shell variable is used as the number of commands to save in a history list. The text of the last `$HISTSIZE' commands (default 500) is saved. The shell stores each command in the history list prior to parameter and variable expansion but after history expansion is performed, subject to the values of the shell variables `HISTIGNORE' and `HISTCONTROL'. When the shell starts up, the history is initialized from the file named by the `HISTFILE' variable (default `~/.bash_history'). The file named by the value of `HISTFILE' is truncated, if necessary, to contain no more than the number of lines specified by the value of the `HISTFILESIZE' variable. When an interactive shell exits, the last `$HISTSIZE' lines are copied from the history list to the file named by `$HISTFILE'. If the `histappend' shell option is set (*note Bash Builtins::), the lines are appended to the history file, otherwise the history file is overwritten. If `HISTFILE' is unset, or if the history file is unwritable, the history is not saved. After saving the history, the history file is truncated to contain no more than `$HISTFILESIZE' lines. If `HISTFILESIZE' is not set, no truncation is performed. The builtin command `fc' may be used to list or edit and re-execute a portion of the history list. 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 (*note Commands For History::). The shell allows control over which commands are saved on the history list. The `HISTCONTROL' and `HISTIGNORE' variables may be set to cause the shell to save only a subset of the commands entered. The `cmdhist' shell option, if enabled, causes the shell to attempt to save each line of a multi-line command in the same history entry, adding semicolons where necessary to preserve syntactic correctness. The `lithist' shell option causes the shell to save the command with embedded newlines instead of semicolons. The `shopt' builtin is used to set these options. *Note Bash Builtins::, for a description of `shopt'.  File: bashref.info, Node: Bash History Builtins, Next: History Interaction, Prev: Bash History Facilities, Up: Using History Interactively Bash History Builtins ===================== Bash provides two builtin commands which manipulate the history list and history file. `fc' `fc [-e ENAME] [-nlr] [FIRST] [LAST]' `fc -s [PAT=REP] [COMMAND]' Fix Command. In the first form, a range of commands from FIRST to LAST is selected from the history list. Both FIRST and LAST may be specified as a string (to locate the most recent command beginning with that string) or as a number (an index into the history list, where a negative number is used as an offset from the current command number). If LAST is not specified it is set to FIRST. If FIRST is not specified it is set to the previous command for editing and -16 for listing. If the `-l' flag is given, the commands are listed on standard output. The `-n' flag suppresses the command numbers when listing. The `-r' flag reverses the order of the listing. Otherwise, the editor given by ENAME is invoked on a file containing those commands. If ENAME is not given, the value of the following variable expansion is used: `${FCEDIT:-${EDITOR:-vi}}'. This says to use the value of the `FCEDIT' variable if set, or the value of the `EDITOR' variable if that is set, or `vi' if neither is set. When editing is complete, the edited commands are echoed and executed. In the second form, COMMAND is re-executed after each instance of PAT in the selected command is replaced by REP. A useful alias to use with the `fc' command is `r='fc -s'', so that typing `r cc' runs the last command beginning with `cc' and typing `r' re-executes the last command (*note Aliases::). `history' history [N] history -c history -d OFFSET history [-anrw] [FILENAME] history -ps ARG With no options, display the history list with line numbers. Lines prefixed with a `*' have been modified. An argument of N lists only the last N lines. Options, if supplied, have the following meanings: `-c' Clear the history list. This may be combined with the other options to replace the history list completely. `-d OFFSET' Delete the history entry at position OFFSET. OFFSET should be specified as it appears when the history is displayed. `-a' Append the new history lines (history lines entered since the beginning of the current Bash session) to the history file. `-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' Read the current history file and append its contents to the history list. `-w' Write out the current history to the history file. `-p' Perform history substitution on the ARGs and display the result on the standard output, without storing the results in the history list. `-s' The ARGs are added to the end of the history list as a single entry. When any of the `-w', `-r', `-a', or `-n' options is used, if FILENAME is given, then it is used as the history file. If not, then the value of the `HISTFILE' variable is used.  File: bashref.info, Node: History Interaction, Prev: Bash History Builtins, Up: Using History Interactively History Expansion ================= The History library provides a history expansion feature that is similar to the history expansion provided by `csh'. This section describes the syntax used to manipulate the history information. History expansions introduce words from the history list into the input stream, making it easy to repeat commands, insert the arguments to a previous command into the current input line, or fix errors in previous commands quickly. History expansion takes place in two parts. The first is to determine which line from the history list should be used during substitution. The second is to select portions of that line for inclusion into the current one. The line selected from the history is called the "event", and the portions of that line that are acted upon are called "words". Various "modifiers" are available to manipulate the selected words. The line is broken into words in the same fashion that Bash does, so that several words surrounded by quotes are considered one word. History expansions are introduced by the appearance of the history expansion character, which is `!' by default. Only `\' and `'' may be used to escape the history expansion character. Several shell options settable with the `shopt' builtin (*note Bash Builtins::) may be used to tailor the behavior of history expansion. If the `histverify' shell option is enabled, and Readline is being used, history substitutions are not immediately passed to the shell parser. Instead, the expanded line is reloaded into the Readline editing buffer for further modification. If Readline is being used, and the `histreedit' shell option is enabled, a failed history expansion will be reloaded into the Readline editing buffer for correction. The `-p' option to the `history' builtin command may be used to see what a history expansion will do before using it. The `-s' option to the `history' builtin may be used to add commands to the end of the history list without actually executing them, so that they are available for subsequent recall. This is most useful in conjunction with Readline. The shell allows control of the various characters used by the history expansion mechanism with the `histchars' variable. * Menu: * Event Designators:: How to specify which history line to use. * Word Designators:: Specifying which words are of interest. * Modifiers:: Modifying the results of substitution.  File: bashref.info, Node: Event Designators, Next: Word Designators, Up: History Interaction Event Designators ----------------- An event designator is a reference to a command line entry in the history list. `!' Start a history substitution, except when followed by a space, tab, the end of the line, `=' or `('. `!N' Refer to command line N. `!-N' Refer to the command N lines back. `!!' Refer to the previous command. This is a synonym for `!-1'. `!STRING' Refer to the most recent command starting with STRING. `!?STRING[?]' Refer to the most recent command containing STRING. The trailing `?' may be omitted if the STRING is followed immediately by a newline. `^STRING1^STRING2^' Quick Substitution. Repeat the last command, replacing STRING1 with STRING2. Equivalent to `!!:s/STRING1/STRING2/'. `!#' The entire command line typed so far.  File: bashref.info, Node: Word Designators, Next: Modifiers, Prev: Event Designators, Up: History Interaction Word Designators ---------------- Word designators are used to select desired words from the event. A `:' separates the event specification from the word designator. It may be omitted if the word designator begins with a `^', `$', `*', `-', or `%'. Words are numbered from the beginning of the line, with the first word being denoted by 0 (zero). Words are inserted into the current line separated by single spaces. 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' designates the second argument of the most recent command starting with the letters `fi'. Here are the word designators: `0 (zero)' The `0'th word. For many applications, this is the command word. `N' The Nth word. `^' The first argument; that is, word 1. `$' The last argument. `%' The word matched by the most recent `?STRING?' search. `X-Y' A range of words; `-Y' abbreviates `0-Y'. `*' All of the words, except the `0'th. 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*' Abbreviates `X-$' `X-' Abbreviates `X-$' like `X*', but omits the last word. If a word designator is supplied without an event specification, the previous command is used as the event.  File: bashref.info, Node: Modifiers, Prev: Word Designators, Up: History Interaction Modifiers --------- After the optional word designator, you can add a sequence of one or more of the following modifiers, each preceded by a `:'. `h' Remove a trailing pathname component, leaving only the head. `t' Remove all leading pathname components, leaving the tail. `r' Remove a trailing suffix of the form `.SUFFIX', leaving the basename. `e' Remove all but the trailing suffix. `p' Print the new command but do not execute it. `q' Quote the substituted words, escaping further substitutions. `x' Quote the substituted words as with `q', but break into words at spaces, tabs, and newlines. `s/OLD/NEW/' Substitute NEW for the first occurrence of OLD in the event line. Any delimiter may be used in place of `/'. The delimiter may be quoted in OLD and NEW with a single backslash. If `&' appears in NEW, it is replaced by OLD. A single backslash will quote the `&'. The final delimiter is optional if it is the last character on the input line. `&' Repeat the previous substitution. `g' Cause changes to be applied over the entire event line. Used in conjunction with `s', as in `gs/OLD/NEW/', or with `&'.  File: bashref.info, Node: Installing Bash, Next: Reporting Bugs, Prev: Command Line Editing, Up: Top Installing Bash *************** This chapter provides basic instructions for installing Bash on the various supported platforms. The distribution supports the GNU operating systems, nearly every version of Unix, and several non-Unix systems such as BeOS and Interix. Other independent ports exist for MS-DOS, OS/2, Windows 95/98, and Windows NT. * Menu: * Basic Installation:: Installation instructions. * Compilers and Options:: How to set special options for various systems. * Compiling For Multiple Architectures:: How to compile Bash for more than one kind of system from the same source tree. * Installation Names:: How to set the various paths used by the installation. * Specifying the System Type:: How to configure Bash for a particular system. * Sharing Defaults:: How to share default configuration values among GNU programs. * Operation Controls:: Options recognized by the configuration program. * Optional Features:: How to enable and disable optional features when building Bash.  File: bashref.info, Node: Basic Installation, Next: Compilers and Options, Up: Installing Bash Basic Installation ================== These are installation instructions for Bash. The simplest way to compile Bash is: 1. `cd' to the directory containing the source code and type `./configure' to configure Bash for your system. If you're using `csh' on an old version of System V, you might need to type `sh ./configure' instead to prevent `csh' from trying to execute `configure' itself. Running `configure' takes some time. While running, it prints messages telling which features it is checking for. 2. Type `make' to compile Bash and build the `bashbug' bug reporting script. 3. Optionally, type `make tests' to run the Bash test suite. 4. Type `make install' to install `bash' and `bashbug'. This will also install the manual pages and Info file. The `configure' shell script attempts to guess correct values for various system-dependent variables used during compilation. It uses those values to create a `Makefile' in each directory of the package (the top directory, the `builtins', `doc', and `support' directories, each directory under `lib', and several others). It also creates a `config.h' file containing system-dependent definitions. Finally, it creates a shell script named `config.status' that you can run in the future to recreate the current configuration, a file `config.cache' that saves the results of its tests to speed up reconfiguring, and a file `config.log' containing compiler output (useful mainly for debugging `configure'). If at some point `config.cache' contains results you don't want to keep, you may remove or edit it. To find out more about the options and arguments that the `configure' script understands, type bash-2.04$ ./configure --help at the Bash prompt in your Bash source directory. If you need to do unusual things to compile Bash, please try to figure out how `configure' could check whether or not to do them, and mail diffs or instructions to so they can be considered for the next release. The file `configure.in' is used to create `configure' by a program called Autoconf. You only need `configure.in' if you want to change it or regenerate `configure' using a newer version of Autoconf. If you do this, make sure you are using Autoconf version 2.50 or newer. You can remove the program binaries and object files from the source code directory by typing `make clean'. To also remove the files that `configure' created (so you can compile Bash for a different kind of computer), type `make distclean'.  File: bashref.info, Node: Compilers and Options, Next: Compiling For Multiple Architectures, Prev: Basic Installation, Up: Installing Bash Compilers and Options ===================== Some systems require unusual options for compilation or linking that the `configure' script does not know about. You can give `configure' initial values for variables by setting them in the environment. Using a Bourne-compatible shell, you can do that on the command line like this: CC=c89 CFLAGS=-O2 LIBS=-lposix ./configure On systems that have the `env' program, you can do it like this: env CPPFLAGS=-I/usr/local/include LDFLAGS=-s ./configure The configuration process uses GCC to build Bash if it is available.  File: bashref.info, Node: Compiling For Multiple Architectures, Next: Installation Names, Prev: Compilers and Options, Up: Installing Bash Compiling For Multiple Architectures ==================================== You can compile Bash for more than one kind of computer at the same time, by placing the object files for each architecture in their own directory. To do this, you must use a version of `make' that supports the `VPATH' variable, such as GNU `make'. `cd' to the directory where you want the object files and executables to go and run the `configure' script from the source directory. You may need to supply the `--srcdir=PATH' argument to tell `configure' where the source files are. `configure' automatically checks for the source code in the directory that `configure' is in and in `..'. If you have to use a `make' that does not supports the `VPATH' variable, you can compile Bash for one architecture at a time in the source code directory. After you have installed Bash for one architecture, use `make distclean' before reconfiguring for another architecture. Alternatively, if your system supports symbolic links, you can use the `support/mkclone' script to create a build tree which has symbolic links back to each file in the source directory. Here's an example that creates a build directory in the current directory from a source directory `/usr/gnu/src/bash-2.0': bash /usr/gnu/src/bash-2.0/support/mkclone -s /usr/gnu/src/bash-2.0 . The `mkclone' script requires Bash, so you must have already built Bash for at least one architecture before you can create build directories for other architectures.  File: bashref.info, Node: Installation Names, Next: Specifying the System Type, Prev: Compiling For Multiple Architectures, Up: Installing Bash Installation Names ================== By default, `make install' will install into `/usr/local/bin', `/usr/local/man', etc. You can specify an installation prefix other than `/usr/local' by giving `configure' the option `--prefix=PATH', or by specifying a value for the `DESTDIR' `make' variable when running `make install'. You can specify separate installation prefixes for architecture-specific files and architecture-independent files. If you give `configure' the option `--exec-prefix=PATH', `make install' will use PATH as the prefix for installing programs and libraries. Documentation and other data files will still use the regular prefix.  File: bashref.info, Node: Specifying the System Type, Next: Sharing Defaults, Prev: Installation Names, Up: Installing Bash Specifying the System Type ========================== There may be some features `configure' can not figure out automatically, but need to determine by the type of host Bash will run on. Usually `configure' can figure that out, but if it prints a message saying it can not guess the host type, give it the `--host=TYPE' option. `TYPE' can either be a short name for the system type, such as `sun4', or a canonical name with three fields: `CPU-COMPANY-SYSTEM' (e.g., `i386-unknown-freebsd4.2'). See the file `support/config.sub' for the possible values of each field.  File: bashref.info, Node: Sharing Defaults, Next: Operation Controls, Prev: Specifying the System Type, Up: Installing Bash Sharing Defaults ================ If you want to set default values for `configure' scripts to share, you can create a site shell script called `config.site' that gives default values for variables like `CC', `cache_file', and `prefix'. `configure' looks for `PREFIX/share/config.site' if it exists, then `PREFIX/etc/config.site' if it exists. Or, you can set the `CONFIG_SITE' environment variable to the location of the site script. A warning: the Bash `configure' looks for a site script, but not all `configure' scripts do.  File: bashref.info, Node: Operation Controls, Next: Optional Features, Prev: Sharing Defaults, Up: Installing Bash Operation Controls ================== `configure' recognizes the following options to control how it operates. `--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' Print a summary of the options to `configure', and exit. `--quiet' `--silent' `-q' Do not print messages saying which checks are being made. `--srcdir=DIR' Look for the Bash source code in directory DIR. Usually `configure' can determine that directory automatically. `--version' Print the version of Autoconf used to generate the `configure' script, and exit. `configure' also accepts some other, not widely used, boilerplate options. `configure --help' prints the complete list.  File: bashref.info, Node: Optional Features, Prev: Operation Controls, Up: Installing Bash Optional Features ================= The Bash `configure' has a number of `--enable-FEATURE' options, where FEATURE indicates an optional part of Bash. There are also several `--with-PACKAGE' options, where PACKAGE is something like `bash-malloc' or `purify'. To turn off the default use of a package, use `--without-PACKAGE'. To configure Bash without a feature that is enabled by default, use `--disable-FEATURE'. Here is a complete list of the `--enable-' and `--with-' options that the Bash `configure' recognizes. `--with-afs' Define if you are using the Andrew File System from Transarc. `--with-bash-malloc' Use the Bash version of `malloc' in `lib/malloc/malloc.c'. This is not the same `malloc' that appears in GNU libc, but an older version derived from the 4.2 BSD `malloc'. This `malloc' is very fast, but wastes some space on each allocation. This option is enabled by default. The `NOTES' file contains a list of systems for which this should be turned off, and `configure' disables this option automatically for a number of systems. `--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' A synonym for `--with-bash-malloc'. `--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 4.2 and later versions. If PREFIX is `yes' or not supplied, `configure' uses the values of the make variables `includedir' and `libdir', which are subdirectories of `prefix' by default, to find the installed version of Readline if it is not in the standard system include and library directories. If PREFIX is `no', Bash links with the version in `lib/readline'. If PREFIX is set to any other value, `configure' treats it as a directory pathname and looks for the installed version of Readline in subdirectories of that directory (include files in PREFIX/`include' and the library in PREFIX/`lib'). `--with-purify' Define this to use the Purify memory allocation checker from Rational Software. `--enable-minimal-config' This produces a shell with minimal features, close to the historical Bourne shell. There are several `--enable-' options that alter how Bash is compiled and linked, rather than changing run-time features. `--enable-largefile' Enable support for large files (http://www.sas.com/standards/large_file/x_open.20Mar96.html) if the operating system requires special compiler options to build programs which can access large files. `--enable-profiling' This builds a Bash binary that produces profiling information to be processed by `gprof' each time it is executed. `--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. The `minimal-config' option can be used to disable all of the following options, but it is processed first, so individual options may be enabled using `enable-FEATURE'. All of the following options except for `disabled-builtins' and `xpg-echo-default' are enabled by default, unless the operating system does not provide the necessary support. `--enable-alias' Allow alias expansion and include the `alias' and `unalias' builtins (*note Aliases::). `--enable-arith-for-command' Include support for the alternate form of the `for' command that behaves like the C language `for' statement (*note Looping Constructs::). `--enable-array-variables' Include support for one-dimensional array shell variables (*note Arrays::). `--enable-bang-history' Include support for `csh'-like history substitution (*note History Interaction::). `--enable-brace-expansion' Include `csh'-like brace expansion ( `b{a,b}c' ==> `bac bbc' ). See *Note Brace Expansion::, for a complete description. `--enable-command-timing' Include support for recognizing `time' as a reserved word and for displaying timing statistics for the pipeline following `time' (*note Pipelines::). This allows pipelines as well as shell builtins and functions to be timed. `--enable-cond-command' Include support for the `[[' conditional command (*note Conditional Constructs::). `--enable-directory-stack' Include support for a `csh'-like directory stack and the `pushd', `popd', and `dirs' builtins (*note The Directory Stack::). `--enable-disabled-builtins' Allow builtin commands to be invoked via `builtin xxx' even after `xxx' has been disabled using `enable -n xxx'. See *Note Bash Builtins::, for details of the `builtin' and `enable' builtin commands. `--enable-dparen-arithmetic' Include support for the `((...))' command (*note Conditional Constructs::). `--enable-extended-glob' Include support for the extended pattern matching features described above under *Note Pattern Matching::. `--enable-help-builtin' Include the `help' builtin, which displays help on shell builtins and variables (*note Bash Builtins::). `--enable-history' Include command history and the `fc' and `history' builtin commands (*note Bash History Facilities::). `--enable-job-control' This enables the job control features (*note Job Control::), if the operating system supports them. `--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 (*note Redirections::). `--enable-process-substitution' This enables process substitution (*note Process Substitution::) if the operating system provides the necessary support. `--enable-prompt-string-decoding' Turn on the interpretation of a number of backslash-escaped characters in the `$PS1', `$PS2', `$PS3', and `$PS4' prompt strings. See *Note Printing a Prompt::, for a complete list of prompt string escape sequences. `--enable-progcomp' Enable the programmable completion facilities (*note Programmable Completion::). If Readline is not enabled, this option has no effect. `--enable-readline' Include support for command-line editing and history with the Bash version of the Readline library (*note Command Line Editing::). `--enable-restricted' Include support for a "restricted shell". If this is enabled, Bash, when called as `rbash', enters a restricted mode. See *Note The Restricted Shell::, for a description of restricted mode. `--enable-select' Include the `select' builtin, which allows the generation of simple menus (*note Conditional Constructs::). `--enable-usg-echo-default' A synonym for `--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 2. *Note Bash Builtins::, for a description of the escape sequences that `echo' recognizes. The file `config-top.h' contains C Preprocessor `#define' statements for options which are not settable from `configure'. Some of these are not meant to be changed; beware of the consequences if you do. Read the comments associated with each definition for more information about its effect.  File: bashref.info, Node: Reporting Bugs, Next: Major Differences From The Bourne Shell, Prev: Installing Bash, Up: Top Reporting Bugs ************** Please report all bugs you find in Bash. But first, you should make sure that it really is a bug, and that it appears in the latest version of Bash that you have. Once you have determined that a bug actually exists, use the `bashbug' command to submit a bug report. If you have a fix, you are encouraged to mail that as well! Suggestions and `philosophical' bug reports may be mailed to or posted to the Usenet newsgroup `gnu.bash.bug'. All bug reports should include: * The version number of Bash. * The hardware and operating system. * The compiler used to compile Bash. * A description of the bug behaviour. * A short script or `recipe' which exercises the bug and may be used to reproduce it. `bashbug' inserts the first three items automatically into the template it provides for filing a bug report. Please send all reports concerning this manual to .  File: bashref.info, Node: Major Differences From The Bourne Shell, Next: Builtin Index, Prev: Reporting Bugs, Up: Top Major Differences From The Bourne Shell *************************************** Bash implements essentially the same grammar, parameter and variable expansion, redirection, and quoting as the Bourne Shell. Bash uses the POSIX 1003.2 standard as the specification of how these features are to be implemented. There are some differences between the traditional Bourne shell and Bash; this section quickly details the differences of significance. A number of these differences are explained in greater depth in previous sections. This section uses the version of `sh' included in SVR4.2 as the baseline reference. * Bash is POSIX-conformant, even where the POSIX specification differs from traditional `sh' behavior (*note Bash POSIX Mode::). * Bash has multi-character invocation options (*note Invoking Bash::). * Bash has command-line editing (*note Command Line Editing::) and the `bind' builtin. * Bash provides a programmable word completion mechanism (*note Programmable Completion::), and two builtin commands, `complete' and `compgen', to manipulate it. * Bash has command history (*note Bash History Facilities::) and the `history' and `fc' builtins to manipulate it. * Bash implements `csh'-like history expansion (*note History Interaction::). * Bash has one-dimensional array variables (*note Arrays::), and the appropriate variable expansions and assignment syntax to use them. Several of the Bash builtins take options to act on arrays. Bash provides a number of built-in array variables. * The `$'...'' quoting syntax, which expands ANSI-C backslash-escaped characters in the text between the single quotes, is supported (*note ANSI-C Quoting::). * Bash supports the `$"..."' quoting syntax to do 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 (*note Locale Translation::). * Bash implements the `!' keyword to negate the return value of a pipeline (*note Pipelines::). Very useful when an `if' statement needs to act only if a test fails. * Bash has the `time' reserved word and command timing (*note Pipelines::). The display of the timing statistics may be controlled with the `TIMEFORMAT' variable. * Bash implements the `for (( EXPR1 ; EXPR2 ; EXPR3 ))' arithmetic for command, similar to the C language (*note Looping Constructs::). * Bash includes the `select' compound command, which allows the generation of simple menus (*note Conditional Constructs::). * Bash includes the `[[' compound command, which makes conditional testing part of the shell grammar (*note Conditional Constructs::). * Bash includes brace expansion (*note Brace Expansion::) and tilde expansion (*note Tilde Expansion::). * Bash implements command aliases and the `alias' and `unalias' builtins (*note Aliases::). * Bash provides shell arithmetic, the `((' compound command (*note Conditional Constructs::), and arithmetic expansion (*note Shell Arithmetic::). * Variables present in the shell's initial environment are automatically exported to child processes. The Bourne shell does not normally do this unless the variables are explicitly marked using the `export' command. * Bash includes the POSIX pattern removal `%', `#', `%%' and `##' expansions to remove leading or trailing substrings from variable values (*note Shell Parameter Expansion::). * The expansion `${#xx}', which returns the length of `${xx}', is supported (*note Shell Parameter Expansion::). * The expansion `${var:'OFFSET`[:'LENGTH`]}', which expands to the substring of `var''s value of length LENGTH, beginning at OFFSET, is present (*note Shell Parameter Expansion::). * The expansion `${var/[/]'PATTERN`[/'REPLACEMENT`]}', which matches PATTERN and replaces it with REPLACEMENT in the value of `var', is available (*note Shell Parameter Expansion::). * The expansion `${!PREFIX}*' expansion, which expands to the names of all shell variables whose names begin with PREFIX, is available (*note Shell Parameter Expansion::). * Bash has INDIRECT variable expansion using `${!word}' (*note Shell Parameter Expansion::). * Bash can expand positional parameters beyond `$9' using `${NUM}'. * The POSIX `$()' form of command substitution is implemented (*note Command Substitution::), and preferred to the Bourne shell's ```' (which is also implemented for backwards compatibility). * Bash has process substitution (*note Process Substitution::). * Bash automatically assigns variables that provide information about the current user (`UID', `EUID', and `GROUPS'), the current host (`HOSTTYPE', `OSTYPE', `MACHTYPE', and `HOSTNAME'), and the instance of Bash that is running (`BASH', `BASH_VERSION', and `BASH_VERSINFO'). *Note Bash Variables::, for details. * The `IFS' variable is used to split only the results of expansion, not all words (*note Word Splitting::). This closes a longstanding shell security hole. * Bash implements the full set of POSIX 1003.2 filename expansion operators, including CHARACTER CLASSES, EQUIVALENCE CLASSES, and COLLATING SYMBOLS (*note Filename Expansion::). * Bash implements extended pattern matching features when the `extglob' shell option is enabled (*note Pattern Matching::). * It is possible to have a variable and a function with the same name; `sh' does not separate the two name spaces. * Bash functions are permitted to have local variables using the `local' builtin, and thus useful recursive functions may be written (*note Bash Builtins::). * Variable assignments preceding commands affect only that command, even builtins and functions (*note Environment::). In `sh', all variable assignments preceding commands are global unless the command is executed from the file system. * Bash performs filename expansion on filenames specified as operands to input and output redirection operators (*note Redirections::). * Bash contains the `<>' redirection operator, allowing a file to be opened for both reading and writing, and the `&>' redirection operator, for directing standard output and standard error to the same file (*note Redirections::). * Bash treats a number of filenames specially when they are used in redirection operators (*note Redirections::). * Bash can open network connections to arbitrary machines and services with the redirection operators (*note Redirections::). * The `noclobber' option is available to avoid overwriting existing files with output redirection (*note The Set Builtin::). The `>|' redirection operator may be used to override `noclobber'. * The Bash `cd' and `pwd' builtins (*note Bourne Shell Builtins::) each take `-L' and `-P' options to switch between logical and 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 (*note Bash Builtins::). * The `command' builtin allows selective disabling of functions when command lookup is performed (*note Bash Builtins::). * Individual builtins may be enabled or disabled using the `enable' builtin (*note Bash Builtins::). * The Bash `exec' builtin takes additional options that allow users to control the contents of the environment passed to the executed command, and what the zeroth argument to the command is to be (*note Bourne Shell Builtins::). * Shell functions may be exported to children via the environment using `export -f' (*note Shell Functions::). * The Bash `export', `readonly', and `declare' builtins can take a `-f' option to act on shell functions, a `-p' option to display variables with various attributes set in a format that can be used as shell input, a `-n' option to remove various variable attributes, and `name=value' arguments to set variable attributes and values simultaneously. * The Bash `hash' builtin allows a name to be associated with an arbitrary filename, even when that filename cannot be found by searching the `$PATH', using `hash -p' (*note Bourne Shell Builtins::). * Bash includes a `help' builtin for quick reference to shell facilities (*note Bash Builtins::). * The `printf' builtin is available to display formatted output (*note Bash Builtins::). * The Bash `read' builtin (*note Bash Builtins::) 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. The Bash `read' builtin also accepts a prompt string with the `-p' option and will use Readline to obtain the line when given the `-e' option. The `read' builtin also has additional options to control input: the `-s' option will turn off echoing of input characters as they are read, the `-t' option will allow `read' to time out if input does not arrive within a specified number of seconds, the `-n' option will allow reading only a specified number of characters rather than a full line, and the `-d' option will read until a particular character rather than newline. * The `return' builtin may be used to abort execution of scripts executed with the `.' or `source' builtins (*note Bourne Shell Builtins::). * Bash includes the `shopt' builtin, for finer control of shell optional capabilities (*note Bash Builtins::), and allows these options to be set and unset at shell invocation (*note Invoking Bash::). * Bash has much more optional behavior controllable with the `set' builtin (*note The Set Builtin::). * The `test' builtin (*note Bourne Shell Builtins::) is slightly different, as it implements the POSIX algorithm, which specifies the behavior based on the number of arguments. * The `trap' builtin (*note Bourne Shell Builtins::) allows a `DEBUG' pseudo-signal specification, similar to `EXIT'. Commands specified with a `DEBUG' trap are executed after every simple command. The `DEBUG' trap is not inherited by shell functions. The `trap' builtin (*note Bourne Shell Builtins::) allows an `ERR' pseudo-signal specification, similar to `EXIT' and `DEBUG'. Commands specified with an `ERR' trap are executed after a simple command fails, with a few exceptions. The `ERR' trap is not inherited by shell functions. * The Bash `type' builtin is more extensive and gives more information about the names it finds (*note Bash Builtins::). * The Bash `umask' builtin permits a `-p' option to cause the output to be displayed in the form of a `umask' command that may be reused as input (*note Bourne Shell Builtins::). * Bash implements a `csh'-like directory stack, and provides the `pushd', `popd', and `dirs' builtins to manipulate it (*note The Directory Stack::). Bash also makes the directory stack visible as the value of the `DIRSTACK' shell variable. * Bash interprets special backslash-escaped characters in the prompt strings when interactive (*note Printing a Prompt::). * The Bash restricted mode is more useful (*note The Restricted Shell::); the SVR4.2 shell restricted mode is too limited. * The `disown' builtin can remove a job from the internal shell job table (*note Job Control Builtins::) or suppress the sending of `SIGHUP' to a job when the shell exits as the result of a `SIGHUP'. * The SVR4.2 shell has two privilege-related builtins (`mldmode' and `priv') not present in Bash. * Bash does not have the `stop' or `newgrp' builtins. * Bash does not use the `SHACCT' variable or perform shell accounting. * The SVR4.2 `sh' uses a `TIMEOUT' variable like Bash uses `TMOUT'. More features unique to Bash may be found in *Note Bash Features::. 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: * Bash does not fork a subshell when redirecting into or out of a shell control structure such as an `if' or `while' statement. * Bash does not allow unbalanced quotes. The SVR4.2 shell will silently insert a needed closing quote at `EOF' under certain circumstances. This can be the cause of some hard-to-find errors. * The SVR4.2 shell uses a baroque memory management scheme based on trapping `SIGSEGV'. If the shell is started from a process with `SIGSEGV' blocked (e.g., by using the `system()' C library function call), it misbehaves badly. * In a questionable attempt at security, the SVR4.2 shell, when invoked without the `-p' option, will alter its real and effective UID and GID if they are less than some magic threshold value, commonly 100. This can lead to unexpected results. * The SVR4.2 shell does not allow users to trap `SIGSEGV', `SIGALRM', or `SIGCHLD'. * The SVR4.2 shell does not allow the `IFS', `MAILCHECK', `PATH', `PS1', or `PS2' variables to be unset. * The SVR4.2 shell treats `^' as the undocumented equivalent of `|'. * Bash allows multiple option arguments when it is invoked (`-x -v'); the SVR4.2 shell allows only one option argument (`-xv'). In fact, some versions of the shell dump core if the second argument begins with a `-'. * The SVR4.2 shell exits a script if any builtin fails; Bash exits a script only if one of the POSIX 1003.2 special builtins fails, and only for certain failures, as enumerated in the POSIX 1003.2 standard. * The SVR4.2 shell behaves differently when invoked as `jsh' (it turns on job control).  File: bashref.info, Node: Builtin Index, Next: Reserved Word Index, Prev: Major Differences From The Bourne Shell, Up: Top Index of Shell Builtin Commands ******************************* * Menu: * .: Bourne Shell Builtins. * :: Bourne Shell Builtins. * [: Bourne Shell Builtins. * alias: Bash Builtins. * bg: Job Control Builtins. * bind: Bash Builtins. * break: Bourne Shell Builtins. * builtin: Bash Builtins. * cd: Bourne Shell Builtins. * command: Bash Builtins. * compgen: Programmable Completion Builtins. * complete: Programmable Completion Builtins. * continue: Bourne Shell Builtins. * declare: Bash Builtins. * dirs: Directory Stack Builtins. * disown: Job Control Builtins. * echo: Bash Builtins. * enable: Bash Builtins. * eval: Bourne Shell Builtins. * exec: Bourne Shell Builtins. * exit: Bourne Shell Builtins. * export: Bourne Shell Builtins. * fc: Bash History Builtins. * fg: Job Control Builtins. * getopts: Bourne Shell Builtins. * hash: Bourne Shell Builtins. * help: Bash Builtins. * history: Bash History Builtins. * jobs: Job Control Builtins. * kill: Job Control Builtins. * let: Bash Builtins. * local: Bash Builtins. * logout: Bash Builtins. * popd: Directory Stack Builtins. * printf: Bash Builtins. * pushd: Directory Stack Builtins. * pwd: Bourne Shell Builtins. * read: Bash Builtins. * readonly: Bourne Shell Builtins. * return: Bourne Shell Builtins. * set: The Set Builtin. * shift: Bourne Shell Builtins. * shopt: Bash Builtins. * source: Bash Builtins. * suspend: Job Control Builtins. * test: Bourne Shell Builtins. * times: Bourne Shell Builtins. * trap: Bourne Shell Builtins. * type: Bash Builtins. * typeset: Bash Builtins. * ulimit: Bash Builtins. * umask: Bourne Shell Builtins. * unalias: Bash Builtins. * unset: Bourne Shell Builtins. * wait: Job Control Builtins.  File: bashref.info, Node: Reserved Word Index, Next: Variable Index, Prev: Builtin Index, Up: Top Index of Shell Reserved Words ***************************** * Menu: * !: Pipelines. * [[: Conditional Constructs. * ]]: Conditional Constructs. * case: Conditional Constructs. * do: Looping Constructs. * done: Looping Constructs. * elif: Conditional Constructs. * else: Conditional Constructs. * esac: Conditional Constructs. * fi: Conditional Constructs. * for: Looping Constructs. * function: Shell Functions. * if: Conditional Constructs. * in: Conditional Constructs. * select: Conditional Constructs. * then: Conditional Constructs. * time: Pipelines. * until: Looping Constructs. * while: Looping Constructs. * {: Command Grouping. * }: Command Grouping.  File: bashref.info, Node: Variable Index, Next: Function Index, Prev: Reserved Word Index, Up: Top Parameter and Variable Index **************************** * Menu: * !: Special Parameters. * #: Special Parameters. * $: Special Parameters. * *: Special Parameters. * -: Special Parameters. * 0: Special Parameters. * ?: Special Parameters. * @: Special Parameters. * _: Special Parameters. * auto_resume: Job Control Variables. * BASH: Bash Variables. * BASH_ENV: Bash Variables. * BASH_VERSINFO: Bash Variables. * BASH_VERSION: Bash Variables. * bell-style: Readline Init File Syntax. * CDPATH: Bourne Shell Variables. * COLUMNS: Bash Variables. * comment-begin: Readline Init File Syntax. * COMP_CWORD: Bash Variables. * COMP_LINE: Bash Variables. * COMP_POINT: Bash Variables. * COMP_WORDS: Bash Variables. * completion-query-items: Readline Init File Syntax. * COMPREPLY: Bash Variables. * convert-meta: Readline Init File Syntax. * DIRSTACK: Bash Variables. * disable-completion: Readline Init File Syntax. * editing-mode: Readline Init File Syntax. * enable-keypad: Readline Init File Syntax. * EUID: Bash Variables. * expand-tilde: Readline Init File Syntax. * FCEDIT: Bash Variables. * FIGNORE: Bash Variables. * FUNCNAME: Bash Variables. * GLOBIGNORE: Bash Variables. * GROUPS: Bash Variables. * histchars: Bash Variables. * HISTCMD: Bash Variables. * HISTCONTROL: Bash Variables. * HISTFILE: Bash Variables. * HISTFILESIZE: Bash Variables. * HISTIGNORE: Bash Variables. * history-preserve-point: Readline Init File Syntax. * HISTSIZE: Bash Variables. * HOME: Bourne Shell Variables. * horizontal-scroll-mode: Readline Init File Syntax. * HOSTFILE: Bash Variables. * HOSTNAME: Bash Variables. * HOSTTYPE: Bash Variables. * IFS: Bourne Shell Variables. * IGNOREEOF: Bash Variables. * input-meta: Readline Init File Syntax. * INPUTRC: Bash Variables. * isearch-terminators: Readline Init File Syntax. * keymap: Readline Init File Syntax. * LANG: Bash Variables. * LC_ALL: Bash Variables. * LC_COLLATE: Bash Variables. * LC_CTYPE: Bash Variables. * LC_MESSAGES <1>: Bash Variables. * LC_MESSAGES: Locale Translation. * LC_NUMERIC: Bash Variables. * LINENO: Bash Variables. * LINES: Bash Variables. * MACHTYPE: Bash Variables. * MAIL: Bourne Shell Variables. * MAILCHECK: Bash Variables. * MAILPATH: Bourne Shell Variables. * mark-modified-lines: Readline Init File Syntax. * match-hidden-files: Readline Init File Syntax. * meta-flag: Readline Init File Syntax. * OLDPWD: Bash Variables. * OPTARG: Bourne Shell Variables. * OPTERR: Bash Variables. * OPTIND: Bourne Shell Variables. * OSTYPE: Bash Variables. * output-meta: Readline Init File Syntax. * PATH: Bourne Shell Variables. * PIPESTATUS: Bash Variables. * POSIXLY_CORRECT: Bash Variables. * PPID: Bash Variables. * PROMPT_COMMAND: Bash Variables. * PS1: Bourne Shell Variables. * PS2: Bourne Shell Variables. * PS3: Bash Variables. * PS4: Bash Variables. * PWD: Bash Variables. * RANDOM: Bash Variables. * REPLY: Bash Variables. * SECONDS: Bash Variables. * SHELLOPTS: Bash Variables. * SHLVL: Bash Variables. * show-all-if-ambiguous: Readline Init File Syntax. * TEXTDOMAIN: Locale Translation. * TEXTDOMAINDIR: Locale Translation. * TIMEFORMAT: Bash Variables. * TMOUT: Bash Variables. * UID: Bash Variables. * visible-stats: Readline Init File Syntax.  File: bashref.info, Node: Function Index, Next: Concept Index, Prev: Variable Index, Up: Top Function Index ************** * Menu: * abort (C-g): Miscellaneous Commands. * accept-line (Newline or Return): Commands For History. * backward-char (C-b): Commands For Moving. * backward-delete-char (Rubout): Commands For Text. * backward-kill-line (C-x Rubout): Commands For Killing. * backward-kill-word (M-): Commands For Killing. * backward-word (M-b): Commands For Moving. * beginning-of-history (M-<): Commands For History. * beginning-of-line (C-a): Commands For Moving. * call-last-kbd-macro (C-x e): Keyboard Macros. * capitalize-word (M-c): Commands For Text. * character-search (C-]): Miscellaneous Commands. * character-search-backward (M-C-]): Miscellaneous Commands. * clear-screen (C-l): Commands For Moving. * complete (): Commands For Completion. * copy-backward-word (): Commands For Killing. * copy-forward-word (): Commands For Killing. * copy-region-as-kill (): Commands For Killing. * delete-char (C-d): Commands For Text. * delete-char-or-list (): Commands For Completion. * delete-horizontal-space (): Commands For Killing. * digit-argument (M-0, M-1, ... M--): Numeric Arguments. * do-uppercase-version (M-a, M-b, M-X, ...): Miscellaneous Commands. * downcase-word (M-l): Commands For Text. * dump-functions (): Miscellaneous Commands. * dump-macros (): Miscellaneous Commands. * dump-variables (): Miscellaneous Commands. * end-kbd-macro (C-x )): Keyboard Macros. * end-of-history (M->): Commands For History. * end-of-line (C-e): Commands For Moving. * exchange-point-and-mark (C-x C-x): Miscellaneous Commands. * forward-backward-delete-char (): Commands For Text. * forward-char (C-f): Commands For Moving. * forward-search-history (C-s): Commands For History. * forward-word (M-f): Commands For Moving. * history-search-backward (): Commands For History. * history-search-forward (): Commands For History. * insert-comment (M-#): Miscellaneous Commands. * insert-completions (M-*): Commands For Completion. * kill-line (C-k): Commands For Killing. * kill-region (): Commands For Killing. * kill-whole-line (): Commands For Killing. * kill-word (M-d): Commands For Killing. * menu-complete (): Commands For Completion. * next-history (C-n): Commands For History. * non-incremental-forward-search-history (M-n): Commands For History. * non-incremental-reverse-search-history (M-p): Commands For History. * possible-completions (M-?): Commands For Completion. * prefix-meta (): Miscellaneous Commands. * previous-history (C-p): Commands For History. * quoted-insert (C-q or C-v): Commands For Text. * re-read-init-file (C-x C-r): Miscellaneous Commands. * redraw-current-line (): Commands For Moving. * reverse-search-history (C-r): Commands For History. * revert-line (M-r): Miscellaneous Commands. * self-insert (a, b, A, 1, !, ...): Commands For Text. * set-mark (C-@): Miscellaneous Commands. * start-kbd-macro (C-x (): Keyboard Macros. * transpose-chars (C-t): Commands For Text. * transpose-words (M-t): Commands For Text. * undo (C-_ or C-x C-u): Miscellaneous Commands. * universal-argument (): Numeric Arguments. * unix-line-discard (C-u): Commands For Killing. * unix-word-rubout (C-w): Commands For Killing. * upcase-word (M-u): Commands For Text. * yank (C-y): Commands For Killing. * yank-last-arg (M-. or M-_): Commands For History. * yank-nth-arg (M-C-y): Commands For History. * yank-pop (M-y): Commands For Killing.  File: bashref.info, Node: Concept Index, Prev: Function Index, Up: Top Concept Index ************* * Menu: * alias expansion: Aliases. * arithmetic evaluation: Shell Arithmetic. * arithmetic expansion: Arithmetic Expansion. * arithmetic, shell: Shell Arithmetic. * arrays: Arrays. * background: Job Control Basics. * Bash configuration: Basic Installation. * Bash installation: Basic Installation. * Bourne shell: Basic Shell Features. * brace expansion: Brace Expansion. * builtin: Definitions. * command editing: Readline Bare Essentials. * command execution: Command Search and Execution. * command expansion: Simple Command Expansion. * command history: Bash History Facilities. * command search: Command Search and Execution. * command substitution: Command Substitution. * command timing: Pipelines. * commands, conditional: Conditional Constructs. * commands, grouping: Command Grouping. * commands, lists: Lists. * commands, looping: Looping Constructs. * commands, pipelines: Pipelines. * commands, shell: Shell Commands. * commands, simple: Simple Commands. * comments, shell: Comments. * completion builtins: Programmable Completion Builtins. * configuration: Basic Installation. * control operator: Definitions. * directory stack: The Directory Stack. * editing command lines: Readline Bare Essentials. * environment: Environment. * evaluation, arithmetic: Shell Arithmetic. * event designators: Event Designators. * execution environment: Command Execution Environment. * exit status <1>: Exit Status. * exit status: Definitions. * expansion: Shell Expansions. * expansion, arithmetic: Arithmetic Expansion. * expansion, brace: Brace Expansion. * expansion, filename: Filename Expansion. * expansion, parameter: Shell Parameter Expansion. * expansion, pathname: Filename Expansion. * expansion, tilde: Tilde Expansion. * expressions, arithmetic: Shell Arithmetic. * expressions, conditional: Bash Conditional Expressions. * field: Definitions. * filename: Definitions. * filename expansion: Filename Expansion. * foreground: Job Control Basics. * functions, shell: Shell Functions. * history builtins: Bash History Builtins. * history events: Event Designators. * history expansion: History Interaction. * history list: Bash History Facilities. * History, how to use: Programmable Completion Builtins. * identifier: Definitions. * initialization file, readline: Readline Init File. * installation: Basic Installation. * interaction, readline: Readline Interaction. * interactive shell <1>: Invoking Bash. * interactive shell: Interactive Shells. * internationalization: Locale Translation. * job: Definitions. * job control <1>: Job Control Basics. * job control: Definitions. * kill ring: Readline Killing Commands. * killing text: Readline Killing Commands. * localization: Locale Translation. * login shell: Invoking Bash. * matching, pattern: Pattern Matching. * metacharacter: Definitions. * name: Definitions. * native languages: Locale Translation. * notation, readline: Readline Bare Essentials. * operator, shell: Definitions. * parameter expansion: Shell Parameter Expansion. * parameters: Shell Parameters. * parameters, positional: Positional Parameters. * parameters, special: Special Parameters. * pathname expansion: Filename Expansion. * pattern matching: Pattern Matching. * pipeline: Pipelines. * POSIX: Definitions. * POSIX Mode: Bash POSIX Mode. * process group: Definitions. * process group ID: Definitions. * process substitution: Process Substitution. * programmable completion: Programmable Completion. * prompting: Printing a Prompt. * quoting: Quoting. * quoting, ANSI: ANSI-C Quoting. * Readline, how to use: Job Control Variables. * redirection: Redirections. * reserved word: Definitions. * restricted shell: The Restricted Shell. * return status: Definitions. * shell arithmetic: Shell Arithmetic. * shell function: Shell Functions. * shell script: Shell Scripts. * shell variable: Shell Parameters. * shell, interactive: Interactive Shells. * signal: Definitions. * signal handling: Signals. * special builtin <1>: Special Builtins. * special builtin: Definitions. * startup files: Bash Startup Files. * suspending jobs: Job Control Basics. * tilde expansion: Tilde Expansion. * token: Definitions. * translation, native languages: Locale Translation. * variable, shell: Shell Parameters. * variables, readline: Readline Init File Syntax. * word: Definitions. * word splitting: Word Splitting. * yanking text: Readline Killing Commands.  Tag Table: Node: Top1164 Node: Introduction3300 Node: What is Bash?3525 Node: What is a shell?4626 Node: Definitions6860 Node: Basic Shell Features9600 Node: Shell Syntax10824 Node: Shell Operation11848 Node: Quoting13133 Node: Escape Character14392 Node: Single Quotes14864 Node: Double Quotes15199 Node: ANSI-C Quoting16100 Node: Locale Translation17009 Node: Comments17892 Node: Shell Commands18497 Node: Simple Commands19378 Node: Pipelines19999 Node: Lists21535 Node: Looping Constructs23048 Node: Conditional Constructs25492 Node: Command Grouping31416 Node: Shell Functions32793 Node: Shell Parameters35329 Node: Positional Parameters36903 Node: Special Parameters37794 Node: Shell Expansions40452 Node: Brace Expansion42372 Node: Tilde Expansion44041 Node: Shell Parameter Expansion46372 Node: Command Substitution53172 Node: Arithmetic Expansion54494 Node: Process Substitution55338 Node: Word Splitting56375 Node: Filename Expansion57827 Node: Pattern Matching59785 Node: Quote Removal62916 Node: Redirections63202 Node: Executing Commands70105 Node: Simple Command Expansion70772 Node: Command Search and Execution72693 Node: Command Execution Environment74690 Node: Environment77397 Node: Exit Status79048 Node: Signals80243 Node: Shell Scripts82154 Node: Shell Builtin Commands84665 Node: Bourne Shell Builtins86095 Node: Bash Builtins101581 Node: The Set Builtin125866 Node: Special Builtins132847 Node: Shell Variables133819 Node: Bourne Shell Variables134255 Node: Bash Variables136034 Node: Bash Features151763 Node: Invoking Bash152645 Node: Bash Startup Files158078 Node: Interactive Shells162948 Node: What is an Interactive Shell?163350 Node: Is this Shell Interactive?163985 Node: Interactive Shell Behavior164791 Node: Bash Conditional Expressions168058 Node: Shell Arithmetic171352 Node: Aliases173783 Node: Arrays176286 Node: The Directory Stack179306 Node: Directory Stack Builtins180012 Node: Printing a Prompt182890 Node: The Restricted Shell185306 Node: Bash POSIX Mode186784 Node: Job Control192616 Node: Job Control Basics193082 Node: Job Control Builtins197362 Node: Job Control Variables201657 Node: Command Line Editing202806 Node: Introduction and Notation203804 Node: Readline Interaction205421 Node: Readline Bare Essentials206607 Node: Readline Movement Commands208387 Node: Readline Killing Commands209343 Node: Readline Arguments211251 Node: Searching212286 Node: Readline Init File214463 Node: Readline Init File Syntax215517 Node: Conditional Init Constructs226248 Node: Sample Init File228772 Node: Bindable Readline Commands231941 Node: Commands For Moving233140 Node: Commands For History233988 Node: Commands For Text236876 Node: Commands For Killing238913 Node: Numeric Arguments240863 Node: Commands For Completion241990 Node: Keyboard Macros245570 Node: Miscellaneous Commands246128 Node: Readline vi Mode250490 Node: Programmable Completion251399 Node: Programmable Completion Builtins256447 Node: Using History Interactively263433 Node: Bash History Facilities264112 Node: Bash History Builtins266672 Node: History Interaction270238 Node: Event Designators272789 Node: Word Designators273716 Node: Modifiers275345 Node: Installing Bash276662 Node: Basic Installation277804 Node: Compilers and Options280489 Node: Compiling For Multiple Architectures281223 Node: Installation Names282880 Node: Specifying the System Type283691 Node: Sharing Defaults284400 Node: Operation Controls285065 Node: Optional Features286016 Node: Reporting Bugs293871 Node: Major Differences From The Bourne Shell294968 Node: Builtin Index309390 Node: Reserved Word Index312981 Node: Variable Index314457 Node: Function Index320619 Node: Concept Index325109  End Tag Table bash-2.05a/doc/article.ms100664 436 0 121442 5651255634 13545 0ustar chetwheel.de SE \" start example .sp .5 .RS .ft CR .nf .. .de EE \" end example .fi .sp .5 .RE .ft R .. .TL Bash \- The GNU shell* .AU Chet Ramey Case Western Reserve University chet@po.cwru.edu .FS *An earlier version of this article appeared in The Linux Journal. .FE .NH 1 Introduction .PP .B Bash is the shell, or command language interpreter, that will appear in the GNU operating system. The name is an acronym for the \*QBourne-Again SHell\*U, a pun on Steve Bourne, the author of the direct ancestor of the current .UX shell \fI/bin/sh\fP, which appeared in the Seventh Edition Bell Labs Research version of \s-1UNIX\s+1. .PP Bash is an \fBsh\fP\-compatible shell that incorporates useful features from the Korn shell (\fBksh\fP) and the C shell (\fBcsh\fP), described later in this article. It is ultimately intended to be a conformant implementation of the IEEE POSIX Shell and Utilities specification (IEEE Working Group 1003.2). It offers functional improvements over sh for both interactive and programming use. .PP While the GNU operating system will most likely include a version of the Berkeley shell csh, Bash will be the default shell. Like other GNU software, Bash is quite portable. It currently runs on nearly every version of .UX and a few other operating systems \- an independently-supported port exists for OS/2, and there are rumors of ports to DOS and Windows NT. Ports to \s-1UNIX\s+1-like systems such as QNX and Minix are part of the distribution. .PP The original author of Bash was Brian Fox, an employee of the Free Software Foundation. The current developer and maintainer is Chet Ramey, a volunteer who works at Case Western Reserve University. .NH 1 What's POSIX, anyway? .PP .I POSIX is a name originally coined by Richard Stallman for a family of open system standards based on \s-1UNIX\s+1. There are a number of aspects of \s-1UNIX\s+1 under consideration for standardization, from the basic system services at the system call and C library level to applications and tools to system administration and management. Each area of standardization is assigned to a working group in the 1003 series. .PP The POSIX Shell and Utilities standard has been developed by IEEE Working Group 1003.2 (POSIX.2).\(dd .FS \(ddIEEE, \fIIEEE Standard for Information Technology -- Portable Operating System Interface (POSIX) Part 2: Shell and Utilities\fP, 1992. .FE It concentrates on the command interpreter interface and utility programs commonly executed from the command line or by other programs. An initial version of the standard has been approved and published by the IEEE, and work is currently underway to update it. There are four primary areas of work in the 1003.2 standard: .IP \(bu Aspects of the shell's syntax and command language. A number of special builtins such as .B cd and .B exec are being specified as part of the shell, since their functionality usually cannot be implemented by a separate executable; .IP \(bu A set of utilities to be called by shell scripts and applications. Examples are programs like .I sed, .I tr, and .I awk. Utilities commonly implemented as shell builtins are described in this section, such as .B test and .B kill . An expansion of this section's scope, termed the User Portability Extension, or UPE, has standardized interactive programs such as .I vi and .I mailx; .IP \(bu A group of functional interfaces to services provided by the shell, such as the traditional \f(CRsystem()\fP C library function. There are functions to perform shell word expansions, perform filename expansion (\fIglobbing\fP), obtain values of POSIX.2 system configuration variables, retrieve values of environment variables (\f(CRgetenv()\fP\^), and other services; .IP \(bu A suite of \*Qdevelopment\*U utilities such as .I c89 (the POSIX.2 version of \fIcc\fP), and .I yacc. .PP Bash is concerned with the aspects of the shell's behavior defined by POSIX.2. The shell command language has of course been standardized, including the basic flow control and program execution constructs, I/O redirection and pipelining, argument handling, variable expansion, and quoting. The .I special builtins, which must be implemented as part of the shell to provide the desired functionality, are specified as being part of the shell; examples of these are .B eval and .B export . Other utilities appear in the sections of POSIX.2 not devoted to the shell which are commonly (and in some cases must be) implemented as builtin commands, such as .B read and .B test . POSIX.2 also specifies aspects of the shell's interactive behavior as part of the UPE, including job control and command line editing. Interestingly enough, only \fIvi\fP-style line editing commands have been standardized; \fIemacs\fP editing commands were left out due to objections. .PP While POSIX.2 includes much of what the shell has traditionally provided, some important things have been omitted as being \*Qbeyond its scope.\*U There is, for instance, no mention of a difference between a .I login shell and any other interactive shell (since POSIX.2 does not specify a login program). No fixed startup files are defined, either \- the standard does not mention .I .profile . .NH 1 Basic Bash features .PP Since the Bourne shell provides Bash with most of its philosophical underpinnings, Bash inherits most of its features and functionality from sh. Bash implements all of the traditional sh flow control constructs (\fIfor\fP, \fIif\fP, \fIwhile\fP, etc.). All of the Bourne shell builtins, including those not specified in the POSIX.2 standard, appear in Bash. Shell \fIfunctions\fP, introduced in the SVR2 version of the Bourne shell, are similar to shell scripts, but are defined using a special syntax and are executed in the same process as the calling shell. Bash has shell functions which behave in a fashion upward-compatible with sh functions. There are certain shell variables that Bash interprets in the same way as sh, such as .B PS1 , .B IFS , and .B PATH . Bash implements essentially the same grammar, parameter and variable expansion semantics, redirection, and quoting as the Bourne shell. Where differences appear between the POSIX.2 standard and traditional sh behavior, Bash follows POSIX. .PP The Korn Shell (\fBksh\fP) is a descendent of the Bourne shell written at AT&T Bell Laboratories by David Korn\(dg. It provides a number of useful features that POSIX and Bash have adopted. Many of the interactive facilities in POSIX.2 have their roots in the ksh: for example, the POSIX and ksh job control facilities are nearly identical. Bash includes features from the Korn Shell for both interactive use and shell programming. For programming, Bash provides variables such as .B RANDOM and .B REPLY , the .B typeset builtin, the ability to remove substrings from variables based on patterns, and shell arithmetic. .FS \(dgMorris Bolsky and David Korn, \fIThe KornShell Command and Programming Language\fP, Prentice Hall, 1989. .FE .B RANDOM expands to a random number each time it is referenced; assigning a value to .B RANDOM seeds the random number generator. .B REPLY is the default variable used by the .B read builtin when no variable names are supplied as arguments. The .B typeset builtin is used to define variables and give them attributes such as \fBreadonly\fP. Bash arithmetic allows the evaluation of an expression and the substitution of the result. Shell variables may be used as operands, and the result of an expression may be assigned to a variable. Nearly all of the operators from the C language are available, with the same precedence rules: .SE $ echo $((3 + 5 * 32)) 163 .EE .LP For interactive use, Bash implements ksh-style aliases and builtins such as .B fc (discussed below) and .B jobs . Bash aliases allow a string to be substituted for a command name. They can be used to create a mnemonic for a \s-1UNIX\s+1 command name (\f(CRalias del=rm\fP), to expand a single word to a complex command (\f(CRalias news='xterm -g 80x45 -title trn -e trn -e -S1 -N &'\fP), or to ensure that a command is invoked with a basic set of options (\f(CRalias ls="/bin/ls -F"\fP). .PP The C shell (\fBcsh\fP)\(dg, originally written by Bill Joy while at Berkeley, is widely used and quite popular for its interactive facilities. Bash includes a csh-compatible history expansion mechanism (\*Q! history\*U), brace expansion, access to a stack of directories via the .B pushd , .B popd , and .B dirs builtins, and tilde expansion, to generate users' home directories. Tilde expansion has also been adopted by both the Korn Shell and POSIX.2. .FS \(dgBill Joy, An Introduction to the C Shell, \fIUNIX User's Supplementary Documents\fP, University of California at Berkeley, 1986. .FE .PP There were certain areas in which POSIX.2 felt standardization was necessary, but no existing implementation provided the proper behavior. The working group invented and standardized functionality in these areas, which Bash implements. The .B command builtin was invented so that shell functions could be written to replace builtins; it makes the capabilities of the builtin available to the function. The reserved word \*Q!\*U was added to negate the return value of a command or pipeline; it was nearly impossible to express \*Qif not x\*U cleanly using the sh language. There exist multiple incompatible implementations of the .B test builtin, which tests files for type and other attributes and performs arithmetic and string comparisons. POSIX considered none of these correct, so the standard behavior was specified in terms of the number of arguments to the command. POSIX.2 dictates exactly what will happen when four or fewer arguments are given to .B test , and leaves the behavior undefined when more arguments are supplied. Bash uses the POSIX.2 algorithm, which was conceived by David Korn. .NH 2 Features not in the Bourne Shell .PP There are a number of minor differences between Bash and the version of sh present on most other versions of \s-1UNIX\s+1. The majority of these are due to the POSIX standard, but some are the result of Bash adopting features from other shells. For instance, Bash includes the new \*Q!\*U reserved word, the .B command builtin, the ability of the .B read builtin to correctly return a line ending with a backslash, symbolic arguments to the .B umask builtin, variable substring removal, a way to get the length of a variable, and the new algorithm for the .B test builtin from the POSIX.2 standard, none of which appear in sh. .PP Bash also implements the \*Q$(...)\*U command substitution syntax, which supersedes the sh `...` construct. The \*Q$(...)\*U construct expands to the output of the command contained within the parentheses, with trailing newlines removed. The sh syntax is accepted for backwards compatibility, but the \*Q$(...)\*U form is preferred because its quoting rules are much simpler and it is easier to nest. .PP The Bourne shell does not provide such features as brace expansion, the ability to define a variable and a function with the same name, local variables in shell functions, the ability to enable and disable individual builtins or write a function to replace a builtin, or a means to export a shell function to a child process. .PP Bash has closed a long-standing shell security hole by not using the .B $IFS variable to split each word read by the shell, but splitting only the results of expansion (ksh and the 4.4 BSD sh have fixed this as well). Useful behavior such as a means to abort execution of a script read with the \*Q.\*U command using the \fBreturn\fP builtin or automatically exporting variables in the shell's environment to children is also not present in the Bourne shell. Bash provides a much more powerful environment for both interactive use and programming. .NH 1 Bash-specific Features .PP This section details a few of the features which make Bash unique. Most of them provide improved interactive use, but a few programming improvements are present as well. Full descriptions of these features can be found in the Bash documentation. .NH 2 Startup Files .PP Bash executes startup files differently than other shells. The Bash behavior is a compromise between the csh principle of startup files with fixed names executed for each shell and the sh \*Qminimalist\*U behavior. An interactive instance of Bash started as a login shell reads and executes .I ~/.bash_profile (the file .bash_profile in the user's home directory), if it exists. An interactive non-login shell reads and executes .I ~/.bashrc . A non-interactive shell (one begun to execute a shell script, for example) reads no fixed startup file, but uses the value of the variable .B $ENV , if set, as the name of a startup file. The ksh practice of reading .B $ENV for every shell, with the accompanying difficulty of defining the proper variables and functions for interactive and non-interactive shells or having the file read only for interactive shells, was considered too complex. Ease of use won out here. Interestingly, the next release of ksh will change to reading .B $ENV only for interactive shells. .NH 2 New Builtin Commands .PP There are a few builtins which are new or have been extended in Bash. The .B enable builtin allows builtin commands to be turned on and off arbitrarily. To use the version of .I echo found in a user's search path rather than the Bash builtin, \f(CRenable -n echo\fP suffices. The .B help builtin provides quick synopses of the shell facilities without requiring access to a manual page. .B Builtin is similar to .B command in that it bypasses shell functions and directly executes builtin commands. Access to a csh-style stack of directories is provided via the .B pushd , .B popd , and .B dirs builtins. .B Pushd and .B popd insert and remove directories from the stack, respectively, and .B dirs lists the stack contents. On systems that allow fine-grained control of resources, the .B ulimit builtin can be used to tune these settings. .B Ulimit allows a user to control, among other things, whether core dumps are to be generated, how much memory the shell or a child process is allowed to allocate, and how large a file created by a child process can grow. The .B suspend command will stop the shell process when job control is active; most other shells do not allow themselves to be stopped like that. .B Type, the Bash answer to .B which and .B whence, shows what will happen when a word is typed as a command: .SE $ type export export is a shell builtin $ type -t export builtin $ type bash bash is /bin/bash $ type cd cd is a function cd () { builtin cd ${1+"$@"} && xtitle $HOST: $PWD } .EE .LP Various modes tell what a command word is (reserved word, alias, function, builtin, or file) or which version of a command will be executed based on a user's search path. Some of this functionality has been adopted by POSIX.2 and folded into the .B command utility. .NH 2 Editing and Completion .PP One area in which Bash shines is command line editing. Bash uses the .I readline library to read and edit lines when interactive. Readline is a powerful and flexible input facility that a user can configure to individual tastes. It allows lines to be edited using either emacs or vi commands, where those commands are appropriate. The full capability of emacs is not present \- there is no way to execute a named command with M-x, for instance \- but the existing commands are more than adequate. The vi mode is compliant with the command line editing standardized by POSIX.2. .PP Readline is fully customizable. In addition to the basic commands and key bindings, the library allows users to define additional key bindings using a startup file. The .I inputrc file, which defaults to the file .I ~/.inputrc , is read each time readline initializes, permitting users to maintain a consistent interface across a set of programs. Readline includes an extensible interface, so each program using the library can add its own bindable commands and program-specific key bindings. Bash uses this facility to add bindings that perform history expansion or shell word expansions on the current input line. .PP Readline interprets a number of variables which further tune its behavior. Variables exist to control whether or not eight-bit characters are directly read as input or converted to meta-prefixed key sequences (a meta-prefixed key sequence consists of the character with the eighth bit zeroed, preceded by the .I meta-prefix character, usually escape, which selects an alternate keymap), to decide whether to output characters with the eighth bit set directly or as a meta-prefixed key sequence, whether or not to wrap to a new screen line when a line being edited is longer than the screen width, the keymap to which subsequent key bindings should apply, or even what happens when readline wants to ring the terminal's bell. All of these variables can be set in the inputrc file. .PP The startup file understands a set of C preprocessor-like conditional constructs which allow variables or key bindings to be assigned based on the application using readline, the terminal currently being used, or the editing mode. Users can add program-specific bindings to make their lives easier: I have bindings that let me edit the value of .B $PATH and double-quote the current or previous word: .SE # Macros that are convenient for shell interaction $if Bash # edit the path "\eC-xp": "PATH=${PATH}\ee\eC-e\eC-a\eef\eC-f" # prepare to type a quoted word -- insert open and close double # quotes and move to just after the open quote "\eC-x\e"": "\e"\e"\eC-b" # Quote the current or previous word "\eC-xq": "\eeb\e"\eef\e"" $endif .EE .LP There is a readline command to re-read the file, so users can edit the file, change some bindings, and begin to use them almost immediately. .PP Bash implements the .B bind builtin for more dyamic control of readline than the startup file permits. .B Bind is used in several ways. In .I list mode, it can display the current key bindings, list all the readline editing directives available for binding, list which keys invoke a given directive, or output the current set of key bindings in a format that can be incorporated directly into an inputrc file. In .I batch mode, it reads a series of key bindings directly from a file and passes them to readline. In its most common usage, .B bind takes a single string and passes it directly to readline, which interprets the line as if it had just been read from the inputrc file. Both key bindings and variable assignments may appear in the string given to .B bind . .PP The readline library also provides an interface for \fIword completion\fP. When the .I completion character (usually TAB) is typed, readline looks at the word currently being entered and computes the set of filenames of which the current word is a valid prefix. If there is only one possible completion, the rest of the characters are inserted directly, otherwise the common prefix of the set of filenames is added to the current word. A second TAB character entered immediately after a non-unique completion causes readline to list the possible completions; there is an option to have the list displayed immediately. Readline provides hooks so that applications can provide specific types of completion before the default filename completion is attempted. This is quite flexible, though it is not completely user-programmable. Bash, for example, can complete filenames, command names (including aliases, builtins, shell reserved words, shell functions, and executables found in the file system), shell variables, usernames, and hostnames. It uses a set of heuristics that, while not perfect, is generally quite good at determining what type of completion to attempt. .NH 2 History .PP Access to the list of commands previously entered (the \fIcommand history\fP) is provided jointly by Bash and the readline library. Bash provides variables (\fB$HISTFILE\fP, \fB$HISTSIZE\fP, and \fB$HISTCONTROL\fP) and the .B history and .B fc builtins to manipulate the history list. The value of .B $HISTFILE specifes the file where Bash writes the command history on exit and reads it on startup. .B $HISTSIZE is used to limit the number of commands saved in the history. .B $HISTCONTROL provides a crude form of control over which commands are saved on the history list: a value of .I ignorespace means to not save commands which begin with a space; a value of .I ignoredups means to not save commands identical to the last command saved. \fB$HISTCONTROL\fP was named \fB$history_control\fP in earlier versions of Bash; the old name is still accepted for backwards compatibility. The .B history command can read or write files containing the history list and display the current list contents. The .B fc builtin, adopted from POSIX.2 and the Korn Shell, allows display and re-execution, with optional editing, of commands from the history list. The readline library offers a set of commands to search the history list for a portion of the current input line or a string typed by the user. Finally, the .I history library, generally incorporated directly into the readline library, implements a facility for history recall, expansion, and re-execution of previous commands very similar to csh (\*Qbang history\*U, so called because the exclamation point introduces a history substitution): .SE $ echo a b c d e a b c d e $ !! f g h i echo a b c d e f g h i a b c d e f g h i $ !-2 echo a b c d e a b c d e $ echo !-2:1-4 echo a b c d a b c d .EE .LP The command history is only saved when the shell is interactive, so it is not available for use by shell scripts. .NH 2 New Shell Variables .PP There are a number of convenience variables that Bash interprets to make life easier. These include .B FIGNORE , which is a set of filename suffixes identifying files to exclude when completing filenames; .B HOSTTYPE , which is automatically set to a string describing the type of hardware on which Bash is currently executing; .B command_oriented_history , which directs Bash to save all lines of a multiple-line command such as a \fIwhile\fP or \fIfor\fP loop in a single history entry, allowing easy re-editing; and .B IGNOREEOF , whose value indicates the number of consecutive EOF characters that an interactive shell will read before exiting \- an easy way to keep yourself from being logged out accidentally. The .B auto_resume variable alters the way the shell treats simple command names: if job control is active, and this variable is set, single-word simple commands without redirections cause the shell to first look for and restart a suspended job with that name before starting a new process. .NH 2 Brace Expansion .PP Since sh offers no convenient way to generate arbitrary strings that share a common prefix or suffix (filename expansion requires that the filenames exist), Bash implements \fIbrace expansion\fP, a capability picked up from csh. Brace expansion is similar to filename expansion, but the strings generated need not correspond to existing files. A brace expression consists of an optional .I preamble , followed by a pair of braces enclosing a series of comma-separated strings, and an optional .I postamble . The preamble is prepended to each string within the braces, and the postamble is then appended to each resulting string: .SE $ echo a{d,c,b}e ade ace abe .EE .LP As this example demonstrates, the results of brace expansion are not sorted, as they are by filename expansion. .NH 2 Process Substitution .PP On systems that can support it, Bash provides a facility known as \fIprocess substitution\fP. Process substitution is similar to command substitution in that its specification includes a command to execute, but the shell does not collect the command's output and insert it into the command line. Rather, Bash opens a pipe to the command, which is run in the background. The shell uses named pipes (FIFOs) or the .I /dev/fd method of naming open files to expand the process substitution to a filename which connects to the pipe when opened. This filename becomes the result of the expansion. Process substitution can be used to compare the outputs of two different versions of an application as part of a regression test: .SE $ cmp <(old_prog) <(new_prog) .EE .NH 2 Prompt Customization .PP One of the more popular interactive features that Bash provides is the ability to customize the prompt. Both .B $PS1 and .B $PS2, the primary and secondary prompts, are expanded before being displayed. Parameter and variable expansion is performed when the prompt string is expanded, so any shell variable can be put into the prompt (e.g., .B $SHLVL , which indicates how deeply the current shell is nested). Bash specially interprets characters in the prompt string preceded by a backslash. Some of these backslash escapes are replaced with the current time, the date, the current working directory, the username, and the command number or history number of the command being entered. There is even a backslash escape to cause the shell to change its prompt when running as root after an \fIsu\fP. Before printing each primary prompt, Bash expands the variable .B $PROMPT_COMMAND and, if it has a value, executes the expanded value as a command, allowing additional prompt customization. For example, this assignment causes the current user, the current host, the time, the last component of the current working directory, the level of shell nesting, and the history number of the current command to be embedded into the primary prompt: .SE $ PS1='\eu@\eh [\et] \eW($SHLVL:\e!)\e$ ' chet@odin [21:03:44] documentation(2:636)$ cd .. chet@odin [21:03:54] src(2:637)$ .EE .LP The string being assigned is surrounded by single quotes so that if it is exported, the value of .B $SHLVL will be updated by a child shell: .SE chet@odin [21:17:35] src(2:638)$ export PS1 chet@odin [21:17:40] src(2:639)$ bash chet@odin [21:17:46] src(3:696)$ .EE .LP The \fP\e$\fP escape is displayed as \*Q\fB$\fP\*U when running as a normal user, but as \*Q\fB#\fP\*U when running as root. .NH 2 File System Views .PP Since Berkeley introduced symbolic links in 4.2 BSD, one of their most annoying properties has been the \*Qwarping\*U to a completely different area of the file system when using .B cd , and the resultant non-intuitive behavior of \*Q\fBcd ..\fP\*U. The \s-1UNIX\s+1 kernel treats symbolic links .I physically . When the kernel is translating a pathname in which one component is a symbolic link, it replaces all or part of the pathname while processing the link. If the contents of the symbolic link begin with a slash, the kernel replaces the pathname entirely; if not, the link contents replace the current component. In either case, the symbolic link is visible. If the link value is an absolute pathname, the user finds himself in a completely different part of the file system. .PP Bash provides a .I logical view of the file system. In this default mode, command and filename completion and builtin commands such as .B cd and .B pushd which change the current working directory transparently follow symbolic links as if they were directories. The .B $PWD variable, which holds the shell's idea of the current working directory, depends on the path used to reach the directory rather than its physical location in the local file system hierarchy. For example: .SE $ cd /usr/local/bin $ echo $PWD /usr/local/bin $ pwd /usr/local/bin $ /bin/pwd /net/share/sun4/local/bin $ cd .. $ pwd /usr/local $ /bin/pwd /net/share/sun4/local $ cd .. $ pwd /usr $ /bin/pwd /usr .EE .LP One problem with this, of course, arises when programs that do not understand the shell's logical notion of the file system interpret \*Q..\*U differently. This generally happens when Bash completes filenames containing \*Q..\*U according to a logical hierarchy which does not correspond to their physical location. For users who find this troublesome, a corresponding .I physical view of the file system is available: .SE $ cd /usr/local/bin $ pwd /usr/local/bin $ set -o physical $ pwd /net/share/sun4/local/bin .EE .NH 2 Internationalization .PP One of the most significant improvements in version 1.13 of Bash was the change to \*Qeight-bit cleanliness\*U. Previous versions used the eighth bit of characters to mark whether or not they were quoted when performing word expansions. While this did not affect the majority of users, most of whom used only seven-bit ASCII characters, some found it confining. Beginning with version 1.13, Bash implemented a different quoting mechanism that did not alter the eighth bit of characters. This allowed Bash to manipulate files with \*Qodd\*U characters in their names, but did nothing to help users enter those names, so version 1.13 introduced changes to readline that made it eight-bit clean as well. Options exist that force readline to attach no special significance to characters with the eighth bit set (the default behavior is to convert these characters to meta-prefixed key sequences) and to output these characters without conversion to meta-prefixed sequences. These changes, along with the expansion of keymaps to a full eight bits, enable readline to work with most of the ISO-8859 family of character sets, used by many European countries. .NH 2 POSIX Mode .PP Although Bash is intended to be POSIX.2 conformant, there are areas in which the default behavior is not compatible with the standard. For users who wish to operate in a strict POSIX.2 environment, Bash implements a \fIPOSIX mode\fP. When this mode is active, Bash modifies its default operation where it differs from POSIX.2 to match the standard. POSIX mode is entered when Bash is started with the .B -posix option. This feature is also available as an option to the \fBset\fP builtin, \fBset -o posix\fP. For compatibility with other GNU software that attempts to be POSIX.2 compliant, Bash also enters POSIX mode if the variable .B $POSIXLY_CORRECT is set when Bash is started or assigned a value during execution. .B $POSIX_PEDANTIC is accepted as well, to be compatible with some older GNU utilities. When Bash is started in POSIX mode, for example, it sources the file named by the value of .B $ENV rather than the \*Qnormal\*U startup files, and does not allow reserved words to be aliased. .NH 1 New Features and Future Plans .PP There are several features introduced in the current version of Bash, version 1.14, and a number under consideration for future releases. This section will briefly detail the new features in version 1.14 and describe several features that may appear in later versions. .NH 2 New Features in Bash-1.14 .PP The new features available in Bash-1.14 answer several of the most common requests for enhancements. Most notably, there is a mechanism for including non-visible character sequences in prompts, such as those which cause a terminal to print characters in different colors or in standout mode. There was nothing preventing the use of these sequences in earlier versions, but the readline redisplay algorithm assumed each character occupied physical screen space and would wrap lines prematurely. .PP Readline has a few new variables, several new bindable commands, and some additional emacs mode default key bindings. A new history search mode has been implemented: in this mode, readline searches the history for lines beginning with the characters between the beginning of the current line and the cursor. The existing readline incremental search commands no longer match identical lines more than once. Filename completion now expands variables in directory names. The history expansion facilities are now nearly completely csh-compatible: missing modifiers have been added and history substitution has been extended. .PP Several of the features described earlier, such as .B "set -o posix" and .B $POSIX_PEDANTIC , are new in version 1.14. There is a new shell variable, .B OSTYPE , to which Bash assigns a value that identifies the version of \s-1UNIX\s+1 it's running on (great for putting architecture-specific binary directories into the \fB$PATH\fP). Two variables have been renamed: .B $HISTCONTROL replaces .B $history_control , and .B $HOSTFILE replaces .B $hostname_completion_file . In both cases, the old names are accepted for backwards compatibility. The ksh .I select construct, which allows the generation of simple menus, has been implemented. New capabilities have been added to existing variables: .B $auto_resume can now take values of .I exact or .I substring , and .B $HISTCONTROL understands the value .I ignoreboth , which combines the two previously acceptable values. The .B dirs builtin has acquired options to print out specific members of the directory stack. The .B $nolinks variable, which forces a physical view of the file system, has been superseded by the .B \-P option to the .B set builtin (equivalent to \fBset -o physical\fP); the variable is retained for backwards compatibility. The version string contained in .B $BASH_VERSION now includes an indication of the patch level as well as the \*Qbuild version\*U. Some little-used features have been removed: the .B bye synonym for .B exit and the .B $NO_PROMPT_VARS variable are gone. There is now an organized test suite that can be run as a regression test when building a new version of Bash. .PP The documentation has been thoroughly overhauled: there is a new manual page on the readline library and the \fIinfo\fP file has been updated to reflect the current version. As always, as many bugs as possible have been fixed, although some surely remain. .NH 2 Other Features .PP There are a few features that I hope to include in later Bash releases. Some are based on work already done in other shells. .PP In addition to simple variables, a future release of Bash will include one-dimensional arrays, using the ksh implementation of arrays as a model. Additions to the ksh syntax, such as \fIvarname\fP=( ... ) to assign a list of words directly to an array and a mechanism to allow the .B read builtin to read a list of values directly into an array, would be desirable. Given those extensions, the ksh .B "set \-A" syntax may not be worth supporting (the .B \-A option assigns a list of values to an array, but is a rather peculiar special case). .PP Some shells include a means of \fIprogrammable\fP word completion, where the user specifies on a per-command basis how the arguments of the command are to be treated when completion is attempted: as filenames, hostnames, executable files, and so on. The other aspects of the current Bash implementation could remain as-is; the existing heuristics would still be valid. Only when completing the arguments to a simple command would the programmable completion be in effect. .PP It would also be nice to give the user finer-grained control over which commands are saved onto the history list. One proposal is for a variable, tentatively named .B HISTIGNORE , which would contain a colon-separated list of commands. Lines beginning with these commands, after the restrictions of .B $HISTCONTROL have been applied, would not be placed onto the history list. The shell pattern-matching capabilities could also be available when specifying the contents of .B $HISTIGNORE . .PP One thing that newer shells such as .B wksh (also known as .B dtksh ) provide is a command to dynamically load code implementing additional builtin commands into a running shell. This new builtin would take an object file or shared library implementing the \*Qbody\*U of the builtin (\fIxxx_builtin()\fP for those familiar with Bash internals) and a structure containing the name of the new command, the function to call when the new builtin is invoked (presumably defined in the shared object specified as an argument), and the documentation to be printed by the .B help command (possibly present in the shared object as well). It would manage the details of extending the internal table of builtins. .PP A few other builtins would also be desirable: two are the POSIX.2 .B getconf command, which prints the values of system configuration variables defined by POSIX.2, and a .B disown builtin, which causes a shell running with job control active to \*Qforget about\*U one or more background jobs in its internal jobs table. Using .B getconf , for example, a user could retrieve a value for .B $PATH guaranteed to find all of the POSIX standard utilities, or find out how long filenames may be in the file system containing a specified directory. .PP There are no implementation timetables for any of these features, nor are there concrete plans to include them. If anyone has comments on these proposals, feel free to send me electronic mail. .NH 1 Reflections and Lessons Learned .PP The lesson that has been repeated most often during Bash development is that there are dark corners in the Bourne shell, and people use all of them. In the original description of the Bourne shell, quoting and the shell grammar are both poorly specified and incomplete; subsequent descriptions have not helped much. The grammar presented in Bourne's paper describing the shell distributed with the Seventh Edition of \s-1UNIX\s+1\(dg is so far off that it does not allow the command \f(CWwho|wc\fP. In fact, as Tom Duff states: .QP Nobody really knows what the Bourne shell's grammar is. Even examination of the source code is little help.\(dd .FS \(dgS. R. Bourne, \*QUNIX Time-Sharing System: The UNIX Shell\*U, \fIBell System Technical Journal\fP, 57(6), July-August, 1978, pp. 1971-1990. .FE .FS \(ddTom Duff, \*QRc \- A Shell for Plan 9 and \s-1UNIX\s+1 systems\*U, \fIProc. of the Summer 1990 EUUG Conference\fP, London, July, 1990, pp. 21-33. .FE .LP The POSIX.2 standard includes a \fIyacc\fP grammar that comes close to capturing the Bourne shell's behavior, but it disallows some constructs which sh accepts without complaint \- and there are scripts out there that use them. It took a few versions and several bug reports before Bash implemented sh-compatible quoting, and there are still some \*Qlegal\*U sh constructs which Bash flags as syntax errors. Complete sh compatibility is a tough nut. .PP The shell is bigger and slower than I would like, though the current version is substantially faster than previously. The readline library could stand a substantial rewrite. A hand-written parser to replace the current \fIyacc\fP-generated one would probably result in a speedup, and would solve one glaring problem: the shell could parse commands in \*Q$(...)\*U constructs as they are entered, rather than reporting errors when the construct is expanded. .PP As always, there is some chaff to go with the wheat. Areas of duplicated functionality need to be cleaned up. There are several cases where Bash treats a variable specially to enable functionality available another way (\fB$notify\fP vs. \fBset -o notify\fP and \fB$nolinks\fP vs. \fBset -o physical\fP, for instance); the special treatment of the variable name should probably be removed. A few more things could stand removal; the .B $allow_null_glob_expansion and .B $glob_dot_filenames variables are of particularly questionable value. The \fB$[...]\fP arithmetic evaluation syntax is redundant now that the POSIX-mandated \fB$((...))\fP construct has been implemented, and could be deleted. It would be nice if the text output by the .B help builtin were external to the shell rather than compiled into it. The behavior enabled by .B $command_oriented_history , which causes the shell to attempt to save all lines of a multi-line command in a single history entry, should be made the default and the variable removed. .NH 1 Availability .PP As with all other GNU software, Bash is available for anonymous FTP from .I prep.ai.mit.edu:/pub/gnu and from other GNU software mirror sites. The current version is in .I bash-1.14.1.tar.gz in that directory. Use .I archie to find the nearest archive site. The latest version is always available for FTP from .I bash.CWRU.Edu:/pub/dist. Bash documentation is available for FTP from .I bash.CWRU.Edu:/pub/bash. .PP The Free Software Foundation sells tapes and CD-ROMs containing Bash; send electronic mail to \f(CRgnu@prep.ai.mit.edu\fP or call \f(CR+1-617-876-3296\fP for more information. .PP Bash is also distributed with several versions of \s-1UNIX\s+1-compatible systems. It is included as /bin/sh and /bin/bash on several Linux distributions (more about the difference in a moment), and as contributed software in BSDI's BSD/386* and FreeBSD. .FS *BSD/386 is a trademark of Berkeley Software Design, Inc. .FE .PP The Linux distribution deserves special mention. There are two configurations included in the standard Bash distribution: a \*Qnormal\*U configuration, in which all of the standard features are included, and a \*Qminimal\*U configuration, which omits job control, aliases, history and command line editing, the directory stack and .B pushd/popd/dirs, process substitution, prompt string special character decoding, and the .I select construct. This minimal version is designed to be a drop-in replacement for the traditional \s-1UNIX\s+1 /bin/sh, and is included as the Linux /bin/sh in several packagings. .NH 1 Conclusion .PP Bash is a worthy successor to sh. It is sufficiently portable to run on nearly every version of \s-1UNIX\s+1 from 4.3 BSD to SVR4.2, and several \s-1UNIX\s+1 workalikes. It is robust enough to replace sh on most of those systems, and provides more functionality. It has several thousand regular users, and their feedback has helped to make it as good as it is today \- a testament to the benefits of free software. bash-2.05a/doc/htmlpost.sh100755 436 0 2147 6776411027 13727 0ustar chetwheel#! /bin/sh # # Some of these should really be done by man2html # # The ~/xxx links don't really work -- netscape doesn't expand the home # directory of the user running navigator # sed -e 's|gnu.bash.bug|gnu.bash.bug|g' \ -e 's|/bin/bash|/bin/bash|g' \ -e 's|/etc/profile|/etc/profile|g' \ -e 's|~/.bash_profile|~/.bash_profile|g' \ -e 's|~/.bash_login|~/.bash_login|g' \ -e 's|~/.profile|~/.profile|g' \ -e 's|~/.bashrc|~/.bashrc|g' \ -e 's|~/.bash_logout|~/.bash_logout|g' \ -e 's|~/.bash_history|~/.bash_history|g' \ -e 's|~/.inputrc|~/.inputrc|g' \ -e 's|/etc/inputrc|/etc/inputrc|g' bash-2.05a/examples/ 40775 436 0 0 7373775227 12501 5ustar chetwheelbash-2.05a/examples/bashdb/ 40775 436 0 0 7373775245 13724 5ustar chetwheelbash-2.05a/examples/bashdb/PERMISSION100444 436 0 2345 6007453636 15422 0ustar chetwheelFrom mikel@ora.com Tue Aug 1 12:13:20 1995 Flags: 10 Return-Path: mikel@ora.com Received: from ruby.ora.com (ruby.ora.com [198.112.208.25]) by odin.INS.CWRU.Edu with ESMTP (8.6.12+cwru/CWRU-2.1-ins) id MAA01565; Tue, 1 Aug 1995 12:13:18 -0400 (from mikel@ora.com for ) Received: (from fax@localhost) by ruby.ora.com (8.6.12/8.6.11) with UUCP id MAA23251; Tue, 1 Aug 1995 12:07:51 -0400 Received: by los.ora.com (4.1/Spike-2.1) id AA00672; Tue, 1 Aug 95 08:57:32 EDT Date: Tue, 1 Aug 95 08:57:32 EDT From: mikel@ora.com (Michael Loukides) Message-Id: <9508011257.AA00672@los.ora.com> Subject: Re: Ksh debugger from Rosenblatt's book [for bash] To: Chet Ramey Cc: cmarie@ora.com, cam@iinet.com.au, brosenblatt@tm.com In-Reply-To: Chet Ramey , Mon, 31 Jul 1995 16:22:48 -0400 I've modified a (modified) version of Bill Rosenblatt's ksh debugger to work with bash-2.0. Does ORA have any problem with me distributing it with bash-2.0? That's great! Go ahead and circulate it; in fact, we should probably grab it and stick it in our ftp archive, and put a reference to it in the book. (Too late to actually discuss the thing, at least for this edition). ------- bash-2.05a/examples/bashdb/README100664 436 12 441 6007236633 15040 0ustar chetlstaffThis is a modified version of the Korn Shell debugger from Bill Rosenblatt's `Learning the Korn Shell', published by O'Reilly and Associates (ISBN 1-56592-054-6). The original `kshdb' is available for anonymous FTP with the URL ftp://ftp.uu.net/published/oreilly/nutshell/ksh/ksh.tar.Z bash-2.05a/examples/bashdb/bashdb100644 436 0 1404 6267766700 15161 0ustar chetwheel# kshdb - Korn Shell Debugger main file # adapted from 'Learning the Korn Shell' by Bill Rosenblatt (O'Reilly) # by Cigy Cyriac (cigy@felix.tulblr.unisys.com) # Main driver: constructs full script (with preamble) and runs it echo 'Bourne-Again Shell Debugger version 0.1' _pname=${0##*/} [ $# -eq 0 ] && { echo "${_pname}: usage: ${_pname} " exit 1 } _guineapig=$1 [ -r $_guineapig ] || { echo "${_pname}: cannot read $_guineapig." >&2 exit 1 } shift _tmpdir=/tmp _libdir=. _dbgfile=$_tmpdir/bashdb$$ #temp file for script being debugged cat $_libdir/bashdb.pre $_guineapig > $_dbgfile if [ -f "$BASH" ]; then exec $BASH $_dbgfile $_guineapig $_tmpdir $_libdir "$@" else exec bash $_dbgfile $_guineapig $_tmpdir $_libdir "$@" fi # end of bashdb bash-2.05a/examples/bashdb/bashdb.fns100644 436 0 11573 6271450724 15765 0ustar chetwheel# bashdb.fns - Bourne-Again Shell Debugger functions _BUFSIZ=100 # Here after each statement in script being debugged. # Handle single-step and breakpoints. _steptrap() { let _curline=$1-1 # no. of line that just ran let "$_curline < 1" && let _curline=1 let "$_curline > $_firstline+$_BUFSIZ" && _readin $_curline let " $_trace" && _msg "$PS4, line $_curline: ${_lines[$(($_curline-$_firstline+1))]}" # if in step mode, decrement counter let " $_steps >= 0" && let _steps="$_steps - 1" # first check if line num or string brkpt. reached if _at_linenumbp || _at_stringbp; then _msg "Reached breakpoint at line $_curline" _cmdloop # enter debugger # if not, check whether break condition exists and is true elif [ -n "$_brcond" ] && eval $_brcond; then _msg "Break condition $_brcond true at line $_curline" _cmdloop # enter debugger # next, check if step mode and no. of steps is up elif let "$_steps == 0"; then _msg "Stopped at line $_curline" _cmdloop # enter debugger fi } # Debugger command loop. # Here at start of debugger session, when brkpt. reached, or after single-step. _cmdloop() { local cmd args # added support for default command (last one entered) while read -e -p "bashdb> [$lastcmd $lastargs] " cmd args; do if [ -z "$cmd" ]; then cmd=$lastcmd args=$lastargs fi lastcmd="$cmd" lastargs=$args # made commands to be debugger commands by default, no need for '*' prefix case $cmd in bp ) _setbp $args ;; #set brkpt at line num or string bc ) _setbc $args ;; # set break condition cb ) _clearbp ;; # clear all brkpts. g ) return ;; # start/resume execution s ) let _steps=${args:-1} return ;; # single-step N times(default 1) x ) _xtrace ;; # toggle execution trace pr ) _print $args ;; # print lines in file \? | h | help ) _menu ;; # print command menu hi ) history ;; # show command history q ) _cleanup; exit ;; # quit \! ) eval $args ;; # run shell command * ) _msg "Invalid command: $cmd" ; _menu ;; esac done } # see if next line no. is a brkpt. _at_linenumbp() { if [ -z "${_linebp}" ]; then return 1 fi echo "${_curline}" | egrep "(${_linebp%\|})" >/dev/null 2>&1 return $? } # search string brkpts to see if next line in script matches. _at_stringbp() { local l; if [ -z "$_stringbp" ]; then return 1; fi l=${_lines[$_curline-$_firstline+1]} echo "${l}" | egrep "*(${_stringbp%\|})*" >/dev/null 2>&1 return $? } # print message to stderr _msg() { echo -e "$@" >&2 } # set brkpt(s) at given line numbers and/or strings # by appending lines to brkpt file _setbp() { declare -i n case "$1" in "") _listbp ;; [0-9]*) #number, set brkpt at that line n=$1 _linebp="${_linebp}$n|" _msg "Breakpoint at line " $1 ;; *) #string, set brkpt at next line w/string _stringbp="${_stringbp}$@|" _msg "Breakpoint at next line containing $@." ;; esac } # list brkpts and break condition. _listbp() { _msg "Breakpoints at lines:" _msg "${_linebp//\|/ }" _msg "Breakpoints at strings:" _msg "${_stringbp//\|/ }" _msg "Break on condition:" _msg "$_brcond" } # set or clear break condition _setbc() { if [ -n "$@" ] ; then _brcond=$args _msg "Break when true: $_brcond" else _brcond= _msg "Break condition cleared" fi } # clear all brkpts _clearbp() { _linebp= _stringbp= _msg "All breakpoints cleared" } # toggle execution trace feature _xtrace() { let _trace="! $_trace" _msg "Execution trace \c" let " $_trace" && _msg "on." || _msg "off." } # print command menu _menu() { # made commands to be debugger commands by default, no need for '*' prefix _msg 'bashdb commands: bp N set breakpoint at line N bp string set breakpoint at next line containing "string" bp list breakpoints and break condition bc string set break condition to "string" bc clear break condition cb clear all breakpoints g start/resume execution s [N] execute N statements (default 1) x toggle execution trace on/off (default on) pr [start|.] [cnt] print "cnt" lines from line no. "start" ?, h, help print this menu hi show command history q quit ! cmd [args] execute command "cmd" with "args" default: last command (in "[ ]" at the prompt) Readline command line editing (emacs/vi mode) is available' } # erase temp files before exiting _cleanup() { rm $_dbgfile 2>/dev/null } # read $_BUFSIZ lines from $_guineapig into _lines array, starting from line $1 # save number of first line read in _firstline _readin() { declare -i _i=1 let _firstline=$1 SEDCMD="$_firstline,$(($_firstline+$_BUFSIZ))p" sed -n "$SEDCMD" $_guineapig > /tmp/_script.$$ while read -r _lines[$_i]; do _i=_i+1 done < /tmp/_script.$$ rm -f /tmp/_script.$$ 2>/dev/null } _print() { typeset _start _cnt if [ -z "$1" ] || [ "$1" = . ]; then _start=$_curline else _start=$1 fi _cnt=${2:-9} SEDCMD="$_start,$(($_start+$_cnt))p" pr -tn $_guineapig | sed -n "$SEDCMD" } bash-2.05a/examples/bashdb/bashdb.pre100644 436 0 1455 6267770234 15751 0ustar chetwheel# bashdb.pre - Bourne-Again Shell Debugger preamble file # prepended to script being ddebugged #arguments: # $1 = name of original guineapig script # $2 = dir where temp files are stored # $3 = dir where bashdb.pre and bashdb.fns are stored # separate history file for bashdb HISTFILE=~/.bashdb_history set -o history set +H # prompt for trace line PS4="${1}" _dbgfile=$0 _guineapig=$1 _tmpdir=$2 _libdir=$3 shift 3 #move user's args into place . $_libdir/bashdb.fns #read in the debugger functions _linebp= _stringbp= let _trace=1 #init execution trace flag to on #read guineapig file into _lines array _readin 1 trap _cleanup EXIT #erase files before exiting let _steps=1 #no. of statements to run after setting trap #set LINENO, gets incremented to 1 LINENO=0 trap '_steptrap $LINENO' DEBUG : bash-2.05a/examples/complete/ 40775 436 0 0 7373775245 14311 5ustar chetwheelbash-2.05a/examples/complete/complete-examples100664 436 0 25371 7276256530 17776 0ustar chetwheel# # Completion examples # # # This encapsulates the default bash completion code # call with the word to be completed as $1 # # Since programmable completion does not use the bash default completions # or the readline default of filename completion when the compspec does # not generate any matches, this may be used as a `last resort' in a # completion function to mimic the default bash completion behavior. # _bash_def_completion () { local h t COMPREPLY=() # command substitution if [[ "$1" == \$\(* ]]; then t=${1#??} COMPREPLY=( $(compgen -c -P '$(' $t) ) fi # variables with a leading `${' if [ ${#COMPREPLY[@]} -eq 0 ] && [[ "$1" == \$\{* ]]; then t=${1#??} COMPREPLY=( $(compgen -v -P '${' -S '}' $t) ) fi # variables with a leading `$' if [ ${#COMPREPLY[@]} -eq 0 ] && [[ "$1" == \$* ]]; then t=${1#?} COMPREPLY=( $(compgen -v -P '$' $t ) ) fi # username expansion if [ ${#COMPREPLY[@]} -eq 0 ] && [[ "$1" == ~* ]] && [[ "$1" != */* ]]; then t=${1#?} COMPREPLY=( $( compgen -u -P '~' $t ) ) fi # hostname if [ ${#COMPREPLY[@]} -eq 0 ] && [[ "$1" == *@* ]]; then h=${1%%@*} t=${1#*@} COMPREPLY=( $( compgen -A hostname -P "${h}@" $t ) ) fi # glob pattern if [ ${#COMPREPLY[@]} -eq 0 ]; then # sh-style glob pattern if [[ $1 == *[*?[]* ]]; then COMPREPLY=( $( compgen -G "$1" ) ) # ksh-style extended glob pattern - must be complete elif shopt -q extglob && [[ $1 == *[?*+\!@]\(*\)* ]]; then COMPREPLY=( $( compgen -G "$1" ) ) fi fi # final default is filename completion if [ ${#COMPREPLY[@]} -eq 0 ]; then COMPREPLY=( $(compgen -f "$1" ) ) fi } # # Return 1 if $1 appears to contain a redirection operator. Handles backslash # quoting (barely). # _redir_op() { case "$1" in *\\'[\<\>]'*) return 1;; *[\<\>]*) return 0;; *) return 1;; esac } # _redir_test tests the current word ($1) and the previous word ($2) for # redirection operators and does filename completion on the current word # if either one contains a redirection operator _redir_test() { if _redir_op "$1" ; then COMPREPLY=( $( compgen -f "$1" ) ) return 0 elif _redir_op "$2" ; then COMPREPLY=( $( compgen -f "$1" ) ) return 0 fi return 1 } # optional, but without this you can't use extended glob patterns shopt -s extglob # # Easy ones for the shell builtins # # nothing for: alias, break, continue, dirs, echo, eval, exit, getopts, # let, logout, popd, printf, pwd, return, shift, suspend, test, times, # umask # complete -f -- . source complete -A enabled builtin complete -d cd # this isn't exactly right yet -- needs to skip shell functions and # do $PATH lookup (or do compgen -c and filter out matches that also # appear in compgen -A function) complete -c command # could add -S '=', but that currently screws up because readline appends # a space unconditionally complete -v export local readonly complete -A helptopic help # currently same as builtins complete -d pushd complete -A shopt shopt complete -c type complete -a unalias complete -v unset # # Job control builtins: fg, bg, disown, kill, wait # kill not done yet # complete -A stopped -P '%' bg complete -j -P '%' fg jobs disown # this is not quite right at this point _wait_func () { local cur cur=${COMP_WORDS[COMP_CWORD]} case "$cur" in %*) COMPREPLY=( $(compgen -A running -P '%' ${cur#?} ) ) ;; [0-9]*) COMPREPLY=( $(jobs -p | grep ^${cur}) ) ;; *) COMPREPLY=( $(compgen -A running -P '%') $(jobs -p) ) ;; esac } complete -F _wait_func wait # # more complicated things, several as yet unimplemented # #complete -F _bind_func bind _declare_func() { local cur prev nflag opts cur=${COMP_WORDS[COMP_CWORD]} prev=${COMP_WORDS[COMP_CWORD-1]} COMPREPLY=() if (( $COMP_CWORD <= 1 )) || [[ $cur == '-' ]]; then COMPREPLY=(-a -f -F -i -r -x -p) return 0; fi if [[ $cur == '+' ]]; then COMPREPLY=(+i +x) return 0; fi if [[ $prev == '-p' ]]; then COMPREPLY=( $(compgen -v $cur) ) return 0; fi return 1 } complete -F _declare_func declare typeset _enable_func() { local cur prev nflag opts cur=${COMP_WORDS[COMP_CWORD]} prev=${COMP_WORDS[COMP_CWORD-1]} COMPREPLY=() if (( $COMP_CWORD <= 1 )) || [[ $cur == '-' ]]; then COMPREPLY=(-a -d -f -n -p -s) return 0; fi if [[ $prev == '-f' ]]; then COMPREPLY=( $( compgen -f $cur ) ) return 0; fi for opts in "${COMP_WORDS[@]}" ; do if [[ $opts == -*n* ]]; then nflag=1; fi done if [ -z "$nflag" ] ; then COMPREPLY=( $( compgen -A enabled $cur ) ) else COMPREPLY=( $( compgen -A disabled $cur ) ) fi return 0; } complete -F _enable_func enable _exec_func() { local cur prev cur=${COMP_WORDS[COMP_CWORD]} prev=${COMP_WORDS[COMP_CWORD-1]} if (( $COMP_CWORD <= 1 )) || [[ $cur == '-' ]]; then COMPREPLY=(-a -c -l) return 0; fi if [[ $prev != -*a* ]]; then COMPREPLY=( $( compgen -c $cur ) ) return 0 fi return 1; } complete -F _exec_func exec _fc_func() { local cur prev cur=${COMP_WORDS[COMP_CWORD]} prev=${COMP_WORDS[COMP_CWORD-1]} if (( $COMP_CWORD <= 1 )) || [[ $cur == '-' ]]; then COMPREPLY=(-e -n -l -r -s) return 0; fi if [[ $prev == -*e ]]; then COMPREPLY=( $(compgen -c $cur) ) return 0 fi return 1 } complete -F _fc_func fc _hash_func() { local cur prev cur=${COMP_WORDS[COMP_CWORD]} prev=${COMP_WORDS[COMP_CWORD-1]} if (( $COMP_CWORD <= 1 )) || [[ $cur == '-' ]]; then COMPREPLY=(-p -r) return 0; fi if [[ $prev == '-p' ]]; then COMPREPLY=( $( compgen -f $cur ) ) return 0; fi COMPREPLY=( $( compgen -c $cur ) ) return 0 } complete -F _hash_func hash _history_func() { local cur prev cur=${COMP_WORDS[COMP_CWORD]} prev=${COMP_WORDS[COMP_CWORD-1]} COMPREPLY=() if (( $COMP_CWORD <= 1 )) || [[ $cur == '-' ]]; then COMPREPLY=(-a -c -d -n -r -w -p -s) return 0; fi if [[ $prev == -[anrw] ]]; then COMPREPLY=( $( compgen -f $cur ) ) fi return 0 } complete -F _history_func history #complete -F _read_func read _set_func () { local cur prev cur=${COMP_WORDS[COMP_CWORD]} prev=${COMP_WORDS[COMP_CWORD-1]} COMPREPLY=() _redir_test "$cur" "$prev" && return 0; if (( $COMP_CWORD <= 1 )) || [[ $cur == '-' ]]; then COMPREPLY=(-a -b -e -f -k -m -n -o -p -t -u -v -x -B -C -H -P --) return 0; fi if [[ $cur == '+' ]]; then COMPREPLY=(+a +b +e +f +k +m +n +o +p +t +u +v +x +B +C +H +P) return 0; fi if [[ $prev == [+-]o ]]; then COMPREPLY=( $(compgen -A setopt $cur) ) return 0; fi return 1; } complete -F _set_func set _trap_func () { local cur cur=${COMP_WORDS[COMP_CWORD]} if (( $COMP_CWORD <= 1 )) || [[ $cur == '-' ]]; then COMPREPLY=(-l -p) return 0; fi COMPREPLY=( $( compgen -A signal ${cur}) ) return 0 } complete -F _trap_func trap # # meta-completion (completion for complete/compgen) # _complete_meta_func() { local cur prev cmd COMPREPLY=() cmd=$1 cur=${COMP_WORDS[COMP_CWORD]} prev=${COMP_WORDS[COMP_CWORD-1]} _redir_test "$cur" "$prev" && return 0; if (( $COMP_CWORD <= 1 )) || [[ "$cur" == '-' ]]; then case "$cmd" in complete) COMPREPLY=(-a -b -c -d -e -f -j -k -v -u -r -p -A -G -W -P -S -X -F -C);; compgen) COMPREPLY=(-a -b -c -d -e -f -j -k -v -u -A -G -W -P -S -X -F -C);; esac return 0 fi if [[ $prev == -A ]]; then COMPREPLY=(alias arrayvar binding builtin command directory \ disabled enabled export file 'function' helptopic hostname job keyword \ running setopt shopt signal stopped variable) return 0 elif [[ $prev == -F ]]; then COMPREPLY=( $( compgen -A function $cur ) ) elif [[ $prev == -C ]]; then COMPREPLY=( $( compgen -c $cur ) ) else COMPREPLY=( $( compgen -c $cur ) ) fi return 0 } complete -F _complete_meta_func complete compgen # # some completions for shell reserved words # #complete -c -k time do if then else elif '{' # # external commands # complete -e printenv complete -c nohup exec nice eval trace truss strace sotruss gdb _make_targets () { local mdef makef gcmd cur prev i COMPREPLY=() cur=${COMP_WORDS[COMP_CWORD]} prev=${COMP_WORDS[COMP_CWORD-1]} # if prev argument is -f, return possible filename completions. # we could be a little smarter here and return matches against # `makefile Makefile *.mk', whatever exists case "$prev" in -*f) COMPREPLY=( $(compgen -f $cur ) ); return 0;; esac # if we want an option, return the possible posix options case "$cur" in -) COMPREPLY=(-e -f -i -k -n -p -q -r -S -s -t); return 0;; esac # make reads `makefile' before `Makefile' # GNU make reads `GNUmakefile' before all other makefiles, but we # check that we're completing `gmake' before checking for it if [ -f GNUmakefile ] && [ ${COMP_WORDS[0]} == gmake ]; then mdef=GNUmakefile elif [ -f makefile ]; then mdef=makefile elif [ -f Makefile ]; then mdef=Makefile else mdef=*.mk # local convention fi # before we scan for targets, see if a makefile name was specified # with -f for (( i=0; i < ${#COMP_WORDS[@]}; i++ )); do if [[ ${COMP_WORDS[i]} == -*f ]]; then eval makef=${COMP_WORDS[i+1]} # eval for tilde expansion break fi done [ -z "$makef" ] && makef=$mdef # if we have a partial word to complete, restrict completions to # matches of that word if [ -n "$2" ]; then gcmd='grep "^$2"' ; else gcmd=cat ; fi # if we don't want to use *.mk, we can take out the cat and use # test -f $makef and input redirection COMPREPLY=( $(cat $makef 2>/dev/null | awk 'BEGIN {FS=":"} /^[^.# ][^=]*:/ {print $1}' | tr -s ' ' '\012' | sort -u | eval $gcmd ) ) } complete -F _make_targets -X '+($*|*.[cho])' make gmake pmake _umount_func () { COMPREPLY=( $(mount | awk '{print $1}') ) } complete -F _umount_func umount _configure_func () { case "$2" in -*) ;; *) return ;; esac case "$1" in \~*) eval cmd=$1 ;; *) cmd="$1" ;; esac COMPREPLY=( $("$cmd" --help | awk '{if ($1 ~ /--.*/) print $1}' | grep ^"$2" | sort -u) ) } complete -F _configure_func configure complete -W '"${GROUPS[@]}"' newgrp complete -f chown ln more cat complete -d mkdir rmdir complete -f strip complete -f -X '*.gz' gzip complete -f -X '*.bz2' bzip2 complete -f -X '*.Z' compress complete -f -X '!*.+(gz|tgz|Gz)' gunzip gzcat zcat zmore complete -f -X '!*.Z' uncompress zmore zcat complete -f -X '!*.bz2' bunzip2 complete -f -X '!*.zip' unzip complete -f -X '!*.+(gif|jpg|jpeg|GIF|JPG|JPEG|bmp)' xv complete -f -X '!*.pl' perl perl5 complete -A hostname rsh telnet rlogin ftp ping xping host traceroute nslookup complete -A hostname rxterm rxterm3 rxvt2 complete -u su complete -g newgrp groupdel groupmod complete -f -X '!*.+(ps|PS)' gs gv ghostview psselect pswrap complete -f -X '!*.+(dvi|DVI)' dvips xdvi dviselect dvitype catdvi complete -f -X '!*.+(pdf|PDF)' acroread4 complete -f -X '!*.texi*' makeinfo texi2dvi texi2html complete -f -X '!*.+(tex|TEX)' tex latex slitex complete -f -X '!*.+(mp3|MP3)' mpg123 complete -f -X '!*.+(htm|html)' links w3m lynx # # other possibilities, left as exercises # #complete -F _find_func find #complete -F _man_func man #complete -F _stty_func stty bash-2.05a/examples/complete/complete.ianmac100644 436 0 27053 7133343576 17405 0ustar chetwheel##### #To: chet@po.cwru.edu, sarahmckenna@lucent.com #Message-Id: #Posted-To: comp.unix.shell, gnu.bash.bug #Subject: bash 2.04 programmable completion examples #Reply-To: ian@linuxcare.com, ian@caliban.org #Summary: examples of programmable completion for bash 2.04 #Date: Thu, 13 Jul 2000 00:52:33 -0400 (EDT) #From: ianmacd@linuxcare.com (Ian Macdonald) ##### ######################################################################### # Turn on extended globbing shopt -s extglob # A lot of the following one-liners were taken directly from the # completion examples provided with the bash 2.04 source distribution # Make directory commands see only directories complete -d cd mkdir rmdir pushd # Make file commands see only files complete -f cat less more chown ln strip complete -f -X '*.gz' gzip complete -f -X '*.Z' compress complete -f -X '!*.+(Z|gz|tgz|Gz)' gunzip zcat zmore complete -f -X '!*.Z' uncompress zmore zcat complete -f -X '!*.+(gif|jpg|jpeg|GIF|JPG|bmp)' ee xv complete -f -X '!*.+(ps|PS|ps.gz)' gv complete -f -X '!*.+(dvi|DVI)' dvips xdvi dviselect dvitype complete -f -X '!*.+(pdf|PDF)' acroread xpdf complete -f -X '!*.texi*' makeinfo texi2dvi texi2html complete -f -X '!*.+(tex|TEX)' tex latex slitex complete -f -X '!*.+(mp3|MP3)' mpg123 # kill sees only signals complete -A signal kill -P '%' # user commands see only users complete -u finger su usermod userdel passwd # bg completes with stopped jobs complete -A stopped -P '%' bg # other job commands complete -j -P '%' fg jobs disown # network commands complete with hostname complete -A hostname ssh rsh telnet rlogin ftp ping fping host traceroute \ nslookup # export and others complete with shell variables complete -v export local readonly unset # set completes with set options complete -A setopt set # shopt completes with shopt options complete -A shopt shopt # helptopics complete -A helptopic help # unalias completes with aliases complete -a unalias # various commands complete with commands complete -c command type nohup exec nice eval strace gdb # bind completes with readline bindings (make this more intelligent) complete -A binding bind # Now we get to the meat of the file, the functions themselves. Some # of these are works in progress. Most assume GNU versions of the # tools in question and may require modifications for use on vanilla # UNIX systems. # # A couple of functions may have non-portable, Linux specific code in # them, but this will be noted where applicable # GNU chown(1) completion. This should be expanded to allow the use of # ':' as well as '.' as the user.group separator. # _chown () { local cur prev user group COMPREPLY=() cur=${COMP_WORDS[COMP_CWORD]} prev=${COMP_WORDS[COMP_CWORD-1]} # do not attempt completion if we're specifying an option if [ "${cur:0:1}" = "-" ]; then return 0; fi # first parameter on line or first since an option? if [ $COMP_CWORD -eq 1 ] || [ "${prev:0:1}" = "-" ]; then case "$cur" in [a-zA-Z]*.*) user=${cur%.*} group=${cur#*.} COMPREPLY=( $( awk 'BEGIN {FS=":"} \ {if ($1 ~ /^'$group'/) print $1}' \ /etc/group ) ) for (( i=0; i < ${#COMPREPLY[@]}; i++ )); do COMPREPLY[i]=$user.${COMPREPLY[i]} done return 0 ;; *) COMPREPLY=( $( compgen -u $cur -S '.' ) ) return 0 ;; esac else COMPREPLY=( $( compgen -f $cur ) ) fi return 0 } complete -F _chown chown # umount(8) completion. This relies on the mount point being the third # space-delimited field in the output of mount(8) # _umount () { local cur COMPREPLY=() cur=${COMP_WORDS[COMP_CWORD]} # could rewrite the cut | grep to be a sed command, but this is # clearer and doesn't result in much overhead COMPREPLY=( $( mount | cut -d' ' -f 3 | grep ^$cur) ) return 0 } complete -F _umount umount # GID completion. This will get a list of all valid group names from # /etc/group and should work anywhere. # _gid_func () { local cur COMPREPLY=() cur=${COMP_WORDS[COMP_CWORD]} COMPREPLY=( $( awk 'BEGIN {FS=":"} {if ($1 ~ /^'$cur'/) print $1}' \ /etc/group ) ) return 0 } complete -F _gid_func groupdel groupmod # mount(8) completion. This will pull a list of possible mounts out of # /etc/fstab, unless the word being completed contains a ':', which # would indicate the specification of an NFS server. In that case, we # query the server for a list of all available exports and complete on # that instead. # _mount () { local cur COMPREPLY=() cur=${COMP_WORDS[COMP_CWORD]} case "$cur" in *:*) COMPREPLY=( $( /usr/sbin/showmount -e --no-headers ${cur%%:*} |\ grep ^${cur#*:} | awk '{print $1}')) return 0 ;; *) COMPREPLY=( $( awk '{if ($2 ~ /\//) print $2}' /etc/fstab | \ grep ^$cur )) return 0 ;; esac } complete -F _mount mount # Linux rmmod(1) completion. This completes on a list of all currently # installed kernel modules. # _rmmod () { local cur COMPREPLY=() cur=${COMP_WORDS[COMP_CWORD]} COMPREPLY=($( lsmod | awk '{if (NR != 1 && $1 ~ /^'$cur'/) print $1}')) return 0 } complete -F _rmmod rmmod # Linux insmod(1) completion. This completes on a list of all # available modules for the version of the kernel currently running. # _insmod () { local cur modpath COMPREPLY=() cur=${COMP_WORDS[COMP_CWORD]} modpath=/lib/modules/`uname -r` COMPREPLY=($( ls -R $modpath | sed -ne 's/^\('$cur'.*\)\.o$/\1/p')) return 0 } complete -F _insmod insmod depmod modprobe # man(1) completion. This relies on the security enhanced version of # GNU locate(1). UNIX variants having non-numeric man page sections # other than l, m and n should add the appropriate sections to the # first clause of the case statement. # # This is Linux specific, in that 'man
' is the # expected syntax. This allows one to do something like # 'man 3 str' to obtain a list of all string handling syscalls on # the system. # _man () { local cur prev COMPREPLY=() cur=${COMP_WORDS[COMP_CWORD]} prev=${COMP_WORDS[COMP_CWORD-1]} case "$prev" in [0-9lmn]) COMPREPLY=($( slocate -ql 0 -r '/man/man'$prev'/'$cur | \ sed -ne 's/^.*\/\('$cur'[^.\/]*\)\..*$/\1/p' )) return 0 ;; *) COMPREPLY=($( slocate -ql 0 -r '/man/man./'$cur | \ sed -ne 's/^.*\/\('$cur'[^.\/]*\)\..*$/\1/p' )) return 0 ;; esac } complete -F _man man # Linux killall(1) completion. This wouldn't be much use on, say, # Solaris, where killall does exactly that: kills ALL processes. # # This could be improved. For example, it currently doesn't take # command line options into account # _killall () { local cur prev COMPREPLY=() cur=${COMP_WORDS[COMP_CWORD]} prev=${COMP_WORDS[COMP_CWORD-1]} case "$prev" in -[A-Z0-9]*) # get a list of processes (the first sed evaluation # takes care of swapped out processes, the second # takes care of getting the basename of the process) COMPREPLY=( $( ps ahx | awk '{if ($5 ~ /^'$cur'/) print $5}' | \ sed -e 's#[]\[]##g' -e 's#^.*/##' )) return 0 ;; esac # first parameter can be either a signal or a process if [ $COMP_CWORD -eq 1 ]; then # standard signal completion is rather braindead, so we need # to hack around to get what we want here, which is to # complete on a dash, followed by the signal name minus # the SIG prefix COMPREPLY=( $( compgen -A signal SIG${cur#-} )) for (( i=0; i < ${#COMPREPLY[@]}; i++ )); do COMPREPLY[i]=-${COMPREPLY[i]#SIG} done fi # get processes, adding to signals if applicable COMPREPLY=( ${COMPREPLY[*]} $( ps ahx | \ awk '{if ($5 ~ /^'$cur'/) print $5}' | \ sed -e 's#[]\[]##g' -e 's#^.*/##' )) return 0 } complete -F _killall killall # GNU find(1) completion. This makes heavy use of ksh style extended # globs and contains Linux specific code for completing the parameter # to the -fstype option. # _find () { local cur prev COMPREPLY=() cur=${COMP_WORDS[COMP_CWORD]#-} prev=${COMP_WORDS[COMP_CWORD-1]} case "$prev" in -@(max|min)depth) COMPREPLY=( $( compgen -W '0 1 2 3 4 5 6 7 8 9' ) ) return 0 ;; -?(a)newer|-fls|-fprint?(0|f)) COMPREPLY=( $( compgen -f $cur ) ) return 0 ;; -fstype) # this is highly non-portable (the option to -d is a tab) COMPREPLY=( $( cut -d' ' -f 2 /proc/filesystems | grep ^$cur ) ) return 0 ;; -gid) COMPREPLY=( $( awk 'BEGIN {FS=":"} \ {if ($3 ~ /^'$cur'/) print $3}' /etc/group ) ) return 0 ;; -group) COMPREPLY=( $( awk 'BEGIN {FS=":"} \ {if ($1 ~ /^'$cur'/) print $1}' /etc/group ) ) return 0 ;; -?(x)type) COMPREPLY=( $( compgen -W 'b c d p f l s' $cur ) ) return 0 ;; -uid) COMPREPLY=( $( awk 'BEGIN {FS=":"} \ {if ($3 ~ /^'$cur'/) print $3}' /etc/passwd ) ) return 0 ;; -user) COMPREPLY=( $( compgen -u $cur ) ) return 0 ;; -[acm]min|-[acm]time|-?(i)?(l)name|-inum|-?(i)path|-?(i)regex| \ -links|-perm|-size|-used|-exec|-ok|-printf) # do nothing, just wait for a parameter to be given return 0 ;; esac # complete using basic options ($cur has had its dash removed here, # as otherwise compgen will bomb out with an error, since it thinks # the dash is an option to itself) COMPREPLY=( $( compgen -W 'daystart depth follow help maxdepth \ mindepth mount noleaf version xdev amin anewer atime \ cmin cnewer ctime empty false fstype gid group ilname \ iname inum ipath iregex links lname mmin mtime name \ newer nouser nogroup perm regex size true type uid \ used user xtype exec fls fprint fprint0 fprintf ok \ print print0 printf prune ls' $cur ) ) # this removes any options from the list of completions that have # already been specified somewhere on the command line. COMPREPLY=( $( echo "${COMP_WORDS[@]}-" | \ (while read -d '-' i; do [ "$i" == "" ] && continue # flatten array with spaces on either side, # otherwise we cannot grep on word boundaries of # first and last word COMPREPLY=" ${COMPREPLY[@]} " # remove word from list of completions COMPREPLY=( ${COMPREPLY/ ${i%% *} / } ) done echo ${COMPREPLY[@]}) ) ) # put dashes back for (( i=0; i < ${#COMPREPLY[@]}; i++ )); do COMPREPLY[i]=-${COMPREPLY[i]} done return 0 } complete -F _find find # Linux ifconfig(8) completion # _ifconfig () { local cur COMPREPLY=() cur=${COMP_WORDS[COMP_CWORD]} case "${COMP_WORDS[1]}" in -|*[0-9]*) COMPREPLY=( $( compgen -W '-a up down arp promisc allmulti \ metric mtu dstaddr netmask add del \ tunnel irq io_addr mem_start media \ broadcast pointopoint hw multicast \ address txqueuelen' $cur )) COMPREPLY=( $( echo " ${COMP_WORDS[@]}" | \ (while read -d ' ' i; do [ "$i" == "" ] && continue # flatten array with spaces on either side, # otherwise we cannot grep on word # boundaries of first and last word COMPREPLY=" ${COMPREPLY[@]} " # remove word from list of completions COMPREPLY=( ${COMPREPLY/ $i / } ) done echo ${COMPREPLY[@]}) ) ) return 0 ;; esac COMPREPLY=( $( ifconfig -a | sed -ne 's/^\('$cur'[^ ]*\).*$/\1/p' )) } complete -F _ifconfig ifconfig # Linux ipsec(8) completion (for FreeS/WAN). Very basic. # _ipsec () { local cur COMPREPLY=() cur=${COMP_WORDS[COMP_CWORD]} COMPREPLY=( $( compgen -W 'auto barf eroute klipsdebug look manual \ pluto ranbits rsasigkey setup showdefaults \ showhostkey spi spigrp tncfg whack' $cur )) } complete -F _ipsec ipsec ######################################################################### bash-2.05a/examples/complete/complete2.ianmac100664 436 0 15320 7145773733 17470 0ustar chetwheel##### #From: ian@linuxcare.com (Ian Macdonald) #Newsgroups: comp.unix.shell #Subject: More bash 2.04 completions #Date: 12 Aug 2000 09:53:40 GMT #Organization: Linuxcare, Inc. #Lines: 274 #Message-ID: #Reply-To: ian@linuxcare.com ##### # Turn on extended globbing shopt -s extglob # cvs(1) completion # _cvs () { local cur prev COMPREPLY=() cur=${COMP_WORDS[COMP_CWORD]} prev=${COMP_WORDS[COMP_CWORD-1]} if [ $COMP_CWORD -eq 1 ] || [ "${prev:0:1}" = "-" ]; then COMPREPLY=( $( compgen -W 'add admin checkout commit diff \ export history import log rdiff release remove rtag status \ tag update' $cur )) else COMPREPLY=( $( compgen -f $cur )) fi return 0 } complete -F _cvs cvs # rpm(8) completion. This isn't exhaustive yet, but still provides # quite a lot of functionality. # _rpm() { dashify() { local i for (( i=0; i < ${#COMPREPLY[@]}; i++ )); do if [ ${#COMPREPLY[i]} -le 2 ]; then COMPREPLY[i]=-${COMPREPLY[i]} else COMPREPLY[i]=--${COMPREPLY[i]} fi done } local cur cur_nodash prev COMPREPLY=() cur=${COMP_WORDS[COMP_CWORD]} cur_nodash=${cur#-} prev=${COMP_WORDS[COMP_CWORD-1]} if [ $COMP_CWORD = 1 ]; then # first parameter on line case "$cur" in -b*) COMPREPLY=( $( compgen -W 'ba bb bc bi bl bp bs' \ $cur_nodash ) ) dashify return 0 ;; -t*) COMPREPLY=( $( compgen -W 'ta tb tc ti tl tp ts' \ $cur_nodash ) ) dashify return 0 ;; --*) COMPREPLY=( $( compgen -W 'help version initdb \ checksig recompile rebuild resign addsign rebuilddb \ showrc setperms setgids' ${cur_nodash#-} ) ) dashify; return 0 ;; *) COMPREPLY=( $( compgen -W 'b e F i q t U V' \ $cur_nodash ) ) dashify return 0 ;; esac fi case "${COMP_WORDS[1]}" in -[iFU]*) # complete on list of relevant options COMPREPLY=( $( compgen -W 'percent force test replacepkgs \ replacefiles root excludedocs includedocs noscripts rcfile \ ignorearch dbpath prefix ignoreos nodeps allfiles ftpproxy \ ftpport justdb httpproxy httpport noorder relocate badreloc \ notriggers excludepath ignoresize oldpackage' ${cur_nodash#-} )) dashify; # return if $cur is an option [ "${cur:0:1}" = "-" ] && return 0 # add a list of RPMS to possible completions COMPREPLY=( ${COMPREPLY[@]} $( compgen -G $cur\*.rpm ) ) return 0 ;; -qp*) # complete on list of relevant options COMPREPLY=( $( compgen -W 'scripts root rcfile whatprovides \ whatrequires requires triggeredby ftpport ftpproxy httpproxy \ httpport provides triggers dump changelog dbpath filesbypkg' \ ${cur_nodash#-} ) ) dashify; # return if $cur is an option [ "${cur:0:1}" = "-" ] && return 0 # add a list of RPMS to possible completions COMPREPLY=( ${COMPREPLY[@]} $( compgen -G $cur\*.rpm ) ) return 0 ;; -*f) # standard filename completion COMPREPLY=( $( compgen -f $cur ) ) return 0 ;; -e) # complete on list of relevant options COMPREPLY=( $( compgen -W 'allmatches noscripts notriggers \ nodeps test' ${cur_nodash#-} ) ) dashify; # return if $cur is an option [ "${cur:0:1}" = "-" ] && return 0 # complete on basename of installed RPMs COMPREPLY=( $( rpm -qa | \ sed -ne 's/^\('$cur'.*\)-[0-9a-zA-Z._]\+-[0-9.]\+$/\1/p' ) ) return 0 ;; -qa*) # complete on list of relevant options COMPREPLY=( $( compgen -W 'scripts root rcfile whatprovides \ whatrequires requires triggeredby ftpport ftpproxy httpproxy \ httpport provides triggers dump changelog dbpath specfile \ querybynumber last filesbypkg' ${cur_nodash#-} ) ) dashify; return 0 ;; -q*) # complete on list of relevant options COMPREPLY=( $( compgen -W 'scripts root rcfile whatprovides \ whatrequires requires triggeredby ftpport ftpproxy httpproxy \ httpport provides triggers dump changelog dbpath specfile \ querybynumber last filesbypkg' ${cur_nodash#-} ) ) dashify; # return if $cur is an option [ "${cur:0:1}" = "-" ] && return 0 # add a list of RPMS to possible completions COMPREPLY=( ${COMPREPLY[@]} $( rpm -qa | \ sed -ne 's/^\('$cur'.*\)-[0-9a-zA-Z._]\+-[0-9.]\+$/\1/p' ) ) return 0 ;; -[Vy]*) # complete on list of relevant options COMPREPLY=( $( compgen -W 'root rcfile dbpath nodeps nofiles \ noscripts nomd5 nopgp' ${cur_nodash#-} ) ) dashify; # return if $cur is an option [ "${cur:0:1}" = "-" ] && return 0 # add a list of RPMS to possible completions COMPREPLY=( ${COMPREPLY[@]} $( rpm -qa | \ sed -ne 's/^\('$cur'.*\)-[0-9a-zA-Z._]\+-[0-9.]\+$/\1/p' ) ) return 0 ;; -b*) # complete on list of relevant options COMPREPLY=( $( compgen -W 'short-circuit timecheck clean \ rmsource test sign buildroot target buildarch buildos' \ ${cur_nodash#-} ) ) dashify; # return if $cur is an option [ "${cur:0:1}" = "-" ] && return 0 # complete on .spec files COMPREPLY=( $( compgen -G $cur\*.spec ) ) return 0 ;; -t*) # complete on list of relevant options COMPREPLY=( $( compgen -W 'short-circuit timecheck clean \ rmsource test sign buildroot target buildarch buildos' \ ${cur_nodash#-} ) ) dashify; # return if $cur is an option [ "${cur:0:1}" = "-" ] && return 0 # complete on .tar.gz files COMPREPLY=( $( compgen -G $cur\*.tar.gz ) ) return 0 ;; --re@(build|compile)) # complete on source RPMs COMPREPLY=( $( compgen -G $cur\*.src.rpm ) ) return 0 ;; --@(checksig|@(re|add)sign)) # complete on RPMs COMPREPLY=( $( compgen -G $cur\*.rpm ) ) return 0 ;; --set@(perms|gids)) # complete on installed RPMs COMPREPLY=( ${COMPREPLY[@]} $( rpm -qa | \ sed -ne 's/^\('$cur'.*\)-[0-9a-zA-Z._]\+-[0-9.]\+$/\1/p' ) ) return 0 ;; esac } complete -F _rpm rpm # chsh(1) completion # _chsh() { local cur prev COMPREPLY=() cur=${COMP_WORDS[COMP_CWORD]} prev=${COMP_WORDS[COMP_CWORD-1]} if [ "$prev" = "-s" ]; then COMPREPLY=( $( chsh -l | grep ^$cur ) ) else COMPREPLY=( $( compgen -u $cur ) ) fi } complete -F _chsh chsh # chkconfig(8) completion # _chkconfig() { local cur prev COMPREPLY=() cur=${COMP_WORDS[COMP_CWORD]} cur_nodash=${cur#--} prev=${COMP_WORDS[COMP_CWORD-1]} if [ $COMP_CWORD -eq 1 ]; then COMPREPLY=( $( compgen -W 'list add del level' $cur_nodash ) ) for (( i=0; i < ${#COMPREPLY[@]}; i++ )); do COMPREPLY[i]=--${COMPREPLY[i]} done return 0 fi if [ $COMP_CWORD -eq 4 ]; then COMPREPLY=( $( compgen -W 'on off reset' $cur ) ) return 0 fi case "$prev" in @([1-6]|--@(list|add|del))) COMPREPLY=( $( compgen -W "`(cd /etc/rc.d/init.d; echo *)`" \ $cur) ) return 0 ;; --level) COMPREPLY=( $( compgen -W '1 2 3 4 5 6' $cur ) ) return 0 ;; esac } complete -F _chkconfig chkconfig ### bash-2.05a/examples/complete/complete.freebsd100644 436 0 1733 7237620117 17536 0ustar chetwheel#Date: Wed, 31 Jan 2001 12:53:56 -0800 #From: Aaron Smith #To: freebsd-ports@freebsd.org #Subject: useful bash completion function for pkg commands #Message-ID: <20010131125356.G52003@gelatinous.com> #hi all. i just wanted to share this bash completion function i wrote that #completes package names for pkg_info and pkg_delete. i find this a great #help when dealing with port management. programmed completion requires #bash-2.04. _pkg_func () { local cur cur=${COMP_WORDS[COMP_CWORD]} if [[ $cur == '-' ]]; then if [[ ${COMP_WORDS[0]} == 'pkg_info' ]]; then COMPREPLY=(-a -c -d -D -i -k -r -R -p -L -q -I -m -v -e -l) return 0; elif [[ ${COMP_WORDS[0]} == 'pkg_delete' ]]; then COMPREPLY=(-v -D -d -n -f -p) return 0; fi fi COMPREPLY=( $(compgen -d /var/db/pkg/$cur | sed sN/var/db/pkg/NNg) ) return 0 } complete -F _pkg_func pkg_delete pkg_info bash-2.05a/examples/complete/complete.gnu-longopt100600 436 0 2521 7305250147 20357 0ustar chetwheel# # Originally from: # #Message-ID: <3B13EC65.179451AE@wanadoo.fr> #Date: Tue, 29 May 2001 20:37:25 +0200 #From: Manu Rouat #Subject: [bash] Universal command options completion? # # #In the recent versions of bash (after 2.04) programmable #completion is available. A useful completion function #is , for a particular command, to enumerate all flags #that can be used in the command. Now, most GNU unix #commands have so-called 'long options' for example: # #ls --color=always --no-group --size # #and these are all listed when you issue a '--help' flag. #So the idea is to use that, then parse the output of the #'--help' and reinject this to compgen. The basis of the #following 'universal' completion funtion was the _configure_func' #written by Ian McDonnald (or is it Chet Ramey ?) #A dedicated function will always be better, but this is quite #convenient. I chose to use 'long options' because they are #easy to parse and explicit too (it's the point I guess...) #Lots of room for improvement ! _longopt_func () { case "$2" in -*) ;; *) return ;; esac case "$1" in \~*) eval cmd=$1 ;; *) cmd="$1" ;; esac COMPREPLY=( $("$cmd" --help | sed -e '/--/!d' -e 's/.*--\([^ ]*\).*/--\1/'| \ grep ^"$2" |sort -u) ) } complete -o default -F _longopt_func ldd wget bash id info # some examples that work bash-2.05a/examples/functions/ 40775 436 0 0 7373775250 14505 5ustar chetwheelbash-2.05a/examples/functions/array-stuff100644 436 0 3256 7011571725 16762 0ustar chetwheel# usage: reverse arrayname reverse() { local -a R local -i i local rlen temp # make r a copy of the array whose name is passed as an arg eval R=\( \"\$\{$1\[@\]\}\" \) # reverse R rlen=${#R[@]} for ((i=0; i < rlen/2; i++ )) do temp=${R[i]} R[i]=${R[rlen-i-1]} R[rlen-i-1]=$temp done # and assign R back to array whose name is passed as an arg eval $1=\( \"\$\{R\[@\]\}\" \) } A=(1 2 3 4 5 6 7) echo "${A[@]}" reverse A echo "${A[@]}" reverse A echo "${A[@]}" # unset last element of A alen=${#A[@]} unset A[$alen-1] echo "${A[@]}" # ashift -- like shift, but for arrays ashift() { local -a R local n case $# in 1) n=1 ;; 2) n=$2 ;; *) echo "$FUNCNAME: usage: $FUNCNAME array [count]" >&2 exit 2;; esac # make r a copy of the array whose name is passed as an arg eval R=\( \"\$\{$1\[@\]\}\" \) # shift R R=( "${R[@]:$n}" ) # and assign R back to array whose name is passed as an arg eval $1=\( \"\$\{R\[@\]\}\" \) } ashift A 2 echo "${A[@]}" ashift A echo "${A[@]}" ashift A 7 echo "${A[@]}" # Sort the members of the array whose name is passed as the first non-option # arg. If -u is the first arg, remove duplicate array members. array_sort() { local -a R local u case "$1" in -u) u=-u ; shift ;; esac if [ $# -eq 0 ]; then echo "array_sort: argument expected" >&2 return 1 fi # make r a copy of the array whose name is passed as an arg eval R=\( \"\$\{$1\[@\]\}\" \) # sort R R=( $( printf "%s\n" "${A[@]}" | sort $u) ) # and assign R back to array whose name is passed as an arg eval $1=\( \"\$\{R\[@\]\}\" \) return 0 } A=(3 1 4 1 5 9 2 6 5 3 2) array_sort A echo "${A[@]}" A=(3 1 4 1 5 9 2 6 5 3 2) array_sort -u A echo "${A[@]}" bash-2.05a/examples/functions/array-to-string100664 436 0 524 7206524460 17536 0ustar chetwheel#! /bin/bash # Format: array_to_string vname_of_array vname_of_string separator array_to_string() { (( ($# < 2) || ($# > 3) )) && { "$FUNCNAME: usage: $FUNCNAME arrayname stringname [separator]" return 2 } local array=$1 string=$2 ((3==$#)) && [[ $3 = ? ]] && local IFS="${3}${IFS}" eval $string="\"\${$array[*]}\"" return 0 } bash-2.05a/examples/functions/autoload100644 436 0 5423 7361047547 16335 0ustar chetwheel# # An almost ksh-compatible `autoload'. A function declared as `autoload' will # be read in from a file the same name as the function found by searching the # $FPATH (which works the same as $PATH), then that definition will be run. # # To do this without source support, we define a dummy function that, when # executed, will load the file (thereby re-defining the function), then # execute that newly-redefined function with the original arguments. # # It's not identical to ksh because ksh apparently does lazy evaluation # and looks for the file to load from only when the function is referenced. # This one requires that the file exist when the function is declared as # `autoload'. # # usage: autoload func [func...] # # The first cut of this was by Bill Trost, trost@reed.bitnet # # Chet Ramey # chet@ins.CWRU.Edu # # Declare a function ($1) to be autoloaded from a file ($2) when it is first # called. This defines a `temporary' function that will `.' the file # containg the real function definition, then execute that new definition with # the arguments given to this `fake' function. The autoload function defined # by the file and the file itself *must* be named identically. # aload() { eval $1 '() { . '$2' ; '$1' "$@" ; return $? ; }' } # # Search $FPATH for a file the same name as the function given as $1, and # autoload the function from that file. There is no default $FPATH. # autoload() { # # Save the list of functions; we're going to blow away the arguments # in a second. If any of the names contain white space, TFB. # local args="$*" # # This should, I think, list the functions marked as autoload and not # yet defined, but we don't have enough information to do that here. # if [ $# -eq 0 ] ; then echo "usage: autoload function [function...]" >&2 return 1 fi # # If there is no $FPATH, there is no work to be done # if [ -z "$FPATH" ] ; then echo autoload: FPATH not set or null >&2 return 1 fi # # This treats FPATH exactly like PATH: a null field anywhere in the # FPATH is treated the same as the current directory. # # The path splitting command is taken from Kernighan and Pike # # fp=$(echo $FPATH | sed 's/^:/.:/ # s/::/:.:/g # s/:$/:./ # s/:/ /g') # replaced with builtin mechanisms 2001 Oct 10 fp=${FPATH/#:/.:} fp=${fp//::/:.:} fp=${fp/%:/:.} fp=${fp//:/ } for FUNC in $args ; do # # We're blowing away the arguments to autoload here... # We have to; there are no arrays (well, there are, but # this doesn't use them yet). # set -- $fp while [ $# -ne 0 ] ; do if [ -f $1/$FUNC ] ; then break # found it! fi shift done if [ $# -eq 0 ] ; then echo "$FUNC: autoload function not found" >&2 continue fi # echo auto-loading $FUNC from $1/$FUNC aload $FUNC $1/$FUNC done return 0 } bash-2.05a/examples/functions/autoload.v2100644 436 0 7672 7361047217 16665 0ustar chetwheel# # An almost ksh-compatible `autoload'. A function declared as `autoload' will # be read in from a file the same name as the function found by searching the # $FPATH (which works the same as $PATH), then that definition will be run. # # To do this without source support, we define a dummy function that, when # executed, will load the file (thereby re-defining the function), then # execute that newly-redefined function with the original arguments. # # It's not identical to ksh because ksh apparently does lazy evaluation # and looks for the file to load from only when the function is referenced. # This one requires that the file exist when the function is declared as # `autoload'. # # usage: autoload [-pu] [func ...] # # options: # -p print in a format that can be reused as input # -u unset each function and remove it from the autoload list # # The first cut of this was by Bill Trost, trost@reed.edu # # Chet Ramey # chet@ins.CWRU.Edu unset _AUTOLOADS _aindex=0 # # Declare a function ($1) to be autoloaded from a file ($2) when it is first # called. This defines a `temporary' function that will `.' the file # containg the real function definition, then execute that new definition with # the arguments given to this `fake' function. The autoload function defined # by the file and the file itself *must* be named identically. # _aload() { eval $1 '() { . '$2' ; '$1' "$@" ; return $? ; }' _autoload_addlist "$1" } _autoload_addlist() { local i=0 while (( i < $_aindex )); do case "${_AUTOLOADS[i]}" in "$1") return 1 ;; esac (( i += 1 )) done _AUTOLOADS[_aindex]="$1" (( _aindex += 1 )) return 0 } _autoload_dump() { local func for func in ${_AUTOLOADS[@]}; do [ -n "$1" ] && echo -n "autoload " echo "$func" done } # Remove $1 from the list of autoloaded functions _autoload_remove_one() { local i=0 nnl=0 local -a nlist while (( i < _aindex )); do case "${_AUTOLOADS[i]}" in "$1") ;; *) nlist[nnl]="${_AUTOLOADS[i]}" ; (( nnl += 1 ));; esac (( i += 1 )) done unset _AUTOLOADS _aindex eval _AUTOLOADS=( ${nlist[@]} ) _aindex=$nnl } # Remove all function arguments from the list of autoloaded functions _autoload_remove() { local func i es=0 # first unset the autoloaded functions for func; do i=0 while (( i < _aindex )); do case "${_AUTOLOADS[i]}" in "$func") unset -f $func ; break ;; esac (( i += 1 )) done if (( i == _aindex )); then echo "autoload: $func: not an autoloaded function" >&2 es=1 fi done # then rebuild the list of autoloaded functions for func ; do _autoload_remove_one "$func" done return $es } # # Search $FPATH for a file the same name as the function given as $1, and # autoload the function from that file. There is no default $FPATH. # autoload() { local -a fp local _autoload_unset nfp i if (( $# == 0 )) ; then _autoload_dump return 0 fi OPTIND=1 while getopts pu opt do case "$opt" in p) _autoload_dump printable; return 0;; u) _autoload_unset=y ;; *) echo "autoload: usage: autoload [-pu] [function ...]" >&2 return 1 ;; esac done shift $(( $OPTIND - 1 )) if [ -n "$_autoload_unset" ]; then _autoload_remove "$@" return $? fi # # If there is no $FPATH, there is no work to be done # if [ -z "$FPATH" ] ; then echo "autoload: FPATH not set or null" >&2 return 1 fi # # This treats FPATH exactly like PATH: a null field anywhere in the # FPATH is treated the same as the current directory. # # This turns $FPATH into an array, substituting `.' for `' # eval fp=( $( IFS=':' set -- ${FPATH} for p in "$@" ; do echo -n "${p:-.} "; done ) ) nfp=${#fp[@]} for FUNC ; do i=0; while (( i < nfp )) ; do if [ -f ${fp[i]}/$FUNC ] ; then break # found it! fi (( i += 1 )) done if (( i == nfp )) ; then echo "autoload: $FUNC: autoload function not found" >&2 es=1 continue fi # echo auto-loading $FUNC from ${fp[i]}/$FUNC _aload $FUNC ${fp[i]}/$FUNC es=0 done return $es } bash-2.05a/examples/functions/autoload.v3100644 436 0 5046 6570557160 16663 0ustar chetwheel#From: Mark Kennedy #Message-ID: <35E2B899.63A02DF5@ny.ubs.com> #Date: Tue, 25 Aug 1998 09:14:01 -0400 #To: chet@nike.ins.cwru.edu #Subject: a newer version of the ksh-style 'autoload' #enclosed you'll find 'autoload.v3', a version of the autoloader #that emulates the ksh semantics of delaying the resolution (and loading) of the function #until its first use. i took the liberty of simplifying the code a bit although it still uses the #same functional breakdown. i recently went through the exercise of converting #my ksh-based environment to bash (a very, very pleasant experience) #and this popped out. # the psuedo-ksh autoloader. # The first cut of this was by Bill Trost, trost@reed.bitnet. # The second cut came from Chet Ramey, chet@ins.CWRU.Edu # The third cut came from Mark Kennedy, mtk@ny.ubs.com. 1998/08/25 unset _AUTOLOADS _aload() { local func for func; do eval $func '() { local f=$(_autoload_resolve '$func') if [[ $f ]]; then . $f '$func' "$@" return $? else return 1 fi }' _autoload_addlist $func done } _autoload_addlist() { local func for func in ${_AUTOLOADS[@]}; do [[ $func = "$1" ]] && return done _AUTOLOADS[${#_AUTOLOADS[@]}]=$1 } _autoload_dump() { local func for func in ${_AUTOLOADS[@]}; do [[ $1 ]] && echo -n "autoload " echo $func done } _autoload_remove_one() { local func local -a NEW_AUTOLOADS for func in ${_AUTOLOADS[@]}; do [[ $func != "$1" ]] && NEW_AUTOLOADS[${#NEW_AUTOLOADS[@]}]=$func done _AUTOLOADS=( ${NEW_AUTOLOADS[@]} ) } _autoload_remove() { local victim func for victim; do for func in ${_AUTOLOADS[@]}; do [[ $victim = "$func" ]] && unset -f $func && continue 2 done echo "autoload: $func: not an autoloaded function" >&2 done for func; do _autoload_remove_one $func done } _autoload_resolve() { if [[ ! "$FPATH" ]]; then echo "autoload: FPATH not set or null" >&2 return fi local p for p in $( (IFS=':'; set -- ${FPATH}; echo "$@") ); do p=${p:-.} if [ -f $p/$1 ]; then echo $p/$1; return; fi done echo "autoload: $1: function source file not found" >&2 } autoload() { if (( $# == 0 )) ; then _autoload_dump; return; fi local opt OPTIND while getopts pu opt do case $opt in p) _autoload_dump printable; return;; u) shift $((OPTIND-1)); _autoload_remove "$@"; return;; *) echo "autoload: usage: autoload [-pu] [function ...]" >&2; return;; esac done shift $(($OPTIND-1)) _aload "$@" } bash-2.05a/examples/functions/basename100644 436 0 1205 5127706336 16266 0ustar chetwheel# Date: Fri, 11 Oct 91 11:22:36 edt # From: friedman@gnu.ai.mit.edu # To: bfox@gnu.ai.mit.edu # A replacement for basename(1). Not all the systems I use have this # program. Usage: basename [path] {extension} function basename () { local path="$1" local suffix="$2" local tpath="${path%/}" # Strip trailing '/' characters from path (unusual that this should # ever occur, but basename(1) seems to deal with it.) while [ "${tpath}" != "${path}" ]; do tpath="${path}" path="${tpath%/}" done path="${path##*/}" # Strip off pathname echo ${path%${suffix}} # Also strip off extension, if any. } bash-2.05a/examples/functions/basename2100644 436 0 1372 6466673002 16355 0ustar chetwheel#From: "Grigoriy Strokin" #Newsgroups: comp.unix.shell #Subject: fast basename and dirname functions for BASH/SH #Date: Sat, 27 Dec 1997 21:18:40 +0300 # #Please send your comments to grg@philol.msu.ru function basename() { local name="${1##*/}" echo "${name%$2}" } function dirname() { local dir="${1%${1##*/}}" [ "${dir:=./}" != "/" ] && dir="${dir%?}" echo "$dir" } # Two additional functions: # 1) namename prints the basename without extension # 2) ext prints extension of a file, including "." function namename() { local name=${1##*/} local name0="${name%.*}" echo "${name0:-$name}" } function ext() { local name=${1##*/} local name0="${name%.*}" local ext=${name0:+${name#$name0}} echo "${ext:-.}" } bash-2.05a/examples/functions/coproc.bash100664 436 0 3300 7353675112 16714 0ustar chetwheel# coprocess.bash # # vi:set sts=2 sw=2 ai: # coprocess_pid= # # coprocess - Start, control, and end coprocesses. # function coprocess () { while (( $# > 0 )) ; do case "$1" in # # coprocess close # c|cl|clo|clos|close) shift exec 61>&- 62<&- coprocess_pid= if [ "$1" = "-SIGPIPE" ] ; then # Only print message in an interactive shell case "$-" in *i*) echo 'SIGPIPE' >&2 ;; esac return 1 fi return 0 ;; # # coprocess open # o|op|ope|open) shift local fifo="/var/tmp/coprocess.$$.$RANDOM" local cmd="/bin/bash" if (( $# > 0 )) ; then cmd="$@" fi mkfifo "$fifo.in" || return $? mkfifo "$fifo.out" || { ret=$? rm -f "$fifo.in" return $? } ( "$@" <$fifo.in >$fifo.out ; rm -f "$fifo.in" "$fifo.out" ) & coprocess_pid=$! exec 61>$fifo.in 62<$fifo.out return 0 ;; # # coprocess print - write to the coprocess # p|pr|pri|prin|print) shift local old_trap=$(trap -p SIGPIPE) trap 'coprocess close -SIGPIPE' SIGPIPE if [ $# -eq 1 -a "$1" = "--stdin" ] ; then cat >&61 else echo "$@" >&61 fi local ret=$? eval "$old_trap" return $ret ;; # # coprocess read - read from the coprocess # r|re|rea|read) shift local old_trap=$(trap -p SIGPIPE) trap '_coprocess_close -SIGPIPE' SIGPIPE builtin read "$@" <&62 local ret=$? eval "$old_trap" return $ret ;; s|st|sta|stat|statu|status) if [ -z "$coprocess_pid" ] ; then echo 'no active coprocess' return 1 else echo " coprocess is active [$coprocess_pid]" return 0 fi ;; *) coprocess print "$@" return $? ;; esac shift done coprocess status return $? } bash-2.05a/examples/functions/coshell.README100644 436 0 3040 7353675421 17102 0ustar chetwheelDate: Fri, 21 Sep 2001 14:50:29 -0400 From: "Jason M. Felice" To: bash-maintainers@gnu.org, chet@po.cwru.edu Subject: Bash co-processes functions Message-ID: <20010921145029.A6093@argo.eraserhead.net> Mime-Version: 1.0 Attached to this message you will find coprocess.bash and coshell.bash. Here's a brief synopsis of use: coprocess open telnet localhost while coprocess read il ; do echo "$il" case "$il" in *ogin:*) coprocess print 'user' ;; *ord:*) echo 'pass' |coprocess print --stdin ;; *$ *) coprocess print 'exit' break ;; esac done coprocess close And here's an example of the coshell function: coshell open ssh -l root otherbox coshell eval hostname coshell ls -l if coshell test -d /tmp ; then echo 'otherbox has a /tmp!' ; fi coshell sendfile /var/lib/upgrade.rpm /tmp/test.rpm || exit $? coshell eval rpm -ivh /tmp/test.rpm || exit $? coshell eval rm -f /tmp/test.rpm || exit $? coshell close exit 0 There are a few minor issues that I'd like to work out, but it works well enough for me ;-) The issues are: - Shell quoting issue with 'coshell eval' commands - need to somehow re-quote words. - Interactive commands hang 'coshell eval', tried redirecting in 0 )) ; do case "$1" in # # coshell open # o|op|ope|open) shift coprocess open "$@" local ret=$? # This should eat any ssh error messages or what not. coshell eval : >/dev/null 2>&1 return $ret ;; # # coshell close # c|cl|clo|close) shift coprocess close "$@" return $? ;; # # coshell eval # e|ev|eva|eval) shift local cookie=$RANDOM if (( $# == 0 )) ; then echo "coshell eval: no argumentsl" >&2 return 1 fi if [ x$coprocess_pid = x ] ; then echo "coshell eval: no active coshell" >&2 return 1 fi coprocess print "$@" coprocess print "coprocess_rc=\$?" coprocess print "printf 'coprocess-$cookie----\n%d\n' \$coprocess_rc" if [ x$coprocess_pid = x ] ; then return 0 fi local ol while coprocess read ol ; do case "$ol" in *coprocess-$cookie----*) ol="${ol%coprocess-$cookie----}" echo -n "$ol" break ;; esac echo "$ol" done coprocess read ol return $ol ;; # # coshell sendfile # s|se|sen|send|sendf|sendfi|sendfil|sendfile) shift if (( $# != 2 )) ; then echo "coshell sendfile: syntax is 'coshell sendfile SRC TARGET'" >&2 return 1 fi if [ x$coprocess_pid = x ] ; then echo "coshell sendfile: no active coshell" >&2 return 1 fi local target=$2 if coshell test -d "$target" ; then target="$target/${1##*/}" fi coprocess print "uudecode <&2 return 1 fi if [ x$coprocess_pid = x ] ; then echo "coshell getfile: no active coshell" >&2 return 1 fi local target=$2 if test -d "$target" ; then target="$target/${1##*/}" fi coshell eval uuencode -m "$target" "<" "$1" |uudecode return $? ;; *) coshell eval "$@" return $? ;; esac shift done coprocess status return $? } bash-2.05a/examples/functions/csh-compat100644 436 0 1543 6173524726 16561 0ustar chetwheel# C-shell compatabilty package. # setenv VAR VALUE function setenv () { export $1="$2" } function unsetenv () { unset $1 } # Can't write foreach yet. Need pattern matching, and a few extras. function foreach () { echo 'Can'\''t do `foreach'\'' yet. Type "help for".' } # Make this work like csh's. Special case "term" and "path". #set () { #} chdir () { builtin cd "$@" } # alias - convert csh alias commands to bash functions # from Mohit Aron # posted to usenet as <4i5p17$bnu@larry.rice.edu> function alias () { if [ "x$2" = "x" ] then declare -f $1 else echo $2 | egrep -s '(\!|#)' 2>/dev/null if [ $? -eq 0 ] then comm=$(echo $2 | sed 's/\\!\*/\"$\@\"/g s/\\!:\([1-9]\)/\"$\1\"/g s/#/\\#/g') else comm="$2 \"\$@\"" fi eval function $1 \(\) "{" command "$comm" "; }" fi } bash-2.05a/examples/functions/dirfuncs100644 436 0 4715 5613517052 16334 0ustar chetwheel# # Directory manipulation functions from the book 'The Korn Shell' # Modified for use with bash Mon Apr 18 08:37 1994 by # Ken Konecki (kenk@wfg.com) # # Modified by Chet Ramey # # This could stand to have calls to `select' added back in # alias integer="declare -i" integer _push_max=${CDSTACK-31} _push_top=${CDSTACK-31} unalias cd # alias cd=_cd # Display directory stack -- $HOME display as ~ dirs() { dir="${PWD#$HOME/}" case $dir in $HOME) dir=\~ ;; /*) ;; *) dir=\~/$dir ;; esac integer i=_push_top integer n=1 echo "$n) $dir" while let "i < $_push_max" do n=n+1 eval "echo \$n\) \$_push_stack_$i" i=i+1 done } # Change directory and put directory on front of stack cd() { typeset dir= integer n=0 type=4 i case $1 in -|-1|2) # cd - n=_push_top type=1 ;; -[1-9]|-[1-9][0-9]) # cd -n n=_push_top+${1#-}-1 type=2 ;; 1) # keep present directory echo "$PWD" return ;; [2-9]|[1-9][0-9]) # cd n n=_push_top+${1}-2 type=2 ;; *) if let "_push_top <= 0"; then type=3 n=_push_max fi ;; esac if let "type < 3"; then if let "n >= _push_max"; then echo cd: Directory stack not that deep return 1 else eval dir=\${_push_stack_$n} fi fi case $dir in ~*) dir=$HOME${dir#\~} ;; esac cd2 ${dir:-$@} > /dev/null || return 1 dir=${OLDPWD#$HOME/} case $dir in $HOME) dir=\~ ;; /*) ;; *) dir=\~/$dir ;; esac case $type in 1) # swap first two elements eval _push_stack_$_push_top=\$dir ;; 2|3) # put $dir on top and shift down by one until top i=_push_top unset _dirlist while let "i < $_push_max" ; do eval _dirlist=\"\$_dirlist \$_push_stack_$i\" i=i+1 done i=_push_top for dir in "$dir" ${_dirlist} ; do let "i > n" && break eval _push_stack_$i=\$dir i=i+1 done ;; 4) # push name _push_top=_push_top-1; eval _push_stack_$_push_top=\$dir ;; esac echo "$PWD" } # Menu-driven change directory command function mcd { dirs echo -n "Select by number or enter a name: " read cd $REPLY } # Emulate ksh cd substitution cd2() { case "$#" in 0) builtin cd "$HOME" ;; 1) builtin cd "$1" ;; 2) newDir=$(echo $PWD | sed -e "s:$1:$2:g") case "$newDir" in $PWD) echo "bash:: cd: bad substitution" >&2 ; return 1 ;; *) builtin cd "$newDir" ;; esac ;; *) echo "bash: cd: wrong arg count" 1>&2 ; return 1 ;; esac } bash-2.05a/examples/functions/dirname100644 436 0 1075 5127706332 16133 0ustar chetwheel# Date: Fri, 11 Oct 91 11:22:36 edt # From: friedman@gnu.ai.mit.edu # To: bfox@gnu.ai.mit.edu # A replacement for dirname(1). This one appears less often on some # systems I use than basename(1), and I really depend on it for some # things. Usage: dirname [path] function dirname () { local dir="$1" local tdir="${dir%/}" # Strip trailing '/' characters from dir (unusual that this should # ever occur, but dirname(1) seems to deal with it.) while [ "${tdir}" != "${dir}" ]; do tdir="${dir}" dir="${tdir%/}" done echo "${dir%/*}" } bash-2.05a/examples/functions/emptydir100664 436 0 1127 7206522104 16342 0ustar chetwheel#! /bin/bash # #Derived from: # #From: damercer@mmm.com (Dan Mercer) #Newsgroups: comp.unix.admin,comp.unix.shell,comp.unix.programmer,comp.sys.sun.admin #Subject: Re: Command to find out if a directory is empty #Date: 17 Aug 2000 14:35:56 GMT #Message-ID: <8ngt8c$fmr$1@magnum.mmm.com> # usage: emptydir [dirname] ; default dirname is "." emptydir() { typeset file dir=${1:-.} [[ -d $dir ]] || { echo "$FUNCNAME: $dir is not a directory" >&2 return 2 } for file in $dir/.* $dir/* do case ${file#$dir/} in .|..) ;; \*) [[ -e $file ]];let $?;return;; *) return 1;; esac done } bash-2.05a/examples/functions/exitstat100644 436 0 1150 5757166643 16371 0ustar chetwheel# Contributed by Noah Friedman and Roland McGrath. # To be run by the PROMPT_COMMAND variable, so that one can see what # the exit status of processes are. function check_exit_status () { local status="$?" local signal="" if [ ${status} -ne 0 -a ${status} != 128 ]; then # If process exited by a signal, determine name of signal. if [ ${status} -gt 128 ]; then signal="$(builtin kill -l $((${status} - 128)) 2>/dev/null)" if [ "$signal" ]; then signal="($signal)"; fi fi echo "[Exit ${status} ${signal}]" 1>&2 fi return 0 } PROMPT_COMMAND=check_exit_status bash-2.05a/examples/functions/external100644 436 0 2472 5127706350 16340 0ustar chetwheel# Contributed by Noah Friedman. # To avoid using a function in bash, you can use the `builtin' or # `command' builtins, but neither guarantees that you use an external # program instead of a bash builtin if there's a builtin by that name. So # this function can be used like `command' except that it guarantees the # program is external by first disabling any builtin by that name. After # the command is done executing, the state of the builtin is restored. function external () { local state="" local exit_status if builtin_p "$1"; then state="builtin" enable -n "$1" fi command "$@" exit_status=$? if [ "$state" = "builtin" ]; then enable "$1" fi return ${exit_status} } # What is does is tell you if a particular keyword is currently enabled as # a shell builtin. It does NOT tell you if invoking that keyword will # necessarily run the builtin. For that, do something like # # test "$(builtin type -type [keyword])" = "builtin" # # Note also, that disabling a builtin with "enable -n" will make builtin_p # return false, since the builtin is no longer available. function builtin_p () { local word set $(builtin type -all -type "$1") for word in "$@" ; do if [ "${word}" = "builtin" ]; then return 0 fi done return 1 } bash-2.05a/examples/functions/fact100644 436 0 465 7245505106 15412 0ustar chetwheel# Who said shells can't use recursion? Here is a factorial function. # You call it with a number as an argument, and it returns the factorial # of that number. fact () { local num=$1; if [ "$num" = 1 ] ; then echo 1 return ; fi; echo $(( $num * $(fact $(( $num - 1 )) ) )) } bash-2.05a/examples/functions/fstty100644 436 0 2035 5134373116 15660 0ustar chetwheel# # A function that works as a front end for both stty and the `bind' # builtin, so the tty driver and readline see the same changes # # # Convert between the stty ^H control character form and the readline \C-H # form # cvt() { echo "$@" | cat -v | sed 's/\^/\\C-/' } # # stty front-end. Parses the argument list and creates two command strings, # one for stty, another for bind. # fstty() { local cmd="" bargs="" local e while [ $# -gt 0 ] do case "$1" in -a) cmd="$cmd everything" ;; erase) shift; e=$(cvt "$1") cmd="$cmd erase $1" bargs="$bargs '\"$e\": backward-delete-char'" ;; kill) shift e=$(cvt "$1") cmd="$cmd kill $1" bargs="$bargs '\"$e\": unix-line-discard'" ;; werase) shift; e=$(cvt "$1") cmd="$cmd erase $1" bargs="$bargs '\"$e\": backward-kill-word'" ;; lnext) shift; e=$(cvt "$1") cmd="$cmd erase $1" bargs="$bargs '\"$e\": quoted-insert'" ;; *) cmd="$cmd $1" ;; esac shift done command stty $cmd if [ -n "$bargs" ]; then builtin bind $bargs fi } bash-2.05a/examples/functions/func100644 436 0 672 4763061717 15437 0ustar chetwheel# # func -- print out definitions for functions named by arguments # # usage: func name [name ...] # # Chet Ramey # chet@ins.CWRU.Edu func() { local status=0 if [ $# -eq 0 ] ; then echo "usage: func name [name...]" 1>&2 return 1 fi for f do if [ "$(builtin type -type $f)" != "function" ] ; then echo "func: $f: not a function" 1>&2 status=1 # one failed continue fi builtin type $f | sed 1d done return $status } bash-2.05a/examples/functions/gethtml100664 436 0 1056 7231357767 16175 0ustar chetwheel# # get_html -- get a web page from a remote server # # Original Author: Jeff Korn # Modified for bash by Chet Ramey # # Example: get_html cnswww.cns.cwru.edu /~chet/ | more get_html() { local host port (($# < 2)) && { echo "usage: $FUNCNAME hostname path [port]" >&2 return 1 } host="$1" port="${3:-80}" exec 3<> /dev/tcp/$host/$port || { echo "$FUNCNAME: $host/$port: cannot connect" >&2 exit 1 } echo -e "GET $2 HTTP/1.0\n" >&3 cat <&3 exec 3<&- return 0 } get_html "$@" bash-2.05a/examples/functions/getoptx.bash100644 436 0 21571 6466673254 17162 0ustar chetwheel#From: "Grigoriy Strokin" #Newsgroups: comp.unix.shell #Subject: BASH: getopt function that parses long-named options #Date: Mon, 22 Dec 1997 20:35:18 +0300 #Hi, I have written a BASH function named getoptex, that is like bash builtin #"getopts", but does parse long-named options and optional arguments. It only #uses builtin bash commands, so it is very fast. In order to use it in your #bash scripts, include a command ". getopt.sh" ( getopt.sh) to the file #containing your script, and that will define functions getopt, getoptex, and #optlistex (the file getopt.sh with its detailed description is listed #below). #*** file getopt.sh *** #! /bin/bash # # getopt.sh: # functions like getopts but do long-named options parsing # and support optional arguments # # Version 1.0 1997 by Grigoriy Strokin (grg@philol.msu.ru), Public Domain # Date created: December 21, 1997 # Date modified: December 21, 1997 # # IMPORTANT FEATURES # # 1) Parses both short and long-named options # 2) Supports optional arguments # 3) Only uses bash builtins, thus no calls to external # utilities such as expr or sed is done. Therefore, # parsing speed is high enough # # # DESCRIPTION # # FUNCTION getopt # Usage: getopt OPTLIST {"$@"|ALTERNATIVE_PARAMETERS} # # like getopts, but parse options with both required and optional arguments, # Options with optional arguments must have "." instead of ":" after them. # Furthemore, a variable name to place option name cannot be specified # and is always placed in OPTOPT variable # # This function is provided for compatibility with getopts() # OPTLIST style, and it actually calls getoptex (see bellow) # # NOTE that a list of parameters is required and must be either "$@", # if processing command line arguments, or some alternative parameters. # # FUNCTION getoptex # Usage: getoptex OPTION_LIST {"$@"|ALTERNATIVE_PARAMETERS} # # like getopts, but parse long-named options. # # Both getopt and getoptex return 0 if an option has been parsed, # and 1 if all options are already parsed or an error occured # # Both getopt and getoptex set or test the following variables: # # OPTERR -- tested for whether error messages must be given for invalid options # # OPTOPT -- set to the name of an option parsed, # or to "?" if no more options or error # OPTARG -- set to the option argument, if any; # unset if ther is no argument; # on error, set to the erroneous option name # # OPTIND -- Initialized to 1. # Then set to the number of the next parameter to be parsed # when getopt or getoptex will be called next time. # When all options are parsed, contains a number of # the first non-option argument. # # # OPTOFS -- If a parameter number $OPTIND containg an option parsed # does not contain any more options, OPTOFS is unset; # otherwise, OPTOFS is set to such a number of "?" signs # which is equal to the number of options parsed # # You might not set variables OPTIND and OPTOFS yourself # unless you want to parse a list of parameters more than once. # Otherwise, you whould unset OPTIND (or set it to 1) # and unset OPTOFS each time you want to parse a new parameters list # # Option list format is DIFFERENT from one for getopts or getopt. getopts-style # option list can be converted to getoptex-style using a function optlistex # (see bellow) # # DESCRIPTION of option list used with getoptex: # Option names are separated by whitespace. Options consiting of # more than one character are treated as long-named (--option) # # Special characters can appear at the and of option names specifying # whether an argument is required (default is ";"): # ";" (default) -- no argument # ":" -- required argument # "," -- optional argument # # For example, an option list "a b c help version f: file: separator." # defines the following options: # -a, -b, -c, --help, --version -- no argument # -f, --file -- argument required # --separator -- optional argument # # FUNCTION optlistex # Usage new_style_optlist=`optlistex OLD_STYLE_OPTLIST` # # Converts getopts-style option list in a format suitable for use with getoptex # Namely, it inserts spaces after each option name. # # # HOW TO USE # # In order o use in your bash scripts the functions described, # include a command ". getopt.sh" to the file containing the script, # which will define functions getopt, getoptex, and optlistex # # EXAMPLES # # See files 'getopt1' and 'getopt2' that contain sample scripts that use # getopt and getoptex functions respectively # # # Please send your comments to grg@philol.msu.ru function getoptex() { let $# || return 1 local optlist="${1#;}" let OPTIND || OPTIND=1 [ $OPTIND -lt $# ] || return 1 shift $OPTIND if [ "$1" != "-" -a "$1" != "${1#-}" ] then OPTIND=$[OPTIND+1]; if [ "$1" != "--" ] then local o o="-${1#-$OPTOFS}" for opt in ${optlist#;} do OPTOPT="${opt%[;.:]}" unset OPTARG local opttype="${opt##*[^;:.]}" [ -z "$opttype" ] && opttype=";" if [ ${#OPTOPT} -gt 1 ] then # long-named option case $o in "--$OPTOPT") if [ "$opttype" != ":" ]; then return 0; fi OPTARG="$2" if [ -z "$OPTARG" ]; then # error: must have an agrument let OPTERR && echo "$0: error: $OPTOPT must have an argument" >&2 OPTARG="$OPTOPT"; OPTOPT="?" return 1; fi OPTIND=$[OPTIND+1] # skip option's argument return 0 ;; "--$OPTOPT="*) if [ "$opttype" = ";" ]; then # error: must not have arguments let OPTERR && echo "$0: error: $OPTOPT must not have arguments" >&2 OPTARG="$OPTOPT" OPTOPT="?" return 1 fi OPTARG=${o#"--$OPTOPT="} return 0 ;; esac else # short-named option case "$o" in "-$OPTOPT") unset OPTOFS [ "$opttype" != ":" ] && return 0 OPTARG="$2" if [ -z "$OPTARG" ] then echo "$0: error: -$OPTOPT must have an argument" >&2 OPTARG="$OPTOPT" OPTOPT="?" return 1 fi OPTIND=$[OPTIND+1] # skip option's argument return 0 ;; "-$OPTOPT"*) if [ $opttype = ";" ] then # an option with no argument is in a chain of options OPTOFS="$OPTOFS?" # move to the next option in the chain OPTIND=$[OPTIND-1] # the chain still has other options return 0 else unset OPTOFS OPTARG="${o#-$OPTOPT}" return 0 fi ;; esac fi done echo "$0: error: invalid option: $o" fi; fi OPTOPT="?" unset OPTARG return 1 } function optlistex { local l="$1" local m # mask local r # to store result while [ ${#m} -lt $[${#l}-1] ]; do m="$m?"; done # create a "???..." mask while [ -n "$l" ] do r="${r:+"$r "}${l%$m}" # append the first character of $l to $r l="${l#?}" # cut the first charecter from $l m="${m#?}" # cut one "?" sign from m if [ -n "${l%%[^:.;]*}" ] then # a special character (";", ".", or ":") was found r="$r${l%$m}" # append it to $r l="${l#?}" # cut the special character from l m="${m#?}" # cut one more "?" sign fi done echo $r } function getopt() { local optlist=`optlistex "$1"` shift getoptex "$optlist" "$@" return $? } #************************************** # cut here #************************************** #*** (end of getopt.sh) *** #*** file getopt1 *** #! /bin/bash # getopt1: # Sample script using the function getopt # # Type something like "getopt1 -ab -d 10 -e20 text1 text2" # on the command line to see how it works # # See getopt.sh for more information #. getopt.sh #echo Using getopt to parse arguments: #while getopt "abcd:e." "$@" #do # echo "Option <$OPTOPT> ${OPTARG:+has an arg <$OPTARG>}" #done #shift $[OPTIND-1] #for arg in "$@" #do # echo "Non option argument <$arg>" #done # #************************************** # cut here #************************************** #*** (end of getopt1) *** # # #*** file getopt2 *** # #! /bin/bash # getopt2: # Sample script using the function getoptex # # Type something like "getopt2 -ab -d 10 -e20 --opt1 --opt4=100 text1 text2" # to see how it works # # See getopt.sh for more information . getopt.sh #echo Using getoptex to parse arguments: #while getoptex "a; b; c; d: e. opt1 opt2 opt3 opt4: opt5." "$@" #do # echo "Option <$OPTOPT> ${OPTARG:+has an arg <$OPTARG>}" #done #shift $[OPTIND-1] #for arg in "$@" #do # echo "Non option argument <$arg>" #done # #************************************** # cut here #************************************** #*** (end of getopt2) *** bash-2.05a/examples/functions/inetaddr100644 436 0 1747 6616406465 16324 0ustar chetwheel# # inet2hex - Internet address conversion, dotted-decimal to hex # inet2hex () { local IFS IFS=. set -- $1 if (( $# != 4 )); then echo "inet2hex: incorrect input format: $1" >&2 echo "inet2hex: usage: inet2hex XX.XX.XX.XX" >&2 return 2 fi printf "0x%02x%02x%02x%02x\n" $1 $2 $3 $4 } # # hex2inet - Internet address conversion, hex to dotted-decimal # hex2inet () { local x1 x2 x3 x4 local rev OPTIND=1 while getopts "r" o do case "$o" in r) rev=true;; *) echo "hex2inet: usage: hex2inet [0x]XXXXXXXX" >&2 ; exit 2;; esac done shift $(( $OPTIND - 1 )) case "$1" in 0x*) h=${1#??} ;; *) h=$1 ;; esac if (( ${#h} != 8 )); then echo "hex2inet: $h not in inet format" >&2 echo "hex2inet: usage: hex2inet [0x]XXXXXXXX" >&2 return 2 fi x1=$(( 0x${h:0:2} )) x2=$(( 0x${h:2:2} )) x3=$(( 0x${h:4:2} )) x4=$(( 0x${h:6:2} )) if [ -z "$rev" ] ; then printf "%d.%d.%d.%d\n" $x1 $x2 $x3 $x4 else printf "%d.%d.%d.%d\n" $x4 $x3 $x2 $x1 fi return 0 } bash-2.05a/examples/functions/inpath100644 436 0 272 6477042172 15761 0ustar chetwheelinpath() { local PROG path=$(echo $PATH | sed 's/^:/.:/ s/::/:.:/g s/:$/:./ s/:/ /g') for x in $path do [ -x $x/$1 ] && { PROG=$x/$1; break; } done [ -n "$PROG" ] } bash-2.05a/examples/functions/isnum.bash100644 436 0 2252 6756030212 16555 0ustar chetwheel#From: jrmartin@rainey.blueneptune.com (James R. Martin) #Newsgroups: comp.unix.shell #Subject: Re: testing user input on numeric or character value #Date: 26 Nov 1997 01:28:43 GMT # isnum returns True if its argument is a valid number, # and False (retval=1) if it is any other string. # The first pattern requires a digit before the decimal # point, and the second after the decimal point. # BASH NOTE: make sure you have executed `shopt -s extglob' before # trying to use this function, or it will not work isnum() # string { case $1 in ?([-+])+([0-9])?(.)*([0-9])?([Ee]?([-+])+([0-9])) ) return 0;; ?([-+])*([0-9])?(.)+([0-9])?([Ee]?([-+])+([0-9])) ) return 0;; *) return 1;; esac } isnum2() # string { case $1 in ?([-+])+([[:digit:]])?(.)*([[:digit:]])?([Ee]?([-+])+([[:digit:]])) ) return 0;; ?([-+])*([[:digit:]])?(.)+([[:digit:]])?([Ee]?([-+])+([[:digit:]])) ) return 0;; *) return 1;; esac } isint() # string { case $1 in ?([-+])+([0-9]) ) return 0;; *) return 1;; esac } isint2() # string { case $1 in ?([-+])+([[:digit:]]) ) return 0;; *) return 1;; esac } bash-2.05a/examples/functions/isnum2100644 436 0 742 6472111674 15714 0ustar chetwheelisnum2() { case "$1" in '[-+]' | '') return 1;; # empty or bare `-' or `+' [-+]*[!0-9]*) return 1;; # non-digit with leading sign [-+]*) return 0;; # OK *[!0-9]*) return 1;; # non-digit *) return 0;; # OK esac } # this one handles floating point isnum3() { case "$1" in '') return 1;; # empty *[!0-9.+-]*) return 1;; # non-digit, +, -, or . *?[-+]*) return 1;; # sign as second or later char *.*.*) return 1;; # multiple decimal points *) return 0;; # OK esac } bash-2.05a/examples/functions/jdate.bash100644 436 0 3730 6477040742 16524 0ustar chetwheel#From: damatex@CAM.ORG (Mario Boudreault) #Newsgroups: comp.unix.shell #Subject: JULIAN DATE CONVERSION SUB #Date: 4 Aug 1995 10:23:28 -0400 #Message-ID: <3vtah0$jb3@ocean.CAM.ORG> #For those using shells and who want to convert dates to a julian number #here is a shell script (wihtout validation) that can be used as a base #program for your shell scripts. #Special thanks to Ed Ferguson@ti.com who sent me the algorithm to compute #that date. # # MODIFIED BY CHET RAMEY TO CONVERT TO bash v2 SYNTAX # # cnvdate - Conversion de dates en julienne et vice et versa... # # Par : Mario Boudreault Damatex Inc Montreal, Canada # Date: 2 Aout 1995 # Rev.: 2 Aout 1995 # # Usage: # cvdate [-j] YYYMMDD pour convertir en nbre de jours # cvdate -d {julian number} pour convertir en AAAAMMJJ # jul_date() { # # Separe ANNEE, MOIS et JOUR... # YEAR=`echo $DATE | awk ' { print substr($0,1,4) } '` MONTH=`echo $DATE | awk ' { print substr($0,5,2) } '` DAY=`echo $DATE | awk ' { print substr($0,7,2) } '` # # Execute la formule magique... # A=$(( $DAY - 32075 + 1461 * ( $YEAR + 4800 - ( 14 - $MONTH ) / 12 ) \ / 4 + 367 * ( $MONTH - 2 + ( 14 - $MONTH ) / 12 * 12 ) / 12 - \ 3 * ( ( $YEAR + 4900 - ( 14 - $MONTH ) / 12 ) / 100 ) / 4 )) echo $A } day_date() { TEMP1=$(( $DATE + 68569 )) TEMP2=$(( 4 * $TEMP1 / 146097 )) TEMP1=$(( $TEMP1 - ( 146097 * $TEMP2 + 3 ) / 4 )) Y=$(( 4000 * ( $TEMP1 + 1 ) / 1461001 )) TEMP1=$(( $TEMP1 - 1461 * $Y / 4 + 31 )) M=$(( 80 * $TEMP1 / 2447 )) D=$(( $TEMP1 - 2447 * $M / 80 )) TEMP1=$(( $M / 11 )) M=$(( $M + 2 - 12 * $TEMP1 )) Y=$(( 100 * ( $TEMP2 - 49 ) + $Y + $TEMP1 )) M=`echo $M | awk ' { M=$0 ; if ( length($0) == 1 ) M="0"$0 } END { print M } '` D=`echo $D | awk ' { D=$0 ; if ( length($0) == 1 ) D="0"$0 } END { print D } '` echo $Y$M$D } # main() if [ $# -eq 1 ]; then DATE=$1 jul_date elif [ "$1" = '-j' ]; then DATE=$2 jul_date elif [ "$1" = '-d' ]; then DATE=$2 day_date fi # # Termine # exit 0 bash-2.05a/examples/functions/jj.bash100644 436 0 157 5225126657 16020 0ustar chetwheeljj () { p=$(jobs $1); echo $p case "$p" in [*) echo matches '[*' ;; *) echo not a match\? ;; esac } bash-2.05a/examples/functions/keep100644 436 0 2054 5757163136 15446 0ustar chetwheel# From: Seth Chaiklin # To: chet@ins.CWRU.Edu # Subject: bash functions (sorta) # # keep: # usage: keep program # declare the a program should be "kept". i.e. try to fg a stopped one # and only when that fails start a fresh program. # keep() { case $# in 1|2) ;; *) echo "usage: keep [alias] program" 1>&2 ; return 1;; esac # progname pn=${1##*/} # set up an alias for the kept program if [ $# = 1 ]; then alias "$pn=fg $1 2>/dev/null || $1" else alias "$1=fg $2 2>/dev/null || $2" fi } # # unkeep: # usage: unkeep program # unset the alias set up by the keep function # unkeep() { if [ $# != 1 ]; then echo "usage: unkeep program" return 2 fi # unset the alias for the kept program unalias "${1##*/}" } # # kept: # lists all kept programs in 'alias: program' form # kept() { alias | grep "fg.*2>" | sed "s/alias \(.*\)='fg.*||\(.*\)'$/\1:\2/" } # some things that should be kept #keep /usr/local/bin/emacs #keep e ${EDITOR:-/usr/local/bin/emacs} #keep edit ${EDITOR:-/usr/local/bin/emacs} #keep /usr/local/bin/emm bash-2.05a/examples/functions/ksh-cd100644 436 0 1173 7245511601 15660 0ustar chetwheel# # ksh-like `cd': cd [-LP] [dir [change]] # cd() { OPTIND=1 while getopts "LP" opt do case $opt in L|P) CDOPTS="$CDOPTS -$opt" ;; *) echo "$FUNCNAME: usage: $FUNCNAME [-LP] [dir] [change]" >&2 return 2;; esac done shift $(( $OPTIND - 1 )) case $# in 0) builtin cd $CDOPTS "$HOME" ;; 1) builtin cd $CDOPTS "$@" ;; 2) old="$1" new="$2" case "$PWD" in *$old*) ;; *) echo "${0##*/}: $FUNCNAME: bad substitution" >&2 ; return 1 ;; esac dir=${PWD//$old/$new} builtin cd $CDOPTS "$dir" && echo "$PWD" ;; *) echo "${0##*/}: $FUNCNAME: usage: $FUNCNAME [-LP] [dir] [change]" >&2 return 2 ;; esac } bash-2.05a/examples/functions/ksh-compat-test100644 436 0 2272 7025474200 17532 0ustar chetwheel# # replacements for test/[ that do arithmetic expansion on the operands to # the arithmetic operators, like ksh. # function test() { local -i n1 n3 case "$#" in 3) case "$2" in -lt|-gt|-eq|-ne|-le|-ge) n1=$(( $1 )) n3=$(( $3 )) builtin test "$n1" $2 "$n3" return $?;; *) builtin test "$@" ;; esac;; *) builtin test "$@" ;; esac } function [() { local -i n1 n3 case "$#" in 4) case "$2" in -lt|-gt|-eq|-ne|-le|-ge) n1=$(( $1 )) n3=$(( $3 )) builtin [ "$n1" $2 "$n3" ] return $?;; *) builtin [ "$@" ;; esac;; *) builtin [ "$@" ;; esac } q=7 [ q -lt 10 ] echo $? [ $q -lt 10 ] echo $? bash-2.05a/examples/functions/kshenv100644 436 0 10341 7245512611 16024 0ustar chetwheel# # .kshenv -- functions and aliases to provide the beginnings of a ksh # environment for bash. # # Chet Ramey # chet@ins.CWRU.Edu # # # These are definitions for the ksh compiled-in `exported aliases'. There # are others, but we already have substitutes for them: "history", "type", # and "hash". # alias r="fc -s" alias functions="typeset -f" alias integer="typeset -i" alias nohup="nohup " alias command="command " alias stop="kill -s STOP" alias redirect="command exec" alias hist="fc" # # An almost-ksh compatible `whence' command. This is as hairy as it is # because of the desire to exactly mimic ksh (whose behavior was determined # empirically). # # This depends somewhat on knowing the format of the output of the bash # `builtin type' command. # whence() { local vflag pflag fflag defarg c local path vflag= aflag= pflag= fflag= path= if [ "$#" = "0" ] ; then echo "whence: usage: whence [-afpv] name..." >&2 return 2 fi OPTIND=1 while getopts "avfp" c do case "$c" in a) defarg=-a ;; f) fflag=1 ;; # no-op p) pflag=1 ;; v) vflag=1 ;; ?) echo "whence: $1: unknown option" >&2 echo "whence: usage: whence [-afpv] name..." >&2 return 2 ;; esac done shift $(( $OPTIND - 1 )) if [ "$#" = "0" ] ; then echo "whence: usage: whence [-afpv] name..." >&2 return 2 fi for cmd do if [ "$vflag" ] ; then if [ -z "$defarg" ]; then builtin type $cmd | sed 1q else if builtin type $defarg -t $cmd | grep 'function$' >/dev/null 2>&1; then # HAIRY awk script to suppress # printing of function body -- could # do it with sed, but I don't have # that kind of time builtin type $defarg $cmd | awk ' BEGIN {printit = 1;} $1 == "'$cmd'" && $2 == "()" {printit=0; next; } /^}$/ { if (printit == 0) printit=1 ; else print $0; next ; } /.*/ { if (printit) print $0; }' else builtin type $defarg $cmd fi fi else path=$(builtin type $defarg -p $cmd) if [ "$path" ] ; then echo $path else case "$cmd" in /*) echo "" ;; *) case "$(builtin type -t $cmd)" in "") echo "" ;; *) echo "$cmd" ;; esac ;; esac fi fi done return 0 } # # For real ksh homeboy fanatics, redefine the `type' builtin with a ksh # version. # #type() #{ # whence -v "$*" #} # # ksh-like `cd': cd [-LP] [dir [change]] # cd() { OPTIND=1 while getopts "LP" opt do case $opt in L|P) CDOPTS="$CDOPTS -$opt" ;; *) echo "$FUNCNAME: usage: $FUNCNAME [-LP] [dir] [change]" >&2 return 2;; esac done shift $(( $OPTIND - 1 )) case $# in 0) builtin cd $CDOPTS "$HOME" ;; 1) builtin cd $CDOPTS "$@" ;; 2) old="$1" new="$2" case "$PWD" in *$old*) ;; *) echo "${0##*/}: $FUNCNAME: bad substitution" >&2 ; return 1 ;; esac dir=${PWD//$old/$new} builtin cd $CDOPTS "$dir" && echo "$PWD" ;; *) echo "${0##*/}: $FUNCNAME: usage: $FUNCNAME [-LP] [dir] [change]" >&2 return 2 ;; esac } # # ksh print emulation # # print [-Rnprsu[n]] [-f format] [arg ...] # # - end of options # -R BSD-style -- only accept -n, no escapes # -n do not add trailing newline # -p no-op (no coprocesses) # -r no escapes # -s print to the history file # -u n redirect output to fd n # -f format printf "$format" "$@" # print() { local eflag=-e local nflag= fflag= c local fd=1 OPTIND=1 while getopts "fRnprsu:" c do case $c in R) eflag= ;; r) eflag= ;; n) nflag=-n ;; s) sflag=y ;; f) fflag=y ;; u) fd=$OPTARG ;; p) ;; esac done shift $(( $OPTIND - 1 )) if [ -n "$fflag" ]; then builtin printf "$@" >&$fd return fi case "$sflag" in y) builtin history -s "$*" ;; *) builtin echo $eflag $nflag "$@" >&$fd esac } # substring function # this function should be equivalent to the substring built-in which was # eliminated after the 06/29/84 version substring () { local lpat flag str #local variables set -f case $1 in -l|-L) flag=$1 lpat=$2 shift 2 ;; esac # test for too few or too many arguments if [ x"$1" = x -o $# -gt 2 ]; then print -u2 'substring: bad argument count' return 1 fi str=$1 if [ x"$flag" = x-l ]; then #substring -l lpat str=${str#$lpat} elif [ x"$flag" = x-L ]; then str=${str##$lpat} #substring -L lpat fi if [ x"$2" != x ]; then echo ${str%$2} else echo $str fi return 0 } bash-2.05a/examples/functions/login100644 436 12 177 5760432410 16000 0ustar chetlstaff# replace the `login' and `newgrp' builtins in old bourne shells login() { exec login "$@" } newgrp() { exec newgrp "$@" } bash-2.05a/examples/functions/lowercase100644 436 0 1041 7076675071 16503 0ustar chetwheel#! /bin/bash # # original from # @(#) lowercase.ksh 1.0 92/10/08 # 92/10/08 john h. dubois iii (john@armory.com) # # conversion to bash v2 syntax done by Chet Ramey lowercase() { for file; do [ -f "$file" ] || continue filename=${file##*/} case "$file" in */*) dirname=${file%/*} ;; *) dirname=.;; esac nf=$(echo $filename | tr A-Z a-z) newname="${dirname}/${nf}" if [ "$nf" != "$filename" ]; then mv "$file" "$newname" echo "lowercase: $file -> $newname" else echo "lowercase: $file not changed." fi done } bash-2.05a/examples/functions/manpage100644 436 0 5332 5275252274 16131 0ustar chetwheel# Written from scratch by Tom Tromey (tromey@cns.caltech.edu) # # manpage -- find and print a manual page. # usage: manpage section name [printing] # function manpage () { local i h cmd zot sec local num="$1" local page="$2" local printing="$3" local mp mp="${MANPATH:-/usr/man}" if [ "$#" -lt 2 ]; then return 1; fi # should print usage if [ "$num" != "" ]; then sec="${num%%[a-zA-Z]*}" else sec='[168234571lnpo]' num="$sec" fi for i in $(echo "$mp" | tr : ' '); do if [ ! -d "$i" ]; then continue; fi file="$i"/man"$sec"/"$page"."$num"* set $file file="$1" if [ -f "$file" ]; then zot=$(head -1 "$file") cmd=${MANROFF:-"nroff -man - | col | cat -s"} h=${zot##"'"'\"'} if [ "$h" != "$zot" ]; then while [ "$h" != "" ]; do case "$h" in *e) cmd="${MANEQN:-neqn} | $cmd";; *r) cmd="refer | $cmd";; *t) cmd="tbl | $cmd";; *v) cmd="vgrind | $cmd";; *) ;; # should print error esac h=${h%?} done fi if [ "$printing" != "" ]; then (cd "$i"; eval "$cmd") < "$file" | ${PAGER:-more} else (cd "$i"; eval "$cmd") < "$file" > /tmp/manpage-$$ ${PAGER:-more} /tmp/manpage-$$ rm -f /tmp/manpage-$$ fi break fi done } function whatis_internal () { local j for j in $(echo "$MANPATH" | tr : ' '); do if [ -f "$j/whatis" ]; then eval $2 -i -e "$1" $j/whatis fi done } function whatis () { local name=$(basename "$1") whatis_internal "$name" "grep -w" } function apropos () { whatis_internal "$1" "fgrep" } # Note: "-" and "-t" together not supported. This man could be # made a lot better, but it does everything I want. function man () { local PAGER printing mpath MANROFF num mpath="${MANPATH:-/usr/man}" while true; do case "$1" in -) PAGER=cat printing= ;; -t) MANROFF=${TROFF:-"ptroff -man -t"} PAGER="${TCAT:-lpr}" printing=yes ;; -M) mpath="$2" shift;; *) break;; esac shift done local MANPATH="$mpath" case "$1" in -f | -k) local g a if [ "$1" = "-f" ]; then g="grep -w" a=$(basename "$2") else g=fgrep a="$2" fi whatis_internal "$a" "$g" ;; [0-9npol] | [0-9][a-z]* | new | public | old | local) if [ "$1" = "new" ]; then num=n elif [ "$1" = "public" ]; then num=p elif [ "$1" = "old" ]; then num=o elif [ "$1" = "local" ]; then num=l else num="$1" fi shift manpage "$num" "$1" "$printing" ;; *) manpage "$num" "$1" "$printing" ;; esac } bash-2.05a/examples/functions/mhfold100644 436 0 533 5757160476 15757 0ustar chetwheel# To: chet@ins.CWRU.Edu # Subject: Bash functions # From: Sandeep Mehta # print MH folders, useful only because folders(1) doesn't print # mod date/times mhfold() { list=`folders | tail +2 | awk '{print $1}'` /bin/ls -lag ~/Mail > /tmp/fold$$ for i in $list; do grep $i /tmp/fold$$ done /bin/rm -f /tmp/fold$$ } bash-2.05a/examples/functions/notify.bash100644 436 0 1334 5225124254 16732 0ustar chetwheeltrap _notify CHLD NOTIFY_ALL=false unset NOTIFY_LIST unalias false false() { return 1 } _notify () { local i j local newlist= if $NOTIFY_ALL then return # let bash take care of this itself elif [ -z "$NOTIFY_LIST" ]; then return else set -- $NOTIFY_LIST for i in "$@" do j=$(jobs -n %$i) if [ -n "$j" ]; then echo "$j" jobs -n %$i >/dev/null else newlist="newlist $i" fi done NOTIFY_LIST="$newlist" fi } notify () { local i j if [ $# -eq 0 ]; then NOTIFY_ALL=: set -b return else for i in "$@" do # turn a valid job spec into a job number j=$(jobs $i) case "$j" in [*) j=${j%%]*} j=${j#[} NOTIFY_LIST="$NOTIFY_LIST $j" ;; esac done fi } bash-2.05a/examples/functions/pathfuncs100644 436 0 2334 6702716307 16511 0ustar chetwheel#From: "Simon J. Gerraty" #Message-Id: <199510091130.VAA01188@zen.void.oz.au> #Subject: Re: a shell idea? #Date: Mon, 09 Oct 1995 21:30:20 +1000 # NAME: # add_path.sh - add dir to path # # DESCRIPTION: # These functions originated in /etc/profile and ksh.kshrc, but # are more useful in a separate file. # # SEE ALSO: # /etc/profile # # AUTHOR: # Simon J. Gerraty # @(#)Copyright (c) 1991 Simon J. Gerraty # # This file is provided in the hope that it will # be of use. There is absolutely NO WARRANTY. # Permission to copy, redistribute or otherwise # use this file is hereby granted provided that # the above copyright notice and this notice are # left intact. # is $1 missing from $2 (or PATH) ? no_path() { eval "case :\$${2-PATH}: in *:$1:*) return 1;; *) return 0;; esac" } # if $1 exists and is not in path, append it add_path () { [ -d ${1:-.} ] && no_path $* && eval ${2:-PATH}="\$${2:-PATH}:$1" } # if $1 exists and is not in path, prepend it pre_path () { [ -d ${1:-.} ] && no_path $* && eval ${2:-PATH}="$1:\$${2:-PATH}" } # if $1 is in path, remove it del_path () { no_path $* || eval ${2:-PATH}=`eval echo :'$'${2:-PATH}: | sed -e "s;:$1:;:;g" -e "s;^:;;" -e "s;:\$;;"` } bash-2.05a/examples/functions/recurse100664 436 0 3363 7206520645 16171 0ustar chetwheel#!/bin/bash #From: kaz@ashi.footprints.net (Kaz Kylheku) #Newsgroups: comp.os.linux.misc #Subject: Re: bash question: subdirectories #Message-ID: #Date: Tue, 08 Feb 2000 16:24:35 GMT #Actually it can be made to. That is to say, it is possible to code a recursive #descender function in the bash language. Here is an example. # #What is nice about this is that you can embed the function into your shell #script. The function changes the current working directory as it descends. #So it can handle arbitrarily deep paths. Whereas paths generated by the #find command can cause a problem when they get too long; the kernel has a #hard limit on the length of the string passed to the open() and other #system calls. #There are races; what if the directory tree is blown away during the traversal? #The function won't be able to crawl back up using the .. link and will just #bail. # Recursive Directory Traverser # Author: Kaz Kylheku # Date: Feb 27, 1999 # Copyright 1999 # Function parameter usage: # $1 directory to search # $2 pattern to search for # $3 command to execute # $4 secret argument for passing down path function recurse { local file local path if [ "$4" = "" ] ; then path="${1%/}/" else path="$4$1/" fi if cd "$1" ; then for file in $2; do if [ -f "$file" -o -d "$file" ]; then eval "$3" fi done for file in .* * ; do if [ "$file" = "." -o "$file" = ".." ] ; then continue fi if [ -d "$file" -a ! -L "$file" ]; then recurse "$file" "$2" "$3" "$path" fi done cd .. fi } recurse "$1" "$2" 'echo "$path$file"' bash-2.05a/examples/functions/repeat2100644 436 0 1576 5757161112 16064 0ustar chetwheel# To: chet@ins.CWRU.Edu # Subject: Bash functions # From: Sandeep Mehta ########################################## # # repeat - clone of C shell builtin `repeat' # # usage: repeat # # It has been tested inside other functions and in conditionals like # if [ "`repeat `" ]; then COMMANDS [ else COMMANDS ] fi # Please send me fixes/enhancements. # # Sandeep Mehta ########################################## repeat() { local rcount=$1 if [ $# -le 1 ] || [ -z "$rcount" ]; then echo "usage: repeat " 1>&2 return 2 fi shift local acmd=("$@") if [ $rcount -le 0 ]; then echo "count must be greater than 0" echo "usage: repeat " 1>&2 return 2 fi st=0 while [ $rcount -gt 0 ]; do eval "${acmd[@]}" st=$? rcount=$((rcount - 1)) done return $st } bash-2.05a/examples/functions/repeat3100644 436 0 433 6571265561 16044 0ustar chetwheel# From psamuels@jake.niar.twsu.edu (Peter Samuelson) # posted to usenet, Message-ID: <6rtp8j$2a0$1@jake.niar.twsu.edu> repeat () { local i max; # note that you can use \$i in the command string max=$1; shift; i=1; while ((i <= max)); do eval "$@"; ((i = i + 1)); done; } bash-2.05a/examples/functions/seq100644 436 0 1020 5757164320 15276 0ustar chetwheel# Generate a sequence from m to n, m defaults to 1. seq () { declare -i lo hi i # makes local local _SEQ case $# in 1) seq 1 "$1" ; return $? ;; 2) lo=$1 hi=$2 i=$lo _SEQ="" while let "i <= hi"; do _SEQ="${_SEQ}$i " let i+=1 done echo "${_SEQ# }" return 0 ;; *) echo seq: usage: seq [low] high 1>&2 ; return 2 ;; esac } # like the APL `iota' function (or at least how I remember it :-) iota() { case $# in 1) seq 1 "$1"; return $?;; *) echo "iota: usage: iota high" 1>&2; return 2;; esac } bash-2.05a/examples/functions/seq2100644 436 0 1456 6634006330 15364 0ustar chetwheel# Generate a sequence from m to n, m defaults to 1. seq () { declare -i lo hi i # makes local local _SEQ INIT COMPARE STEP case "$1" in -r) INIT='i=$hi _SEQ=""' COMPARE='let "i >= $lo"' STEP='let i-=1' ; shift ;; *) INIT='i=$lo _SEQ=""' COMPARE='let "i <= $hi"' STEP='let i+=1' ;; esac case $# in 1) lo=1 hi="$1" ;; 2) lo=$1 hi=$2 ;; *) echo seq: usage: seq [-r] [low] high 1>&2 ; return 2 ;; esac # equivalent to the as-yet-unimplemented # for (( "$INIT" ; "$COMPARE" ; "$STEP" )); do _SEQ="${_SEQ}$i "; done eval "$INIT" while eval "$COMPARE"; do _SEQ="${_SEQ}$i " eval "$STEP" done echo "${_SEQ# }" return 0 } # like the APL `iota' function (or at least how I remember it :-) iota() { case $# in 1) seq 1 "$1"; return $?;; *) echo "iota: usage: iota high" 1>&2; return 2;; esac } bash-2.05a/examples/functions/shcat100644 436 0 71 5757166517 15567 0ustar chetwheelshcat() { while read -r line do echo "$line" done } bash-2.05a/examples/functions/shcat2100644 436 0 256 6477036216 15666 0ustar chetwheelshcat() { while read -r line do echo "$line" done } shcat2() { while [ $# -ge 1 ]; do case "$1" in -) shcat ;; *) shcat < "$1" ;; esac shift done exit 0 } bash-2.05a/examples/functions/sort-pos-params100644 436 0 1740 7255665176 17600 0ustar chetwheel# Sort the positional paramters. # Make sure the positional parameters are passed as arguments to the function. # If -u is the first arg, remove duplicate array members. sort_posparams() { local -a R local u case "$1" in -u) u=-u ; shift ;; esac # if you want the case of no positional parameters to return success, # remove the error message and return 0 if [ $# -eq 0 ]; then echo "$FUNCNAME: argument expected" >&2 return 1 fi # make R a copy of the positional parameters R=( "${@}" ) # sort R. R=( $( printf "%s\n" "${R[@]}" | sort $u) ) printf "%s\n" "${R[@]}" return 0 } # will print everything on separate lines set -- 3 1 4 1 5 9 2 6 5 3 2 sort_posparams "$@" # sets without preserving quoted parameters set -- $( sort_posparams "$@" ) echo "$@" echo $# # sets preserving quoted parameters, beware pos params with embedded newlines set -- 'a b' 'a c' 'x z' oifs=$IFS IFS=$'\n' set -- $( sort_posparams "$@" ) IFS="$oifs" echo "$@" echo $# sort_posparams bash-2.05a/examples/functions/substr100644 436 0 2174 4763061720 16037 0ustar chetwheel# # substr -- a function to emulate the ancient ksh builtin # # # -l == shortest from left # -L == longest from left # -r == shortest from right (the default) # -R == longest from right substr() { local flag pat str local usage="usage: substr -lLrR pat string or substr string pat" case "$1" in -l | -L | -r | -R) flag="$1" pat="$2" shift 2 ;; -*) echo "substr: unknown option: $1" echo "$usage" return 1 ;; *) flag="-r" pat="$2" ;; esac if [ "$#" -eq 0 -o "$#" -gt 2 ] ; then echo "substr: bad argument count" return 2 fi str="$1" # # We don't want -f, but we don't want to turn it back on if # we didn't have it already # case "$-" in "*f*") ;; *) fng=1 set -f ;; esac case "$flag" in -l) str="${str#$pat}" # substr -l pat string ;; -L) str="${str##$pat}" # substr -L pat string ;; -r) str="${str%$pat}" # substr -r pat string ;; -R) str="${str%%$pat}" # substr -R pat string ;; *) str="${str%$2}" # substr string pat ;; esac echo "$str" # # If we had file name generation when we started, re-enable it # if [ "$fng" = "1" ] ; then set +f fi } bash-2.05a/examples/functions/substr2100644 436 0 2556 4763061722 16127 0ustar chetwheel# # substr -- a function to emulate the ancient ksh builtin # # -l == remove shortest from left # -L == remove longest from left # -r == remove shortest from right (the default) # -R == remove longest from right substr() { local flag pat str local usage="usage: substr -lLrR pat string or substr string pat" local options="l:L:r:R:" OPTIND=1 while getopts "$options" c do case "$c" in l | L | r | R) flag="-$c" pat="$OPTARG" ;; '?') echo "$usage" return 1 ;; esac done if [ "$OPTIND" -gt 1 ] ; then shift $[ $OPTIND -1 ] fi if [ "$#" -eq 0 -o "$#" -gt 2 ] ; then echo "substr: bad argument count" return 2 fi str="$1" # # We don't want -f, but we don't want to turn it back on if # we didn't have it already # case "$-" in "*f*") ;; *) fng=1 set -f ;; esac case "$flag" in -l) str="${str#$pat}" # substr -l pat string ;; -L) str="${str##$pat}" # substr -L pat string ;; -r) str="${str%$pat}" # substr -r pat string ;; -R) str="${str%%$pat}" # substr -R pat string ;; *) str="${str%$2}" # substr string pat ;; esac echo "$str" # # If we had file name generation when we started, re-enable it # if [ "$fng" = "1" ] ; then set +f fi } bash-2.05a/examples/functions/term100644 436 0 740 4763061722 15443 0ustar chetwheel# # term -- a shell function to set the terminal type interactively or not. # term() { local t if [ $# != 0 ] ; then eval $(tset -sQ $1) else # interactive if [ -z "$TERM" ] ; then TERM="unknown" fi case "$TERM" in network|dialup|unknown|lat) TERM=unknown ;; *) eval $(tset -sQ) ;; esac while [ "$TERM" = "unknown" ] ; do echo -n "Terminal type: " read t if [ -n "$t" ] ; then eval $(tset -sQ $t) fi done fi } bash-2.05a/examples/functions/whatis100644 436 0 2026 5535173404 16011 0ustar chetwheel# # whatis -- and implementation of the 10th Edition Unix sh builtin `whatis' # command. # # usage: whatis arg [...] # # For each argument, whatis prints the associated value as a parameter, # builtin, function, alias, or executable file as appropriate. In each # case, the value is printed in a form which would yield the same value # if typed as input to the shell itself. # whatis() { local wusage='usage: whatis arg [arg...]' local fail=0 if [ $# -eq 0 ] ; then echo "$wusage" return 1 fi for arg do case $(builtin type -type $arg 2>/dev/null) in "alias") builtin alias "$arg" ;; "function") builtin type "$arg" | sed 1d ;; "builtin") echo builtin "$arg" ;; "file") builtin type -path "$arg" ;; *) # OK, we could have a variable, or we could have nada if [ "$(eval echo \${$arg+set})" = "set" ] ; then # It is a variable, and it is set echo -n "$arg=" eval echo '\"'\$$arg'\"' else echo whatis: $arg: not found fail=1 fi ;; esac done return $fail } bash-2.05a/examples/functions/whence100644 436 0 1736 5521337070 15766 0ustar chetwheel# # An almost-ksh compatible `whence' command. This is as hairy as it is # because of the desire to exactly mimic ksh. # # This depends somewhat on knowing the format of the output of the bash # `builtin type' command. # # Chet Ramey # chet@ins.CWRU.Edu # whence() { local vflag= path= if [ "$#" = "0" ] ; then echo "whence: argument expected" return 1 fi case "$1" in -v) vflag=1 shift 1 ;; -*) echo "whence: bad option: $1" return 1 ;; *) ;; esac if [ "$#" = "0" ] ; then echo "whence: bad argument count" return 1 fi for cmd do if [ "$vflag" ] ; then echo $(builtin type $cmd | sed 1q) else path=$(builtin type -path $cmd) if [ "$path" ] ; then echo $path else case "$cmd" in /*) if [ -x "$cmd" ]; then echo "$cmd" fi ;; *) case "$(builtin type -type $cmd)" in "") ;; *) echo "$cmd" ;; esac ;; esac fi fi done return 0 } bash-2.05a/examples/functions/which100644 436 0 1530 6702437472 15620 0ustar chetwheel# # which - emulation of `which' as it appears in FreeBSD # # usage: which [-as] command [command...] # which() { local aflag sflag ES a opt OPTIND=1 while builtin getopts as opt ; do case "$opt" in a) aflag=-a ;; s) sflag=1 ;; ?) echo "which: usage: which [-as] command [command ...]" >&2 exit 2 ;; esac done (( $OPTIND > 1 )) && shift $(( $OPTIND - 1 )) # without command arguments, exit with status 1 ES=1 # exit status is 0 if all commands are found, 1 if any are not found for command; do # if $command is a function, make sure we add -a so type # will look in $PATH after finding the function a=$aflag case "$(builtin type -t $command)" in "function") a=-a;; esac if [ -n "$sflag" ]; then builtin type -p $a $command >/dev/null 2>&1 else builtin type -p $a $command fi ES=$? done return $ES } bash-2.05a/examples/functions/xalias.bash100644 436 12 727 6122101752 17061 0ustar chetlstaff# xalias - convert csh alias commands to bash functions # from Mohit Aron # posted to usenet as <4i5p17$bnu@larry.rice.edu> function xalias () { if [ "x$2" = "x" ] then declare -f $1 else echo $2 | egrep -q '(\!|#)' if [ $? -eq 0 ] then comm=$(echo $2 | sed 's/\\!\*/\"$\@\"/g s/\\!:\([1-9]\)/\"$\1\"/g s/#/\\#/g') else comm="$2 \"\$@\"" fi eval function $1 \(\) "{" command "$comm" "; }" fi } bash-2.05a/examples/functions/xfind.bash100644 436 0 1714 6712333467 16546 0ustar chetwheel#! /bin/bash #From: kaz@cafe.net (Kaz Kylheku) #Newsgroups: comp.unix.shell #Subject: Why not roll your own @#$% find! (was: splitting directory off from filename) #Message-ID: <6n1117$tp1@espresso.cafe.net> #Date: Fri, 26 Jun 1998 20:47:34 GMT # $1 = dirname, $2 = pattern, optional $3 = action xfind() { local x local dir="$1" # descend into specified directory builtin cd -L "$1" || { echo "${FUNCNAME}: cannot change dir to $1" >&2 return 1 } # # default action is to print the filename # if [ -n "$3" ]; then action="$3" else action='printf -- "%s\n"' fi # process ordinary files that match pattern for x in $2 ; do if [ -f "$x" ] ; then eval "$action" "$x" fi done # now descend into subdirectories, avoiding symbolic links # and directories that start with a period. for x in * ; do if [ -d "$x" -a ! -L "$x" ] ; then $FUNCNAME "$x" "$2" "$action" fi done # finally, pop back up builtin cd -L .. } #xfind "$@" bash-2.05a/examples/scripts/ 40775 436 0 0 7373775250 14164 5ustar chetwheelbash-2.05a/examples/scripts/adventure.sh100775 436 0 33504 7121246335 16626 0ustar chetwheel#!/bin/bash # ash -- "Adventure shell" # last edit: 86/04/21 D A Gwyn # SCCS ID: @(#)ash.sh 1.4 OPATH=$PATH ask() { echo -n "$@" '[y/n] ' read ans case "$ans" in y*|Y*) return 0 ;; *) return 1 ;; esac } CAT=${PAGER:-more} ash_inst() { cat <<- EOF Instructions for the Adventure shell Welcome to the Adventure shell! In this exploration of the UNIX file system, I will act as your eyes and hands. As you move around, I will describe whatever is visible and will carry out your commands. The general form of a command is Verb Object Extra_stuff. Most commands pay no attention to the "Extra_stuff", and many do not need an "Object". A typical command is get all which picks up all files in the current "room" (directory). You can find out what you are carrying by typing the command inventory The command "help" results in a full description of all commands that I understand. To quit the Adventure shell, type quit There are UNIX monsters lurking in the background. These are also known as "commands with arguments". Good luck! EOF } ash_help() { echo "I understand the following commands (synonyms in parentheses):" echo "" echo "change OBJECT to NEW_NAME changes the name of the object" echo "clone OBJECT as NEW_NAME duplicates the object" echo "drop OBJECTS leaves the objects in the room" echo "enter (go) PASSAGE takes the labeled passage" echo "examine OBJECTS describes the objects in detail" echo "feed OBJECT to MONSTER stuffs the object into a UNIX monster" echo "get (take) OBJECTS picks up the specified objects" echo "gripe (bug) report a problem with the Adventure shell" echo "help prints this summary" echo "inventory (i) tells what you are carrying" echo "kill (destroy) OBJECTS destroys the objects" echo "look (l) describes the room, including hidden objects" echo "open (read) OBJECT shows the contents of an object" echo "quit (exit) leaves the Adventure shell" echo "resurrect OBJECTS attempts to restore dead objects" echo "steal OBJECT from MONSTER obtains the object from a UNIX monster" echo "throw OBJECT at daemon feeds the object to the printer daemon" echo "up takes the overhead passage" echo "wake MONSTER awakens a UNIX monster" echo "where (w) tells you where you are" echo "xyzzy moves you to your home" } MAINT=chet@ins.cwru.edu PATH=/usr/ucb:/bin:/usr/bin:/usr/local/bin:. export PATH trap 'echo Ouch!' 2 3 #trap '' 18 # disable Berkeley job control #ash_lk(){ echo " $1 " | fgrep " $2 " >&- 2>&-; } ash_lk(){ echo " $1 " | fgrep -q " $2 " >/dev/null 2>&1 ; } ash_pr(){ echo $* | tr ' ' '\012' | pr -5 -t -w75 -l$[ ( $# + 4 ) / 5 ]; } ash_rm(){ echo " $1 " | sed -e "s/ $2 / /" -e 's/^ //' -e 's/ $//'; } # enable history, bang history expansion, and emacs editing set -o history set -o histexpand set -o emacs cd LIM=.limbo # $HOME/$LIM contains "destroyed" objects mkdir $LIM || { echo "ash: cannot mkdir $LIM: exiting" exit 1 } KNAP=.knapsack # $HOME/$KNAP contains objects being "carried" if [ ! -d $KNAP ] then mkdir $KNAP >/dev/null 2>&1 if [ $? = 0 ] then echo 'You found a discarded empty knapsack.' else echo 'You have no knapsack to carry things in.' exit 1 fi else echo 'One moment while I peek in your old knapsack...' fi kn=`echo \`ls -a $KNAP | sed -e '/^\.$/d' -e '/^\.\.$/d'\`` if ask 'Welcome to the Adventure shell! Do you need instructions?' then ash_inst echo -n 'Type a newline to continue: ' read fi wiz=false cha=false prev=$LIM while : do room=`pwd` if [ $room != $prev ] then if [ $room = $HOME ] then echo 'You are in your own home.' else echo "You have entered $room." fi exs= obs= hexs= hobs= f=false for i in `ls -a` do case $i in .|..) ;; .*) if [ -f $i ] then hobs="$hobs $i" elif [ -d $i ] then hexs="$hexs $i" else f=true fi ;; *) if [ -f $i ] then obs="$obs $i" elif [ -d $i ] then exs="$exs $i" else f=true fi ;; esac done if [ "$obs" ] then echo 'This room contains:' ash_pr $obs else echo 'The room looks empty.' fi if [ "$exs" ] then echo 'There are exits labeled:' ash_pr $exs echo 'as well as a passage overhead.' else echo 'There is a passage overhead.' fi if sh -c $f then echo 'There are shadowy figures in the corner.' fi prev=$room fi read -e -p '-advsh> ' verb obj x # prompt is '-advsh> ' if [ $? != 0 ] then verb=quit # EOF fi case $verb in change) if [ "$obj" ] then if ash_lk "$obs $hobs" "$obj" then set -- $x case "$1" in to) if [ "$2" ] then if [ -f $2 ] then echo "You must destroy $2 first." set -- fi if [ "$2" ] then if mv $obj $2 # >&- 2>&- then echo "The $obj shimmers and turns into $2." obs=`ash_rm "$2 $obs" "$obj"` else echo "There is a cloud of smoke but the $obj is unchanged." fi fi else echo 'To what?' fi ;; *) echo "Change $obj to what?" ;; esac else if ash_lk "$kn" "$obj" then echo 'You must drop it first.' else echo "I see no $obj here." fi fi else echo 'Change what?' fi ;; clone) if [ "$obj" ] then if ash_lk "$obs $hobs" "$obj" then if [ ! -r $obj ] then echo "The $obj does not wish to be cloned." else set -- $x case "$1" in as) if [ "$2" ] then if [ -f $2 ] then echo "You must destroy $2 first." else if cp $obj $2 # >&- 2>&- then echo "Poof! When the smoke clears, you see the new $2." obs="$obs $2" else echo 'You hear a dull thud but no clone appears.' fi fi else echo 'As what?' fi ;; *) echo "Clone $obj as what?" ;; esac fi else if ash_lk "$kn" "$obj" then echo 'You must drop it first.' else echo "I see no $obj here." fi fi else echo 'Clone what?' fi ;; drop) if [ "$obj" ] then for it in $obj $x do if ash_lk "$kn" "$it" then if [ -w $it ] then echo "You must destroy $it first." else if mv $HOME/$KNAP/$it $it # >&- 2>&- then echo "$it: dropped." kn=`ash_rm "$kn" "$it"` obs=`echo $it $obs` else echo "The $it is caught in your knapsack." fi fi else echo "You're not carrying the $it!" fi done else echo 'Drop what?' fi ;; enter|go) if [ "$obj" ] then if [ $obj != up ] then if ash_lk "$