Bash FAQ & Answers
6000 expert Bash answers researched from official documentation. Every answer cites authoritative sources you can verify.
Jump to section:
Shell Parameters > Shell Variables
151 questionsIf PROMPT_COMMAND is set, the value is interpreted as a command to execute before the printing of each primary prompt ($PS1).
Yes, nameref variables can reference array variables and subscripted array variables.
BASHPID expands to the process id of the current Bash process. This differs from $$ under certain circumstances, such as subshells that do not require Bash to be re-initialized.
A zero-length (null) directory name in the value of PATH indicates the current directory. A null directory name may appear as two adjacent colons, or as an initial or trailing colon.
If set to a number greater than zero, PROMPT_DIRTRIM is used as the number of trailing directory components to retain when expanding the \w and \W prompt string escapes. Characters removed are replaced with an ellipsis.
When used in the text of the message, $_ expands to the name of the current mail file.
The default value of HISTFILESIZE is 500. This is the maximum number of lines contained in the history file.
GROUPS is an array variable containing the list of groups of which the current user is a member.
Unsetting BASH_XTRACEFD or assigning it the empty string causes the trace output to be sent to the standard error.
EUID contains the numeric effective user id of the current user. This variable is readonly.
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.
BASH_SOURCE is an array variable whose members are the source filenames corresponding to the elements in the FUNCNAME array variable.
SHLVL is 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.
A variable is a parameter denoted by a name. A variable has a value and zero or more attributes.
HISTCONTROL='ignoreboth' is shorthand for both 'ignorespace' and 'ignoredups'.
BASH_REMATCH is an array variable whose members are assigned by the '=~' binary operator to the [[ conditional command. The element with index 0 is the portion of the string matching the entire regular expression. The element with index n is the portion of the string matching the nth parenthesized subexpression.
The default value of HISTFILE is ~/.bash_history. This is the file to which the command history is saved.
FCEDIT is the editor used as a default by the -e option to the fc builtin command.
When $@ expansion occurs within double quotes and word splitting is performed, each parameter expands to a separate word. That is, '$@' is equivalent to '$1' '$2' …
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.
HISTCMD is the history number, or index in the history list, of the current command.
LINES is used by the select builtin command to determine the column length for printing selection lists. It is automatically set upon receipt of a SIGWINCH.
BASH_COMMAND is the command currently being executed or about to be executed, unless the shell is executing a command as the result of a trap, in which case it is the command executing at the time of the trap.
MACHTYPE is a string that fully describes the system type on which Bash is executing, in the standard gnu cpu-company-system format.
When HISTCONTROL includes 'ignorespace', lines which begin with a space character are not saved in the history list.
If set to a value greater than zero, TMOUT is treated as the default timeout for the read builtin.
DIRSTACK is 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.
FUNCNAME is an array variable containing the names of all shell functions currently in the execution call stack. The element with index 0 is the name of any currently-executing shell function. The bottom-most element is 'main'.
INPUTRC is the name of the Readline initialization file, overriding the default of ~/.inputrc.
HISTIGNORE is a colon-separated list of patterns used to decide which command lines should be saved on the history list.
When += is applied to a variable with the integer attribute set, the variable's current value and the new value are each evaluated as arithmetic expressions, and the sum is assigned as the variable's value.
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.
histchars contains up to three characters which control history expansion, quick substitution, and tokenization. The first character is the history expansion character (normally '!'), the second is quick substitution (normally '^'), and the optional third is the history comment character (usually '#').
If Bash is started with the -c option, $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.
If POSIXLY_CORRECT is in the environment when bash starts, the shell enters posix mode before reading the startup files, as if the --posix invocation option had been supplied.
When there are no positional parameters, '$@' and $@ expand to nothing (i.e., they are removed).
The shell sets BASH_ARGC only when in extended debugging mode (extdebug option to the shopt builtin).
Setting BASH_XTRACEFD to 2 (the standard error file descriptor) and then unsetting it will result in the standard error being closed.
If HOSTFILE is set, but has no value, or does not name a readable file, Bash attempts to read /etc/hosts to obtain the list of possible hostname completions.
When += is applied to an array variable using compound assignment, the variable's value is not unset (as it is when using '='), and new values are appended to the array beginning at one greater than the array's maximum index for indexed arrays, or added as additional key-value pairs in an associative array.
If set to an integer corresponding to a valid file descriptor, Bash will write the trace output generated when 'set -x' is enabled to that file descriptor.
BASH_CMDS is an associative array variable whose members correspond to the internal hash table of commands as maintained by the hash builtin.
$0 expands to the name of the shell or shell script, set at shell initialization.
$! expands to the process ID of the job most recently placed into the background, whether executed as an asynchronous command or using the bg builtin.
UID contains the numeric real user id of the current user. This variable is readonly.
OPTIND is initialized to 1 each time the shell or a shell script is invoked.
The shell sets BASH_ARGV only when in extended debugging mode (extdebug option to the shopt builtin).
FIGNORE is a colon-separated list of suffixes to ignore when performing filename completion. A sample value is '.o:~'.
The default value of PS4 is '+ '. This is the prompt printed before the command line is echoed when the -x option is set.
LC_COLLATE 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.
Yes, if HISTTIMEFORMAT is set, timestamps are written to the history file so they may be preserved across shell sessions.
COMP_LINE is the current command line. This variable is available only in shell functions and external commands invoked by the programmable completion facilities.
A nameref is a reference to another variable, created using the -n option to declare or local. Whenever the nameref variable is referenced, assigned to, unset, or has its attributes modified, the operation is actually performed on the variable specified by the nameref variable's value.
When HISTCONTROL includes 'erasedups', all previous lines matching the current line are removed from the history list before that line is saved.
TIMEFORMAT='%S' displays the number of CPU seconds spent in system mode.
GLOBIGNORE is 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.
BASH_LINENO is an array variable whose members are the line numbers in source files corresponding to each member of FUNCNAME.
The first character of PS4 is replicated multiple times, as necessary, to indicate multiple levels of indirection when tracing with set -x.
If DIRSTACK is unset, it loses its special properties, even if it is subsequently reset.
LC_CTYPE determines the interpretation of characters and the behavior of character classes within filename expansion and pattern matching.
If COMP_WORDBREAKS is unset, it loses its special properties, even if it is subsequently reset.
If the variable exists but does not have a numeric value (or has no value), the default is 10.
HISTTIMEFORMAT uses the history comment character to distinguish timestamps from other history lines.
When += is applied to a string-valued variable, the value is expanded and appended to the variable's value.
If FUNCNAME is unset, it loses its special properties, even if it is subsequently reset.
COMP_TYPE is set to an integer value corresponding to the type of completion attempted: TAB for normal completion, '?' for listing completions after successive tabs, '!' for listing alternatives on partial word completion, '@' to list completions if the word is not unmodified, or '%' for menu completion.
If POSIXLY_CORRECT is set while the shell is running, bash enables posix mode, as if the command 'set -o posix' had been executed.
A parameter is an entity that stores values. It can be a name, a number, or one of the special characters listed in the Bash documentation.
At most three places after the decimal point may be specified for the precision p; values of p greater than 3 are changed to 3.
If Bash is invoked with a file of commands, $0 is set to the name of that file.
When HISTCONTROL includes 'ignoredups', lines which match the previous history entry are not saved.
TIMEFORMAT='%P' displays the CPU percentage, computed as (%U + %S) / %R.
Each list entry in MAILPATH can specify the message printed when new mail arrives by separating the filename from the message with a '?'.
Attributes are assigned using the declare builtin command. The export and readonly builtins assign specific attributes.
If HISTTIMEFORMAT is set and not null, its value is used as a format string for strftime to print the timestamp associated with each history entry displayed by the history builtin.
Assignment to SECONDS resets the count to the value assigned, and the expanded value becomes the value assigned plus the number of seconds since the assignment.
SHELL contains the full pathname to the shell. If it is not set when the shell starts, Bash assigns to it the full pathname of the current user's login shell.
If IFS is null, the parameters in $* are joined without intervening separators.
MAILCHECK specifies how often (in seconds) the shell should check for mail. The default is 60 seconds.
If Bash finds EMACS in the environment when the shell starts with value 't', it assumes the shell is running in an emacs shell buffer and disables line editing.
LANG is used to determine the locale category for any category not specifically selected with a variable starting with LC_.
The default value of HISTSIZE is 500. This is the maximum number of commands to remember on the history list.
If set, Bash uses TMPDIR's value as the name of a directory in which Bash creates temporary files for the shell's use.
$$ expands to the process ID of the shell. In a subshell, it expands to the process ID of the invoking shell, not the subshell.
If HISTCMD is unset, it loses its special properties, even if it is subsequently reset.
Each time RANDOM is referenced, a random integer between 0 and 32767 is generated.
If BASH_ENV 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.
COMPREPLY is an array variable from which Bash reads the possible completions generated by a shell function invoked by the programmable completion facility.
COMP_CWORD is 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.
If GROUPS is unset, it loses its special properties, even if it is subsequently reset.
BASH_SUBSHELL is incremented by one each time a subshell or subshell environment is spawned.
BASHOPTS is a colon-separated list of enabled shell options. Each word in the list is a valid argument for the -s option to the shopt builtin command.
When $* 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 variable.
Namerefs can be unset using the -n option to the unset builtin. Otherwise, if unset is executed with the name of a nameref variable as an argument, the variable referenced by the nameref variable is unset.
COLUMNS is used by the select builtin command to determine the terminal width when printing selection lists. It is automatically set upon receipt of a SIGWINCH.
COMP_WORDS is an array variable consisting of the individual words in the current command line, split as Readline would split it using COMP_WORDBREAKS.
The default value of PS1 is '\s-\v$ '. This is the primary prompt string.
If set to the value 1, Bash displays error messages generated by the getopts builtin command.
If TIMEFORMAT is not set, Bash acts as if it had the value $'\nreal\t%3lR\nuser\t%3lU\nsys\t%3lS'.
COMP_KEY is the key (or final key of a key sequence) used to invoke the current completion function.
PIPESTATUS is an array variable containing a list of exit status values from the processes in the most-recently-executed foreground pipeline.
LINENO is the line number in the script or shell function currently executing.
The second and subsequent lines of a multi-line compound command are not tested by HISTIGNORE and are added to the history regardless of the value of HISTIGNORE.
If MAILCHECK is unset, or set to a value that is not a number greater than or equal to zero, the shell disables mail checking.
PPID contains the process id of the shell's parent process. This variable is readonly.
BASH_ARGV is an array variable containing all of the parameters in the current bash execution call stack.
BASH_ALIASES is an associative array variable whose members correspond to the internal list of aliases as maintained by the alias builtin.
LC_ALL overrides the value of LANG and any other LC_ variable specifying a locale category.
COMP_POINT is 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 equals ${#COMP_LINE}.
COMP_WORDBREAKS is the set of characters that the Readline library treats as word separators when performing word completion.
LC_MESSAGES determines the locale used to translate double-quoted strings preceded by a '$' (see Locale Translation).
The default path is system-dependent and is set by the administrator who installs bash. A common value is '/usr/local/bin:/usr/local/sbin:/usr/bin:/usr/sbin:/bin:/sbin'.
In an interactive shell, TMOUT is interpreted as the number of seconds to wait for input after issuing the primary prompt. Bash terminates after that number of seconds if input does not arrive.
SHELLOPTS is 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.
Invoking Bash > Command-Line Options
133 questionsbash -O extdebug enables extended debugging mode. This provides additional debugging features: the BASH_ARGC, BASH_ARGV, BASH_SOURCE, and BASH_LINENO variables are set, trap handlers receive additional info, and the DEBUG trap is inherited by shell functions.
bash -O cdable_vars allows cd to treat a variable as a directory name if the directory doesn't exist. For example, if mydir='/home/user/docs', then cd mydir would cd to /home/user/docs. The variable value must be an absolute path.
No, -c and -s options are mutually exclusive. The -c option reads commands from a string argument, while -s reads from standard input. You can only use one or the other, not both.
set -e (errexit) does NOT cause exit on: commands in if/while/until conditions, commands whose exit status is being tested with !, part of && or || chains (except the last), piped commands (unless pipefail is set), or any command in a compound command except the last. The ERR trap also overrides this behavior.
The -x option causes bash to print a trace of simple commands, for commands, case commands, select commands, and arithmetic for commands and their arguments or associated word lists after they are expanded and before they are executed. Equivalent to 'set -x' or 'set -o xtrace'.
An interactive login shell reads /etc/profile first, then looks for ~/.bash_profile, ~/.bash_login, and ~/.profile in order, executing the first one found and ignoring the others. When a login shell exits, it reads ~/.bash_logout if it exists.
bash -O huponexit causes bash to send SIGHUP to all jobs when an interactive login shell exits. This terminates background jobs. Disabled by default.
set -o keyword (or -k) causes all argument assignments to be placed in the environment for a command, not just those before the command name. This allows 'VAR=value command' anywhere in the command line.
bash -O shift_verbose causes the shift builtin to print an error message when the shift count exceeds the number of positional parameters. Without this, silent failure occurs.
set -o allexport (or -a) causes all variable definitions to be automatically exported to the environment of child commands. Any variable assignment or modification will be exported automatically without needing 'export' command.
When bash is invoked as 'sh' or with --posix, and running interactively or with a shell script, it uses the value of ENV variable to name the startup file. Bash expands $ENV and executes commands from that file if it exists and is readable.
Bash starts as a login shell if: invoked with -l or --login option, invoked with argument zero (program name) starting with -, or invoked as a login shell by the system (e.g., from /bin/login). Login shells read /etc/profile and ~/.bash_profile.
The -h option causes bash to remember the location of commands as they are looked up for execution. This is enabled by default and is equivalent to 'set -h' or 'set -o hashall'. It affects command hash table behavior.
The --noprofile option prevents bash from reading the system-wide startup file /etc/profile and any personal startup files (~/.bash_profile, ~/.bash_login, or ~/.profile) for a login shell. This skips all profile initialization.
set -o xtrace (or -x) enables debugging mode where commands are printed after expansion but before execution. Each line is prefixed with PS4 (default: +).
The -f option disables pathname expansion (globbing). This prevents special characters like *, ?, and [...] from being expanded to matching filenames. This is equivalent to 'set -f' or 'set -o noglob'.
bash -O cmdhist causes bash to save multi-line commands in a single history entry. This is enabled by default, allowing easy recall of multi-line commands. Without it, each line is a separate history entry.
set -o noexec (or -n) causes commands to be read but not executed. This is useful for syntax checking scripts. Shell syntax is parsed, but commands are not run.
bash -O dotglob includes filenames beginning with . in the results of pathname expansion. By default, * doesn't match dotfiles. With dotglob, ls * would show .bashrc and other hidden files.
set -o errtrace (or -E) causes ERR traps to be inherited by shell functions, command substitutions, and subshells. Without this, ERR traps only trigger in the main shell, not in these contexts.
-e (errexit) causes bash to exit if any command in a script fails (non-zero exit status), but only checks the last command in a pipeline by default. -o pipefail makes the pipeline exit status be the rightmost non-zero exit, so -e will trigger if any command in the pipe fails.
When bash is invoked with the name 'rbash' (e.g., via symlink or rename), it starts as a restricted shell. This is equivalent to invoking bash with the -r or --restricted option.
bash -O expand_aliases enables alias expansion. Aliases are expanded by default in interactive shells but not in non-interactive shell scripts. This option enables alias expansion in scripts if needed.
The -n option causes bash to read commands but not execute them. This is useful for checking shell scripts for syntax errors. Equivalent to 'set -n' or 'set -o noexec'. bash -n script.sh will check syntax without running.
The --login option is equivalent to -l. It makes bash act as if it had been invoked as a login shell, causing it to read and execute login shell startup files like /etc/profile and ~/.bash_profile.
The -T option causes bash to exit if a pipeline command (not just the entire pipeline) returns a non-zero status. This is stronger than set -e which only looks at the last command in a pipeline. Equivalent to 'set -T' or 'set -o pipefail'.
When invoked with -c, bash runs the command string and does NOT read any startup files. It's a non-interactive, non-login shell. However, if BASH_ENV is set and bash is not in POSIX mode, the file specified by BASH_ENV will be sourced before executing the command.
set -o braceexpand enables brace expansion (the default). This allows patterns like {a,b,c} or {1..5} to expand to multiple words. Disabling with +o braceexpand or set +B turns off this feature.
bash -O failglob causes patterns that match no files to cause an error message rather than being left unexpanded. This is useful for catching typos in glob patterns.
Bash processes options in the order they appear on the command line, but certain options like -c affect behavior immediately. Options like -O, -o can set shell options. After option processing, remaining arguments are: if -c was used, the command string and remaining args become $0, $1, etc.; if no -c, the first remaining arg is the script filename, rest become positional parameters.
The --dump-strings option is equivalent to -D. It causes bash to list all double-quoted strings prefixed with $ to standard output without executing the script. These strings are subject to language translation.
set -o emacs enables Emacs-style command-line editing in the interactive shell. This uses key bindings similar to Emacs editor (Ctrl+F for forward, Ctrl+B for backward, etc.). This is typically the default.
bash -O lastpipe causes the last command in a pipeline to be executed in the current shell, not a subshell. This allows variables set in the last pipeline command to persist after the pipeline completes. Only works when job control is disabled.
The --init-file option is a synonym for --rcfile. It takes a filename as an argument and causes bash to execute commands from that file instead of ~/.bashrc for an interactive shell.
set -o noclobber (or -C) prevents shell redirection from overwriting existing regular files. The > operator will fail if the file exists. Use >| to override.
The -l option makes bash act as if it had been invoked as a login shell. A login shell reads certain startup files like /etc/profile, ~/.bash_profile, ~/.bash_login, or ~/.profile (whichever is found first, the rest are ignored).
When bash is started non-interactively (e.g., to run a shell script), if the environment variable BASH_ENV is set and non-empty, bash expands its value and uses that file as startup file, executing commands from it (like sourcing it). This is similar to ENV in POSIX sh.
bash -O xpg_echo causes the echo builtin to expand backslash escape sequences by default, without requiring -e flag. For example, echo 'hello\nworld' would print an actual newline. Without this option, echo doesn't expand escapes unless -e is used.
When bash is invoked with --posix, it follows POSIX startup rules: as a login shell, it reads /etc/profile and then ~/.profile (not ~/.bash_profile). For non-interactive shells, it checks ENV variable instead of BASH_ENV.
bash -O histverify causes the results of history substitution to be shown for review before execution. The substituted command is loaded into readline buffer, requiring Enter to execute. This prevents accidental execution of wrong history substitutions.
bash -O localvar_inherit causes a local variable in a function to inherit the value and attributes of a variable with the same name at the previous scope. Without this, local variables start unset.
When a login shell is started, the first character of argument zero (the program name) is typically a hyphen (-). This tells bash to read startup files like /etc/profile and ~/.bash_profile. Programs like login traditionally do this.
The --dump-po-strings option outputs strings in GNU gettext PO format with each translatable string formatted as:
#: filename:line
msgid "original string"
msgstr ""
This creates a valid .po file suitable for translation tools.
bash -O histappend causes the history list to be appended to $HISTFILE when the shell exits, rather than overwriting the file. This preserves history from multiple concurrent shell sessions.
bash -O lithist causes newlines in multi-line commands to be saved in the history with embedded newlines rather than using semicolons. This preserves the visual structure of commands in history.
The -t option causes bash to exit after reading and executing one command. Equivalent to 'set -t' or 'set -o onecmd'. This is useful for single-command execution from a pipe or file.
The --posix option changes bash behavior to match the POSIX standard more strictly. This affects: default value of ENV variable, special variables handling, startup files, disabling non-POSIX extensions, and more. It can also be enabled with 'set -o posix' within a running shell.
bash -O direxpand causes directory names to be expanded during word completion. For example, Tab completion of ~/doc would expand to ~/Documents/ rather than keeping it as ~/doc.
set -o pipefail (or -T) causes a pipeline to return the exit status of the last command in the pipe that exited with a non-zero status, or zero if all commands exited successfully. Without this, the pipeline returns the exit status of the last command only.
bash -O extglob enables extended pattern matching features. This allows patterns like !(pattern) - match anything except pattern, @(pattern1|pattern2) - match exactly one, *(pattern) - match zero or more, +(pattern) - match one or more, ?(pattern) - match zero or one.
bash -O checkwinsize checks the window size after each command and updates LINES and COLUMNS if the window size has changed. This is enabled by default in interactive shells.
bash -O globasciiranges causes range expressions in glob patterns like [a-z] to be interpreted in ASCII alphabetical order rather than using the current locale's collation order. This is the default in POSIX mode.
bash -O cdspell corrects minor spelling errors in directory names for cd command. For example, cd /usr/locl might autocorrect to /usr/local. It only works when the corrected component exists.
Use 'set -o' without arguments to display all current shell options and their settings. Use 'set -o optionname' to enable an option, 'set +o optionname' to disable. Use '+o' to display options in a format that can be re-used as input.
bash -O histreedit causes a failed history substitution to be reloaded into the readline editing buffer for correction. Without this, a failed history substitution (like !$ when no previous command) results in an error.
bash -O progcomp_alias causes programmable completion to also attempt alias expansion when completing. This allows completion to work with aliases.
set -o history enables command history (enabled by default). This allows commands to be saved to the history list and recalled. Disabling with +o history or set +H turns off command history saving.
The -D option causes bash to list all double-quoted strings prefixed with $ to standard output. These are the strings that are subject to language translation when the current locale is not C or POSIX. This does not execute the script but extracts translatable strings.
The -c option causes bash to read and execute commands from the first non-option argument argument (which must be present), then exit. Any remaining arguments after the command string are assigned to positional parameters starting at $0. Example: bash -c 'echo hello' world
The -v option causes shell input lines to be echoed as they are read. This shows each line before it's executed, useful for debugging. Equivalent to 'set -v' or 'set -o verbose'. Different from -x which shows the expanded command.
set -o onecmd (or -t) causes bash to exit after reading and executing a single command. This is useful for processing one command at a time from input.
When used with set, -- signifies the end of options. After --, all remaining arguments are assigned to positional parameters ($1, $2, etc.) even if they start with -. This allows setting positional parameters that look like options.
The -i option specifies that the shell should be interactive. This forces bash to behave as an interactive shell even if standard input is not a terminal. An interactive shell enables job control, reads commands from stdin with readline, and displays primary and secondary prompts.
bash -O progcomp enables programmable completion. This is the default and allows bash to use custom completion functions specified with complete and compgen builtins.
bash -O dirspell attempts spelling correction on directory names during completion. Similar to cdspell but works during tab completion, not just cd command.
set -o errexit (-e) exits if a pipeline command returns non-zero, except when the exit status is being tested (if, while, until, !, ||, &&), part of compound command except last, or part of any command in a && or || list except the last. It's disabled in subshells by default unless ERR trap is set.
set +o without arguments displays all current shell options in a format that can be re-input to the shell to restore the current settings. This is useful for saving and restoring option states.
Use 'shopt' without arguments to display all current shopt options and their settings. Use 'shopt -s optionname' to enable (set) an option, 'shopt -u optionname' to disable (unset). Use 'shopt -p' to display in a reusable format.
The --norc option prevents bash from reading the ~/.bashrc initialization file for an interactive shell. It's equivalent to setting --norc or skipping the standard personal rc file.
set -o noclobber (or -C) prevents redirection from overwriting existing files. Using > file will fail if file exists. To force overwrite, use >| instead. This protects against accidental data loss when redirecting output.
bash -O promptvars enables prompt string variable expansion and command substitution in prompt strings like PS1. This is enabled by default. Disabling treats prompts as literal strings without expanding $ variables.
bash -O hostcomplete enables hostname completion when completing words containing @. Tab completion attempts to complete hostnames from /etc/hosts. This is enabled by default in interactive shells.
set -o noglob (or -f) disables pathname expansion (globbing). Wildcards like *, ?, and [...] are not expanded to matching filenames.
When -a is used with set (or bash -a), it automatically export all variables that are subsequently defined or modified. This is equivalent to 'set -a' or 'set -o allexport'. Note: this is typically used with set, not as a direct bash invocation option.
Many bash invocation options can be toggled after startup using the 'set' builtin. For example, 'set -x' enables tracing like -x, 'set +x' disables it. 'set -o errexit' enables -e behavior. However, some options like --norc, --noprofile, --rcfile only affect startup and cannot be changed later.
bash -v (verbose) prints shell input lines as they are read, before any expansion. bash -x (xtrace) prints commands after expansion but before execution. So -v shows what's in the script file, while -x shows what bash will actually execute with variables expanded.
bash -O nullglob causes patterns that match no files to expand to a null string rather than the pattern itself. Without this, echo .nonexistent prints '.nonexistent'; with nullglob it prints nothing.
set -o nounset (or -u) causes unset variables to be treated as an error when performing parameter expansion. An error is printed to stderr and the shell exits.
bash +O optionname disables (unsets) a shopt option. For example, bash +O extglob script.sh disables extended globbing. The + prefix means 'disable' while -O means 'enable'.
The -P option causes bash to not follow symbolic links when executing commands like cd that change the current working directory. It uses the physical directory structure instead. Equivalent to 'set -P' or 'set -o physical'.
set -o vi enables Vi-style command-line editing in the interactive shell instead of Emacs mode. This uses key bindings similar to the vi editor (ESC to enter command mode, i for insert mode, etc.).
set -o functrace (or -T) causes DEBUG and RETURN traps to be inherited by shell functions and command substitutions. This enables debugging in function calls.
The -k option causes all arguments assignment statements to be placed in the environment for a command, not just those preceding the command name. This allows variable assignments anywhere in the command line. Equivalent to 'set -k' or 'set -o keyword'.
The -B option enables brace expansion (equivalent to set -o braceexpand). This is enabled by default and allows patterns like {a,b,c} to expand to 'a b c' or {1..5} to '1 2 3 4 5'.
shopt -q optionname suppresses output and returns exit status 0 if the option is enabled, 1 if disabled. This is useful for testing option state in scripts without printing anything.
The -C option prevents bash from overwriting existing files with > redirection. You can still override this with >| operator. Equivalent to 'set -C' or 'set -o noclobber'. This provides protection against accidental file overwrites.
bash -O checkhash causes bash to check if a command found in the hash table still exists before executing it. If the command has been deleted, it's searched for in PATH again. This is off by default.
The --norc option prevents bash from reading ~/.bashrc for an interactive shell. This skips the personal initialization file that would normally be sourced by interactive non-login shells.
When invoked as 'sh', bash reads /etc/profile and then ~/.profile if it's a login shell. For non-interactive shells, it doesn't read any startup files. It does NOT read ~/.bashrc or /etc/bash.bashrc when invoked as sh.
set -o ignoreeof prevents an interactive shell from exiting upon receiving EOF (Ctrl+D). The user must use 'exit' or 'logout' instead. This prevents accidental shell termination from pressing Ctrl+D.
The --version option displays version information about this instance of bash and then exits successfully. This shows the bash version number, release status, and copyright information.
When using bash -c 'command_string', arguments after the command string are assigned to positional parameters starting at $0. For example: bash -c 'echo $0 $1 $2' arg0 arg1 arg2 prints 'arg0 arg1 arg2'. The command string itself is not assigned to any parameter.
When bash is invoked with the name 'sh' (e.g., via a symlink), it tries to mimic the startup behavior of historical versions of sh as closely as possible while conforming to POSIX. In this mode, bash doesn't read ~/.bashrc and looks for ENV variable for its interactive startup file.
The +T option disables the DEBUG and RETURN trap inheritance (disables functrace). This is the opposite of -T which enables it.
set -o huponexit causes bash to send SIGHUP to all jobs when an interactive login shell exits. This terminates background jobs when you log out. Disabled by default.
set -o physical (or -P) causes bash to not follow symbolic links when changing directories with cd. It uses the physical directory structure instead of the logical one with symlinks.
bash -O execfail causes a non-interactive shell to not exit if it cannot execute the file specified as an argument (e.g., the script file doesn't exist or isn't executable). The shell just reports the error and continues. Default is to exit.
bash -O sourcepath enables the source builtin to use PATH to find the file to source. This is enabled by default. If disabled, source only looks in the current directory.
The -p option turns on privileged mode. In this mode, the $BASH_ENV and $ENV files are not processed, shell functions are not inherited from the environment, and SHELLOPTS, BASHOPTS, CDPATH, and GLOBIGNORE are ignored if set in the environment. This is used when bash runs with real/effective UID/GID differences.
The -b option causes bash to report termination status of background jobs immediately, rather than waiting until just before printing the next primary prompt. This is equivalent to 'set -b' or 'set -o notify'.
bash -O nocasematch causes pattern matching in [[ ... ]] and case statements to be case-insensitive. For example, [[ $name == 'test' ]] matches 'test', 'TEST', 'TeSt', etc.
set -o histexpand (or -H) enables history expansion using ! character. This allows !! (last command), !$ (last argument), !n (command number n), etc. Disabling with +o histexpand turns this feature off.
When bash is invoked without options on a terminal (stdin is a tty), it starts as an interactive, non-login shell. It reads ~/.bashrc for initialization. It enables job control, readline editing, and displays prompts.
The --debugger option arranges for the debugger profile to be executed before the shell starts. This allows debugging facilities to be enabled at shell startup. It is equivalent to --debugger or -T but with more explicit naming.
The --noediting option prevents bash from using the GNU Readline library for command-line editing when running interactively. This disables command history, line editing, and tab completion in interactive sessions.
bash -O mailwarn causes bash to print a warning message when a mail file is accessed after the shell has first noticed that mail exists in it. This warns if mail was already read.
The --rcfile option takes a filename as an argument and causes bash to execute commands from that file instead of ~/.bashrc for an interactive shell. Example: bash --rcfile /my/custom/rcfile
The -r option makes the shell restricted. A restricted shell cannot: change directories with cd, change the value of SHELL, PATH, ENV, or BASH_ENV, specify command names containing /, redirect output using >, >|, <>, >&, &>, or >>, or turn off restricted mode with set +r or set +o restricted.
set -o hashall (or -h) enables command hashing (default). Bash remembers the location of commands in a hash table to avoid PATH searches. Disabling with +o hashall turns off this optimization.
The -G option causes the pattern '**' to match all files and zero or more directories and subdirectories when used in pathname expansion. This enables recursive globbing (requires globstar).
An interactive non-login shell (not started with -l or name not starting with -) reads ~/.bashrc for initialization. This happens unless invoked with --norc. The system-wide /etc/bash.bashrc may also be read if configured.
The +O option disables (unsets) the shopt option named by the following option argument. This is the opposite of -O. Example: bash +O extglob script.sh disables extended pattern matching.
The -- option signals the end of options. All arguments after -- are treated as filenames and arguments, even if they start with -. This allows handling filenames that begin with -. Example: bash -- -x script.sh treats -x as a filename, not an option.
The +E option disables ERR trap inheritance. This is the opposite of -E. When disabled, ERR traps are not inherited by shell functions, command substitutions, or subshell commands.
The --wordexp option causes bash to print the word expansion results and exit. This shows how bash would expand arguments without executing them. This is a debugging option to test brace expansion, tilde expansion, parameter expansion, etc.
bash -O no_empty_cmd_completion prevents attempting completion on an empty line. Without this, pressing Tab on an empty line shows all available commands.
The -m option enables job control. This is enabled by default for interactive shells and allows background job control with commands like bg, fg, jobs, etc. Equivalent to 'set -m' or 'set -o monitor'.
shopt -u optionname disables (unsets) a shell option. This is the opposite of -s which sets/enables options. Example: shopt -u dotglob disables dotglob.
set -o monitor (or -m) enables job control. This allows background/foreground jobs, bg, fg, jobs commands. This is on by default for interactive shells.
When an option is prefixed with + instead of -, it disables that option. For example: bash +o posix disables POSIX mode, bash +x disables command tracing. This is the opposite behavior of the - prefix which enables options.
The -e option causes bash to exit immediately if a command exits with a non-zero status (with some exceptions like pipelines with '!', while/until loops, if conditions, etc.). This is equivalent to 'set -e' or 'set -o errexit'.
When used with shopt, -- marks the end of options. After --, all remaining arguments are treated as option names even if they start with -. This allows setting options that look like flags.
The -O option enables (sets) the shopt option named by the following option argument. This allows setting shell options like extglob, dotglob, etc. at invocation time. Example: bash -O extglob script.sh enables extended pattern matching.
The -H option enables ! style history expansion. This is on by default for interactive shells. It allows commands like !!, !$, !n to reference history. Equivalent to 'set -H' or 'set -o histexpand'.
Bash determines if it's interactive by checking: if it's started with -i option, if standard input is a terminal (tty), and if the -c option is NOT present, and if the -s option is present (implying stdin reading). An interactive shell has job control enabled, displays prompts (PS1/PS2), and reads commands with readline.
The --restricted option makes the shell restricted. This is equivalent to the -r option. A restricted shell has limitations on commands that can change the working environment or run other programs.
The --verbose option is equivalent to set -v. It causes shell input lines to be echoed as they are read. This prints each command before executing it, useful for debugging scripts.
The -u option causes bash to treat unset variables as an error when performing parameter expansion. An error message will be written to stderr and the shell will exit. Equivalent to 'set -u' or 'set -o nounset'.
bash -O nocaseglob enables case-insensitive pathname matching. When globbing, * matches both uppercase and lowercase files. For example, *.txt matches file.TXT and file.txt. This is a shopt option, not a set option.
The -s option causes bash to read commands from standard input. This allows positional parameters to be set even when reading from stdin. If there are no arguments remaining after option processing, bash reads from stdin. Any remaining arguments are assigned to positional parameters.
The --help option displays a usage message and exits successfully. This shows a brief summary of bash command-line options and then terminates the shell.
bash -O localvar_unset causes unset of a local variable to unset the variable at all higher scopes. Without this, unsetting a local variable only unsets the local scope, revealing the variable from the calling scope.
The --pretty-print option is an alias for --pretty-print which formats the output in a more readable way when used with options like -O shopt. When combined with +O, it displays shopt options in a formatted table.
Bash Builtin Commands > Bourne Shell Builtins
72 questionsThe times builtin prints the accumulated user and system times for the shell and for all processes run as children of the shell. It outputs two lines: one for the shell and one for child processes.
The -d option for read specifies the delimiter character that marks the end of input (instead of newline). The first character of delim is used. If delim is empty, read reads until a NUL character.
When read encounters EOF without reading any characters (either because -n N was satisfied or the input was empty), it returns a non-zero exit status (failure).
With set -e, the shell exits immediately if a simple command fails. However, the exit status of a pipeline is the status of the last command by default. Use set -o pipefail to make the pipeline fail if any command in it fails.
The ulimit -m option controls the maximum resident set size (memory size) of the shell, in kilobytes.
When echo writes to a closed pipe, it receives a SIGPIPE signal and typically exits with status 141 (128 + 13). This happens when the reading end of a pipe has terminated.
The -r option for read disables backslash escaping. This prevents the backslash from acting as an escape character, so backslashes are treated literally.
When readonly is invoked with the -p option and no variable names, it displays all readonly variables in a format that can be reused as input to the shell. Each is displayed with 'declare -r' prefix.
When cd fails (e.g., directory doesn't exist, permission denied), it returns a non-zero exit status (1) and prints an error message to stderr.
When unset attempts to unset a variable that doesn't exist, it returns a non-zero exit status (failure) and displays an error message. Use the -f option to unset functions and -v for variables.
The false builtin always returns an exit status of 1 (failure). It does nothing and fails.
The ulimit -a option displays all current resource limits. It shows both soft limits (unless -H is specified) for all available resource types.
If break is used with an argument n greater than the number of enclosing loops, bash returns a non-zero exit status and only breaks out of the outermost loop.
The -n option in the read builtin specifies the number of characters to read (not the number of bytes). When -n N is used, read returns after reading exactly N characters or on EOF.
When read times out (due to -t option), it returns a non-zero exit status (greater than 128) indicating the timeout occurred.
trap 'command' SIGINT sets the handler for SIGINT to execute 'command', while trap - SIGINT resets the signal handler for SIGINT to its default action. An empty string '' would ignore the signal entirely.
The : (colon) builtin does nothing and returns a successful exit status (0). It is also known as the null command and is often used for providing side effects like variable assignment or as a placeholder in then/else clauses.
$0 contains the name of the shell or shell script. This is set at shell initialization and is not modified by the shift builtin.
The export -n option removes the export property from each specified variable, causing it to no longer be exported to child processes. The variable itself remains defined in the current shell.
If CDPATH is set, cd searches each colon-separated directory in CDPATH for the target directory. If the directory is found in CDPATH, cd prints the full path of the new directory.
The set -x option causes the shell to print each command and its expanded arguments as it is executed. This is useful for debugging - you see the actual values being used.
SIGTERM is signal number 15. It is the default signal sent by the kill command to terminate a process.
The -a option for read makes it read words into an indexed array, starting at index 0. Each word becomes an array element.
The umask -S option causes the mask to be printed in symbolic form (e.g., u=rwx,g=rx,o=rx) rather than octal.
The set -f option disables pathname expansion (globbing). This prevents the shell from expanding wildcards like *, ?, and [..] into filenames.
Yes, the cd builtin updates the PWD variable to the new working directory after successfully changing directories. If the -P option is used, $PWD is set to the physical directory path with symbolic links resolved.
Yes, cd without any arguments or with cd - changes to $OLDPWD, which is the previous working directory. cd - also prints the new working directory path.
When help is asked about a non-existent builtin, it returns a non-zero exit status and prints an error message.
The echo builtin returns 0 (success) regardless of whether -n is used or not. The -n option suppresses the trailing newline but does not affect the exit status.
The ulimit -v option controls the maximum amount of virtual memory available to the shell and its child processes, in kilobytes.
When pwd is invoked with the -P option (physical), it prints the absolute pathname of the current working directory with all symbolic links resolved. Without -P, it may print the logical pathname with symbolic links intact.
The set -v option causes the shell to print each command as it is read, before executing it. This is useful for debugging shell scripts.
When eval is given no arguments, it returns a status of 0. It does nothing and succeeds.
The set -o option enables a shell option, while set +o disables it. For single-letter options, set -option enables and set +option disables (e.g., set -e enables exit-on-error, set +e disables it).
Yes, export marks variables for export to child processes, but the variables remain available in the current shell as well. Exported variables are available to child processes but not to parent processes.
exit terminates the shell or script, while return returns from a function or sourced script. In the main script (not a function), return behaves like exit and terminates the script.
Yes, the break builtin accepts an optional argument n, which specifies the number of enclosing loops to exit from. If n is not specified, break exits from the innermost enclosing loop. n must be >= 1.
The : (colon) builtin always returns exit status 0 (success), regardless of its arguments.
When wait is invoked with no arguments, it waits for all background jobs to complete and returns the exit status of the last command that was waited for.
When hash is invoked with no arguments, it lists all remembered command locations (the hash table of command paths). This shows the full path of each command that has been executed.
The ulimit -u option controls the maximum number of user processes (threads) that can be created by the shell.
The ulimit -n option controls the maximum number of open file descriptors for the shell and its child processes.
If shift n is given a value greater than $# (the number of positional parameters), shift returns exit status 1 (failure) and does not modify the positional parameters.
No, the source (or .) builtin reads and executes commands from a file without requiring it to be executable. It executes commands in the current shell environment, unlike executing a script which creates a subshell.
The . (source) builtin executes commands from a file in the current shell environment, preserving variable changes and side effects. Executing a script directly runs it in a subshell, so variable changes are not preserved in the parent shell.
When umask is invoked with no arguments, it displays the current file creation mask in octal format. This mask determines which permission bits are cleared when creating new files.
When trap is invoked with no arguments, it prints a list of all signal handlers and the commands associated with each, in a format that can be reused as shell input.
If no status is given to the return builtin, it returns the exit status of the last command executed.
No, the shift builtin does not accept negative numbers. The shift builtin shifts positional parameters to the left by n (default 1). The number must be a non-negative integer less than or equal to $#.
Limits set by ulimit affect the current shell and all child processes spawned from it. Child processes inherit the limits.
When invoked with no arguments, the export builtin displays a list of all exported variables in a format that can be reused as input to the shell. Each exported variable is displayed with 'declare -x' prefix.
No, a readonly variable cannot be unset or have its value changed. Attempting to unset a readonly variable or modify its value results in an error.
No, unset cannot unset readonly variables or functions. Attempting to unset a readonly variable results in an error message and the variable remains set.
The set -n option causes the shell to read commands but not execute them. This is useful for syntax checking shell scripts.
The hash -r option empties the hash table, causing the shell to forget all remembered command locations. The next time each command is invoked, its path will be searched for again.
The ulimit -S option sets or displays the soft limit for a resource. The soft limit is the current enforced limit and can be raised up to the hard limit.
The hash -d option removes the specified commands from the hash table, causing the shell to forget their locations. The next invocation will search for the command again.
When trap is given an empty string ('') as the command for a signal, that signal is ignored by the shell and all commands it executes. The signal handling is reset to the default action when the command is '-' (a single dash).
The help builtin displays help information for shell builtins. When invoked without arguments, it lists all builtins. It cannot be used to display help for external commands.
The value of n in shift n must be less than or equal to $# (the number of positional parameters). If n is greater than $#, shift returns a non-zero exit status and does not change the positional parameters.
Yes, if return is used outside of a function or a script executed with the . or source commands, it causes the shell to exit with the specified status. If used in a function, it returns from the function.
No, the hard limit can only be decreased, not increased (unless you have root privileges). The hard limit is the maximum possible value and cannot be raised except by a privileged process.
The ulimit -H option sets or displays the hard limit for a resource. The hard limit is the maximum value to which the soft limit can be raised.
The ulimit -c option controls the maximum size of core files created when a program terminates abnormally, in 512-byte blocks.
When exec successfully replaces the shell with a new command, the exit status of the exec command is the exit status of the new command. If exec fails to find or execute the command, the shell exits with a non-zero status.
The help -s option displays a short usage summary for each specified builtin, rather than the full detailed help text.
The continue builtin accepts an optional argument n, which specifies the number of enclosing loops to skip to the next iteration of. If n is not specified, continue continues with the next iteration of the innermost enclosing loop. n must be >= 1.
The default core file size limit (ulimit -c) is typically 0 blocks, meaning core files will not be created when a program crashes.
When IFS is unset, read uses the default delimiters: space, tab, and newline. The words are split on whitespace and leading/trailing whitespace is ignored.
Yes, the exit builtin executes any trap commands set on the EXIT signal before the shell terminates. This allows cleanup actions to be performed.
The set -u option treats unset variables as an error when expanding. If an unset variable is expanded, bash displays an error message and exits (if not interactive). This helps catch typos in variable names.
The true builtin always returns an exit status of 0 (success). It does nothing and succeeds.
Modifying Shell Behavior > Completion and Readline Integration
69 questionsThe -q option queries about which keys invoke the named function. For example: 'bind -q reverse-search-history' shows which keys are bound to that function.
If set to a negative value, readline will never ask whether to view completions; they are simply listed immediately.
The default value is Off. When set to On, tilde expansion is performed when readline attempts word completion.
The default value is Off. When set to On, menu completion displays the common prefix of the list of possible completions (which may be empty) before cycling through the list.
COMP_TYPE is set to an integer value corresponding to the type of completion attempted: TAB for normal completion, '?' for listing completions after successive tabs, '!' for listing alternatives on partial word completion, '@' to list completions if the word is not unmodified, or '%' for menu completion.
The -E option applies the completions and actions to 'empty' commands -- completion attempted on a blank line (before any command is typed).
COMP_WORDS is an array variable consisting of the individual words in the current command line. The line is split into words as readline would split it, using COMP_WORDBREAKS. This variable is available only in shell functions and external commands invoked by the programmable completion facilities.
The compgen builtin displays possible completions depending on the options. It is intended to be used from within a shell function generating possible completions. If the optional WORD argument is supplied, matches against WORD are generated.
COMP_LINE contains the current command line. This variable is available only in shell functions and external commands invoked by the programmable completion facilities.
The default value is Off. When set to On, readline attempts to briefly move the cursor to an opening parenthesis when a closing parenthesis is inserted.
If multiple options are supplied, the -D option takes precedence over -E, and both take precedence over -I.
The -I option applies the completions and actions to the initial (usually the command) word. It allows defining completion for the command name itself.
The -V option lists readline variable names and values (without formatting for reuse).
The default value is Off. When set to On, history lines that have been modified are displayed with a preceding asterisk (*).
The default value is On. When set to On, readline allows certain commands to designate the region as active. When active, readline highlights the text in the region using the value of active-region-start-color.
The default value is Off. When set to On, this alters the default completion behavior when inserting a single match into the line. It's only active when performing completion in the middle of a word, and readline does not insert characters from the completion that match characters after point.
The -p option lists readline functions and bindings in a form that can be reused as input.
The default value is unset, which means the number of history entries is not limited. If set to zero, existing history entries are deleted and no new entries are saved. If set to a value less than zero, the number of history entries is not limited.
The default value is Off. 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 acceptable keymap names are: emacs, emacs-standard, emacs-meta, emacs-ctlx, vi, vi-move, vi-command, and vi-insert.
COMP_POINT is 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}.
The default value is Off. When 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 -s option lists key sequences that invoke macros and their values in a form that can be reused as input.
The default value is Off. When set to On, 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. This setting is automatically enabled for terminals of height 1.
COMPREPLY is an array variable from which bash reads the possible completions generated by a shell function invoked by the programmable completion facility. Each array element contains one possible completion.
The default value is On. When set to On, readline uses an internal more-like pager to display a screenful of possible completions at a time.
The -X option lists key sequences bound with -x and associated commands in a form that can be reused as input.
The comment-begin variable is the string that is inserted in vi mode when the insert-comment command is executed. This command is bound to M-# in emacs mode and to # in vi command mode. The default value is '#'.
The compopt builtin modifies or displays completion options for each NAME, or if no NAMEs are supplied, the completion currently being executed. If no OPTIONs are given, it prints the completion options for each NAME or the current completion specification.
If an attempt is made to set history-size to a non-numeric value, the maximum number of history entries will be set to 500.
COMP_WORDBREAKS is the set of characters that the readline library treats as word separators when performing word completion. If COMP_WORDBREAKS is unset, it loses its special properties, even if it is subsequently reset.
The default value is 'emacs'. This variable controls whether readline begins with a set of key bindings similar to Emacs or vi. editing-mode can be set to either 'emacs' or 'vi'.
The default value is On. When set to On, readline will try to enable any meta modifier key the terminal claims to support when it is called. On many terminals, the meta key is used to send eight-bit characters.
The default value is 'C-[ C-J' (ESC and C-J). This is the string of characters that should terminate an incremental search without subsequently executing the character as a command.
The -x option causes a shell command to be executed when KEYSEQ is entered. The syntax is: bind '-x keyseq:shell-command'. This allows binding key sequences to shell commands rather than readline functions.
The -v option lists readline variable names and values in a form that can be reused as input.
The default value is Off. When set to On, completed names which are symbolic links to directories have a slash appended (subject to the value of mark-directories).
The default value is On. When set to On, completed directory names have a slash appended.
The default value is Off. When set to On, words which have more than one possible completion without any possible partial completion (the possible completions don't share a common prefix) cause the matches to be listed immediately instead of ringing the bell.
The default value is Off. When set to On, a string is added to the beginning of the prompt indicating the editing mode: emacs, vi command, or vi insertion.
Use '+o' instead of '-o' to turn off the specified option. For example: 'compopt +o nospace' turns off the nospace option.
The default value is On. When set to On, readline will convert characters with the eighth bit set to an ASCII key sequence by stripping the eighth bit and prefixing it with an escape character. readline will set it to Off if the locale contains eight-bit characters.
When a variable value is read, empty or null values, 'on' (case-insensitive), and '1' are equivalent to On. All other values are equivalent to Off.
The default value is 100. This variable determines when the user is queried about viewing the number of possible completions. If the number of possible completions is greater than or equal to this value, readline will ask whether the user wishes to view them.
The -p option prints existing completion specifications in a reusable format that allows them to be reused as input.
The default value is -1. This variable controls the number of screen columns used to display possible matches when performing completion. A value of 0 displays matches one per line. The value is ignored if less than 0 or greater than terminal screen width.
The default value is Off. When set to On, and completion-ignore-case is enabled, readline treats hyphens (-) and underscores (_) as equivalent when performing case-insensitive filename matching and completion.
The default value is Off. When set to On, readline displays completions with matches sorted horizontally in alphabetical order, rather than down the screen.
The default value is 0. This variable specifies the length in characters of the common prefix of possible completions that is displayed without modification. When set to a value greater than zero, common prefixes longer than this value are replaced with an ellipsis.
The default value is On. When set to On, readline attempts to bind the control characters treated specially by the kernel's terminal driver to their readline equivalents.
Readline reads from the file specified by the INPUTRC environment variable. If INPUTRC is unset, the default is ~/.inputrc. If that file does not exist or cannot be read, the ultimate default is /etc/inputrc.
The -r option removes a completion specification for each NAME specified, or if no NAMEs are supplied, all completion specifications.
The default value is 500 (milliseconds). This specifies how long readline will wait for a character when reading an ambiguous key sequence. If set to a value less than or equal to zero, or to a non-numeric value, readline will wait until another key is pressed.
The -D option applies the completions and actions as the default for commands without any specific completion defined. It is used to define fallback completion behavior.
COMP_CWORD is an index into COMP_WORDS of the word containing the current cursor position. This variable is available only in shell functions and external commands invoked by the programmable completion facilities.
The default value is Off. When set to On, readline performs filename matching and completion in a case-insensitive fashion.
The default value is Off. When set to On, readline will undo all changes to history lines before returning when accept-line is executed. By default, history lines may be modified and retain individual undo lists across calls to readline.
The readline 'bell-style' variable accepts three values: 'none' (never rings the bell), 'visible' (uses a visible bell if available), or 'audible' (attempts to ring the terminal's bell). The default value is 'audible'.
The default value is On. When set to On, readline configures the terminal to insert each paste into the editing buffer as a single string of characters, instead of treating each character as if it had been read from the keyboard.
COMP_KEY contains the key (or final key of a key sequence) used to invoke the current completion function.
The default value is Off. When set to On, words which have more than one possible completion cause the matches to be listed immediately instead of ringing the bell.
Both variables default to Off. 'colored-completion-prefix' displays the common prefix of possible completions in a different color when On. 'colored-stats' displays possible completions using different colors to indicate file type when On. Both use color definitions from LS_COLORS.
Bash Builtin Commands > Shell Behavior Modification
68 questionsThe set -f option disables pathname expansion (globbing). This means that wildcard characters like *, ?, and [...] are not expanded to match filenames.
The current set of options can be found in the $- special variable. This variable contains the letters of all currently enabled single-letter options.
The set -b option causes bash to report the status of terminated background jobs immediately, rather than before the next primary prompt. This is effective only when job control is enabled.
When shopt -s dirspell is set, bash attempts spelling correction on directory names during word completion if the directory name initially supplied does not exist.
The set -a option causes each variable or function that is created or modified to be given the export attribute and marked for export to the environment of subsequent commands.
When shopt -s shift_verbose is set, the shift builtin prints an error message when the shift count exceeds the number of positional parameters.
The set -m option enables monitor mode (job control). This option is on by default for interactive shells on systems that support it. All processes run in a separate process group. When a background job completes, the shell prints a line containing its exit status.
The special parameters '@' and '', or array variables subscripted with '@' or '', are exempt from the nounset (-u) option. The nounset option treats unset variables and parameters as an error except for these special cases.
When shopt -s complete_fullquote is set, readline library filename completion quotes all filenames that contain shell metacharacters or characters in the value of the shell variable compseps. This option is enabled by default.
When shopt -s cdable_vars 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.
When shopt -s no_empty_cmd_completion is 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.
When shopt -s noexpand_translation is set, bash encloses the translated results of $"..." quoting in single quotes instead of double quotes. If the string is not translated, this has no effect.
When shopt -s cmdhist is set, bash attempts to save all lines of a multi-line command in the same history entry. This allows easy re-editing of multi-line commands. This option is enabled by default, but only has an effect if command history is enabled.
The login_shell option is set by bash if the shell is started as a login shell. This option is read-only and cannot be unset or modified.
When set -E is set, any trap on ERR is inherited by shell functions, command substitutions, and commands executed in a subshell environment. The ERR trap is normally not inherited in such cases.
When shopt -s histreedit is set, and readline is being used, a user is given the opportunity to re-edit a failed history substitution.
The set -v option causes bash to print shell input lines as they are read.
Using + rather than - with the set command causes options to be turned off. For example, set +e disables errexit, set +u disables nounset, and set +o pipefail disables pipefail.
The set -t option causes the shell to exit after reading and executing one command.
The set -H option enables ! style history substitution (like !! for the previous command). This option is on by default when the shell is interactive.
When shopt -s nocaseglob is set, bash matches filenames in a case-insensitive fashion when performing pathname expansion.
The shopt -u option disables (unsets) each specified optname. For example, shopt -u dotglob disables the dotglob option.
When set -P is enabled, the shell does not resolve symbolic links when executing commands such as cd that change the current working directory. It uses the physical directory structure instead. By default, bash follows the logical chain of directories when performing commands which change the current directory.
When shopt -s checkwinsize is set, bash checks the window size after each external (non-builtin) command and, if necessary, updates the values of LINES and COLUMNS. This option is enabled by default.
When shopt -s execfail 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.
Using set -o displays the current shell options in a readable format. Using set +o displays a series of set commands to recreate the current option settings. Using shopt displays all shopt options and their status. Using shopt -p displays them in a reusable format.
When shopt -s checkhash 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.
When shopt -s inherit_errexit is set, command substitution inherits the value of the errexit option, instead of unsetting it in the subshell environment. This option is enabled when posix mode is enabled.
When shopt -s huponexit is set, bash will send SIGHUP to all jobs when an interactive login shell exits.
When shopt -s force_fignore is set, the suffixes specified by the FIGNORE shell variable cause words to be ignored when performing word completion even if the ignored words are the only possible completions. This option is enabled by default.
When shopt -s failglob is set, patterns which fail to match filenames during pathname expansion result in an expansion error. Without this option, non-matching patterns are either left unchanged (default) or removed (if nullglob is set).
When shopt -s hostcomplete is set, and readline is being used, bash will attempt to perform hostname completion when a word containing a @ is being completed. This option is enabled by default.
When set -o posix is used, bash changes its behavior where the default operation differs from the POSIX standard to match the standard (posix mode). This affects many aspects of shell behavior to ensure compliance with POSIX.
When shopt -s globasciirange is set, bash uses the traditional POSIX behavior for range expressions in pattern matching. That is, the current locale's collating sequence is not taken into account, so 'b' will not collate between 'A' and 'B', and upper-case and lower-case ASCII characters will collate together.
The shopt -s option enables (sets) each specified optname. For example, shopt -s dotglob enables the dotglob option.
The shopt -q option suppresses normal output (quiet mode). 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.
When shopt -s nocasematch is set, bash matches patterns in a case-insensitive fashion when executing case or [[ conditional commands, when performing pattern substitution word expansions, or when filtering possible completions as part of programmable completion.
When shopt -s direxpand is set, bash replaces directory names with the results of word expansion when performing filename completion. This changes the contents of the readline editing buffer. If not set, bash attempts to preserve what the user typed.
After expanding each simple command, for command, case command, select command, or arithmetic for command, bash displays the expanded value of PS4, followed by the command and its expanded arguments or associated word list. This is useful for debugging scripts.
When shopt -s expand_aliases is set, aliases are expanded as described under ALIASES. This option is enabled by default for interactive shells. Aliases are not expanded when the shell is not interactive, unless the expand_aliases shell option is set using shopt.
When shopt -s lithist is set, and the cmdhist option is enabled, multi-line commands are saved to the history with embedded newlines rather than using semicolon separators where possible.
When shopt -s extquote is set, $'string' and $"string" quoting is performed within ${parameter} expansions enclosed in double quotes. This option is enabled by default.
The set -e option causes bash to exit immediately if a pipeline (which may consist of a single simple command), a list, or a compound command exits with a non-zero status. The shell does not exit if the command that fails is part of the command list immediately following a while or until keyword, part of the test following the if or elif reserved words, part of any command executed in a && or || list except the command following the final && or ||, any command in a pipeline but the last, or if the command's return value is being inverted with !.
When shopt -s globstar is set, the pattern ** used in a pathname expansion context will match all files and zero or more directories and subdirectories. If the pattern is followed by a /, only directories and subdirectories match.
The set -B option enables the shell to perform brace expansion. This option is on by default. Brace expansion allows generation of arbitrary strings like {a,b,c} which expands to 'a b c'.
The set -h option causes bash to remember the location of commands as they are looked up for execution. This is enabled by default. This is the command hashing mechanism.
When shopt -s histverify is set, and readline is being used, the results of history substitution are not immediately passed to the shell parser. Instead, the expanded line is reloaded into the readline editing buffer for further modification.
The set -k option causes all arguments in the form of assignment statements to be placed in the environment for a command, not just those that precede the command name.
When shopt -s nullglob is set, bash allows patterns which match no files to expand to a null string, rather than being left unchanged. Without this option, if no matching filenames are found, the word is left unchanged.
When shopt -s xpg_echo is set, the echo builtin expands backslash escape sequences by default.
The set -u option treats unset variables and parameters other than the special parameters '@' and '', or array variables subscripted with '@' or '', as an error when performing parameter expansion. If expansion is attempted on an unset variable or parameter, the shell prints an error message, and, if not interactive, exits with a non-zero status.
When set -T is set, any traps on DEBUG and RETURN are inherited by shell functions, command substitutions, and commands executed in a subshell environment. The DEBUG and RETURN traps are normally not inherited in such cases.
When shopt -s gnu_errfmt is set, shell error messages are written in the standard GNU error message format.
The shopt -p option displays all settable options in a form that may be reused as input. 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.
When set -C is enabled, bash does not overwrite an existing file with the >, >&, and <> redirection operators. This can be overridden when creating output files by using the redirection operator >| instead of >.
When shopt -s autocd is set, a command name that is the name of a directory is executed as if it were the argument to the cd command. This option is only used by interactive shells.
When shopt -s promptvars is set, prompt strings undergo parameter expansion, command substitution, and arithmetic expansion after being expanded. This option is enabled by default.
The -- option signals the end of options. All remaining arguments are assigned to the positional parameters. The -x and -v options are turned off. If there are no args, the positional parameters remain unchanged.
Setting GLOBIGNORE to a non-null value has the effect of enabling the dotglob shell option, so all 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. The filenames '.' and '..' are always ignored when GLOBIGNORE is set and not null.
When shopt -s globskipdots is set, pathname expansion will never match the filenames '.' and '..', even if the pattern begins with a '.'. This option is enabled by default.
When set -o pipefail is enabled, the return value of a pipeline is the value of the last (rightmost) command to exit with a non-zero status, or zero if all commands in the pipeline exit successfully. This option is disabled by default. Without this option, the return status of a pipeline is the exit status of the last command.
When shopt -s sourcepath is 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.
When shopt -s cdspell is 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 one character too many. If a correction is found, the corrected filename is printed, and the command proceeds. This option is only used by interactive shells.
The set -r option enables restricted shell mode. This option cannot be unset once it has been set.
When shopt -s patsub_replacement is set, bash expands occurrences of & in the replacement string of pattern substitution to the text matched by the pattern. This option is enabled by default.
When shopt -s extglob is set, the extended pattern matching features are enabled. This includes patterns like ?(pattern-list) for zero or one occurrence, *(pattern-list) for zero or more, +(pattern-list) for one or more, @(pattern-list) for one of the given patterns, and !(pattern-list) for anything except the given patterns. The extglob option changes the behavior of the parser, so it must be enabled before parsing constructs containing the patterns.
When shopt -s histappend is 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. By default, the history file is overwritten.
Shell Variables > Interactive Shell Behavior
68 questionsWhen checkwinsize is enabled, Bash checks the window size after each command and, if necessary, updates the values of LINES and COLUMNS. This option is enabled by default.
When histreedit is enabled, and readline is being used, a user is given the opportunity to re-edit a failed history substitution.
When nocasematch is enabled, Bash performs pattern matching in a case-insensitive fashion during case command and [[ conditional command matching. This affects both pattern matching and regular expression matching with =~.
HISTIGNORE contains a colon-separated list of patterns used to decide which commands should be saved on the history list. Patterns containing '&' are ANDed with previous patterns, and patterns containing '|' are ORed. A pattern is matched against the full command line. An '&' pattern matches the previous line. For example, setting HISTIGNORE='ls:ps:pwd' will prevent those commands from being saved in history.
When globstar is enabled, the ** pattern in a pathname expansion context will match all files and zero or more directories and subdirectories. If followed by a /, it matches only directories and subdirectories. This pattern is recursive and can be very powerful for deep directory searches.
When dotglob is enabled, Bash includes filenames beginning with a '.' (dot) in the results of filename expansion. Note that filenames '.' and '..' are never included.
When mail_warn is enabled, Bash displays a warning message before printing the primary prompt if mail has been received since the last time the mail was checked. This option is only available in interactive shells.
When lithist is enabled, and cmdhist is enabled, multi-line commands are saved to the history with embedded newlines rather than using semicolon separators where possible. This preserves the visual structure of the command in history.
When histverify is enabled, and readline is being used, the results of history substitution are not immediately passed to the shell parser. Instead, the expanded line is reloaded into the readline editing buffer for further modification.
INPUTRC contains the filename for the readline startup file, overriding the default ~/.inputrc. If unset, readline reads from ~/.inputrc. If that file doesn't exist, it uses /etc/inputrc.
LC_ALL overrides the value of LANG and any other LC_ variable specifying a locale category. It provides a way to set all locale categories to a single locale.
REPLY stores the user's input when the read builtin is called without variable arguments. It is also used by the select command to store the user's selection. This default variable is used when no variable name is supplied to read or select.
When expand_aliases is enabled, aliases are expanded. This option is enabled by default in interactive shells. Aliases are not expanded when the shell is not interactive unless this option is set.
The default value of MAILCHECK is 60 seconds. This is how often Bash checks for new mail.
When cdspell is enabled, minor errors in the spelling of a directory component in a cd command are corrected. The errors checked for are transposed characters, a missing character, and one character too many. Corrections are only applied if the corrected directory name exists.
When IGNOREEOF is set but has no numeric value, the default is 10 consecutive EOF characters (Ctrl+D) required to exit the shell.
The default history file is ~/.bash_history. This is specified by the HISTFILE variable, which defaults to ~/.bash_history if not set.
When auto_cd is enabled, if a command name is not a valid command but is the name of a directory in the current directory, Bash automatically performs a cd to that directory. This option is only available in interactive shells.
FCEDIT specifies the default editor for the fc builtin command. If not set, the default editor is 'ed'. The fc command is used to list, edit, and re-execute commands from the command history.
TERM specifies the terminal type for readline and other programs that use the terminfo database. Common values include 'xterm-256color', 'vt100', 'screen', etc. It affects display capabilities like color support and cursor movement.
When execfail is enabled, a non-interactive shell will not exit if it cannot execute the file specified as an argument to the exec builtin. An interactive shell does not exit if exec fails. This option is only available in interactive shells.
The default value of HISTFILESIZE is 500. This variable controls the maximum number of lines contained in the history file.
If set to a value greater than zero, TMOUT is treated as the default timeout for the read builtin (see Bash Builtins). The select command terminates if input does not arrive after TMOUT seconds when input is coming from a terminal. In an interactive shell, if TMOUT is set to a value greater than zero and not equal to the default (60 seconds), bash will terminate after waiting for that number of seconds for input.
HISTCONTROL controls how commands are saved to the history list. It can be set to: 'ignorespace' (lines beginning with a space are not saved), 'ignoredups' (lines matching the last history line are not saved), 'ignoreboth' (both ignorespace and ignoredups), or 'erasedups' (all previous lines matching the current line are removed from the history list before that line is saved).
LINES determines the height of the screen used for displaying select menus and line editing prompts. If not set, Bash attempts to set it automatically based on the terminal size. The value is updated by the checkwinsize option if the window size changes.
When dirspell is enabled, Bash attempts spelling correction on directory names during word completion if the name initially supplied does not exist.
DISPLAY contains the X11 display server to connect to for GUI applications. The format is typically 'hostname:display.screen' or ':display' for local displays. Without this variable set, X11 applications cannot open windows.
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, 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 for hostname completion.
TERM_PROGRAM is set by some terminal emulators to indicate which program is running. For example, Terminal.app sets it to 'Apple_Terminal' and iTerm2 sets it to 'iTerm.app'. This allows shell scripts to detect and adapt to specific terminal features.
The default value of PS3 is '#? '. This prompt is used by the select built-in command as the prompt for user selection.
The default value of PS4 is '+ '. This prompt is prepended to each line displayed during script debugging when set -x is enabled.
FIGNORE contains a colon-separated list of suffixes to ignore when performing filename completion. A filename whose suffix matches one of the entries in FIGNORE is excluded from the list of matched filenames. For example, setting FIGNORE='.o:~' will ignore files ending in .o or ~ during completion.
TIMEFORMAT specifies the format for the time string printed by the time reserved word. The format can include escape sequences like %R (real time), %U (user CPU time), %S (system CPU time), %P (CPU percentage), and more. If not set, Bash acts as if $TIMEFORMAT=$'\nreal\t%3lR\nuser\t%3lU\nsys\t%3lS' were set. If the value is null, no timing information is displayed.
When shift_verbose is enabled, the shift builtin prints an error message when the shift count exceeds the number of positional parameters. This can help debugging scripts that use shift.
When restricted_shell is enabled, it indicates the shell is in restricted mode. This is a read-only option that cannot be unset. Restricted mode disables certain operations that could be used to subvert restrictions, such as changing directories, modifying environment variables, or redirecting output.
When compat32 is enabled, Bash changes its behavior to match version 3.2 with respect to the treatment of invalid character classes in bracket expressions used by pattern matching and pathname expansion.
MAILCHECK specifies how often (in seconds) Bash checks for mail in the files specified by the MAILPATH or MAIL variables. The default is 60 seconds. When set to 0, Bash checks for mail before each primary prompt is displayed.
When checkhash is enabled, 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.
IGNOREEOF controls the action of an interactive shell on receipt of an EOF character as the sole input. If set, the value is the number of consecutive EOF characters that must be typed as the first characters on an input line before bash exits. 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, EOF signifies the end of input to the shell.
When hostcomplete is enabled, and readline is being used, Bash will attempt to perform hostname completion when a word containing a @ is being completed. This option is enabled by default.
When cdable_vars is enabled, if an argument to cd is not a directory, it is assumed to be the name of a variable whose value is the directory to change to.
When cmdhist is enabled, 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. This option is enabled by default.
EDITOR specifies the default editor used by various shell commands and programs. When Bash needs to invoke an editor (for example, with fc -e), it uses this variable if VISUAL is not set. Common values include 'vi', 'vim', 'nano', or 'emacs'.
COLUMNS determines the width of the screen used for displaying select menus and line editing prompts. If not set, Bash attempts to set it automatically based on the terminal size. The value is updated by the checkwinsize option if the window size changes.
When xpg_echo is enabled, the echo builtin expands backslash escape sequences by default. This matches the behavior defined by the POSIX standard. Without this option, echo does not expand escape sequences unless the -e option is given.
If HISTTIMEFORMAT is set and not null, its value is used as a format string for strftime(3) to print the timestamp associated with each history entry displayed by the history builtin. If this variable is set, time stamps are written to the history file so they may be preserved across shell sessions.
The default value of PS2 is '> '. This prompt is displayed when Bash needs more input to complete a command.
When promptvars is enabled, prompt strings undergo variable and parameter expansion, command substitution, and arithmetic expansion after being expanded. This option is enabled by default, allowing dynamic prompts using variables like \u, \w, etc.
When sourcepath is enabled, 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.
The default value of TMOUT is 60 seconds. When set to 0, timeout is disabled.
VISUAL specifies the default editor for full-screen editing, preferred over EDITOR when both are set. The distinction is historical: VISUAL is for full-screen editors (like vi or emacs), while EDITOR is for line-oriented editors (like ed). Bash checks VISUAL first, then EDITOR.
PROMPT_COMMAND contains a command that is executed before each primary prompt (PS1) is displayed. If set, its value is executed as a command prior to issuing the primary prompt.
LANG determines the locale category for any category not specifically selected with a variable starting with LC_. It affects how strings are displayed, sorted, and compared throughout the shell.
When progcomp is enabled, programmable completion facilities are enabled. This option is enabled by default in interactive shells. It allows the use of programmable completion functions with the complete and compgen builtins.
The default value of PS1 is '\s-\v$ ' which displays the shell name, version, and a $ (or # for root). For example: 'bash-5.1$ '
When compat31 is enabled, Bash changes its behavior to match version 3.1 with respect to quoted arguments to the [[ conditional command's =~ operator and locale-specific string comparison when using the [[ conditional command's < and > operators.
When huponexit is enabled, Bash will send SIGHUP (hangup signal) to all jobs when an interactive login shell exits. This option is only available in interactive shells.
When nullglob is enabled, Bash allows filename patterns which match no files to expand to a null string, rather than themselves. This is useful in scripts where you want to gracefully handle the case where no files match a pattern.
When login_shell is enabled, it indicates that the shell is a login shell. This is a read-only option that cannot be modified. It is automatically set by Bash when the shell is started as a login shell.
When extglob is enabled, extended pattern matching features are enabled. These include patterns like +(pattern), *(pattern), ?(pattern), @(pattern), and !(pattern).
The default value of HISTSIZE is 500. This variable controls the maximum number of commands to remember in the command history list.
When histappend is enabled, the history list is appended to the file named by the HISTFILE variable when the shell exits, rather than overwriting the file. This allows multiple shell sessions to share the same history file without losing history from other sessions.
When gnu_errfmt is enabled, Bash error messages are displayed in the standard GNU error message format. This option is only available in interactive shells.
When failglob is enabled, patterns which fail to match filenames during filename expansion result in an expansion error. This can be useful for catching typos in scripts.
When interactive_comments is enabled, a word beginning with # causes that word and all remaining characters on that line to be ignored in an interactive shell. This option is enabled by default. This allows comments in interactive command lines.
When nocaseglob is enabled, Bash matches filenames in a case-insensitive fashion when performing filename expansion. This is useful on case-sensitive filesystems when you want to match files regardless of case.
MAPFILE is an array variable that holds the text read by the mapfile builtin when no variable name is supplied. The mapfile builtin reads lines from standard input into an array variable.
GLOBIGNORE is a colon-separated list of patterns defining the set of file names to be ignored by filename expansion. If a file name matched by a filename expansion pattern also matches one of the patterns in GLOBIGNORE, it is removed from the list of matches. When this variable is set, dot files do not need to be matched explicitly.
Command Line Editing > History Operations
64 questions'!$' refers to the last argument of the previous command. For example, if the previous command was 'cat file.txt', '!$' expands to 'file.txt'.
'!:-n' refers to words 0 through n of the previous command. For example, '!:-2' expands to the command name plus the first two arguments.
'!-n' refers to the command that was executed n commands previously. For example, '!-3' refers to the third-to-last command executed.
'!# ' refers to the entire command line typed so far. This is useful for repeating portions of the current line while still typing it.
The ':t' modifier removes all leading pathname components, leaving only the tail (filename). For example, if the argument is '/path/to/file.txt', ':t' expands to 'file.txt'.
histchars is a 2-3 character string controlling history expansion. The first character is the history expansion character (default '!'), the second is the quick substitution character (default '^'), and the third (if present) is the comment character when history expansion is performed (default '#').
When HISTCONTROL=erasedups, all previous lines matching the current line are removed from the history list before that line is saved. This ensures that each unique command appears only once in the history, keeping only the most recent occurrence.
^old^new^ is a quick substitution that reruns the previous command, replacing the first occurrence of 'old' with 'new'. It's equivalent to '!!:s/old/new/'.
The ':&' modifier repeats the previous substitution. For example, after using ':s/foo/bar/', using ':&' would repeat the same substitution (foo to bar) on the same command.
The ':s/old/new/' modifier substitutes the first occurrence of 'old' with 'new' in the command. For example, '!!:s/foo/bar/' reruns the last command replacing 'foo' with 'bar'.
HISTCONTROL controls which commands are saved in the history list. Common values include: 'ignorespace' (don't save commands starting with space), 'ignoredups' (don't save duplicate commands), 'ignoreboth' (both ignorespace and ignoredups), and 'erasedups' (remove all previous occurrences of a command before saving).
The 'history-search-forward' command (typically unbound by default, but can be bound in .inputrc) searches forward through the history for commands matching the text from the beginning of the line up to the cursor position.
The 'operate-and-get-next' command (bound to Ctrl+O by default) accepts the current line for execution and fetches the next line relative to the current line from the history for editing.
'history -s arg' adds 'arg' to the end of the history list as if it had been entered as a command. This doesn't execute the command, just adds it to history.
Ctrl+N or the Down Arrow key moves to the next command in the history list. This is equivalent to the 'next-history' readline command.
'!' refers to all arguments of the previous command. If the previous command was 'echo foo bar baz', '!' expands to 'foo bar baz'.
Alt-< moves to the first line in the history. This is the 'beginning-of-history' readline command.
When there is no previous command, '!$' produces an error message stating 'event not found'. The shell needs at least one previous command in history to expand '!$'.
The ':g&' modifier applies the previous substitution globally to all occurrences in the command, similar to how ':gs' differs from ':s'.
The default history file is ~/.bash_history (located in the user's home directory). This can be changed by setting the HISTFILE variable.
The '!' (exclamation point) character is the default history expansion character. It can be changed using the 'histchars' variable.
'!^' refers to the first argument of the previous command. For example, if the previous command was 'echo foo bar baz', '!^' expands to 'foo'.
The ':r' modifier removes the filename suffix (extension). For example, if the argument is 'file.txt', ':r' expands to 'file'.
HISTFILE specifies the filename where the command history is saved. The default is ~/.bash_history. If unset, the history is not saved when an interactive shell exits.
'history -n' reads the history file and appends its contents to the current history list. This is useful for incorporating history from other concurrent shell sessions.
In history word designators, ':0' refers to the command name (the zeroth word) of the referenced history event. For example, '!!:0' gives just the command name of the last command.
'!#:n' refers to the nth word of the command typed so far (the current command line). For example, in 'echo foo !#:2 bar', if typed as 'echo foo !#:2 bar', the '!#:2' would expand to the second word of the current line.
HISTFILESIZE sets the maximum number of lines to contain in the history file (~/.bash_history) on login. The default is typically 500. Setting it to 0 truncates the history file to zero size.
Alt-> moves to the end of the history (i.e., the current line being edited). This is the 'end-of-history' readline command.
The ':h' modifier removes the trailing pathname component, leaving only the head. For example, if the argument is '/path/to/file.txt', ':h' expands to '/path/to'.
'history -d offset' deletes the history entry at position 'offset'. If offset is negative, it counts from the end of the history list. The history is renumbered after deletion.
'history -p' performs history expansion on each argument but doesn't execute the result. This displays what the expansion would produce. It's useful for debugging history expansion.
Use single quotes around the text containing '!', or use double backslashes before the '!' (e.g., '!'). You can also use 'set +H' to disable history expansion entirely.
The default value of HISTSIZE is 500 commands. This means Bash remembers up to 500 commands in its in-memory history list.
'!?string?' refers to the most recent command that contains 'string' anywhere in the command. The question marks can be omitted if 'string' is followed by a whitespace.
'history -r' reads the history file and appends its contents to the current history list, similar to -n. It's typically used to reload history.
'!:-' refers to all words from 0 to the penultimate (second-to-last) word of the previous command, excluding the last argument.
'!n' refers to command number n in the command history. For example, '!100' executes the 100th command in the history list.
'!:-m' refers to words 0 through m of the previous command, including the command name. For example, '!:-2' would give the command name plus the first 2 arguments.
'history -w' writes out the current history list to the history file, overwriting it completely. This differs from -a which only appends new entries.
'history -a' appends the new history lines (those executed since the beginning of the current session) to the history file.
The ':gs/old/new/' modifier substitutes all occurrences of 'old' with 'new' in the command. The 'g' stands for global replacement, unlike ':s' which only replaces the first occurrence.
'!#:0' refers to the command name (the 0th word) of the command typed so far (the current command line).
The default value of HISTFILESIZE is 500 lines. This is the maximum number of lines saved in the history file (~/.bash_history).
'fc -s [pat=rep ...] [command]' re-executes a command after substituting 'pat' with 'rep'. 'fc -e editor [first] [last]' opens the commands in an editor for editing before execution. If no editor is specified, the value of FCEDIT is used (defaulting to ed if FCEDIT is unset).
'!string' refers to the most recent command that started with 'string'. For example, '!git' would execute the most recent command beginning with 'git'.
Use 'set +H' or 'set +o histexpand' to disable history expansion. Use 'set -H' or 'set -o histexpand' to re-enable it.
'!:n*' refers to words n through the last word of the previous command. For example, '!:2*' expands to from the second argument to the last argument.
The ':q' modifier quotes the substituted words to prevent further expansion. This protects special characters from being interpreted.
If the previous command had no arguments, '!$' expands to nothing (it is empty). This can cause errors if the command requires an argument.
HISTIGNORE is a colon-separated list of patterns determining which commands should not be saved in the history list. Commands matching any pattern are ignored. For example, 'HISTIGNORE="ls:pwd:exit"' would ignore those specific commands.
'fc -l' lists the history commands. The format is 'fc -l [first] [last]' where 'first' and 'last' can be numbers or strings. Without arguments, it lists the last 16 commands.
The default quick substitution character is '^' (caret). This is the second character in the histchars variable. It allows the '^old^new' syntax for quick substitution.
The ':x' modifier quotes the substituted words as if each word were enclosed in double quotes, breaking them at whitespace. This is similar to ':q' but handles each word separately.
'history -c' clears the history list by deleting all the entries. This only affects the current shell session's in-memory history, not the history file.
The 'beginning-of-history' command (bound to Alt-< by default) moves to the first line in the history. You can then use Ctrl+N or down arrow to scroll through.
You can disable history expansion for a single command by adding a space before the command (if 'ignorespace' or 'ignoreboth' is set in HISTCONTROL), or by using single quotes around the '!' character.
Ctrl+P or the Up Arrow key moves to the previous command in the history list. This is equivalent to the 'previous-history' readline command.
The ':e' modifier removes everything except the filename suffix (extension). For example, if the argument is 'file.txt', ':e' expands to '.txt'.
The 'history-search-backward' command (typically unbound by default, but can be bound in .inputrc) searches backward through the history for commands matching the text from the beginning of the line up to the cursor position.
'!:n-' refers to words n through the penultimate (second-to-last) word of the previous command. For example, '!:2-' expands to from the second argument to the second-to-last argument.
FCEDIT specifies the editor used by the 'fc' builtin command when no editor is specified with -e. If unset, 'ed' is used as the default editor.
The ':p' modifier causes the history expansion to be printed but not executed. This is useful for previewing what the expansion will produce before running it.
Ctrl+R (reverse-i-search) performs an incremental reverse search through the command history. As you type, Bash shows matching commands from the history.
Readline Init File > Key Bindings
64 questions$if mode=emacs or $if mode=vi. This allows different key bindings depending on whether readline is in emacs or vi editing mode.
unix-word-rubout, which kills the word behind the cursor, using whitespace as a word boundary.
Use a backslash followed by up to three octal digits. For example: \101 represents the character 'A' (octal 101).
When set to 'on', readline attempts to perform tilde expansion on the completion word. Default is 'on' for Bash.
Readline will wait for additional characters to see if the sequence matches a longer binding before executing the function. This creates potential ambiguity resolved by timeout.
The $if directive allows conditional key bindings based on the application being used (e.g., bash, python) or the editing mode (emacs or vi). Syntax: $if application followed by $endif.
When set to 'on', readline treats the prefix of partially completed words as already completed when adding the final character.
The keyseq-timeout variable (default 500 milliseconds). If no complete match is found within this time, readline uses the available characters or executes a partial match.
clear-screen, typically bound to Ctrl+L in emacs mode. This moves the current line to the top of the screen and clears everything above it.
set variable-name value. For example: set bell-style visible or set editing-mode vi. Do not use quotes around the variable name or value.
set input-meta on\nset output-meta on\nset convert-meta off. This combination enables proper 8-bit/UTF-8 character handling.
When set to 'on', the 8th bit of characters read is used as the meta flag. Default is 'off' where the ESC prefix character is used for Meta commands.
When set to 'on', readline will skip over completed text when iterating through completions, preventing redundant display.
Concatenate the escape sequences. For example: "\C-x\C-e" represents the two-key sequence Ctrl+X followed by Ctrl+E.
Use the bash command: bind -f ~/.inputrc. This reloads the readline initialization file and applies changes immediately.
Use the # character at the beginning of a line. Everything after # until the end of line is treated as a comment.
yank-first-arg, which can be bound to a key to quickly insert the first argument from the previous command in history.
Controls the bell behavior when readline wants to ring the terminal bell. Values: none, visible (flashes screen), or audible (default).
yank-last-arg, typically bound to Alt+. (Meta+period) or Esc+., which inserts the last argument from the previous command.
$else provides an alternative branch within $if conditional constructs. It allows key bindings to be specified when the $if condition is false.
backward-kill-word, which kills the word behind the cursor, using alphanumeric characters as word boundaries (more conservative than unix-word-rubout).
Typical escape sequences: F1: "\eOP" or "\e[11", F2: "\eOQ" or "\e[12", F3: "\eOR" or "\e[13~", etc. These vary by terminal emulator.
When set to 'on', readline will display all possible completions immediately if the completion is ambiguous, instead of requiring a second Tab press.
kill-line, which kills (cuts) text from the current cursor position to the end of the line.
Sets the default editing mode to either emacs (default) or vi. Example: set editing-mode vi changes all key bindings to vi-style.
When set to 'on', readline will accept 8-bit input (characters with the high bit set), necessary for international character support.
When set to 'on', readline will display 8-bit characters directly. When 'off', characters with the high bit set are displayed as a meta-prefixed key sequence.
When set to 'on', readline will convert characters with the high bit set to meta-key sequences before displaying them. Should be 'off' for proper UTF-8 display.
When set to 'on', readline treats hyphens and underscores as equivalent during completion (available in Bash 5.0+).
Searches backward through the command history for lines matching the text from the start of the current line up to the cursor position.
When set to 'on', readline appends a character indicating the file type to filenames during completion (like * for executables, / for directories).
Use \x followed by two hexadecimal digits. For example: \x41 represents the character 'A' (hex 41).
"\e[1;5D": backward-word. The \e[1;5D sequence is the common escape code for Ctrl+Left Arrow.
When set to 'on', readline appends a / to symlinked directories that point to other directories during completion.
abort, typically bound to Ctrl+G. This cancels the current command or partially-entered key sequence and returns to the top-level prompt.
dump-functions, typically invoked via the bash built-in command 'bind -P' to show all readline function bindings.
$if Bash\n "\C-p": history-search-backward\n$endif. This binds Ctrl+P to history-search-backward only in bash, not other readline applications.
The default filename is .inputrc in the user's home directory (~/.inputrc). Readline will also check the environment variable INPUTRC for an alternative filename.
The syntax is: "key-sequence": function-name. For example: "\C-a": beginning-of-line. The key sequence must be in double quotes, followed by a colon, then the function name.
page-completions. When 'on' (default), readline uses internal paging when completions exceed display rows. When 'off', all completions are shown.
beginning-of-line, which moves the cursor to the beginning of the current line.
Use their escape sequences: Up: "\e[A", Down: "\e[B", Right: "\e[C", Left: "\e[D". These are ANSI standard escape sequences.
Use either the \e prefix or \M- prefix. For example: \e. or \M-. represents Meta+period (Alt+period).
possible-completions, typically bound to Tab or ? in emacs mode when there are multiple completions.
Set the completion-ignore-case variable: set completion-ignore-case on. This affects completion matching, not key bindings themselves.
A function that re-reads the .inputrc file and incorporates any changes without restarting the shell. Can be bound to a key for convenience.
When set to 'on', readline will scroll horizontally instead of wrapping long command lines to the next line.
$include filename reads and processes additional key bindings and variable settings from the specified file. This allows modular configuration across multiple files.
Use double backslash: \. For example: to represent the literal backslash key, use "\".
When set to 'on' (default), readline binds the terminal's special characters (like suspend, quit, interrupt) to their readline equivalents.
When set to 'on', readline displays possible completions with color coding based on file type during completion listing.
"\e[3~": backward-delete-char. This is the common escape sequence for the Delete key on most terminals.
Use "\t": "\t" or bind to the self-insert function. This prevents the default completion behavior triggered by Tab.
Create a macro with embedded newline: "\C-xv": "ls -la\C-m". The \C-m represents the Enter key, executing the command.
Use their terminal escape sequences. Common examples: "\e[1" or "\e[H" for Home; "\e[4" or "\e[F" for End. These vary by terminal type.
reverse-search-history, which performs an incremental search backward through the command history.
Use double quotes for the text to insert: "\C-xv": "I love Bash". This binds Ctrl+X followed by V to insert the literal text.
"\e[1;5C": forward-word. The \e[1;5C sequence is the common escape code for Ctrl+Right Arrow.
Use the \C- prefix followed by the character. For example: \C-a represents Ctrl+A, \C-x represents Ctrl+X.
Searches forward through the command history for lines matching the text from the start of the current line up to the cursor position.
Shell Expansions > Text Processing Expansions
64 questionsProcess substitution is supported on systems that support named pipes (FIFOs) or the /dev/fd method of naming open files.
${var%pattern} removes the SHORTEST matching pattern from the END. ${var%%pattern} removes the LONGEST matching pattern from the END.
If nullglob disabled: word left unchanged. If nullglob enabled: word removed. If failglob enabled: error message printed, command not executed.
If nocaseglob is enabled, match is performed WITHOUT REGARD to case of alphabetic characters.
When matching a filename, slash MUST always be matched explicitly by slash in pattern. In other matching contexts, it can be matched by special pattern characters.
The standard form is $(command). The backtick form command is deprecated. Bash performs command substitution by executing command in a subshell and replacing with standard output, with trailing newlines deleted.
The shell scans results of parameter expansion, command substitution, and arithmetic expansion that did NOT occur within double quotes for word splitting.
Brace expansion is a mechanism to generate arbitrary strings that do not need to exist as filenames. It takes the form of an optional preamble, followed by comma-separated strings or a sequence expression between braces, followed by an optional postscript. Brace expansion is performed BEFORE any other expansions, and any characters special to other expansions are preserved in the result. It is strictly textual and Bash does not apply syntactic interpretation to the text between braces.
If pattern is omitted in case modification expansions like ${parameter^^}, it is treated like ?, which matches EVERY character.
A sequence expression takes the form {x..y[..incr]}, where x and y are either integers or letters, and incr is an optional increment integer. The default increment is 1 or -1 as appropriate. When integers are prefixed with 0, the shell forces each term to have the same width with zero-padding.
The double-slash syntax replaces ALL matches of pattern with string, while single-slash replaces only the first match.
If parameter is null or unset, nothing is substituted. Otherwise, the expansion of word is substituted. The value of parameter itself is not used.
The expression undergoes the same expansions as if within double quotes, but double quotes are not treated specially and are removed. All tokens undergo parameter expansion, command substitution, and quote removal. Arithmetic expansions may be nested.
If globskipdots is enabled, . and .. are NEVER matched, even if pattern begins with .
${parameter@Q} expands to the value of parameter quoted in a format that can be reused as input.
Substring indexing is zero-based for regular parameters, but for positional parameters indexing starts at 1 by default. If offset is 0, $0 is prefixed to the list.
The command substitution $(< file) can be used instead of $(cat file) and is faster.
Process substitution is performed SIMULTANEOUSLY with parameter expansion, command substitution, and arithmetic expansion.
${parameter,,pattern} converts uppercase letters matching pattern to lowercase. It examines ALL characters and converts each one that matches pattern.
If length evaluates to a number less than zero, it is interpreted as an offset in characters from the end of the value rather than a number of characters. The expansion is the characters between offset and that result.
${parameter@U} converts all lowercase alphabetic characters to uppercase.
When @ is used within double quotes, each variable name expands to a SEPARATE word. With *, the names are separated by the first character of IFS.
If first character of parameter is ! and not nameref, introduces indirection. Bash uses value formed by expanding rest of parameter as new parameter; this is then expanded. ! must immediately follow left brace.
If offset evaluates to a number less than zero, the value is used as an offset in characters from the END of the value. A negative offset must be separated from the colon by at least one space to avoid confusion with the :- expansion.
If parameter is null or unset, the shell writes the expansion of word (or a message to that effect if word is not present) to standard error and, if the shell is not interactive, exits with a non-zero status. An interactive shell does not exit but does not execute the command.
${parameter,pattern} converts uppercase letters matching pattern to lowercase. It only examines and converts the FIRST character if it matches pattern.
Explicit null arguments (empty double quotes or single quotes) are RETAINED and passed to commands as empty strings.
Yes. When using the backquoted form, escape the inner backquotes with backslashes.
No. There must be NO space between < or > and the left parenthesis. Otherwise, the construct is interpreted as a redirection.
${parameter@a} expands to a string consisting of flag values representing parameter attributes.
Process substitution allows a process input or output to be referred to using a filename. Forms: <(list) or >(list). Process runs asynchronously, input/output appears as filename passed as argument.
${parameter^pattern} converts lowercase letters matching pattern to UPPERCASE. It only examines and converts the FIRST character if it matches pattern.
The string ${ is not considered eligible for brace expansion and inhibits brace expansion until the closing }. This avoids conflicts with parameter expansion.
${var#pattern} removes the SHORTEST matching pattern from the BEGINNING. ${var##pattern} removes the LONGEST matching pattern from the BEGINNING.
${parameter@u} converts the first character to uppercase if it is alphabetic.
If IFS is unset, or its value is exactly
${parameter@L} converts all uppercase alphabetic characters to lowercase.
If name is an array variable, ${!name[@]} expands to the list of array indices (keys). When used within double quotes, each key expands to a separate word.
When pattern is preceded by %, it MUST match at the END of parameter value for replacement to occur.
Arithmetic expansion allows evaluation of an arithmetic expression and substitution of the result. The format is $(( expression )).
GLOBIGNORE restricts matching filenames. Each matching filename also matching patterns in GLOBIGNORE is removed. Setting to non-null enables dotglob. . and .. always ignored when GLOBIGNORE is set and not null.
No. If the command substitution appears within double quotes, Bash does NOT perform word splitting and filename expansion on the results.
Yes. ${var:=word} assigns the expansion of word to parameter if it is unset or null, and the result is the final value. Positional parameters and special parameters cannot be assigned this way.
Bash performs expansions in the following order: 1. Brace expansion, 2. Tilde expansion, 3. Parameter and variable expansion, 4. Arithmetic expansion, 5. Command substitution, 6. Word splitting, 7. Filename expansion.
No, the results of brace expansion are not sorted; left to right order is preserved. For example, echo a{d,c,b}e outputs ade ace abe (not alphabetical).
Yes, embedded newlines are NOT deleted. They may be removed during word splitting if the substitution is not quoted.
Substring expansion expands to up to length characters of the value of parameter starting at offset. If length omitted, expands to substring from offset to end. Both offset and length are arithmetic expressions.
${parameter@E} expands to the value with backslash escape sequences expanded as with the $'...' quoting mechanism.
If the expression is invalid, Bash prints a message indicating failure to standard error and no substitution occurs.
If >(list) is used, writing to the file provides INPUT for list. If <(list) is used, the file should be read to obtain OUTPUT of list.
${var:-word} substitutes word if var is unset OR null. ${var-word} substitutes word ONLY if var is unset (not when null). The colon tests for both existence and non-null value; omitting colon tests only for existence.
${#parameter} substitutes the LENGTH in characters of the value. If parameter is * or @, substitutes number of positional parameters. If parameter is array name, substitutes number of elements.
Unquoted implicit null arguments, resulting from expansion of parameters that have no values, are REMOVED.
After word splitting (unless -f option set), Bash scans each word for unquoted *, ?, and [. If one appears, word is replaced with alphabetically sorted list of matching filenames.
The pattern is expanded and matched against parameter value. The longest match is replaced with string. In single-slash form, only the FIRST match is replaced.
~+ expands to the value of the shell variable PWD (current working directory).
${parameter^^pattern} converts lowercase letters matching pattern to UPPERCASE. It examines ALL characters and converts each one that matches pattern.
When dotglob is enabled, leading . does not need explicit match. However, . and .. must still be matched explicitly even with dotglob.
When pattern is preceded by #, it MUST match at the BEGINNING of parameter value for replacement to occur.
Must use braces: ${11} expands to eleventh positional parameter, while $11 expands to $1 followed by 1.
${parameter@A} expands to a string in the form of an assignment statement or declare command that recreates parameter with its attributes and value.
${!prefix*} expands to the names of variables whose names begin with prefix, separated by the first character of IFS.
Shell Expansions > Pattern-Based Expansions
62 questionsWhen set, range expressions in pattern matching bracket expressions behave as if in the traditional C locale. Pattern matching does not take the current locale's collating sequence into account, so 'b' will not collate between 'A' and 'B', and uppercase and lowercase ASCII characters will collate together.
When dotglob is enabled, the set of filenames includes all files beginning with '.', but '.' and '..' must be matched explicitly. When disabled, the set does not include any filenames beginning with '.' unless the pattern begins with a '.'.
The extglob option changes the behavior of the parser, since parentheses are normally treated as operators with syntactic meaning. To ensure extended matching patterns are parsed correctly, extglob must be enabled before parsing constructs containing the patterns, including shell functions and command substitutions.
The order of expansions is: 1) brace expansion, 2) tilde expansion, parameter and variable expansion, arithmetic expansion, and command substitution (done in a left-to-right fashion), 3) word splitting, and 4) filename expansion.
If the first character following the '[' is a '!' or a '^', then any character not within the range matches.
Bash scans each word for the characters '*', '?', and '['. If one of these characters appears and is not quoted, the word is regarded as a pattern and replaced with an alphabetically sorted list of filenames matching the pattern.
Supplied integers may be prefixed with '0' to force each term to have the same width. When either x or y begins with a zero, the shell attempts to force all generated terms to contain the same number of digits, zero-padding where necessary.
The '?(pattern-list)' operator matches zero or one occurrence of the given patterns, where pattern-list is a list of one or more patterns separated by '|'.
If the nullglob option is set and no matches are found, the word is removed.
Unless otherwise noted, shopt options are disabled (off) by default. The nocaseglob option is disabled by default.
Setting GLOBIGNORE to a non-null value has the effect of enabling the dotglob shell option, so all other filenames beginning with '.' will match. The filenames '.' and '..' are always ignored when GLOBIGNORE is set and not null.
The '@(pattern-list)' operator matches one of the given patterns (exactly one).
Any incorrectly formed brace expansion is left unchanged. A correctly-formed brace expansion must contain unquoted opening and closing braces, and at least one unquoted comma or a valid sequence expression.
Equivalence classes use the syntax [=c=], which matches all characters with the same collation weight (as defined by the current locale) as the character c.
Unless otherwise noted, shopt options are disabled (off) by default. The dotglob option is disabled by default.
If the globskipdots shell option is enabled, the filenames '.' and '..' are never matched, even if the pattern begins with a '.'. This option is enabled by default.
Brace expansion is strictly textual. Bash does not apply any syntactic interpretation to the context of the expansion or the text between the braces. Any characters special to other expansions are preserved in the result.
When letters are supplied in a sequence expression, the expression expands to each character lexicographically between x and y, inclusive, using the default C locale.
The '[...]' matches any one of the enclosed characters. This is known as a bracket expression and matches a single character.
Extended pattern matching operators are recognized when the extglob shell option is enabled using the shopt builtin.
If the characters following the tilde consist of a number N, optionally prefixed by '+' or '-', the tilde-prefix is replaced with the corresponding element from the directory stack. If the number lacks a leading '+' or '-', '+' is assumed.
To avoid conflicts with parameter expansion, the string '${' is not considered eligible for brace expansion and inhibits brace expansion until the closing '}'.
When the globstar shell option is enabled and '' is used in a filename expansion context, two adjacent ''s used as a single pattern match all files and zero or more directories and subdirectories. If followed by a '/', two adjacent '*'s match only directories and subdirectories.
In order to match '.' and '..', the pattern must begin with '.' (for example, '.?'), even if dotglob is set. If globskipdots is enabled, '.' and '..' are never matched, even if the pattern begins with a '.'.
Unless otherwise noted, shopt options are disabled (off) by default. The failglob option is disabled by default.
Unless otherwise noted, shopt options are disabled (off) by default. The extglob option is disabled by default.
Unless otherwise noted, shopt options are disabled (off) by default. The nullglob option is disabled by default.
If the 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.
Collating symbols use the syntax [.symbol.], which matches the collating symbol symbol.
A backslash escapes the following character; the escaping backslash is discarded when matching.
No, both x and y in {x..y} must be of the same type (either both integers or both letters).
The sorting order of characters in range expressions and the characters included are determined by the current locale and LC_COLLATE/LC_ALL variables. In the default C locale, '[a-dx-z]' equals '[abcdxyz]', but in dictionary-order locales it may equal '[aBbCcDdxYyZz]'.
Complicated extended pattern matching against long strings is slow, especially when the patterns contain alternations and the strings contain multiple matches. Using separate matches against shorter strings, or using arrays of strings instead of a single long string, may be faster.
Brace expansion is performed before any other expansions. Any characters special to other expansions are preserved in the result.
To match a '-', include it as the first or last character in the set. To match a ']', include it as the first character in the set.
No, brace expansion generates arbitrary strings but the filenames generated need not exist. This distinguishes it from filename expansion.
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 set) is substituted.
Unless otherwise noted, shopt options are disabled (off) by default. The globasciiranges option is disabled by default.
The nocaseglob shell option, when enabled, causes Bash to match filenames without regard to the case of alphabetic characters.
If the failglob shell option is set and no matches are found, an error message is printed and the command is not executed.
You can force the use of the C locale by setting the LC_COLLATE or LC_ALL environment variable to 'C', or enable the globasciiranges shell option.
The '!(pattern-list)' operator matches anything except one of the given patterns.
The default increment is 1 or -1 as appropriate (depending on whether x is less than or greater than y).
The '+(pattern-list)' operator matches one or more occurrences of the given patterns.
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 the first '='. This allows using tildes in assignments to PATH, MAILPATH, and CDPATH. Bash also performs tilde expansion on words satisfying variable assignment conditions when they appear as arguments to simple commands, except in POSIX mode.
Yes, brace expansions may be nested. The results of each expanded string are not sorted; left to right order is preserved.
Character classes use the syntax [:class:], where class is one of the POSIX classes (alnum, alpha, ascii, blank, cntrl, digit, graph, lower, print, punct, space, upper, word, xdigit).
The POSIX character classes are: alnum, alpha, ascii, blank, cntrl, digit, graph, lower, print, punct, space, upper, word, xdigit. The 'word' character class matches letters, digits, and the character '_'.
Unless otherwise noted, shopt options are disabled (off) by default. The globstar option is disabled by default.
The special pattern characters (*, ?, [, and others) must be quoted if they are to be matched literally.
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.
After word splitting, unless the -f option has been set, Bash scans each word for pattern characters. If -f is set, filename expansion is suppressed.
Only brace expansion, word splitting, and filename expansion can increase the number of words. Other expansions expand a single word to a single word. The exceptions are "$@", $, "${name[@]}", and ${name[]}.
If no matching filenames are found and the shell option nullglob is disabled, the word is left unchanged.
The globskipdots option is enabled by default. This means filename expansion will never match '.' and '..', even if the pattern begins with a '.'.
When a pattern is used for filename expansion, 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 not matching filenames, the '.' character is not treated specially.
A sequence expression takes the form {x..y[..incr]}, where x and y are either integers or letters, and incr (optional) is an integer.
When matching a filename, the slash character must always be matched explicitly by a slash in the pattern, but in other matching contexts it can be matched by a special pattern character.
Bourne Shell Builtins > Variable and Environment Management
58 questionsThe -v option treats each NAME as a shell variable, explicitly causing unset to remove variables.
The -H option enables ! style history substitution. This flag is on by default when the shell is interactive.
The shift builtin shifts positional parameters. It renames positional parameters $N+1,$N+2... to $1,$2... If N is not given, it is assumed to be 1.
The local builtin can accept any option accepted by declare, including -i, -r, -a, -A, -x, etc.
The -n option treats each NAME as a name reference and unsets the variable itself rather than the variable it references.
The -n option removes the export property from each NAME, causing the variable to no longer be exported to child processes.
The -n option makes NAME a reference to the variable named by its value (nameref).
The -p option displays a list of all exported variables and functions in a format that can be reused as input.
When used as 'set --' with no remaining arguments after --, the positional parameters are unset.
The -E option causes the ERR trap to be inherited by shell functions (errtrace).
The -x option makes NAMEs export, equivalent to using the export command.
The -A option refers to associative array variables, allowing you to mark associative arrays as readonly.
The -t option causes the shell to exit after reading and executing one command (onecmd).
The -f option restricts action or display to function names and definitions.
The -e option causes the shell to exit immediately if a command exits with a non-zero status (errexit).
No, readonly variables cannot be unset. The unset command will fail with a non-zero exit status when attempting to unset a readonly variable.
The -a option marks variables which are modified or created for export (allexport).
The export builtin marks shell variables for automatic export to the environment of subsequently executed commands. If VALUE is supplied, it assigns VALUE before exporting.
The readonly builtin returns failure (non-zero exit status) if an invalid option is given or NAME is invalid.
The -b option causes the shell to notify of job termination immediately (notify).
The set - command assigns any remaining arguments to the positional parameters and turns off the -x and -v options.
The -l option converts the value of each NAME to lower case on assignment.
When used in a function, declare makes NAMEs local by default, as with the local command. The -g option suppresses this behavior.
The -u option treats unset variables as an error when substituting (nounset).
The -x option prints commands and their arguments as they are executed (xtrace/debug mode).
The local builtin returns a non-zero exit status if the shell is not executing a function, as local variables can only be used within functions.
The -F option restricts display to function names only (plus line number and source file when debugging).
The -f option treats each NAME as a shell function, causing unset to remove functions instead of variables.
The local builtin creates local variables within functions. Local variables can only be used within a function and are visible only to the function where they are defined and its children.
The -r option makes NAMEs readonly, equivalent to using the readonly command.
The -u option converts the value of each NAME to upper case on assignment.
The -f option refers to shell functions, allowing you to export shell functions to child processes.
The pipefail option causes the return value of a pipeline to be the status of the last command to exit with a non-zero status, or zero if no command exited with a non-zero status.
Using '+' instead of '-' with declare turns off the given attribute (e.g., declare +x NAME to remove export attribute).
The -I option, if creating a local variable, inherits the attributes and value of a variable with the same name at a previous scope.
Shift returns failure (non-zero exit status) if N is negative or greater than $#.
The readonly builtin marks shell variables as unchangeable. The values of these names may not be changed by subsequent assignment.
The -P option prevents the shell from resolving symbolic links when executing commands such as cd which change the current directory (physical).
When given no arguments, set displays the names and values of all shell variables.
The -h option causes the shell to remember the location of commands as they are looked up (hashall).
The -C option disallows existing regular files to be overwritten by redirection of output (noclobber).
The -o option sets shell options by long name, such as errexit, nounset, pipefail, etc.
The -g option creates global variables when used in a shell function; otherwise it is ignored. This suppresses the local behavior of declare in functions.
Without options, unset first tries to unset a variable, and if that fails, it tries to unset a function.
The declare builtin declares variables and gives them attributes. If no NAMEs are given, it displays the attributes and values of all variables.
The -a option refers to indexed array variables, allowing you to mark indexed arrays as readonly.
The -T option causes the DEBUG and RETURN traps to be inherited by shell functions (functrace).
The unset builtin removes values and attributes of shell variables and functions. For each NAME, it removes the corresponding variable or function.
The -k option causes all assignment arguments to be placed in the environment for a command, not just those that precede the command name (keyword).
The -i option gives NAMEs the 'integer' attribute, causing arithmetic evaluation to be performed when the variable is assigned a value.
Interactive Shells > Command Line Editing
56 questionsforward-word (M-f) moves by words composed of alphanumeric characters. shell-forward-word moves by words delimited by non-quoted shell metacharacters.
M-> (Meta->). The command is end-of-history, which moves to the end of the input history (the line currently being entered).
C-n (Control-N). The command is next-history, which fetches the next command from the history list, moving forward in the list.
M-b (Meta-b). Words are composed of alphanumeric characters (letters and digits).
Off. When set to On, readline uses a single line for display, scrolling horizontally when the line becomes longer than screen width rather than wrapping to a new line.
C-r (Control-R). This starts a reverse incremental search through the command history.
Lists current readline variable names and values (shows readable output).
(cmd). If show-mode-in-prompt is enabled, this string is displayed immediately before the last line of the primary prompt when vi editing mode is active and in command mode.
Use 'set -o vi' to enable vi-style line editing. To switch back to Emacs mode, use 'set -o emacs'. These can be used with the set builtin command at any time during an interactive session.
If this variable appears in the environment when the shell starts, bash assumes it is running inside an Emacs shell buffer and may disable line editing, depending on the value of TERM.
The INPUTRC variable. If set, its value is used as the filename for the readline startup file, overriding the default of ~/.inputrc.
(ins). If show-mode-in-prompt is enabled, this string is displayed immediately before the last line of the primary prompt when vi editing mode is active and in insertion mode.
unset (uses HISTSIZE shell variable). If set to zero, existing history entries are deleted and no new entries are saved. If set to a value less than zero, the number of history entries is not limited. If set to a non-numeric value, it defaults to 500.
Use the --noediting option when invoking the shell, or use '+o emacs' or '+o vi' with the set builtin to turn off line editing after the shell is running.
On. When set to On, readline configures the terminal to insert each paste as a single string of characters, preventing readline from executing editing commands bound to key sequences in the pasted text.
$if (tests editing mode, terminal, application, version, or variable), $else (executed if test fails), $endif (terminates $if), $include (reads commands from a file).
emacs, emacs-standard, emacs-meta, emacs-ctlx, vi, vi-move, vi-command, and vi-insert. vi is equivalent to vi-command (vi-move is also a synonym); emacs is equivalent to emacs-standard.
Off. If set to On, adds a string to the beginning of the prompt indicating the editing mode: emacs, vi command, or vi insertion.
Bash. You can use '$if Bash' in .inputrc to include application-specific settings for bash.
@. If show-mode-in-prompt is enabled, this string is displayed immediately before the last line of the primary prompt when emacs editing mode is active.
Off. If set to On, tilde expansion is performed when readline attempts word completion.
ESC (Escape) and C-J (Control-J). These are the default value of the isearch-terminators variable, which can be customized.
Specifies the duration readline waits for a character when reading an ambiguous key sequence, in milliseconds. The default is 500 milliseconds. If set to a value less than or equal to zero, or to a non-numeric value, readline will wait until another key is pressed.
- This determines when the user is queried about viewing the number of possible completions. If the number of possible completions is greater than or equal to this value, readline will ask whether or not the user wishes to view them.
audible. Controls what happens when readline wants to ring the terminal bell. Values are 'none' (never rings), 'visible' (uses visible bell if available), or 'audible' (attempts to ring the terminal's bell).
Emacs mode. By default, the line editing commands are similar to those of Emacs. This can be changed using 'set -o vi' to switch to vi-style editing.
M-f (Meta-f). Words are composed of alphanumeric characters (letters and digits).
emacs. The keymap variable can be set to: emacs, emacs-standard, emacs-meta, emacs-ctlx, vi, vi-command (synonyms: vi or vi-move), and vi-insert. The default value is emacs.
comment-begin, which defaults to '#'. This is the string inserted when the readline insert-comment command is executed (bound to M-# in emacs mode and # in vi command mode).
Displays readline variable names and values in such a way that they can be re-read (parseable format).
Off. If set to On, words with more than one possible completion cause matches to be listed immediately instead of ringing the bell.
=, ==, !=, <=, >=, <, and >. The version number consists of a major version number, optional decimal point, and optional minor version (e.g., 7.1).
clear-screen (bound to C-l / Control-L). Clears the screen, then redraws the current line, leaving the current line at the top of the screen.
emacs. The editing-mode variable controls whether readline begins with key bindings similar to Emacs or vi, and can be set to either 'emacs' or 'vi'.
\C- (control prefix), \M- (meta prefix), \e (escape character), \ (backslash), " (literal "), ' (literal ').
Type C-s (Control-S) to search forward or C-r (Control-R) to search backward for the next entry matching the search string typed so far.
\a (alert/bell), \b (backspace), \d (delete), \f (form feed), \n (newline), \r (carriage return), \t (horizontal tab), \v (vertical tab), \nnn (octal value), \xHH (hexadecimal value).
Off. If set to On, readline performs filename matching and completion in a case-insensitive fashion.
C-g (Control-G). It aborts an incremental search and restores the original line.
~/.inputrc is the default readline initialization file. If the INPUTRC environment variable is set, its value is used instead. If ~/.inputrc does not exist or cannot be read, the ultimate default is /etc/inputrc.
C-p (Control-P). The command is previous-history, which fetches the previous command from the history list, moving back in the list.
Lists current readline function names and bindings (shows readable output).
Displays readline function names and bindings in such a way that they can be re-read (parseable format).
Causes shell-command to be executed whenever keyseq is entered. When executed, the shell sets READLINE_LINE to the contents of the line buffer, and READLINE_POINT and READLINE_MARK to the current location of the insertion point and mark. Numeric arguments are stored in READLINE_ARGUMENT.
On. If set to On, readline uses an internal pager to display a screenful of possible completions at a time.
Bound to C-o (Control-O). It accepts the current line for execution and fetches the next line relative to the current line from the history for editing. A numeric argument specifies the history entry to use instead.
Installing Bash > Installation Customization
55 questionsThis option specifies the directory containing the readline library files when using an installed readline library.
This option enables extended regular expression matching in the [[ compound command's =~ operator.
This option adds support for gprof profiling, allowing performance analysis of the Bash executable.
This option disables the memory scrambling feature that Bash uses to help detect use of freed memory.
--bindir=DIR. This option specifies the directory where user executables will be installed.
There is no specific option to disable just the directory stack. To disable these, you would need to use --enable-minimal-config or modify the source.
The select command is always enabled in Bash. There is no specific configure option to enable it as it's a core feature.
--disable-let-builtin. This option prevents the let builtin from being compiled into Bash.
This option specifies the directory containing the readline header files when using an installed readline library.
This enables support for case modification attributes in parameter expansion and word expansion.
There is no configure option specifically for this. The time reserved word is always available. It can be disabled via the 'time' keyword being unhashable or restricted mode.
There is no default value for TMOUT. When set to a positive integer, it causes the shell to terminate after that many seconds of inactivity.
The special parameter $- expands to the current shell options (flags) set at invocation time or via set. The default depends on how Bash is invoked.
--localedir=DIR. This option sets the directory for locale-specific data files.
--disable-progcomp. This option disables the programmable completion facility.
--enable-dev-fd. This enables the use of /dev/fd for redirections (default is enabled on most systems).
The limit is determined by the system's RLIMIT_NOFILE resource limit. Bash inherits this limit from its parent process or can set it with the ulimit builtin.
This option links Bash statically, creating a binary that doesn't depend on shared libraries. This is useful for creating a standalone bash binary.
This option tells Bash to use the curses library instead of termcap for terminal display.
/usr/local/bin/bash. The bash binary is installed to ${prefix}/bin/bash.
The cond command (test/[) is always enabled in Bash. This configure option does not exist in the standard configure script.
--disable-nls. This option disables the Native Language Support (internationalization) features when building Bash.
- The default HISTFILESIZE is 500, which controls the maximum number of lines in the history file.
- The default MAILCHECK value is 60 seconds, specifying how often Bash checks for new mail.
There is no default timeout - connections will wait indefinitely unless a timeout is set using the TMOUT variable or configured at compile time.
--disable-ulimit-builtin. This option prevents the ulimit builtin from being compiled into Bash.
This enables support for multibyte characters, allowing Bash to properly handle UTF-8 and other character encodings. This is enabled by default.
--disable-bracketed-paste. This option disables bracketed paste mode support in readline.
--with-installed-readline. This option configures Bash to use the readline library already installed on the system rather than the one included in the Bash source distribution.
Array support is always enabled in Bash. There is no --enable-array option as it's a core feature.
This option prevents the alias builtin from being compiled into Bash, removing alias support.
This option makes the echo builtin escape sequences interpret backslash escapes by default, conforming to XPG4 behavior.
--disable-job-control. This option prevents job control features from being compiled into the shell.
--disable-trap-builtin. This option prevents the trap builtin from being compiled into Bash.
This is an alias for --with-gnu-malloc, telling Bash to use its built-in memory allocator.
--datadir=DIR. This option sets the directory for read-only architecture-independent data files.
This tells Bash to use its built-in memory allocator (based on GNU malloc) instead of the system's malloc library.
/usr/local. When running ./configure without the --prefix option, Bash will be installed to /usr/local as the default prefix directory.
.bash_history. The default history file is ~/.bash_history for interactive shells, though this can be changed with the HISTFILE variable.
This option causes the help documentation to be stored in external files rather than compiled into the binary.
There is no compile-time option to set the default editor. The FCEDIT variable controls the default editor for fc, defaulting to 'ed' if FCEDIT is not set.
This option enables support for network redirections using /dev/tcp and /dev/udp special files.
There is no specific --disable-debug option. The --enable-debugger option enables the debugger, and it's disabled by default.
--disable-help-builtin. This option prevents the help builtin from being compiled into Bash.
This option completely disables command history support, preventing history from being recorded or accessed.
There is no configure option to change the default startup file. Interactive shells read ~/.bashrc by default, and this is hardcoded. The files can be changed via runtime configuration or patching source.
Bash starts in POSIX mode when invoked as 'sh' or when --posix is specified. Otherwise, it runs in its default mode with extensions enabled.
- The default HISTSIZE value is 500 if not set in the configuration files.
--sysconfdir=DIR. This option sets the directory for read-only single-machine data, which typically contains the system-wide bashrc and profile files.
- The default umask is 022, which results in permissions of 755 for directories and 644 for files when created.
--enable-debugger. This option compiles Bash with the debugger support enabled.
--disable-printf-builtin. This option prevents the printf builtin from being compiled into Bash.
There is no configure option to disable [[. The extended test command is always available in Bash.
This option disables the C-style for command (( for ((expr1;expr2;expr3)); do... )) syntax.
Readline Init File > Variable Settings
54 questionsThe default value is 'On'. When set to On, readline will convert characters with the eighth bit set to an ASCII key sequence by stripping the eighth bit and prefixing it with an escape character.
The default value is 'Off'. When set to On, tilde expansion is performed when readline attempts word completion.
The default value is 0. This is the length in characters of the common prefix of a list of possible completions that is displayed without modification.
The default value is 'On'. When set to On, readline attempts to bind the control characters treated specially by the kernel's terminal driver to their readline equivalents.
The default value is 'Off'. When 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 'audible'. The bell-style variable controls what happens when readline wants to ring the terminal bell.
The default value is 'C-[ C-J' (ESC and C-J). This is the string of characters that should terminate an incremental search without subsequently executing the character as a command.
The default value is 'Off'. When set to On, readline will display completions with matches sorted horizontally in alphabetical order, rather than down the screen.
A negative value causes readline to never ask the user whether they wish to view possible completions; they are simply listed.
vi is equivalent to vi-command, and emacs is equivalent to emacs-standard.
When set to a value less than or equal to zero, or to a non-numeric value, readline will wait until another key is pressed to decide which key sequence to complete (no timeout).
The default value is 'Off'. When set to On, readline displays possible completions using different colors to indicate their file type, taking color definitions from the LS_COLORS environment variable.
The default value is 'Off'. When set to On, readline does not insert characters from the completion that match characters after point in the word being completed, avoiding duplication.
The default value is 100. This determines when the user is queried about viewing the number of possible completions.
The default value is 'Off'. 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 value is '(ins)'. If show-mode-in-prompt is enabled, this string is displayed when vi editing mode is active and in insertion mode.
The default value is 'On'. When set to On, readline configures the terminal to insert each paste into the editing buffer as a single string of characters, preventing execution of commands in pasted text.
The default value is 'Off'. When set to On, words which have more than one possible completion without any possible partial completion cause the matches to be listed immediately instead of ringing the bell.
The default value is 'Off'. When set to On, the history code attempts to place point at the same location on each history line retrieved with previous-history or next-history.
The editing-mode variable can be set to either 'emacs' or 'vi'.
The default value is 'On'. When set to On, readline allows certain commands to designate the region as active, highlighting the text using the value of active-region-start-color.
The default value is 'Off'. When set to On, readline will undo all changes to history lines before returning when accept-line is executed.
The default value is 'On'. When set to On, readline uses an internal more-like pager to display a screenful of possible completions at a time.
The default value is 'Off'. When set to On, readline attempts to briefly move the cursor to an opening parenthesis when a closing parenthesis is inserted.
The default value is 'unset', meaning the number of history entries is not limited. When set to zero, existing history entries are deleted and no new entries are saved. When set to a value less than zero, the number of history entries is not limited.
If an attempt is made to set history-size to a non-numeric value, the maximum number of history entries will be set to 500.
The default value is 'Off'. When set to On, history lines that have been modified are displayed with a preceding asterisk (*).
The default value is 'Off'. When 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.
Readline variables can take the values On or Off (case-insensitive). When reading a variable value, empty or null values, 'on' (case-insensitive), and '1' are equivalent to On. All other values are equivalent to Off.
Readline will set convert-meta to Off if the locale contains eight-bit characters. This variable is dependent on the LC_CTYPE locale category and may change if the locale is changed.
The default value is 'On'. When set to On, readline will try to enable any meta modifier key the terminal claims to support when it is called.
The default value is '(cmd)'. If show-mode-in-prompt is enabled, this string is displayed when vi editing mode is active and in command mode.
These variables are reset to the default value whenever the terminal type changes. The default is the string that puts the terminal in standout mode (or restores from standout mode) as obtained from the terminal's terminfo description.
Readline will set input-meta to On if the locale contains eight-bit characters. This variable is dependent on the LC_CTYPE locale category and may change if the locale is changed.
The default value is -1. The number of screen columns used to display possible matches when performing completion.
The default value is 'On'. When set to On, on operating systems that indicate they support it, readline echoes a character corresponding to a signal generated from the keyboard.
The default value is '@'. If show-mode-in-prompt is enabled, this string is displayed immediately before the last line of the primary prompt when emacs editing mode is active.
Readline first checks the INPUTRC environment variable. If unset, the default is ~/.inputrc. If that file does not exist or cannot be read, the ultimate default is /etc/inputrc.
The default value is '#' (the hash character). This is the string that is inserted in vi mode when the insert-comment command is executed.
The default value is 'Off'. When 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'. When set to On, completed names which are symbolic links to directories have a slash appended (subject to the value of mark-directories).
The syntax is 'set variable-name value'. For example: 'set editing-mode emacs' or 'set completion-ignore-case On'.
The default value is 'emacs'. This controls whether readline begins with a set of key bindings similar to Emacs or vi.
The default value is 'Off'. When set to On, readline uses a single line for display, scrolling horizontally instead of wrapping to a new line. This setting is automatically enabled for terminals of height 1.
The default value is 'Off'. When set to On, readline will display characters with the eighth bit set directly rather than as a meta-prefixed escape sequence. Readline will set it to On if the locale contains eight-bit characters.
The default value is 500 milliseconds. This specifies the duration readline will wait for a character when reading an ambiguous key sequence.
The default value is 'Off'. When set to On, when listing completions, readline displays the common prefix using a different color taken from LS_COLORS.
The default value is 'Off'. When set to On, readline performs filename matching and completion in a case-insensitive fashion.
The default value is 'emacs'. The set of legal keymap names includes emacs, emacs-standard, emacs-meta, emacs-ctlx, vi, vi-move, vi-command, and vi-insert. The value of editing-mode also affects the default keymap.
The default value is 'On'. When set to On, completed directory names have a slash appended.
The default value is 'Off'. When set to On, a string is added to the beginning of the prompt indicating the editing mode: emacs, vi command, or vi insertion.
The default value is 'Off'. When set to On, a character denoting a file's type as reported by stat(2) is appended to the filename when listing possible completions.
The valid values are: 'none' (readline never rings the bell), 'visible' (readline uses a visible bell if available), 'audible' (readline attempts to ring the terminal's bell).
Conditional Constructs > Branching Conditionals
54 questions-nt (newer than) - true if file1 is newer than file2, or if file1 exists and file2 does not
Yes - they do not evaluate expression2 if the value of expression1 is sufficient to determine the return value
Tilde expansion, parameter expansion, command substitution, arithmetic expansion, and quote removal
The match succeeds if the pattern matches any part of the string. To force matching of the entire string, anchor with ^ and $
Causes the shell to test the patterns in the next clause and execute any associated command-list if the match succeeds, continuing case statement execution as if the pattern list had not matched
Causes execution to continue with the command-list associated with the next clause, if any
Yes, unless otherwise specified, primaries that operate on files follow symbolic links and operate on the target of the link
-eq (equal), -ne (not equal), -lt (less than), -le (less than or equal), -gt (greater than), -ge (greater than or equal)
The quoted portion is matched literally - every character matches itself instead of having special pattern matching meaning
BASH_REMATCH - element with index 0 contains the portion matching the entire regex, and elements with index n contain portions matching the nth parenthesized subexpression
-ot (older than) - true if file1 is older than file2, or if file2 exists and file1 does not
-ef (equal file) - true if file1 and file2 refer to the same device and inode numbers
Tilde expansion, parameter expansion, command substitution, arithmetic expansion, and quote removal
=~ - when used, the string to the right is considered a POSIX extended regular expression and matched accordingly
(expression) for grouping, ! expression for NOT, expression1 && expression2 for AND, expression1 || expression2 for OR
if list; then list; [ elif list; then list; ] ... [ else list; ] fi - The if list is executed, and if its exit status is zero, the then list is executed. Otherwise, each elif list is executed in turn, and if its exit status is zero, the corresponding then list is executed. If no elif succeeds, the else list (if any) is executed.
== and != - the string to the right of the operator is considered a pattern and matched according to the rules described in Pattern Matching
Shell Functions > Parameter and Argument Handling
53 questionsWhen not executing a function, FUNCNAME is unset or has a single element 'main' (depending on Bash version and context). The array only contains meaningful function names when within function call context. In the main script execution, FUNCNAME[0] may not contain a useful value.
When a function is executed, the arguments to the function become the positional parameters during its execution. The special parameter $# is expanded to the number of positional parameters, and $0 remains unchanged (it's the name of the script, not the function).
The ${parameter%pattern} syntax removes the shortest matching pattern from the end of parameter's value. To remove the longest match, use ${parameter%%pattern}. For example, ${1%.*} removes the shortest file extension from $1.
Use command substitution: result=$(my_function args). This captures stdout from the function into the variable. The function's return value (exit status) is still available via $?. Functions can echo both data and use return to provide an exit status.
The ${parameter:=word} syntax assigns default values. If parameter is unset or null, the expansion of word is assigned to parameter and then substituted. This differs from :- in that it actually assigns the value to the variable, not just uses it for expansion.
FUNCNAME is an array variable containing the names of all shell functions currently in the execution call stack. FUNCNAME[0] is the name of the currently executing function, FUNCNAME[1] is the function that called it, FUNCNAME[2] is the function that called that one, and so on.
The ${parameter:-word} triggers on both unset AND null values, while ${parameter-word} only triggers when parameter is unset (not when it's null/empty). The :- version is more commonly used to handle missing arguments regardless of whether they were passed as empty strings.
While they are often equivalent, ${var} is safer and more versatile. Braces are required for: positional parameters with 2+ digits (${10}), expansion operations (${var:-default}), substring expansion (${var:1:3}), and when the variable name is adjacent to alphanumeric characters (echo ${var}text). Braces make the variable boundaries explicit.
Bash functions can only return integer exit status values from 0 to 255, similar to C's exit status conventions. This differs from languages that can return strings, arrays, objects, or arbitrary integers. To return complex data, Bash functions must use echo/printf to stdout, global variables, or output files.
Exit status values range from 0 to 255. Values outside this range are truncated to the lowest 8 bits (e.g., return 257 becomes exit status 1, return 512 becomes exit status 0, and return -1 becomes exit status 255).
OPTIND is the index of the next argument to be processed by getopts. It is initialized to 1 each time the shell or a shell script is invoked. When an option requires an argument, getopts places that argument in OPTARG and increments OPTIND to point to the next argument.
The ${parameter:-word} syntax uses default values. If parameter is unset or null, the expansion of word is substituted. Otherwise, the value of parameter is substituted. For example, ${1:-default} uses 'default' if $1 is unset or null, otherwise uses $1's value.
The local command can create local array variables. For example, local arr=("$@") creates a local array containing all positional parameters. Local arrays hide any global arrays with the same name. However, you cannot use local to make individual array elements local - you must declare the entire array as local.
Use ${!#} to indirectly reference the last parameter, or use eval to access "${$#}" which becomes $N where N is the number of parameters. A simpler method is to use a loop or assign all parameters to an array with arr=("$@") and then access ${arr[-1]} or ${arr[$#-1]}.
The ${parameter:+word} syntax tests for existence and non-null. If parameter is unset or null, nothing is substituted. Otherwise, the expansion of word is substituted. This is the opposite behavior of :- and :=.
The ${!name} syntax performs indirect expansion. If name is the name of a variable (e.g., var=foo; foo=bar), then ${!var} expands to the value of the variable whose name is the value of var (so ${!var} gives bar). This allows for dynamic variable references.
Positional parameters with double-digit positions (10 or higher) must be enclosed in braces, such as ${10}, ${11}, ${12}, etc. Using $10 without braces would be interpreted as $1 followed by the literal character 0.
Variables declared with local or declare inside a function have local scope and hide variables with the same name in outer scopes (including global variables). The local scope remains in effect until the function returns. Bash uses dynamic scoping for variables.
Check if $# equals 0: if [ $# -eq 0 ]; then echo 'No arguments'; fi. Alternatively, use: if [ -z "$1" ]; then echo 'No arguments'; fi. The $# approach is more accurate as it explicitly counts parameters.
The ${#parameter} syntax expands to the length in characters of the value of parameter. If parameter is * or @, the result is the number of positional parameters. For example, ${#1} gives the length of the first argument's string value.
The ${parameter:offset:length} syntax expands to up to length characters of parameter starting at offset. If length is omitted, expands to the substring from offset to the end of the value. Offset and length are arithmetic expressions. The first character is at position 0.
Bash does not impose a fixed limit on the number of positional parameters. The limit is determined by system constraints (available memory and argument size limits). The maximum size of a single argument is determined by ARG_MAX (typically 2MB or more on modern systems).
$# expands to the number of positional parameters passed to the function or script. When a function is called with 5 arguments, $# equals 5 within that function's execution.
When a function calls another function, the new function receives its own set of positional parameters based on the arguments passed to it. The calling function's positional parameters are temporarily replaced and are restored when the called function returns.
Use ${parameter,,} to convert the entire value of parameter to lowercase. Use ${parameter,} to convert only the first character to lowercase. For example, ${1,,} converts all characters in $1 to lowercase.
Starting with Bash 4.0, shift accepts a negative argument which shifts parameters to the right. For example, shift -2 effectively shifts positional parameters $1 and $2 out of existence and sets $# to $# - 2. This is less commonly used but available for specific manipulation needs.
The ${parameter#pattern} syntax removes the shortest matching pattern from the beginning of parameter's value. To remove the longest match, use ${parameter##pattern}. For example, ${1##*/} removes all path components from the beginning of $1, leaving only the filename.
$$ expands to the process ID (PID) of the current shell. This value is unique within a shell session and can be used to create temporary filenames or track shell instances.
When you return a negative value, Bash takes only the lowest 8 bits and interprets it as an unsigned value. For example, return -1 results in exit status 255 (because -1 in two's complement 8-bit is 11111111 binary, which is 255 unsigned). return -2 gives 254, etc.
FUNCNAME[0] contains the name of the currently executing function, while $0 contains the name of the shell script itself. Within a function, you can use ${FUNCNAME[0]} to get the function's name, which $0 cannot provide.
BASH_ARGC is an array containing the number of parameters in each frame of the current bash execution call stack. BASH_ARGV is an array containing all the parameters in the current bash execution call stack. They are only available in debugging mode (when extdebug is enabled with shopt -s extdebug).
When double-quoted, "$@" expands each positional parameter as a separate quoted word (preserving argument boundaries with spaces), while "$*" expands all positional parameters as a single word separated by the first character of IFS (typically space).
$0 always contains the name of the shell or shell script being executed, never the function name. Within a function, $0 remains the script name, while FUNCNAME[0] contains the function name.
The ${parameter:-} syntax with an empty word expands to nothing if parameter is unset or null, and to the value of parameter otherwise. This is useful for providing a default empty string rather than the literal string 'null' or similar when a parameter is missing.
The set -- command with no arguments clears all positional parameters. When followed by arguments (e.g., set -- arg1 arg2), it sets the positional parameters to those arguments, replacing all existing ones. This is commonly used to reset or reassign $1, $2, etc.
The default value of IFS (Internal Field Separator) is space, tab, and newline. When using "$", positional parameters are expanded with the first character of IFS between them. With the default IFS, "$" joins parameters with spaces. If you set IFS=',' then "$*" would join parameters with commas.
When NOT quoted, $@ and $* behave identically. Both expand to all positional parameters, and word splitting and pathname expansion are performed on each parameter. The difference only appears when they are double-quoted.
The ${var@L} operator converts var to lowercase, while ${var@U} converts to uppercase. These are alternatives to ${var,,} and ${var^^} respectively. Both are available in Bash 5.0+. The @ operators are part of a more general transformation syntax introduced in Bash 4.4+.
By convention, exit status 0 indicates success, and non-zero values (1-255) indicate failure. This convention is used by commands, functions, and scripts. The return statement and exit command both follow this convention.
To reset getopts for re-parsing, set OPTIND=1 before calling getopts again. This tells getopts to start processing from the first positional parameter again. Without this reset, getopts remembers its position from previous invocations.
If no return statement is executed in a function, the function returns the exit status of the last command executed within the function. If no commands are executed, the exit status is 0.
Use "$@" to pass all arguments preserving their original separation and quoting. For example: some_command "$@" will pass each argument as originally received by the function. Do not use $* or $@ without quotes as this may break arguments containing spaces.
The shift command shifts positional parameters to the left by a specified number N (default is 1). Parameters from N+1 to $# are renamed to variable names from $1 to $#-N+1. Parameters $1 through $N are unset. $# is updated to reflect the new count.
The ${parameter/pattern/string} syntax replaces the first match of pattern with string. To replace all matches, use ${parameter//pattern/string}. If string is omitted (just ${parameter/pattern/}), the matched portions are deleted. If pattern begins with #, it must match at the beginning; if it begins with %, it must match at the end.
OPTERR defaults to 1, meaning getopts will print error messages to stderr for invalid options or missing option arguments. Setting OPTERR=0 suppresses these automatic error messages, allowing scripts to provide their own custom error handling.
The ${!prefix*} and ${!prefix@} syntax expands to the names of variables whose names begin with prefix. The @ form causes the expansion to result in separate words when quoted, while the * form results in a single word. This is useful for enumerating variables with a common prefix.
The return builtin causes a function to exit with the specified exit status value (0-255). If no value is provided, return returns the exit status of the last command executed. Return can only be used within functions and sourced scripts, not in the main script execution.
Some builtin variables like BASH_REMATCH have special behavior when declared local. Declaring BASH_REMATCH as local in a function creates a new variable that shadows the global one but may not behave identically. The official manual warns about potential issues with declaring certain built-in variables as local.
Use ${parameter^^} to convert the entire value of parameter to uppercase. Use ${parameter^} to convert only the first character to uppercase. For example, ${1^^} converts all characters in $1 to uppercase.
getopts is a builtin that parses positional parameters. Each time it is invoked, it retrieves the next option from the command line, placing it in the variable name specified (typically opt), and the option argument in OPTARG if required. getopts returns true when an option is found, false when the end of options is reached. It silently stops at the first non-option argument unless OPTERR is set to 0.
BASHPID expands to the process ID of the current Bash process. This differs from $$ in subshells: $$ is the PID of the original shell, while BASHPID is the PID of the current shell instance (including subshells). BASHPID is typically the same as $$ unless in a subshell.
$? expands to the exit status of the most recently executed foreground pipeline or command. This is the value returned by the waitpid system call or equivalent.
When offset is negative in ${parameter:offset:length}, it counts from the end of the value. For example, ${1: -3} gives the last 3 characters of $1. Note that when using negative offsets, a space before the negative number is required to distinguish it from the default value syntax.
Bash Builtin Commands > Bash-Specific Builtins
53 questionsWhen -p is used with name arguments, additional options, other than -f and -F, are ignored. It will display the attributes and values of each name.
The option can be any of the options accepted by declare. When local is used within a function, it causes the variable name to have a visible scope restricted to that function and its children.
The return value is 0 unless the shell is not executing a subroutine call or expr does not correspond to a valid position in the call stack.
The -x option marks names for export to subsequent commands via the environment.
The -f option restricts the display to shell functions. The -F option inhibits the display of function definitions; only the function name and attributes are printed. The -F option implies -f.
The -p option returns the name of the disk file that would be executed if name were specified as a command name, or nothing if 'type -t name' would not return file.
When -p is supplied without name arguments, it will display the attributes and values of all variables having the attributes specified by the additional options. If no other options are supplied with -p, declare will display the attributes and values of all shell variables.
When a non-negative integer is supplied as expr, caller displays the line number, subroutine name, and source file corresponding to that position in the current execution call stack. This extra information can be used to print a stack trace.
The -t option gives each name the trace attribute. Traced functions inherit the DEBUG and RETURN traps from the calling shell. The trace attribute has no special meaning for variables.
A list of shell builtins is printed. With no other option arguments, the list consists of all enabled shell builtins. If -n is supplied, only disabled builtins are printed. If -a is supplied, the list includes all builtins with an indication of whether each is enabled.
The -I option causes local variables to inherit the attributes (except the nameref attribute) and value of any existing variable with the same name at a surrounding scope. If there is no existing variable, the local variable is initially unset.
It is an error to use local when not within a function. The return status is 0 unless local is used outside a function, an invalid name is supplied, or name is a readonly variable.
The -a option restricts the variables to indexed arrays; the -A option restricts the variables to associative arrays. If both options are supplied, -A takes precedence.
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 -D option indicates that other supplied options and actions should apply to the 'default' command completion; that is, completion attempted on a command for which no completion has previously been defined.
When called without expr, caller displays the line number and source filename of the current subroutine call. The current frame is frame 0.
If multiple options are supplied, the -D option takes precedence over -E, and both take precedence over -I. If any of -D, -E, or -I are supplied, any other name arguments are ignored; these completions only apply to the case specified by the option.
Actions include: alias, arrayvar, binding, builtin, command, directory, disabled, enabled, export, file, function, group, helptopic, hostname, job, keyword, running, service, setopt, shopt, signal, stopped, user, variable.
The nospace option tells readline not to append a space (the default) to words completed at the end of the line.
The -P option forces a PATH search for each name, even if 'type -t name' would not return file. If a command is hashed, -p and -P print the hashed value, which is not necessarily the file that appears first in PATH.
The -g option forces variables to be created or modified at the global scope, even when declare is executed in a shell function. It is ignored in all other cases.
The return value is true unless an invalid option is supplied, an attempt is made to modify the options for a name for which no completion specification exists, or an output error occurs.
If name is -, the set of shell options is made local to the function: shell options changed using the set builtin inside the function are restored to their original values when the function returns. The restore is effected as if a series of set commands were executed to restore the values that were in place before the function.
The return value is true unless an invalid option is supplied, or no matches were generated.
The -l option converts all upper-case characters to lower-case when the variable is assigned a value. The upper-case attribute is disabled.
When used in a function, declare and typeset make each name local, as with the local command, unless the -g option is supplied.
The -n option disables each specified shell builtin. Disabling a builtin allows a disk command with 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. For example, to use the test binary found via PATH instead of the shell builtin version, run 'enable -n test'.
If the -a option is used, type prints all of the places that contain an executable named name. This includes aliases and functions, if and only if the -p option is not also used.
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 -f option loads a new builtin command name from a shared object filename (on systems that support dynamic loading). Bash uses the value of the BASH_LOADABLES_PATH variable as a colon-separated list of directories to search for filename. The default is system-dependent.
The -D option indicates that other supplied options should apply to the 'default' command completion; that is, completion attempted on a command for which no completion has previously been defined.
If the -f option is supplied, the functions corresponding to the names are marked readonly.
If the last arg evaluates to 0, let returns 1; otherwise, 0 is returned.
The -r option removes a completion specification for each name, or, if no names are supplied, all completion specifications.
When the function is executed, the first argument ($1) is the name of the command whose arguments are being completed, the second argument ($2) is the word being completed, and the third argument ($3) is the word preceding the word being completed on the current command line.
The -i option treats the variable as an integer; arithmetic evaluation is performed when the variable is assigned a value.
compgen generates 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 writes the matches to standard output. If word is specified, only those completions matching word will be displayed.
The return status is 0 unless an invalid option is encountered, one of the names is not a valid shell variable name, or -f is supplied with a name that is not a function.
Using '+' instead of '-' turns off the attribute instead, with the exceptions that +a and +A may not be used to destroy array variables and +r will not remove the readonly attribute.
The filenames option tells readline that the compspec generates filenames, so it can perform any filename-specific processing (like adding a slash to directory names, quoting special characters, or suppressing trailing spaces). Intended to be used with shell functions.
The return value is 0 unless a name is not a shell builtin or there is an error loading a new builtin from a shared object.
The -u option converts all lower-case characters to upper-case when the variable is assigned a value. The lower-case attribute is disabled.
When the function finishes, the possible completions are retrieved from the value of the COMPREPLY array variable.
The -I option indicates that other supplied options should apply to completion on the initial non-assignment word on the line, or after a command delimiter such as ; or |, which is usually command name completion.
typeset is a synonym for declare. Both accept the same options and behave identically: typeset [-aAfFgiIlnrtux] [-p] [name[=value] ...]
The -r option makes names readonly. These names cannot then be assigned values by subsequent assignment statements or unset.
The -n option gives each name the nameref attribute, making it a name reference to another variable. That other variable is defined by the value of name. All references, assignments, and attribute modifications to name, except those using or changing the -n attribute itself, are performed on the variable referenced by name's value. The nameref attribute cannot be applied to array variables.
The -E option indicates that other supplied options should apply to 'empty' command completion; that is, completion attempted on a blank line.
compopt modifies completion options for each name according to the options, or for the currently-executing completion if no names are supplied. If no options are given, it displays the completion options for each name or the current completion.
Controlling the Prompt > Terminal Control
51 questionsThe default value of completion-display-width is -1. A value less than 0 means the terminal screen width is used.
colored-completion-prefix (default: Off) and colored-stats (default: Off). The color definitions are taken from the value of the LS_COLORS environment variable.
\s produces the name of the shell, the basename of $0 (the portion following the final slash).
After the prompt string is decoded, it is expanded via parameter expansion, command substitution, arithmetic expansion, and quote removal. This can have unwanted side effects if escaped portions of the string appear within command substitution or contain characters special to word expansion.
The default value of echo-control-characters is 'On'. When set to On, on operating systems that indicate they support it, readline echoes a character corresponding to a signal generated from the keyboard.
PS0 is expanded and displayed by interactive shells after reading a command and before the command is executed.
When PROMPT_COMMAND is set as an array variable, the value of each set element is executed as a command prior to issuing each primary prompt.
The default value of convert-meta is 'On', which means readline will convert characters with the eighth bit set to an ASCII key sequence by stripping the eighth bit and prefixing an escape character. Readline sets it to Off if the locale contains eight-bit characters.
The default value of bind-tty-special-chars is 'On', which means readline attempts to bind the control characters treated specially by the kernel's terminal driver to their readline equivalents.
[ begins a sequence of non-printing characters, which can be used to embed a terminal control sequence into the prompt.
! produces the history number of this command (its position in the history list).
The default value of PS1 is \s-\v\$ which expands to the shell name (basename of $0), followed by a hyphen, followed by the shell version, followed by $ (or # for effective UID 0).
PROMPT_DIRTRIM, when set to a number greater than zero, is used as the number of trailing directory components to retain when expanding the \w and \W prompt string escapes. Characters removed are replaced with an ellipsis.
The history number is the command's position in the history list (which may include commands restored from the history file), while the command number is the position in the sequence of commands executed during the current shell session.
The escape sequences are: \C- (control prefix), \M- (meta prefix), \e (escape character), \ (backslash), " (literal "), ' (literal ').
\A produces the current time in 24-hour HH:MM format (without seconds).
\d produces the date in "Weekday Month Date" format (e.g., "Tue May 26").
\D{format} passes the format to strftime(3) and inserts the result into the prompt string; an empty format results in a locale-specific time representation. The braces are required.
When PROMPT_COMMAND is set as a non-array variable, its value is used as a command to execute prior to issuing each primary prompt.
The default value of PS2 is `> ' (a greater-than sign followed by a space).
The additional escapes are: \a (alert/bell), \b (backspace), \d (delete), \f (form feed), \n (newline), \r (carriage return), \t (horizontal tab), \v (vertical tab), \nnn (eight-bit character with octal value nnn), \xHH (eight-bit character with hexadecimal value HH).
The promptvars option, when enabled, causes prompt strings to undergo parameter expansion, command substitution, arithmetic expansion, and quote removal. This option is enabled by default.
The default value of bell-style is 'audible', which means readline attempts to ring the terminal's bell.
# produces the command number of this command (its position in the sequence of commands executed during the current shell session).
During execution tracing (when -x option is enabled), the first character of the expanded value of PS4 is replicated multiple times, as necessary, to indicate multiple levels of indirection.
The default value of completion-query-items is 100. This determines when the user is queried about viewing the number of possible completions.
\w produces the value of the PWD shell variable ($PWD), with $HOME abbreviated with a tilde. It uses the value of the PROMPT_DIRTRIM variable for path truncation.
The default value of comment-begin is '#' (the hash character). This is the string inserted when the readline insert-comment command is executed.
Command Line Editing > Completion
51 questionsThe set of characters that the readline library treats as word separators when performing word completion. If unset, it loses its special properties, even if subsequently reset.
completion-ignore-case (default: Off). If set to On, readline performs filename matching and completion in a case-insensitive fashion.
Tell readline not to quote the completed words if they are filenames (quoting filenames is the default).
COMP_LINE (current command line), COMP_POINT (index of current cursor position), COMP_KEY (key that invoked completion), COMP_TYPE (type of completion attempted), COMP_WORDS (array of individual words in command line), and COMP_CWORD (index into COMP_WORDS of the word containing the current cursor position).
menu-complete-backward is identical to menu-complete, but moves backward through the list of possible completions, as if menu-complete had been given a negative argument. Both are unbound by default.
alias (-a), arrayvar, binding, builtin (-b), command (-c), directory (-d), disabled, enabled, export (-e), file (-f), function, group (-g), helptopic, hostname, job (-j), keyword (-k), running, service (-s), setopt, shopt, signal, stopped, user (-u), variable (-v).
complete-username (M-~) for username completion, complete-variable (M-$) for shell variable completion, complete-hostname (M-@) for hostname completion, and complete-command (M-!) for command name completion (attempts to match against aliases, reserved words, shell functions, shell builtins, and executable filenames, in that order).
If set to On, readline will display completions with matches sorted horizontally in alphabetical order, rather than down the screen. Default is Off.
When the function is invoked, the first argument ($1) is the name of the command whose arguments are being completed, the second argument ($2) is the word being completed, and the third argument ($3) is the word preceding the word being completed on the current command line.
TAB (complete command). When pressed, bash attempts completion treating the text as a variable (if begins with $), username (if begins with ~), hostname (if begins with @), or command (including aliases and functions) in turn. If none of these produces a match, filename completion is attempted.
compopt modifies completion options for each name according to the options, or for the currently-executing completion if no names are supplied. If no options given, displays completion options. Unlike complete, it doesn't define new completions but modifies options for existing ones. Can use +o to turn off an option.
The order is: 1) Actions specified by compspec options (-f, -d, etc.) with FIGNORE filtering. 2) Pathname expansion patterns from -G option. 3) Wordlist from -W option after brace/tilde/parameter/arithmetic expansion. 4) Shell function from -F option. 5) Command from -C option. 6) Filter from -X option. 7) Prefix/suffix from -P/-S options. If no matches and -o dirnames was supplied, directory completion is attempted. If -o plusdirs was supplied, directory matches are added to results.
COMP_TYPE is set to an integer value corresponding to the type of completion attempted: TAB for normal completion, ? for listing completions after successive tabs, ! for listing alternatives on partial word completion, @ to list completions if the word is not unmodified, or % for menu completion.
Attempts completion on the text before point, comparing the text against lines from the history list for possible completion matches.
Command completion attempts to match the text against aliases, reserved words, shell functions, shell builtins, and finally executable filenames, in that order.
If set to On, a character denoting a file's type as reported by stat(2) is appended to the filename when listing possible completions. Default is Off.
skip-completed-text (default: Off). When set to On, it alters the default completion behavior when inserting a single match into the line. It's only active when performing completion in the middle of a word. If enabled, readline does not insert characters from the completion that match characters after point in the word being completed, so portions of the word following the cursor are not duplicated.
The -r option removes a completion specification for each name supplied. If no names are supplied, all completion specifications are removed.
The number of screen columns used to display possible matches when performing completion. The value is ignored if less than 0 or greater than terminal screen width. A value of 0 displays matches one per line. Default is -1.
Tell readline not to append a space (the default) to words completed at the end of the line.
Use readline's default filename completion if the compspec generates no matches.
COMP_POINT contains 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}.
If set to On, readline displays possible completions using different colors to indicate their file type. The color definitions are taken from LS_COLORS environment variable. Default is Off.
filterpat is a pattern as used for pathname expansion. It is applied to the list of possible completions generated by the preceding options and arguments, and each completion matching filterpat is removed from the list. A leading ! in filterpat negates the pattern; any completion not matching filterpat is removed. A & in the pattern is replaced with the text of the word being completed.
The word before point is treated as a pattern for pathname expansion, with an asterisk implicitly appended. This pattern is used to generate a list of matching filenames for possible completions.
After any matches defined by the compspec are generated, directory name completion is attempted and any matches are added to the results of the other actions.
The wordlist is split using characters in the IFS special variable as delimiters, and each resultant word is expanded using brace expansion, tilde expansion, parameter and variable expansion, command substitution, and arithmetic expansion. The results are prefix-matched against the word being completed, and matching words become possible completions.
If set to On, completed names which are symbolic links to directories have a slash appended (subject to the value of mark-directories). Default is Off.
First, if the command word is empty, compspecs defined with -E are used. If compspec defined for that command, it's used. If command word is a full pathname, compspec for full pathname is searched first, then portion after final slash. If not found, compspec with -D is used as default. If no default compspec, bash attempts alias expansion and tries to find compspec for expanded command word.
-F function executes a shell function in the current shell environment. The function must put completions in the COMPREPLY array variable. -C command executes a command in a subshell environment, and its output (one completion per line) is used as the possible completions.
If set, the programmable completion facilities are enabled. This option is enabled by default.
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.
The function must put the possible completions in the COMPREPLY array variable, with one completion per array element.
Performs filename completion and inserts the list of possible completions enclosed within braces so the list is available to the shell (for Brace Expansion).
If set, and programmable completion is enabled, bash treats a command name that doesn't have any completions as a possible alias and attempts alias expansion. If it has an alias, bash attempts programmable completion using the command word resulting from the expanded alias.
compgen generates possible completion matches for word according to the options and writes them to standard output. It accepts any option accepted by the complete builtin with the exception of -p and -r.
The default value is 100. It determines when the user is queried about viewing the number of possible completions. If the number of possible completions is greater than or equal to this value, readline will ask whether the user wishes to view them; otherwise they are simply listed. A value of zero means readline should never ask.
mark-directories (default: On). If set to On, completed directory names have a slash appended.
-D applies completions to the 'default' command completion (commands with no specific completion defined). -E applies completions to 'empty' command completion (completion attempted on a blank line). -I applies completions to the initial non-assignment word on the line, or after a command delimiter such as ; or | (usually command name completion). If multiple options are supplied, -D takes precedence over -E, and both take precedence over -I.
If set to On, when listing completions, readline displays the common prefix of the set of possible completions using a different color. The color definitions are taken from LS_COLORS. Default is Off.
Tell readline not to sort the list of possible completions alphabetically.
Perform the rest of the default bash completions if the compspec generates no matches.
Tell readline that the compspec generates filenames, so it can perform any filename-specific processing (like adding a slash to directory names, quoting special characters, or suppressing trailing spaces). Intended to be used with shell functions.
If set to On, readline uses an internal more-like pager to display a screenful of possible completions at a time. Default is On.
The word before point is treated as a pattern for pathname expansion, and the list of matching filenames is inserted, replacing the word. If a numeric argument is supplied, an asterisk is appended before pathname expansion.
Two key variables: 1) show-all-if-ambiguous (default: Off) - if set to On, words with multiple possible completions cause matches to be listed immediately instead of ringing the bell. 2) show-all-if-unmodified (default: Off) - if set to On, words with multiple possible completions without any possible partial completion cause matches to be listed immediately instead of ringing the bell.
The default value is 0. It specifies the length in characters of the common prefix of a list of possible completions that is displayed without modification. When set to a value greater than zero, common prefixes longer than this value are replaced with an ellipsis when displaying possible completions.
complete-filename (M-/) attempts filename completion on the text before point. possible-completions (M-?) lists all the possible completions of the text before point (not just filenames).
The pathname expansion pattern globpat is expanded to generate possible completions. The words generated need not match the word being completed. GLOBIGNORE shell variable is not used to filter matches, but FIGNORE variable is used.
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. Default is Off.
Installing Bash > Build Configuration
51 questionsThe --enable-select-builtins option enables the select builtin command for creating simple menus in Bash scripts.
The --enable-readline option forces Bash to link with the readline library that comes with the Bash source distribution, rather than using a system-installed readline library. This is enabled by default.
The --host=HOST-TYPE option specifies the host system type where the compiled Bash will run, used for cross-compilation. This determines the runtime behavior and system calls.
The --enable-minimal-config option configures Bash with a minimal set of features, disabling many extensions to create a smaller binary suitable for embedded systems or resource-constrained environments.
The --enable-profiling option adds profiling support to the Bash executable, allowing it to be used with profiling tools like gprof to analyze performance characteristics.
The --disable-usable-provided-threads option disables threading support even if the system provides threading capabilities, forcing a single-threaded build.
The --disable-multibyte option removes support for multibyte characters, limiting Bash to single-byte character handling. This reduces binary size and may be useful for embedded systems.
The --disable-net-redirections option removes support for network redirections (/dev/tcp and /dev/udp) from Bash, which may be desirable for security reasons in some environments.
The CFLAGS environment variable passes additional compiler flags to the C compiler during the Bash build (e.g., CFLAGS='-O2 -Wall').
The --disable-printf option removes the printf builtin command from Bash.
The --with-purify option configures Bash to be built with Rational Purify, a memory debugging tool. This is for development and debugging purposes.
The --enable-casemod-expansion option enables case modification expansion in parameter expansion, allowing operations like ${var^^} for uppercase conversion and ${var,,} for lowercase conversion.
The --enable-process-substitution option enables process substitution feature (<(command) and >(command)) for named pipe handling. This is enabled by default on systems that support it.
The --disable-array-variables option removes support for indexed and associative array variables from Bash.
The --enable-dev-fd-stat-buffs option enables the use of /dev/fd for buffering command output instead of temporary files. This is enabled by default on systems that support /dev/fd.
The --build=BUILD-TYPE option specifies the system type where the compilation is being performed, which is typically automatically detected by the configure script.
The --with-afs option enables support for the Andrew File System (AFS), modifying how Bash handles pathnames and authentication in AFS environments.
The --with-gnu-ld option assumes that the system uses the GNU ld linker and enables GNU-specific linker features.
The --enable-mem-scramble option enables memory scrambling, which fills freed memory with a specific pattern to help detect use-after-free bugs during development.
The --enable-casemod-attributes option enables case modification attributes in Bash, which allow string case conversion in parameter expansion.
The --enable-brace-expansion option enables brace expansion, allowing expressions like {a,b,c} or {1..5} to be expanded into multiple words. This is enabled by default.
The --enable-cond-command option enables the conditional command [[...]] for more advanced conditional testing than the test command.
The --disable-nls option disables Native Language Support (internationalization) in Bash, preventing the loading of message translation files and reducing binary size.
The --enable-debugger option enables the Bash debugger, allowing debugging of shell scripts using the debugger bash -D option. This requires special support and is not typically enabled by default.
The --disable-dir-builtin option removes the directory stack builtins (pushd, popd, dirs) from Bash.
The --enable-multibyte option enables support for multibyte characters (such as UTF-8) in Bash. This option is enabled by default in modern Bash versions.
The --enable-static-link option causes Bash to be statically linked with its libraries, creating a self-contained executable that does not depend on shared libraries at runtime.
The --disable-readline option prevents Bash from using the readline library for interactive command-line editing. This results in a smaller binary but with reduced interactive functionality.
The --enable-strict-posix configure option causes Bash to be built with strict POSIX conformance, disabling various GNU extensions and features that are not part of the POSIX standard.
The --target=TARGET-TYPE option is used when building compilers to specify the target system for code generated by the compiler. For Bash, this is typically not needed unless building Bash as part of a cross-compiler toolchain.
The --enable-cond-regexp option enables regular expression matching in the [[ conditional command using the =~ operator.
The CPPFLAGS environment variable passes additional preprocessor flags (such as include paths) when building Bash (e.g., CPPFLAGS='-I/usr/local/include').
The --with-installed-readline option tells the configure script to use an already-installed version of the readline library on the system rather than the version included in the Bash source distribution.
The --disable-history-builtin option removes the history builtin command from Bash, disabling command history management features.
The CC environment variable specifies the C compiler to use when building Bash (e.g., CC=gcc or CC=clang).
The --with-installed-readline=PATH option specifies that Bash should use the readline library installed at the specified PATH prefix, rather than the version included with Bash.
The --enable-help-builtin option enables the help builtin command for displaying information about shell builtins.
The environment variable DESTDIR does NOT change the installation prefix. To set the default prefix, use --prefix=PATH with ./configure. The DESTDIR variable is used only at 'make install' time to relocate the installation root for packaging purposes.
The --enable-extended-glob option enables extended globbing features in pathname expansion by default, which includes pattern matching operators like ?(pattern-list), *(pattern-list), +(pattern-list), @(pattern-list), and !(pattern-list).
The --disable-largefile option disables support for files larger than 2 GB on systems that use 32-bit file offsets. By default, Bash enables largefile support on systems that support it.
The --disable-brace-expansion option removes brace expansion support from Bash, preventing the use of {a,b,c} style expansions.
The --enable-arith-for-command option enables arithmetic for commands, allowing for ((exp1; exp2; exp3)) style loops in Bash scripts.
The --with-curses option tells Bash to use the curses library for terminal handling instead of termcap.
The --without-bash-malloc option forces Bash to use the system's malloc library instead of the Bash-specific malloc implementation included in the source.
The --with-gnu-malloc option is an alias for --with-bash-malloc, specifying that Bash should use its included GNU malloc implementation.
The --enable-job-control option enables job control features in Bash, allowing background job management, fg, bg, jobs commands, and terminal control. This is enabled by default on systems that support it.
The --with-bash-malloc option tells Bash to use its own malloc implementation rather than the system's malloc library. This is the default behavior on most systems.
The LDFLAGS environment variable passes additional flags to the linker during the Bash build (e.g., LDFLAGS='-L/usr/local/lib').
The --disable-job-control option removes job control support from Bash, preventing the use of background jobs and job control builtins.
The default installation prefix for Bash when running ./configure without arguments is /usr/local. This means binaries will be installed to /usr/local/bin, libraries to /usr/local/lib, and documentation to /usr/local/share.
The --enable-net-redirections option enables network redirection support in Bash, allowing redirections like /dev/tcp/host/port and /dev/udp/host/port for network communication.
Shell Expansions > Substitution Expansions
51 questionsThe expansion is a string consisting of flag values representing parameter's attributes.
If the substitution appears within double quotes, Bash does not perform word splitting and filename expansion on the results.
If the expression is invalid, Bash prints a message indicating failure to the standard error and no substitution occurs.
The expansion is a string that is the value of parameter with backslash escape sequences expanded as with the $'…' quoting mechanism.
The expansion is a string that is the value of parameter quoted in a format that can be reused as input.
If parameter is null or unset, the shell writes the expansion of word (or a message to that effect if word is not present) to the standard error and, if it is not interactive, exits with a non-zero status. An interactive shell does not exit, but does not execute the command associated with the expansion.
Positional parameters and special parameters may not be assigned using the := operator.
The expansion is a string in the form of an assignment statement or declare command that, if evaluated, recreates parameter with its attributes and value.
If pattern is omitted, it is treated like '?', which matches every character.
No space may appear between the '<' or '>' and the left parenthesis, otherwise the construct would be interpreted as a redirection.
Substring expansion applied to an associative array produces undefined results.
It converts matching uppercase letters to lowercase. The ',,' variant examines all characters in the expanded value and converts each one that matches pattern.
The exclamation point (!) must immediately follow the left brace in order to introduce indirection.
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.
The order of expansions is: brace expansion; tilde expansion, parameter and variable expansion, arithmetic expansion, and command substitution (done in a left-to-right fashion); word splitting; and filename expansion. Process substitution is performed simultaneously with tilde, parameter, variable, and arithmetic expansion and command substitution.
It expands to the names of variables whose names begin with prefix, separated by the first character of the IFS special variable. When @ is used and the expansion appears within double quotes, each variable name expands to a separate word.
The alternate form is ${ command; }, which executes command in the current execution environment and captures its output, with trailing newlines removed.
% removes the shortest matching pattern from the end, while %% removes the longest matching pattern from the end.
In the first form (${parameter/pattern/string}), only the first match is replaced. If there are two slashes separating parameter and pattern (the second form), all matches of pattern are replaced with string.
The only exceptions to single-word expansion are the expansions of "$@" and $, and "${name[@]}" and ${name[]}.
A negative offset must be separated from the colon by at least one space to avoid being confused with the :- expansion.
The standard form of command substitution is $(command). The backtick form command is deprecated.
Only brace expansion, word splitting, and filename expansion can increase the number of words of the expansion; other expansions expand a single word to a single word.
Bash does not perform tilde expansion on words satisfying the conditions of variable assignments when they appear as arguments to simple commands when in POSIX mode (except for the declaration commands).
The command substitution $(cat file) can be replaced by the equivalent but faster $(< file).
If pattern is preceded by #, it must match at the beginning of the expanded value of parameter.
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.
If HOME is unset, the home directory of the user executing the shell is substituted instead.
With the old-style backquote form, backslash retains its literal meaning except when followed by '$', '`', or ''. When using the $(command) form, all characters between the parentheses make up the command; none are treated specially.
The colon (:) makes a difference. When using :- (with colon), Bash tests for a parameter that is unset or null. When omitting the colon (using -), Bash tests only for a parameter that is unset.
If the login name is invalid, or the tilde expansion fails, the word is left unchanged.
If length is omitted, but the colon after offset is present, it is treated as 0.
If pattern is preceded by %, it must match at the end of the expanded value of parameter.
The '^' variant examines the first character in the expanded value and converts its case if it matches pattern (lowercase to uppercase). The '^^' variant examines all characters in the expanded value and converts each one that matches pattern.
Substring indexing is zero-based unless the positional parameters are used, in which case the indexing starts at 1 by default.
If the first character following the open brace is a '|', the construct expands to the value of the REPLY shell variable after command executes, without removing any trailing newlines, and the standard output of command remains the same as in the calling shell.
It converts matching uppercase letters to lowercase, but only examines the first character in the expanded value and converts its case if it matches pattern.
If the tilde-prefix, sans the tilde, consists of a number without a leading '+' or '-', '+' is assumed.
Any unquoted instances of '&' in the replacement string are replaced with the matching portion of pattern.
Bash replaces the command substitution with the standard output of the command, with any trailing newlines deleted.
Each variable assignment is checked for unquoted tilde-prefixes immediately following a ':' or the first '='. In these cases, tilde expansion is also performed.
removes the shortest matching pattern from the beginning, while ## removes the longest matching pattern from the beginning.
The '$' character introduces parameter expansion, command substitution, or arithmetic expansion.
Yes, command substitutions may be nested. To nest when using the backquoted form, escape the inner backquotes with backslashes.
The character c following the open brace must be a space, tab, newline, or '|', and the close brace must be in a position where a reserved word may appear.
Programmable Completion > Completion Source Mechanisms
49 questionsThe -g option generates group names from the system's group database. Example: compgen -g -- "$cur"
The command name is ${COMP_WORDS[0]}, which is always the first element of the COMP_WORDS array. There is no separate COMP_COMMAND variable.
Quote the command substitution properly: COMPREPLY=($(compgen -W "$words" -- "$cur")). The outer array parentheses and proper quoting ensure filenames with spaces are handled correctly.
The -o nospace option. Example: compopt -o nospace will prevent bash from adding a space after the completed word.
The -C command option executes command and uses its output for completion. Example: compgen -C 'find . -type f' -- "$cur"
The -u option generates usernames from the system's user database. Example: compgen -u -- "$cur"
The compgen built-in command is used to generate possible completions. Syntax: compgen [option] [word]. It displays the matches on standard output but does not apply them to COMPREPLY.
The -A alias option generates alias names. Example: compgen -A alias -- "$cur"
The -o plusdirs option adds directory name completion to any results generated by the completion function. Directory completions are appended to the function's output.
The -r option removes a completion specification. Example: complete -r mycommand removes any completion rules for mycommand.
The -W wordlist option. This tells compen to generate completions from the specified wordlist. Example: compgen -W 'option1 option2 option3' -- "$cur"
Use command substitution with array syntax: COMPREPLY=($(compgen -W "opt1 opt2" -- "$cur")). The parentheses create an array, and the command substitution captures compen's output.
The COMP_TYPE variable indicates the type of completion being attempted. Values include: @ for normal completion (tab), % for successive tab completion (list completions), ! for listing alternatives on partial word completion, and = for menu completion.
The -A option generates hostname completions, sourced from /etc/hosts or other hostname sources. Example: compgen -A hostname -- "$cur"
The -X filterpat option filters out completions that match filterpat. The pattern is applied to each potential completion and any matches are excluded. This is used to exclude certain patterns from completion results.
There is no separate option for enabled vs disabled builtins. Use -A builtin for all builtin names.
The COMPREPLY array variable. A completion function must populate COMPREPLY with the array of completion candidates that will be displayed to the user.
The -o nospace option prevents adding a space after completed words. For directories specifically, the -o dirnames option (or using -d) automatically adds trailing slashes to directory names.
Use compopt +o default to turn off default completion, or compopt -o filenames to explicitly set filename completion mode. The +o syntax negates the option.
The -S option generates service names from /etc/services. Example: compgen -A service -- "$cur"
The -d option enables directory name completion. Example: complete -d mycommand will only complete directory names for mycommand.
The -v option generates shell variable names. Example: compgen -v -- "$cur" will complete variable names matching the current word.
There is no built-in variable for this. The standard pattern is: local prev=${COMP_WORDS[COMP_CWORD-1]} to capture the previous word, often used to determine which option was specified.
The -F function option tells bash to use the specified shell function to generate completions. Example: complete -F _mycommand mycommand will call _mycommand each time tab is pressed on mycommand.
The -W wordlist option defines a space-separated list of words for completion. Example: complete -W 'start stop restart' service completes those specific words.
The -D option defines a completion for all commands that don't already have a completion specification. It's used to set a default completion function.
The compopt built-in command modifies completion options for the current completion. Syntax: compopt [option]. It can change behavior like whether to add spaces, display filenames, etc.
The -o option sets completion options. For example: complete -o default mycommand enables default completion after any matches. Common options include default, dirnames, nospace, filenames, plusdirs.
The -j option to compgen generates job names as completion candidates. Example: compgen -j -- "$cur"
The -f option generates filename completions. Example: compgen -f -- "$cur" will generate all filenames matching the current word.
The COMP_POINT variable contains the index of the cursor position relative to the beginning of the current command. It indicates where the cursor is in COMP_LINE.
The -C command option tells bash to execute the specified command and use its output for completion. Example: complete -C '_mycommand_completer' mycommand
The -A command option or -c option generates command names, including aliases, functions, and builtins. Example: compgen -A command -- "$cur" or compgen -c -- "$cur"
The COMP_WORDS variable is an array containing all individual words in the current command line. You can access specific words like ${COMP_WORDS[COMP_CWORD]} for the current word or ${COMP_WORDS[COMP_CWORD-1]} for the previous word.
There is no built-in variable for this. The standard pattern is: local cur=${COMP_WORDS[COMP_CWORD]} to capture the current word being completed.
The -- signals the end of options. Anything after -- is treated as the word to complete, even if it starts with a hyphen. This prevents words beginning with - from being interpreted as options.
The -P prefix option adds prefix to each completion result. Example: compgen -P 'prefix_' -W 'foo bar' -- "$cur" would produce prefix_foo and prefix_bar.
The COMP_CWORD variable contains the index of the current word in the COMP_WORDS array that is being completed. It's used to identify which argument the cursor is on.
The COMP_KEY variable contains the key (or terminal key sequence) that invoked the current completion function. It's rarely used in custom completions but identifies what key triggered completion.
The -S suffix option adds suffix to each completion result. Example: compgen -S ':' -W 'foo bar' -- "$cur" would produce foo: and bar:.
The -f option enables filename completion. Example: complete -f mycommand will complete filenames for mycommand.
The -o filenames option tells bash that the completion function returns filenames, which causes bash to perform filename-specific processing like de-quoting, adding trailing slashes to directories, and suppressing trailing spaces.
The -A function option generates shell function names. Example: compgen -A function -- "$cur"
The -d option generates directory name completions. Example: compgen -d -- "$cur" will generate all directory names matching the current word.
The -o quoted option ensures completed filenames are properly quoted if they contain special characters.
The -o nosort option affects sorting, but to force exact matches use compopt -o default with no fallback. The -o plusdirs option adds directory completion regardless of other matches.
The -o default option tells bash to also perform default completion (filename completion) even if the completion function doesn't generate any matches.
The -E option defines completion for empty command lines (before any command is typed). It's typically used in bash completion frameworks for special empty-line handling.
The COMP_LINE variable contains the full current command line as a string. This is useful for parsing the entire command context.
Interactive Shells > Prompting and Display
49 questionsLINES and COLUMNS are automatically set if the checkwinsize option is enabled, or in an interactive shell upon receipt of a SIGWINCH signal.
\d displays the date in 'Weekday Month Date' format (e.g., 'Tue May 26').
Emacs-style command line editing interface is enabled by default when the shell is interactive, unless the shell is started with the --noediting option.
[ begins a sequence of non-printing characters, and ] ends it. These are used to embed terminal control sequences into prompts without counting them as characters for cursor positioning.
PS0 is expanded and displayed by interactive shells after reading a command but before the command is executed.
When cmdhist is 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.
When checkwinsize is enabled (default), bash checks the window size after each external (non-builtin) command and updates the values of LINES and COLUMNS if necessary.
The interactive_comments option is enabled by default in interactive shells. When set, it allows a word beginning with # to cause that word and all remaining characters on that line to be ignored (comments).
! displays the history number of the command (its position in the history list), while # displays the command number (position in the sequence of commands executed during the current shell session).
In an interactive shell, TMOUT is interpreted as the number of seconds to wait for a line of input after issuing the primary prompt. Bash terminates after waiting for that number of seconds if a complete line of input does not arrive.
The default value of convert-meta is On. When set, readline converts characters with the eighth bit set to an ASCII key sequence by stripping the eighth bit and prefixing an escape character.
\t displays current time in 24-hour HH:MM:SS format, \T displays current time in 12-hour HH:MM:SS format, @ displays current time in 12-hour am/pm format, and \A displays current time in 24-hour HH:MM format.
The expand_aliases option is enabled by default for interactive shells. When set, aliases are expanded as described under ALIASES.
completion-query-items determines when the user is queried about viewing possible completions. The default is 100. If the number of possible completions is greater than or equal to this value, readline asks whether the user wishes to view them.
The default value of PS1 is '\s-\v$ ' which expands to the shell name (basename of $0), a hyphen, the version number, and either # (for root) or $ (for regular users).
When huponexit is set with shopt, bash sends a SIGHUP to all jobs when an interactive login shell exits.
If bash finds the EMACS variable in the environment with value 't' when the shell starts, it assumes the shell is running in an Emacs shell buffer and disables line editing.
PS3 is used as the prompt for the select command. Unlike PS1, PS2, and PS4, PS3 is not expanded with backslash-escaped special characters.
When checkjobs is enabled, bash lists the status of any stopped and running jobs before exiting an interactive shell. If any jobs are running, exit is deferred until a second exit is attempted without an intervening command.
The default value of PS4 is '+ '. The first character of the expanded PS4 value is replicated multiple times to indicate multiple levels of indirection during execution tracing.
Bash checks for mail before displaying the primary prompt. The frequency is controlled by the MAILCHECK variable (default 60 seconds).
When lithist is set and the cmdhist option is enabled, multi-line commands are saved to the history with embedded newlines rather than using semicolon separators where possible.
The default value of MAILCHECK is 60 seconds. This specifies how often (in seconds) bash checks for mail.
History expansion is enabled by default for interactive shells. It can be disabled using the +H option to the set builtin command.
\D{format} passes the format string to strftime(3) and inserts the result into the prompt. An empty format results in a locale-specific time representation. The braces are required.
The readline initialization file name is taken from the INPUTRC variable. If unset, the default is ~/.inputrc. If that file does not exist or cannot be read, the ultimate default is /etc/inputrc.
By default, bash waits until it is about to print a prompt before reporting changes in a job's status. If the -b option to the set builtin command is enabled, bash reports such changes immediately.
\w displays the value of the PWD shell variable ($PWD) with $HOME abbreviated with a tilde, while \W displays only the basename of $PWD with $HOME abbreviated with a tilde.
$ displays # if the effective UID is 0 (root), otherwise displays $ for regular users.
If IGNOREEOF exists but does not have a numeric value, or has no value, the default value is 10. This means 10 consecutive EOF characters must be typed as the first characters on an input line before bash exits.
The -b option causes bash to report the status of terminated background jobs immediately, rather than before the next primary prompt. This is effective only when job control is enabled.
When autocd is set, a command name that is the name of a directory is executed as if it were the argument to the cd command. This option is only used by interactive shells.
The shell exits by default upon receipt of SIGHUP. Before exiting, an interactive shell resends the SIGHUP to all jobs, running or stopped. Stopped jobs are sent SIGCONT to ensure they receive the SIGHUP.
The -m option enables monitor mode (job control). This option is on by default for interactive shells on systems that support it. When a background job completes, the shell prints a line containing its exit status.
\s displays the name of the shell, which is the basename of $0 (the portion following the final slash).
PROMPT_DIRTRIM, when set to a number greater than zero, specifies the number of trailing directory components to retain when expanding the \w and \W prompt string escapes. Characters removed are replaced with an ellipsis.
\h displays the hostname up to the first dot (short hostname), while \H displays the full hostname.
When an interactive shell that is not a login shell is started, bash reads and executes commands from /etc/bash.bashrc and ~/.bashrc, if these files exist. This can be inhibited with --norc or overridden with --rcfile.
When bash is interactive, in the absence of any traps, it ignores SIGTERM and SIGQUIT. SIGINT is caught and handled.
When cdspell is set, minor errors in the spelling of a directory component in a cd command are automatically corrected. Errors checked include transposed characters, a missing character, and one character too many. This option is only used by interactive shells.
The promptvars option, when enabled (which is the default), causes prompt strings to undergo parameter expansion, command substitution, arithmetic expansion, and quote removal after being expanded with backslash-escaped special characters.
The default value of bell-style is 'audible', which means readline attempts to ring the terminal's bell when it wants to ring the bell.
An interactive shell returns failure if the file specified as an argument to the exec builtin command cannot be executed. This is different from non-interactive shells, which exit unless the execfail shell option is enabled.
Command Line Editing > Line Editing Basics
49 questionsCtrl+D bound to 'delete-char' will exit the shell when pressed at an empty command line (EOF).
Use 'set +o emacs' or 'set +o vi' to turn off line editing after the shell is running. Alternatively, start bash with the '--noediting' option.
The 'bind' builtin command is used to set Readline key bindings and variables.
Alt+Backspace (Meta-Backspace or ESC followed by Backspace) bound to 'unix-word-rubout' function.
Use the command 'set -o vi' to enable vi-style line editing. To switch back to emacs mode, use 'set -o emacs'.
The -x option binds a key sequence to execute a shell command. Syntax: bind '-x keyseq:shell-command'. The SHELL-COMMAND is executed when KEYSEQ is entered.
Use the bind command with syntax: bind '"\C-x\C-r": re-read-init-file'. The key sequence and function must be passed as a single argument in quotes.
The 'bind -p' command lists readline function names and bindings in a form that can be reused as input (e.g., in an inputrc file).
Ctrl+X Ctrl+U (Control-X followed by Control-U) bound to 'unix-line-discard' function.
Ctrl+P (Control-P) or Up Arrow bound to 'previous-history' function.
The 'bind -P' command lists all current readline function names and their bindings.
Alt+B (Meta-B or ESC followed by B) bound to 'backward-word' function.
The default value is '(cmd)'. This string is displayed in the prompt when vi is in command mode if show-mode-in-prompt is enabled.
Alt+F (Meta-F or ESC followed by F) bound to 'forward-word' function.
C- notation denotes Control keys. For example, C-n means Control-N (holding the Control key while pressing N).
Key sequences use special notation: \C-x for Control-x, \M-x for Meta-x, \e for Escape. Example: '"\C-x\C-r": re-read-init-file' binds Ctrl-X Ctrl-R to re-read-init-file.
Alt+T (Meta-T or ESC followed by T) bound to 'transpose-words' function.
The default value is '(ins)'. This string is displayed in the prompt when vi is in insertion mode if show-mode-in-prompt is enabled.
Alt+< (Meta-Less-Than or ESC followed by <) bound to 'beginning-of-history' function.
Alt+> (Meta-Greater-Than or ESC followed by >) bound to 'end-of-history' function.
The 'show-mode-in-prompt' variable when set to 'on' displays the current editing mode in the prompt. Default is 'off'.
Alt+Y (Meta-Y or ESC followed by Y) bound to 'yank-pop' function, used after yanking to cycle through previously killed text.
Ctrl+H (Control-H) or Backspace bound to 'backward-delete-char' function.
M- notation denotes Meta keys. For example, M-x means Meta-X. On keyboards without a meta key, M-x means pressing ESC followed by x.
Bash uses the GNU Readline library for command line editing capabilities. This library provides line editing features similar to Emacs or Vi editors.
The 'keymap' variable sets the current readline keymap. Default value is 'emacs'. Valid keymap names include: emacs, emacs-standard, emacs-meta, emacs-ctlx, vi, vi-command, and vi-insert.
The default value is '@'. This string is displayed in the prompt when emacs mode is active if show-mode-in-prompt is enabled.
The 'completion-ignore-case' variable. If set to 'on', completion is case-insensitive. Default is 'off' (case-sensitive).
The inputrc file configures readline. The path is taken from the INPUTRC environment variable. If INPUTRC is unset, readline reads ~/.inputrc or /etc/inputrc.
Emacs mode is the default editing mode for interactive shells. The 'editing-mode' readline variable defaults to 'emacs'.
The 'editing-mode' variable controls whether readline begins with Emacs or vi key bindings. It can be set to either 'emacs' or 'vi'. Default is 'emacs'.
The -m option selects a keymap to use for the duration of the command. Acceptable keymap names are: emacs, emacs-standard, emacs-meta, emacs-ctlx, vi, vi-move, vi-command, and vi-insert.
Bash Builtin Commands > Programmable Completion Builtins
48 questionsThe '-A action' option specifies the list of completion actions to try. The action can be any of the completion actions like 'alias', 'builtin', 'command', 'directory', etc.
The '--' argument signals the end of options. Any arguments following '--' are treated as words to complete, even if they begin with a dash.
The COMPREPLY variable is an array variable that completion functions should set to the possible completions. Each array element is one possible completion for the current word.
The '-D' option indicates that the remaining options and actions apply to the 'default' command completion - that is, completion attempted for a command that has no defined completion.
The '-c' action specifies command name completion. It generates completions from the list of available commands, including aliases, functions, builtins, and executables in PATH.
The '-o noquote' option tells readline not to quote completed filenames even if they contain special characters that normally require quoting.
The '+o option' syntax unsets or disables the completion option named 'option'. It is the opposite of '-o option'.
The '-o plusdirs' option tells readline to append directory completions to the results of the completion function, after any other completions have been added.
A completion function specified with '-F' is invoked with: the command name as first argument, the word being completed as second argument, the word preceding the current word as third argument, and additional arguments depending on completion context.
The '-o bashdefault' option tells readline to attempt the normal Bash default completion if no other completions are generated. This includes command, variable, and username completion.
The '-d' action specifies directory name completion. It generates completions matching directory names.
The COMP_KEY variable contains the key or final key of a key sequence that caused the current completion to be invoked.
The '-o filenames' option tells readline that the completion function generates filenames. This enables readline to handle things like pathname expansion, directory separators, and adding trailing slashes for directories.
The '-F function' option specifies that function is the name of a shell function that will be called to generate completions. The function is invoked with the command name, word being completed, and previous word as arguments.
The '-j' action specifies job name completion. It generates completions from the list of active jobs.
The '-P prefix' option specifies that prefix should be prepended to each completion after all other options have been applied.
The COMP_WORDS variable is an array containing the individual words on the current command line. All shell substitutions and expansions are applied to this array.
The '-a' action specifies alias name completion. It generates completions from the list of available shell aliases.
The COMP_LINE variable contains the current command line as a single string. It is the full command line before completion is attempted.
The '-o nospace' option tells readline not to append a space after the completed word. This is useful when the completion may be followed by additional characters without a space.
The '-S suffix' option specifies that suffix should be appended to each completion after all other options have been applied.
The '-o nosort' option tells readline not to sort the possible completions alphabetically. Completions are displayed in the order they are generated.
The '-g' action specifies group name completion. It generates completions from the list of system groups.
The '-W wordlist' option specifies that wordlist should be split using the characters in IFS (Internal Field Separator), and the resultant words are used as the possible completions.
The '-k' action specifies keyword completion. It generates completions from the list of shell reserved words.
The '-e' action specifies environment variable name completion. It generates completions from the list of exported shell variables.
The '-r' or '--remove' option removes the completion specification for each specified name. If no names are given, it removes all completion specifications.
The '-I' option indicates that the remaining options and actions apply to the command after an initial command (typically 'sudo', 'doas', or similar) and before the actual command name.
The '-E' option indicates that the remaining options and actions apply to 'empty' command completion - completion attempted on an empty command line.
The '-o dirnames' option tells readline to attempt directory name completion if no other completions are generated.
The '-u' action specifies username completion. It generates completions from the list of system users.
Yes, when called without options, 'compopt' prints the current completion options for the currently-executing completion function.
The '-o history' option tells readline to perform completion from the command history, matching words from previously entered commands.
The three programmable completion builtins in Bash are: complete, compgen, and compopt.
The '-X filterpat' option specifies a filter pattern. The pattern is used to filter out completions that match it. Any completion matching filterpat is removed from the completion list.
If 'compopt' successfully modifies a completion option, it returns a zero (0) exit status. If an error occurs (such as being used outside a completion function), it returns non-zero.
The '-o default' option tells readline to attempt filename completion if no other completions are generated by the completion specification.
The '-f' action specifies file name completion. It generates completions matching file and directory names.
The '-p' or '--print' option prints existing completion specifications in a format that can be reused as input. Without arguments, it prints all completion specifications.
The '-b' action specifies builtin command name completion. It generates completions from the list of Bash builtin commands.
The '-v' action specifies shell variable name completion. It generates completions from the list of all shell variables.
The COMP_TYPE variable contains a value indicating the type of completion attempted. Values include: '!' for normal completion, '@' for menu completion, '%' for menu completion with repeated hits, and '^' for alternate completion.
The COMP_POINT variable contains the index of the current cursor position relative to the beginning of the current command. If the cursor is at the end of the line, its value equals the length of COMP_LINE.
The '-o shellvar' option tells readline to perform shell variable completion. It generates completions matching shell variable names.
The COMP_CWORD variable contains the index of the current word in the COMP_WORDS array. It indicates which word the cursor is currently on or just after.
The '-o dynamic' option tells readline to dynamically regenerate completion list each time it is displayed, rather than generating it once and caching it.
The '-G globpat' option specifies that pathname expansion pattern globpat should be expanded to generate possible completions.
The '-o option' syntax sets the completion option named 'option'. For example, '-o default' enables the default completion behavior.
Invoking Bash > Argument Handling
48 questionsThe -k option (or set -o keyword) causes all keyword arguments to be placed in the environment for a command, not just those preceding the command name. This allows arguments anywhere in the command line to be exported. Example: FOO=bar command vs command FOO=bar.
The --verbose option is equivalent to -v. It causes Bash to print shell input lines as they are read. Each line is displayed before being parsed or executed. Useful for debugging to see exactly what the shell is reading.
The -x option causes Bash to print commands and their arguments as they are executed. Each command is printed after expansion but before execution, prefixed with PS4 (typically '+'). This is essential for debugging to see what's actually running. Equivalent to 'set -x'.
Bash determines if it's a login shell by: 1) if invoked as -bash (argv[0] starts with -), 2) if the -l option was specified, 3) if invoked with the name 'login' on some systems. Login shells read /etc/profile and the first readable of ~/.bash_profile, ~/.bash_login, or ~/.profile.
BASH_ENV specifies a file that Bash reads and executes commands from when starting a non-interactive shell (e.g., running a script). Similar to ENV for POSIX shells. If set, Bash reads this file before executing the script. Not used for interactive shells.
Using + instead of - disables the option. For example, +x disables xtrace (debug printing), while -x enables it. This is shorthand for set +x or set -x. Options can be toggled: bash -xev starts with both xtrace and errexit enabled.
The -v option causes Bash to print shell input lines as they are read. This verbose mode shows each line of a script or input before execution, useful for debugging shell scripts. It's equivalent to 'set -v'.
The -T option (available in Bash 4.4+) makes command substitutions inherit the errexit option. When -e is active, a command inside $() that fails will cause the parent command to fail. Without -T, command substitutions trap failures individually.
The -e option (or set -o errexit) causes Bash to exit immediately if a command exits with a non-zero status. This fails-fast behavior doesn't apply to commands in certain constructs like while/until loops, if tests, or pipelines where the last command's status is what matters.
For interactive login shells: /etc/profile, then ~/.bash_profile, ~/.bash_login, or ~/.profile (first readable one), then ~/.bashrc (if sourced from profile). For interactive non-login shells: /etc/bash.bashrc (if exists), then ~/.bashrc. The --noprofile and --norc options skip these files.
The -- option signals the end of options. All arguments after -- are treated as filenames and arguments, even if they start with a dash. This prevents filenames beginning with - from being interpreted as options. Example: bash -- script.sh -argument
The --rpm-requires option produces a list of requirements for the script. It outputs shell features and commands used, formatted for RPM packaging systems. This helps RPM packages determine what shell capabilities are needed by a script. Only available when Bash is compiled with RPM support.
Single-dash options are single characters that can be combined: bash -x -e is equivalent to bash -xe. Double-dash (--) marks the end of options; everything after -- is treated as a filename or argument, even if it starts with a dash. Long options use double-dash prefix like --help.
The -b option (or set -o notify) causes Bash to report the termination of background jobs immediately, rather than waiting before displaying the next primary prompt. By default, job termination is only reported just before the prompt is displayed.
The -P option (or set -o physical) prevents Bash from following symbolic links when resolving commands. pwd -P and cd use the physical directory structure rather than following symlinks. The $PWD variable reflects the actual path without symlink resolution.
The -l option makes Bash act as a login shell. A login shell reads certain startup files like /etc/profile, ~/.bash_profile, ~/.bash_login, or ~/.profile (whichever is found first and is readable) in that order. The option name stands for 'login'.
The -D option causes Bash to print all double-quoted strings prefixed with $ to standard output. These are strings that may be subject to translation. When used with -n, no commands are executed. This is used for internationalization and creating translation catalogs.
The -i option specifies that the shell should be interactive. An interactive shell runs with job control enabled, reads commands from user input, and displays prompts. Without this option, scripts run non-interactively even if connected to a terminal.
An exit status of 0 indicates successful execution. This is the standard Unix convention where 0 means success and any non-zero value (1-255) indicates failure or an error condition.
The -s option causes Bash to read commands from standard input. This allows reading from a pipe or redirection. If arguments are present after -s, they are assigned to positional parameters ($0, $1, etc.), but the script is still read from stdin. Example: echo 'echo $1' | bash -s hello
The -f option (or set -o noglob) disables pathname expansion (globbing). Wildcards like *, ?, and [...] are treated literally rather than expanded to matching filenames. Useful when working with special characters that shouldn't be expanded.
Arguments after the command string are assigned to positional parameters starting at $0, not $1. Example: bash -c 'echo $0 $1 $2' script_name arg1 arg2 outputs: script_name arg1 arg2. The first argument becomes $0 (script name), second becomes $1, etc.
The -m option (or set -o monitor) enables job control. This allows background and foreground job management, bg/fg commands, and job control signals. It's automatically enabled for interactive shells on systems that support job control.
The --noprofile option prevents Bash from reading system-wide and personal initialization files for login shells. Specifically, it inhibits reading /etc/profile, ~/.bash_profile, ~/.bash_login, and ~/.profile. This provides a clean environment without profile customizations.
The --help option causes Bash to display a brief usage summary and exit successfully. This shows standard options like -c, -i, -l, -r, -s and basic usage information. The output is concise and meant for quick reference.
The --posix option changes Bash's behavior to match the POSIX standard more strictly. It enables POSIX mode, which affects various aspects like default values for environment variables, handling of special characters, and startup file behavior. It makes Bash more compatible with standard Unix shells.
The --noediting option prevents Bash from using the GNU Readline library for command-line editing. This disables interactive editing features like command history, arrow key navigation, and tab completion. Useful when Bash is run by specialized programs.
The -p option (or set -o privileged) turns on privileged mode. When Bash starts as setuid (not recommended), this mode is automatically enabled. It disables reading of user startup files and ignores the ENV file for security. The effective user ID (euid) is not reset to the real user ID.
The -r option makes the shell restricted. A restricted shell cannot: change working directory, change values of SHELL, PATH, ENV, or BASH_ENV, specify command names containing /, redirect output using >, >>, <>, >|, &, >&, >&, and >>&, turn off restricted mode with set +r or set -o restricted. This is for creating controlled environments.
The -C option (or set -o noclobber) prevents redirection from overwriting existing files. Using > file will fail if file exists. Use >| file to force overwrite. This protects against accidental data loss. The +C option re-enables overwriting.
The --version option causes Bash to print version information about this instance of Bash and exit successfully. The output includes the bash version number, release status, and machine type. Example: 'GNU bash, version 5.1.16(1)-release (x86_64-pc-linux-gnu)'.
Bash exit status values range from 0 to 255. Exit status values above 255 are wrapped modulo 256. If a script or command returns 256, it becomes 0; 257 becomes 1, etc. The special exit status 128+N indicates termination by signal N.
The --debugger option (equivalent to set -o debug or set -o debugger) enables debugging mode before the script executes. This allows the shell to enter a debugging state where the DEBUG trap is executed before each simple command, enabling debugging behavior.
The -n option causes Bash to read commands but not execute them. This syntax check mode parses the script without running it, useful for checking for syntax errors before execution. It's often combined with -v for comprehensive syntax checking.
Bash determines interactivity by checking: 1) if standard input is a terminal (isatty(0) returns true), 2) if the -i option was specified, 3) if the -s option was used and stdin is a terminal. Interactive shells display prompts (PS1), enable job control, and read ~/.bashrc.
The -h option (or set -o hashall) enables automatic hashing of command locations. Bash remembers the full path of each command as it's found, avoiding repeated PATH searches. This is enabled by default. The hash built-in displays or modifies this table.
The -a option (or set -o allexport) causes all variables to be automatically exported to child processes. When set, any variable created or modified is automatically marked for export, equivalent to using 'export' on each assignment.
The -O option enables a shell option upon invocation. It takes an argument which is the option name to enable. Example: bash -O globstar enables the globstar option, which allows ** recursive wildcard expansion. The +O option disables the specified option.
The -t option (or set -o onecmd) causes Bash to exit after reading and executing one command. This is useful for single-command execution where you want the shell to terminate immediately. When used with -c, it's essentially the default behavior.
The --norc option prevents Bash from reading ~/.bashrc for an interactive shell. This provides an interactive shell without personal configuration customizations. System-wide resources from /etc/bash.bashrc may still be read depending on compilation.
The -u option (or set -o nounset) causes Bash to treat unset variables as an error when expanding. Attempting to expand $unset_var results in an error message and exits with status 1 (unless -e is disabled). This helps catch typos and uninitialized variables.
The +O option disables a shell option upon invocation. It takes an argument which is the option name to disable. Example: bash +O histexpand disables history expansion. Unlike -O which enables options, +O turns them off.
When using -c, the first argument after the command string becomes $0, and subsequent arguments become $1, $2, etc. For example: bash -c 'echo $0 $1' myname arg1 outputs 'myname arg1' where $0=myname and $1=arg1. If no additional arguments are provided, $0 is set to the shell's name (often 'bash').
The --dump-po-strings option is similar to -D but outputs in a GNU gettext PO (Portable Object) file format. It extracts all translatable strings prefixed with $ from scripts for translation management. Used for internationalization workflows.
ENV (used in POSIX mode) specifies a file that Bash reads and executes when starting an interactive shell or when invoked as sh. Similar to BASH_ENV but for POSIX compatibility. When Bash is in POSIX mode, ENV is checked for the startup file path.
The --init-file file (or abbreviated as --rcfile file) specifies a file to read instead of ~/.bashrc for an interactive shell. This option only works for interactive shells, not scripts. It allows customizing the startup configuration for a specific shell invocation.
The -c option causes Bash to read and execute commands from the first non-option argument argument after processing options, then exit. Any remaining arguments are assigned to positional parameters starting at $0. Example: bash -c 'echo hello' world sets $0 to 'world'.
The --dump-strings option is equivalent to -D. It prints all double-quoted strings prefixed with $ to standard output. These are strings marked for translation in the script.
Readline Interaction > Basic Interaction
48 questionsIf keyseq-timeout is set to a value less than or equal to zero, or to a non-numeric value, readline will wait until another key is pressed to decide which key sequence to complete.
The default value is 'On'. When set to On, readline will try to enable any meta modifier key the terminal claims to support.
The default value is 'Off'. 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 '(ins)'. This string is displayed before the prompt when show-mode-in-prompt is enabled and vi insertion mode is active.
The default value is 'unset', which means the number of history entries is not limited. If set to zero, existing entries are deleted and no new entries are saved. If set to a negative value, the number of history entries is not limited.
The default value is 'On'. When set to On, readline attempts to bind the control characters treated specially by the kernel's terminal driver to their readline equivalents.
The default value is '#' (the hash character), which is inserted in vi mode when the insert-comment command is executed.
The default value is '@'. This string is displayed before the prompt when show-mode-in-prompt is enabled and emacs editing mode is active.
The default value is 'On'. When set to On, readline configures the terminal to insert each paste into the editing buffer as a single string of characters.
The default value is 'Off'. If set to On, tilde expansion is performed when readline attempts word completion.
The default value is 0. This is the length in characters of the common prefix of possible completions displayed without modification.
M-x means Meta-X. On keyboards without a meta key, M-x means ESC x (press Escape key then the x key). This makes ESC the meta prefix.
The default value is 'On'. If set to On, readline uses an internal more-like pager to display a screenful of possible completions at a time.
C-G (Control-G) aborts an incremental search and restores the original line.
By default, ESC and C-J terminate an incremental search. These can be changed via the isearch-terminators variable.
If an attempt is made to set history-size to a non-numeric value, the maximum number of history entries will be set to 500.
If ~/.inputrc does not exist or cannot be read, the ultimate default is /etc/inputrc.
DEL, ESC, ESCAPE, LFD, NEWLINE, RET, RETURN, RUBOUT, SPACE, SPC, and TAB are recognized symbolic character names.
The default value is 'emacs'. Legal keymap names are: emacs, emacs-standard, emacs-meta, emacs-ctlx, vi, vi-move, vi-command, and vi-insert.
The default value is 'Off'. When set to On, readline will enable eight-bit input (it will not clear the eighth bit in characters it reads).
The INPUTRC environment variable specifies the name of the readline initialization file. If unset, the default is ~/.inputrc.
The default value is '(cmd)'. This string is displayed before the prompt when show-mode-in-prompt is enabled and vi command mode is active.
The default value is 'On'. If set to On, completed directory names have a slash appended.
M-C-x means ESC-Control-x, or press the Escape key then hold the Control key while pressing the x key.
Executing universal-argument (C-u) followed by one or more digits, optionally with a leading minus sign, defines the argument. If immediately followed by a non-digit, the argument count for the next command is multiplied by four.
The caller must free the returned line using malloc(3)/free(3) when finished.
Readline variables can take values On or Off (case-insensitive), or '1' for On. Empty or null values are also equivalent to On. All other values are equivalent to Off.
The default value is 'On'. When set to On, readline will convert characters with the eighth bit set to an ASCII key sequence by stripping the eighth bit and prefixing it with an escape character.
readline() returns NULL when EOF is encountered while reading a line and the line is empty.
There is no difference - vi is equivalent to vi-command. Similarly, emacs is equivalent to emacs-standard.
The default value is 500 milliseconds. This specifies how long readline will wait for a character when reading an ambiguous key sequence.
The default value is 'Off'. If set to On, a character denoting a file's type as reported by stat(2) is appended to the filename when listing possible completions.
The default value is 'Off'. When set to On, readline uses a single line for display, scrolling horizontally when the line becomes longer than screen width.
The default value is 'On'. When set to On, readline allows certain commands to designate the region (text between point and mark) as active.
The default is ~/.inputrc. The name is taken from the INPUTRC environment variable. If that file does not exist or cannot be read, the ultimate default is /etc/inputrc.
The default value of bell-style is 'audible'. Other valid values are 'none' and 'visible'.
Passing a negative argument to a command that acts in a forward direction (e.g., kill-line) causes that command to act in a backward direction.
readline() treats EOF as a newline and returns the text of the line read (non-NULL).
The default value is -1. This is the number of screen columns used to display possible matches when performing completion. A value of 0 displays matches one per line.
The default value of editing-mode is 'emacs'. It can be set to either 'emacs' or 'vi'.
The default value is 'C-[ C-J' (ESC and C-J), which are the characters that terminate an incremental search.
The default value is 'Off'. If set to On, readline attempts to briefly move the cursor to an opening parenthesis when a closing parenthesis is inserted.
By default, readline uses Emacs-style line editing commands. A vi-style line editing interface is also available.
The default value is 100. If the number of possible completions is greater than or equal to this value, readline will ask whether or not the user wishes to view them.
Job Control > Job Control Commands
47 questionsIf you run bg on a job that is not stopped (i.e., already running in background), bg has no effect on that job. The bg command is typically used to resume a job that was suspended with Ctrl-Z.
The current job is the most recent job stopped or placed in the background. It is referred to as %% or %+ in job specifications and is the default job used by fg and bg when no jobspec is provided.
The -h option to disown marks each JOBSPEC so that SIGHUP is not sent to the job if the shell receives a SIGHUP, but does not remove the job from the job table.
The wait command can wait for both individual process IDs and job specifications. When given a job specification, wait waits for all processes in that job's process group to terminate.
The disown builtin returns success unless an invalid option or JOBSPEC is given.
No, the fg command accepts only a single job_spec argument. It places that job in the foreground and makes it the current job. Only one job can be in the foreground at a time.
The suspend command suspends the execution of the shell until it receives a SIGCONT signal. This is a job control builtin that allows suspending the shell itself.
When given job or process IDs as arguments, wait waits for each specified job or process to terminate and returns its exit status. The last job or process ID waited for determines the exit status returned.
If you attempt to use bg on a job that has been terminated (not just stopped), bg will fail and report an error. bg can only resume jobs that are in a stopped (suspended) state.
When disown is used without the -h option, the jobs are removed from the shell's job table. The shell will no longer track them, and they will not receive SIGHUP when the shell exits.
The jobs builtin accepts the following options: -l (lists process IDs in addition to normal information), -n (lists only processes that have changed status since the last notification), -p (lists process IDs only), -r (restrict output to running jobs), -s (restrict output to stopped jobs), and -x (runs COMMAND after replacing job specifications with process IDs).
You can refer to a job by a substring in its command using %?string syntax, where string appears anywhere in the command. For example, %?file would match any job command containing 'file'.
When JOB_SPEC is not present to the fg command, the shell uses its notion of the current job. fg places the job in the foreground, making it the current job.
When you run disown on a stopped job, the job is removed from the job table but remains in a stopped state. Unlike disown -r (which only affects running jobs), regular disown affects both running and stopped jobs.
Bash provides the following job control builtins: jobs (list active jobs), bg (resume jobs in background), fg (bring jobs to foreground), disown (remove jobs from job table), wait (wait for jobs to complete), and suspend (suspend the shell).
wait %n (using a job specification) waits for all processes in job n's process group, while wait with a direct PID waits for that specific process. Both return the exit status of the waited-for process.
The disown -a option removes all jobs from the job table if no JOBSPEC is supplied, while disown -r removes only running jobs (not stopped jobs) from the job table.
The -s option in the jobs command restricts the output to only stopped jobs, excluding running jobs from the display.
The bg builtin returns success unless job control is not enabled or an error occurs.
Yes, the bg command accepts multiple job_spec arguments. Each identified job is placed in the background. If no JOB_SPEC is present, the shell's notion of the current job is used.
If you attempt to use fg on a job that is already running in the foreground, the shell will report an error indicating that there is no such job or that the job is already in foreground.
The -x option causes jobs to run the specified COMMAND after all job specifications that appear in ARGS have been replaced with the process ID of that job's process group leader.
The -r option in the jobs command restricts the output to only running jobs, excluding stopped jobs from the display.
When jobs is used with the -x option, it returns the exit status of the executed COMMAND, not the success/failure of job listing itself.
No, disown does not terminate background jobs. It only removes them from the shell's job table, so the shell no longer tracks them or sends SIGHUP to them when the shell exits. The jobs continue running.
Job control must be enabled for job control commands to work. Job control is enabled by default in interactive shells, and can be enabled with 'set -m' or 'set -o monitor'.
When JOB_SPEC is not present to the bg command, the shell uses its notion of the current job. The bg command places the identified jobs in the background, as if they had been started with &.
The suspend -f option forces suspension even if the shell is a login shell. Without -f, suspend refuses to suspend a login shell because doing so could terminate the session.
Yes, if all jobs specified to wait (or all background jobs if no arguments are given) have already completed, wait returns immediately with the exit status of the last completed job.
When the shell exits, it sends SIGHUP to all jobs in its job table by default. Jobs that have been disowned (without -h) or started with nohup are not affected. The shell does not send SIGHUP to jobs that were removed from the job table.
The fg builtin returns the status of the command placed in the foreground, or failure if an error occurs.
When waiting for multiple jobs or processes, wait returns the exit status of the last job or process in the argument list. If any job terminates abnormally, wait reports a non-zero exit status (typically 127).
The jobs -x option runs a command after replacing job specifications with the process group leader's PID. This is different from normal job expansion which happens within the shell's job control syntax. It's used to pass job PIDs as arguments to external commands.
Yes, when disown is used without any JOBSPEC arguments, it uses the shell's notion of the current job and disowns it. You don't need to specify %% explicitly.
The -p option in the jobs command lists only process IDs (PIDs) without any other information like job status or command names.
Yes, the disown command accepts both job specifications and process IDs (PIDs) as arguments. When given a PID, it removes the corresponding process from the job table.
Job specifications refer to jobs and can be: %% or %+ (current job), %- (previous job), %n (job number n), %string (job whose command starts with string), or %?string (job whose command contains string).
The disown builtin accepts three options: -a (remove all jobs if JOBSPEC is not supplied), -h (mark each JOBSPEC so that SIGHUP is not sent to the job if the shell receives a SIGHUP), and -r (remove only running jobs).
Without any JOBSPEC arguments, disown uses the shell's notion of the current job and removes it from the table of active jobs.
The suspend command is typically used in interactive shells. In non-interactive shells, job control is usually disabled and suspend may not work as expected. The shell must have job control enabled for suspend to function.
The suspend command accepts the -f option, which forces the suspension even if the shell is a login shell. Without -f, suspend cannot suspend a login shell.
The jobs command returns failure (non-zero exit status) if an invalid option is given or if an error occurs.
If wait is given a job or process ID that is unknown to the shell, it returns an exit status of 127.
The -l option in the jobs command lists process IDs (PIDs) in addition to the normal information (job number, status, and command).
Pressing Ctrl+Z sends SIGTSTP (terminal stop) to the current foreground job, causing it to suspend (stop). The suspended job can then be resumed in the background with bg or in the foreground with fg.
When wait is used without arguments, it waits for all background jobs to complete.
The -n option in the jobs command lists only processes that have changed status since the last notification. This is useful for seeing only new status changes rather than all active jobs.
Shell Variables > Job Control and Process Management
47 questionsUnlike login shells, non-login interactive shells do not send SIGHUP to jobs when they exit by default. The huponexit option only affects login shells.
exec replaces the current shell with a new command without creating a new process. The new command takes over the same process ID. When used without arguments in a script, it can be used to redirect file descriptors for the remainder of the script.
set -m enables job control. This allows background and foreground jobs, places jobs in separate process groups, and enables job control builtins like fg, bg, and jobs. This is the default for interactive shells.
disown removes jobs from the job table, optionally with options: -h to mark jobs so SIGHUP is not sent on shell exit, -r to remove only running jobs, -a to remove all jobs. This protects jobs from SIGHUP when the shell exits.
The huponexit option is off by default. This means Bash does not send SIGHUP to jobs when an interactive login shell exits.
Bash assigns job numbers sequentially starting from 1. There is no fixed maximum in Bash documentation; practical limits are determined by system resources and the operating system's process table size.
SIGTTOU (signal number 22 on most systems) is sent to a background process group when it attempts to write to the terminal. By default, this causes the process to stop (suspend) until brought to the foreground, unless TOSTOP is set on the terminal.
When no signal is specified, kill sends SIGTERM (signal number 15) to the specified process or job.
There is no hard-coded maximum number of jobs in Bash itself. The limit is determined by the operating system's limits on process IDs, file descriptors, and system resources. Practical limits depend on the RLIMIT_NPROC resource limit.
SIGQUIT (signal number 3) is the quit signal, typically generated by Ctrl+. It causes the current foreground process to terminate and produce a core dump. Bash handles SIGQUIT specially for certain builtins and commands.
At shell startup, $_ expands to the absolute pathname of the shell or script being executed. After that, it expands to the last argument to the previous command, and also set to the full pathname of each command executed and placed in the environment exported to that command.
The -p option to jobs lists only the process group leader's process ID for each job, rather than the full status information.
Disowning a running job removes it from the job table but does not redirect its output. The job continues writing to whatever stdout/stderr it was connected to when started.
The auto_resume variable is unset by default. When unset, job control features that allow resuming jobs by typing their name are disabled.
$? expands to the exit status of the most recently executed foreground pipeline. By convention, an exit status of 0 indicates success, and non-zero indicates failure.
SIGTERM (15) can be caught or ignored by the process, allowing it to perform cleanup operations. SIGKILL (9) cannot be caught, blocked, or ignored, and immediately terminates the process without cleanup.
The -r option to jobs restricts the output to only running jobs, excluding stopped or completed jobs from the listing.
$$ expands to the process ID (PID) of the current Bash shell. This value is set at shell initialization and does not change during the shell's lifetime, even in subshells.
checkjobs is not a standard Bash shell option. There is no 'checkjobs' option in the official Bash shopt documentation. Jobs are checked when using the wait command or jobs command.
SIGINT (signal number 2) is the interrupt signal, typically generated by Ctrl+C. It causes the current foreground process to terminate. Bash handles SIGINT specially for certain builtins and commands.
When a background job attempts to read from stdin, the terminal driver sends a SIGTTIN signal to the process group, causing it to stop. The job will be suspended and must be brought to the foreground with fg to continue.
When no background command has been executed, $! expands to an empty string. It is only set after a background command is started.
HISTCONTROL is unset by default, meaning all commands are saved to the history list. It can be set to 'ignorespace' (lines beginning with space are not saved), 'ignoredups' (duplicate lines are not saved), 'ignoreboth' (both options), or 'erasedups' (all previous lines matching the current line are removed).
%+ refers to the current job (the most recent job started or foregrounded), while %- refers to the previous job (the job before the current job). These are used with job control builtins like fg, bg, and kill.
PROMPT_COMMAND, if set, is executed as a command before each primary prompt is displayed. It is typically used to set dynamic information in the prompt or to perform actions before each command.
When wait is called without arguments, it waits for all background jobs to complete. When wait is called with job specification(s) or process ID(s), it waits for each specified job/PID to complete and returns their exit status.
SIGCONT (signal number 18 on most systems) is used to resume a stopped process. It can be sent to background processes using the 'bg' command or with 'kill -CONT', causing the process to continue execution.
SIGSTOP (signal number 19 on most systems) stops (suspends) a process's execution. It cannot be caught or ignored by the process. The process can be resumed with SIGCONT or the bg/fg commands.
Bash sends a SIGHUP (hangup signal) to all jobs when an interactive login shell exits. This behavior can be suppressed using the shopt builtin with 'huponexit' disabled or with disown.
disown removes jobs from the job table but does not affect running processes. The exit status of disowned jobs is no longer available through the jobs command or wait command after disown completes.
The -s option to jobs restricts the output to only stopped jobs, excluding running or completed jobs from the listing.
SIGTTIN (signal number 21 on most systems) is sent to a background process group when it attempts to read from the terminal. By default, this causes the process to stop (suspend) until brought to the foreground.
There is no standard FG environment variable in Bash. The 'fg' command is a shell builtin, not controlled by an environment variable.
If set, auto_resume enables job control features. If set to 'exact', the string supplied must match a job name exactly. If set to 'substring', the string supplied needs to match a substring of the job name. The 'substring' option is the default.
If wait is used without arguments, it returns 0 if all jobs exited successfully, or non-zero if any job exited with a non-zero status. If given job/PID arguments, it returns the exit status of the last job waited for.
The 'huponexit' shell option, controlled by the shopt builtin. When enabled (shopt -s huponexit), Bash sends SIGHUP to all jobs when an interactive login shell exits.
Running with & backgrounds the job but it still receives SIGHUP when the shell exits (unless disowned). Using nohup makes the command ignore SIGHUP, and nohup redirects stdout to 'nohup.out' by default, while & does not redirect output.
The -n option to jobs only displays jobs whose status has changed since the last notification. This is useful to avoid redundant output when polling job status.
If TMOUT is set to a value greater than zero, TMOUT is treated as the default timeout for the read builtin. The select command command terminates if input is not entered within TMOUT seconds. In an interactive shell, Bash terminates after waiting for that many seconds if input does not arrive.
CHILD_MAX sets the maximum number of child processes that can be created before the shell considers it too expensive to create additional ones. If set to a value greater than zero, the shell will not create more than this number of child processes.
The job table contains: job number, process group ID, process IDs, current working directory, state (Running/Stopped/Done/etc.), the command that started the job, and whether the job is the current (+) or previous (-) job.
SIGTSTP (signal number 20 on most systems) is the typical stop signal generated from the terminal (usually Ctrl+Z). Unlike SIGSTOP, SIGTSTP can be caught or ignored by the process.
The -l option to jobs lists process IDs in addition to the normal job status information. The format shows: job number, '+', '-', or ' ' for current/previous/other job, status (Running/Stopped/Done/etc.), and the command.
Monitor mode (-m) is enabled by default in interactive shells, but disabled in non-interactive scripts. This can be checked with 'echo $-' - if 'm' appears in the output, monitor mode is active.
Job control allows Bash to switch between multiple process groups (jobs). It enables backgrounding (&), foregrounding (fg), listing jobs (jobs), and controlling process groups. Job control is only available in interactive shells when the operating system supports it.
set +m disables job control. Background jobs (&) still run but are not managed by the job control system. All jobs run in the same process group as the shell.
$- expands to the current option flags as specified upon invocation, set by the set builtin command, or set by the shell itself (such as the -i flag for interactive shells).
Command Line Editing > Cursor Movement
46 questions'word' (w/b) treats alphanumeric and underscore as word characters; 'WORD' (W/B) uses only whitespace as delimiter
w (forward by word) or W (forward by WORD, where WORD is whitespace-delimited)
It depends on terminal emulator. Many terminals map this to backward-word (Alt+B), but it's not a readline default binding.
vi-ins-mode-string (default: '(ins)'), vi-cmd-mode-string (default: '(cmd)'), vi-cmov-mode-string
Ctrl+X Ctrl+X (C-x C-x) - swaps the cursor position with the mark, effectively toggling between two positions
bell-style (values: 'none', 'visible', 'audible', default: 'audible') - controls bell when trying to move past line start/end
backward-word moves the cursor; backward-kill-word moves AND deletes the word (bound to Alt+Ctrl+H or Alt+Backspace by default)
horizontal-scroll-mode (Off by default) - when Off, long lines wrap to multiple lines; when On, line scrolls horizontally.
output-meta (On by default in most locales) - if On, displays 8-bit characters directly; if Off, displays as meta-prefixed
tx (where x is the character) - moves forward to just before next x; Tx moves backward to just after previous x
Esc to go from insert to command mode; i, a, I, A, etc. to go from command to insert mode
nG (where n is the line number) - moves to line n in multi-line commands; G alone goes to the last line
Format: '\e[char]: function-name or 'keyseq': function-name. Example: '\e[A': previous-history (Up arrow)
With horizontal-scroll-mode Off (default), cursor moves down to the continuation line on the next screen line.
Emacs editing mode is the default. You can switch to vi mode with 'set -o vi' and back to emacs with 'set -o emacs'.
w moves to the start of the next word; e moves to the end of the current word (or next word if already at end)
show-mode-in-prompt (Off by default) - when On, displays mode indicator in prompt
bind displays or modifies readline key bindings; 'bind -p' lists all current bindings and functions
Moves forward one character; bound to Ctrl+F and Right Arrow by default
Moves backward to the start of the current or previous word; bound to Alt+B by default
C- represents Control key; e.g., C-a means Ctrl+A (hold Control and press 'a')
Most modern terminals map Home to beginning-of-line (Ctrl+A) and End to end-of-line (Ctrl+E), but this is terminal-dependent, not a readline default.
fx (where x is the character to find) - moves forward to next x; Fx moves backward to previous x
completer-word-break-chars or the shell variable COMP_WORDBREAKS (default: ' \t\n"'<>|&;(:')
M- represents Meta, which can be pressed via Alt key or by pressing and releasing Esc before the next character
backward-word moves by readline's word definition; shell-backward-word respects shell quoting and skips over quoted strings
redraw-current-line; no default binding, but useful in custom bindings for complex display updates
Run 'bind -p' or 'bind -P' (uppercase P shows readable function names) to list all readline bindings
; (semicolon) repeats in same direction, , (comma) repeats in opposite direction
Bash relies on terminal capability mappings (termcap/terminfo); proper TERM setting is required for Home/End to work correctly
input-meta (On/Off) and convert-meta (On/Off) - On by default, allowing Alt to work as Meta
^ (caret) moves to first non-whitespace character; 0 (zero) moves to absolute column 0
Shell Syntax > Compound Commands
46 questionsYes. The && and || operators do not evaluate expression2 if the value of expression1 is sufficient to determine the return value of the entire conditional expression.
Yes. Any redirections associated with a compound command apply to all commands within that compound command unless explicitly overridden.
No. Bash sets BASH_REMATCH in the global scope; declaring it as a local variable will lead to unexpected results.
Using ';&' in place of ';;' causes execution to continue with the command-list associated with the next clause, if any, regardless of pattern matching.
BASH_REMATCH is an array variable that records which parts of the string matched the =~ regex pattern. Index 0 contains the portion matching the entire regex. Substrings matched by parenthesized subexpressions are saved in remaining indices, where index n contains the nth parenthesized subexpression match.
If you quote any part of the pattern using any shell quoting mechanism, the quoted portion is matched literally - every character in the quoted portion matches itself instead of having special pattern matching meaning.
Yes. In most cases, wherever a ';' appears in the description of a compound command's syntax, it may be replaced with one or more newlines.
A shell variable that is null or unset evaluates to 0 when referenced by name without using the parameter expansion syntax.
The until loop executes consequent-commands as long as test-commands has an exit status which is NOT zero (i.e., the test fails).
The while loop executes consequent-commands as long as test-commands has an exit status of zero (success).
Yes. The braces are reserved words, so they must be separated from the list by blanks or other shell metacharacters. However, parentheses are operators and are recognized as separate tokens even without whitespace separation.
(list) creates a subshell where commands execute in a child process and variable assignments don't persist after completion. { list; } executes in the current shell environment with no subshell created, so variable assignments remain in effect.
First, evaluate expr1. Then, repeatedly evaluate expr2 until it evaluates to zero. Each time expr2 evaluates to a non-zero value, execute commands and evaluate expr3.
The shell allows arithmetic expressions to be evaluated using the (( compound command, the let builtin, the -i option to the declare builtin, or as one of the shell expansions.
The return status of the while command is the exit status of the last command executed in consequent-commands, or zero if no commands were executed.
The shell performs tilde expansion, parameter and variable expansion, arithmetic expansion, command substitution, process substitution, and quote removal on those words.
It's a common idiom to use '*' as the final pattern to define the default case, since that pattern will always match.
The =~ operator treats the string to the right as a POSIX extended regular expression pattern and matches accordingly using the POSIX regcomp and regexec interfaces.
Evaluation is done in fixed-width integers with no check for overflow, though division by 0 is trapped and flagged as an error.
The word undergoes tilde expansion, parameter expansion, command substitution, process substitution, arithmetic expansion, and quote removal before the shell attempts to match the pattern.
Yes. The semicolon (or newline) following the list is required for { } grouping. The closing brace must be preceded by a semicolon or newline.
The return status of the until command is the exit status of the last command executed in consequent-commands, or zero if no commands were executed.
When used with [[, the == and != operators treat the string to the right as a pattern and match according to Pattern Matching rules, as if the extglob shell option were enabled. The = operator is identical to ==.
The exit status of both (list) and { list; } constructs is the exit status of the list.
If there are no items in the expansion of words, no commands are executed, and the return status is zero.
Using ';;&' in place of ';;' causes the shell to test the patterns in the next clause, if any, and execute any associated command-list if the match succeeds, continuing as if the pattern list had not matched.
For bases greater than 10, digits greater than 9 are represented by lowercase letters, uppercase letters, '@', and '_', in that order.
Constants with a leading 0 are interpreted as octal numbers. A leading '0x' or '0X' denotes hexadecimal.
In decreasing order: (expression), ! expression, expression1 && expression2, expression1 || expression2
The return value is 0 if the string matches the pattern, 1 if it does not, and 2 if the regular expression is syntactically incorrect.
If 'in words' is not present, the for command executes commands once for each positional parameter that is set, as if 'in "$@"' had been specified.
Conditional operators such as '-f' must be unquoted to be recognized as primaries.
Compound commands are the shell programming language constructs. Each construct begins with a reserved word or control operator and is terminated by a corresponding reserved word or operator. They include looping constructs, conditional commands, and mechanisms to group commands.
Case will selectively execute the command-list corresponding to the first pattern that matches word, proceeding from the first pattern to the last.
If the ';;' operator is used, the case command completes after the first pattern match and terminates.
Numbers take the form [base#]n, where the optional base is a decimal number between 2 and 64 representing the arithmetic base.
The return value is the exit status of the last command in commands that is executed, or non-zero if any of the expressions is invalid.
If any expression is omitted in the C-style for loop, it behaves as if it evaluates to 1.
The match succeeds if the pattern matches any part of the string. To match the entire string, anchor the pattern using ^ and $.
Conditional Constructs > Expression Evaluation Constructs
46 questionsBash checks file descriptor 2 when /dev/stderr is used as the file argument to a file test primary.
The file1 -nt file2 operator returns true if file1 is newer (according to modification date) than file2, or if file1 exists and file2 does not.
BASH_REMATCH indices 1 and higher contain substrings matched by parenthesized subexpressions within the regular expression, where BASH_REMATCH[n] contains the portion matching the nth parenthesized subexpression.
The shell performs tilde expansion, parameter and variable expansion, arithmetic expansion, command substitution, process substitution, and quote removal. Word splitting and filename expansion are NOT performed.
Constants with a leading 0 are interpreted as octal numbers. For example, 010 is octal 8, not decimal 10.
The (( compound command returns exit status 0 when the arithmetic expression evaluates to non-zero (any value other than zero).
Bash checks file descriptor 0 when /dev/stdin is used as the file argument to a file test primary.
Each pattern undergoes tilde expansion, parameter expansion, command substitution, arithmetic expansion, process substitution, and quote removal before matching.
Yes, a shell variable need not have its integer attribute turned on to be used in an expression.
Sub-expressions in parentheses are evaluated first and may override the precedence rules. Parentheses can be used to group expressions and force a specific evaluation order.
When used with [[, the < and > operators sort lexicographically using the current locale (using strcoll()). This is different from the test command which uses ASCII ordering.
Each clause must be terminated with ;; (execute command-list and exit case), ;& (continue with next clause's command-list without pattern testing), or ;;& (continue testing patterns in next clause).
The =~ operator returns 0 if the string matches the POSIX extended regular expression pattern.
The match succeeds if the pattern matches any part of the string. To force the pattern to match the entire string, you must anchor the pattern using the ^ and $ regular expression operators.
Division by 0 is trapped and flagged as an error. Arithmetic evaluation is done in fixed-width integers with no check for overflow, but division by zero is specifically caught.
When used with the [[ command, arg1 and arg2 are evaluated as arithmetic expressions. Empty strings resulting from expansions are treated as expressions that evaluate to 0.
The -v varname operator returns true if the shell variable varname is set (has been assigned a value). For indexed arrays subscripted with @ or *, it returns true if the array has any set elements. For associative arrays subscripted with @ or *, it returns true if an element with that key is set.
The -R varname operator returns true if the shell variable varname is set and is a name reference (nameref variable).
The -N file operator returns true if the file exists and has been modified since it was last accessed.
The string to the right of the operator is considered a pattern and matched according to pattern matching rules as if the extglob shell option were enabled. Pattern matching glob characters (*, ?, [...]) are expanded.
If the nocasematch shell option is enabled, the match is performed without regard to the case of alphabetic characters when using == and != operators.
Unless otherwise specified, primaries that operate on files follow symbolic links and operate on the target of the link rather than the link itself. The -h and -L primaries test specifically for symbolic links without following them.
A shell variable that is null or unset evaluates to 0 when referenced by name without using the parameter expansion syntax.
Yes, the && and || operators do not evaluate expression2 if the value of expression1 is sufficient to determine the return value of the entire conditional expression. For &&, expression2 is skipped if expression1 is false; for ||, expression2 is skipped if expression1 is true.
The test command uses ASCII ordering for < and > string comparison operators, not locale-based lexicographic ordering.
Bash checks file descriptor 1 when /dev/stdout is used as the file argument to a file test primary.
The file1 -ot file2 operator returns true if file1 is older than file2, or if file2 exists and file1 does not.
The (( compound command returns exit status 1 when the arithmetic expression evaluates to zero. This follows the shell convention where 0 means success/true and non-zero means failure/false, which inverts the arithmetic truth convention where 0 is false and non-zero is true.
For bases greater than 10, digits greater than 9 are represented by lowercase letters, uppercase letters, @, and _, in that order. If base is less than or equal to 36, lowercase and uppercase letters may be used interchangeably to represent numbers between 10 and 35.
The file1 -ef file2 operator returns true if file1 and file2 refer to the same device and inode numbers (i.e., they are the same file, including hard links).
The = and == operators are identical in function. Both perform pattern matching when used with the [[ command. The = operator should be used with the test command for POSIX conformance.
The BASH_REMATCH array variable records which parts of the string matched the pattern. Index 0 contains the portion matching the entire regular expression, and indices 1 and higher contain substrings matched by parenthesized subexpressions.
A leading 0x or 0X denotes hexadecimal numbers. For example, 0xFF or 0XFF represents decimal 255.
If the regular expression is syntactically incorrect, the conditional expression returns 2.
No, Bash sets BASH_REMATCH in the global scope. Declaring it as a local variable will lead to unexpected results.
Numbers take the form [base#]n, where the optional 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, base 10 is used.
If the nocasematch shell option is enabled, the =~ regular expression match is performed without regard to the case of alphabetic characters.
The word undergoes tilde expansion, parameter expansion, command substitution, process substitution, arithmetic expansion, and quote removal before the shell attempts to match the pattern.
Exponentiation with ** has lower precedence than unary operators (++id, --id, -, +, !, ~) but higher precedence than multiplication, division, and remainder (*, /, %).
The operators in decreasing precedence order are: (expression) for grouping, ! expression (negation), expression1 && expression2 (AND), expression1 || expression2 (OR). The && and || operators do not evaluate expression2 if expression1 is sufficient to determine the result (short-circuit evaluation).
If the nocasematch shell option is enabled, case statement pattern matching is performed without regard to the case of alphabetic characters.
The =~ operator returns 1 if the string does not match the POSIX extended regular expression pattern.
If you quote any part of the pattern using any of the shell's quoting mechanisms, the quoted portion is matched literally. Every character in the quoted portion matches itself instead of having special pattern matching or regular expression meaning.
From highest to lowest precedence: id++ id-- (post-increment/decrement), ++id --id (pre-increment/decrement), - + (unary minus/plus), ! ~ (logical/bitwise negation), ** (exponentiation), * / % (multiplication/division/remainder), + - (addition/subtraction), << >> (bitwise shifts), <= >= < > (comparison), == != (equality/inequality), & (bitwise AND), ^ (bitwise XOR), | (bitwise OR), && (logical AND), || (logical OR), expr ? expr : expr (conditional), = *= /= %= += -= <<= >>= &= ^= |= (assignment), expr1, expr2 (comma).
Job Control > Job Identification and Specification
45 questionsbg returns failure (non-zero) if run when job control is disabled, or when run with job control enabled and any specified jobspec was not found or was started without job control.
If jobspec is not present to fg, the shell's notion of the current job is used.
Signals can be specified in three ways: -s sigspec (case-insensitive signal name like SIGKILL, with or without SIG prefix), -n signum (signal number), or -sigspec (single dash with signal name).
Use %n where n is the job number. For example, %1 refers to job number 1, %2 refers to job number 2.
When bash starts a job asynchronously, it prints a line like '[1] 25647' where the first number in brackets is the job number and the second number is the process ID of the last process in the pipeline.
Three forms refer to the current job: %%, %+, or a single %. The current job is defined as the last job stopped while it was in the foreground or started in the background.
The -x option causes jobs to replace any jobspec found in command or args with the corresponding process group ID, and executes command passing it args, returning its exit status.
Bash associates a job with each pipeline and keeps a table of currently executing jobs. All of the processes in a single pipeline are members of the same job (process group). The job's process group leader is the process whose PID is the PGID.
Normally, bash waits until it is about to print a prompt before reporting changes in a job's status so as not to interrupt any other output. If the -b option to the set builtin command is enabled, bash reports such changes immediately. Any trap on SIGCHLD is executed for each child that exits.
Use %?string where string is the substring to search for. For example, %?ce refers to any job containing the string 'ce' in its command line. If the substring matches more than one job, bash reports an error.
When job control is enabled, wait returns when the job changes state. The -f option causes wait to wait until the job or process terminates before returning.
The -p option lists only the process ID of the job's process group leader.
The -x option causes jobs to replace any jobspec found in command or args with the corresponding process group ID before executing command.
Yes, kill can accept either a pid or a jobspec as its target argument. For example, 'kill %1' sends a signal to job 1.
The -a option means to remove or mark all jobs (when combined with -h).
If none of the supplied arguments is a child of the shell, the exit status is 127.
Yes, each id argument to wait 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 an attempt to exit bash is made while jobs are stopped (or, if the checkjobs shell option has been enabled, running), the shell prints a warning message and, if the checkjobs option is enabled, lists the jobs and their statuses. If a second attempt to exit is made without an intervening command, the shell does not print another warning and any stopped jobs are terminated.
When job control is enabled, the -f option forces wait to wait for the specified id to terminate before returning its status, instead of returning when it changes status.
%- refers to the previous job. If there is only a single job, both %+ and %- can be used to refer to that job.
If jobspec is not present to bg, the shell's notion of the current job is used.
The -h option causes each jobspec to not be removed from the table, but marks it so that SIGHUP is not sent to the job if the shell receives a SIGHUP.
If jobspec is not present to disown, and neither the -a nor the -r option is supplied, the current job is used.
The % character introduces a job specification. For example, %1 refers to job number 1.
Use %string where string is the prefix of the command name. For example, %ce refers to a stopped job whose command name begins with 'ce'. If the prefix matches more than one job, bash reports an error.
If id is not given, wait waits for all running background jobs and the last-executed process substitution (if its process id is the same as $!).
fg returns failure if run when job control is disabled or, when run with job control enabled, if jobspec does not specify a valid job or jobspec specifies a job that was started without job control.
If jobspec is given to the jobs command, output is restricted to information about that job.
The -l option lists process IDs in addition to the normal job information.
The -n option displays information only about jobs that have changed status since the user was last notified of their status.
fg resumes jobspec in the foreground and makes it the current job. If jobspec is not present, the shell's notion of the current job is used.
If id specifies a non-existent process or job, the return status is 127.
The return status of jobs is 0 unless an invalid option is encountered or an invalid jobspec is supplied.
Yes, 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.
The return value of disown is 0 unless a jobspec does not specify a valid job.
The -n option causes wait to wait for a single job from the list of ids or, if no ids are supplied, any job, to complete and returns its exit status.
If wait is interrupted by a signal, the return status will be greater than 128.
If no arguments are supplied and the shell has no unwaited-for children, the exit status is 127.
bg resumes each suspended job specified by jobspec in the background, as if it had been started with &. If jobspec is not present, the shell's notion of the current job is used.
The -r option without a jobspec argument restricts the disown operation to running jobs.
Without options, disown removes each jobspec from the table of active jobs. If jobspec is not present, and neither the -a nor the -r option is supplied, the current job is used.
In jobs command output, the current job is flagged with a +, and the previous job is flagged with a -.
Interactive Shells > History Management
45 questionsThe r modifier removes a trailing suffix of the form .xxx, leaving the basename.
If HISTFILE is unset, the command history is not saved when a shell exits.
In HISTIGNORE patterns, the '&' character matches the previous history line. The '&' can be escaped using a backslash, and the backslash is removed before attempting a match.
The G modifier applies the following 's' or '&' modifier once to each word in the event line.
The !string event designator refers to the most recent command preceding the current position in the history list that starts with string.
No, the second and subsequent lines of a multi-line compound command are not tested against HISTCONTROL and are added to the history regardless of its value.
No, the second and subsequent lines of a multi-line compound command are not tested against HISTIGNORE and are added to the history regardless of its value.
Both q and x quote the substituted words, escaping further substitutions. However, x breaks into words at blanks and newlines, while q does not. They are mutually exclusive; the last one supplied is used.
When HISTFILESIZE is set to a numeric value less than zero, the history file is not truncated (truncation is inhibited).
The shell sets the default value of HISTFILESIZE to the value of HISTSIZE after reading any startup files.
The * word designator refers to all of the words but the zeroth (word 1 through the last word). It is a synonym for '1-$'. If there is only one word in the event, the empty string is returned.
Yes, history expansion is enabled by default for interactive shells. It can be disabled using the +H option to the set builtin command.
When the history file is read, lines beginning with the history comment character followed immediately by a digit are interpreted as timestamps for the following history line. When writing, timestamps are marked with the history comment character to distinguish them from other history lines.
If ename is not given to fc, the value of the FCEDIT variable is used. If FCEDIT is not set, the value of EDITOR is used. If neither variable is set, vi is used as the default editor.
The $ word designator refers to the last word. This is usually the last argument, but will expand to the zeroth word if there is only one word in the line.
The default value of HISTFILE is ~/.bash_history. This is the file in which command history is saved.
The ^string1^string2^ event designator performs quick substitution, repeating the previous command while replacing string1 with string2. It is equivalent to '!!:s^string1^string2^'.
The default value of HISTSIZE is 500. The shell sets this default value after reading any startup files.
When lithist is set and the cmdhist option is enabled, multi-line commands are saved to the history with embedded newlines rather than using semicolon separators.
The !?string[?] event designator refers to the most recent command preceding the current position in the history list containing string. The trailing '?' may be omitted if string is followed immediately by a newline.
The h modifier removes a trailing filename component, leaving only the head (directory path).
The default history expansion character is '!'. This is the first character in the histchars variable.
The t modifier removes all leading filename components, leaving only the tail (filename).
The !! event designator refers to the previous command. It is a synonym for '!-1'.
When histverify is 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.
No, non-interactive shells do not perform history expansion by default.
The valid values for HISTCONTROL are: ignorespace (lines beginning with a space are not saved), ignoredups (lines matching the previous history entry are not saved), ignoreboth (shorthand for both ignorespace and ignoredups), and erasedups (all previous lines matching the current line are removed before saving).
When a shell with history enabled exits, the last $HISTSIZE lines are copied from the history list to $HISTFILE. If histappend is enabled, lines are appended; otherwise the history file is overwritten. If HISTTIMEFORMAT is set, timestamps are written to the history file marked with the history comment character, and the file is then truncated to HISTFILESIZE lines.
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 HISTIGNORE and HISTCONTROL.
When histreedit is set and readline is being used, a user is given the opportunity to re-edit a failed history substitution by reloading it into the readline editing buffer.
The histchars variable contains two or three characters: the first is the history expansion character (default '!'), the second is the quick substitution character (default '^'), and the optional third character indicates the remainder of the line is a comment when found as the first character of a word (default '#').
Each pattern in HISTIGNORE is anchored at the beginning of the line and must match the complete line. There is no implicit '*' appended to patterns. The pattern matching honors the setting of the extglob shell option.
When histappend is set, the history list is appended to the file named by the value of HISTFILE when the shell exits, rather than overwriting the file.
Space, tab, newline, carriage return, =, and (when extglob is enabled) '(' all inhibit history expansion when found immediately following the history expansion character.
When cmdhist is set, bash attempts to save all lines of a multiple-line command in the same history entry, adding semicolons where necessary to preserve syntactic correctness. This option is enabled by default.
The !# event designator refers to the entire command line typed so far.
Word 0 (zero) is the zeroth word, which for the shell is the command word itself.
The history -d offset option deletes the history entry at position offset. If offset is negative, it is interpreted as relative to one greater than the last history position, so negative indices count back from the end of the history.
The default quick substitution character is '^'. This is used as shorthand for re-running the previous command, substituting one string for another.
The !-n event designator refers to the current command minus n (i.e., the nth previous command).
Only backslash () and single quotes can quote the history expansion character (!). Additionally, the history expansion character is treated as quoted if it immediately precedes the closing double quote in a double-quoted string.
When HISTSIZE is set to a numeric value less than zero, every command is saved on the history list with no limit.
History Expansion > Event Designators
45 questionsThe x* word designator abbreviates x-$ (from word x through the last word).
History expansion is performed immediately after a complete line is read, before the shell breaks it into words. It is performed on each line individually without taking quoting on previous lines into account.
If & appears in the new string of a substitution, it is replaced by old. A single backslash will quote the &.
Space, tab, newline, carriage return, and = inhibit history expansion. If the extglob shell option is enabled, ( will also inhibit expansion.
The :s/old/new/ modifier substitutes new for the first occurrence of old in the event line. Any character may be used as the delimiter in place of /. The final delimiter is optional if it is the last character of the event line.
The -p option to the history builtin command may be used to see what a history expansion will do before using it.
The :t modifier removes all leading filename components, leaving the tail (filename).
The % word designator refers to the first word matched by the most recent '?string?' search, if the search string begins with a character that is part of a word.
Only backslash () and single quotes can quote the history expansion character. Additionally, the history expansion character is treated as quoted if it immediately precedes the closing double quote in a double-quoted string.
The !?string[?] event designator refers to the most recent command preceding the current position in the history list containing string. The trailing ? may be omitted if string is followed immediately by a newline.
The zeroth word (0) is the command word. For the shell, this is the command itself.
The :h modifier removes a trailing filename component, leaving only the head (directory path).
The !# event designator represents the entire command line typed so far.
If old is null in a substitution, it is set to the last old substituted, or, if no previous history substitutions took place, the last string in a !?string[?] search.
The :q modifier quotes the substituted words, escaping further substitutions.
The x- word designator abbreviates x-$ like x*, but omits the last word. If x is missing, it defaults to 0.
If a word designator is supplied without an event specification, the previous command is used as the event.
The :g modifier causes changes to be applied over the entire event line. This is used in conjunction with ':s' (e.g., ':gs/old/new/') or ':&'. An 'a' may be used as a synonym for 'g'.
Yes, the :q and :x modifiers are mutually exclusive; the last one supplied is used.
The * word designator selects all of the words but the zeroth. 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.
If string is missing in !?string[?], the string from the most recent search is used. It is an error if there is no previous search string.
The x-y word designator selects a range of words from x to y. The abbreviation '-y' is equivalent to '0-y'.
The !! event designator refers to the previous command. It is a synonym for '!-1'.
Yes, the colon separator may be omitted if the word designator begins with a ^, $, *, -, or %.
The !string event designator refers to the most recent command preceding the current position in the history list that starts with string.
The default quick substitution character is ^ (caret). This is used as shorthand for re-running the previous command, substituting one string for another.
When 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.
The !n event designator refers to command line number n in the history list.
The :r modifier removes a trailing suffix of the form .xxx, leaving the basename.
The histchars variable contains two or three characters which control history expansion and tokenization. The first character is the history expansion character (default !), the second is the quick substitution character (default ^), and the optional third character indicates the comment character (default #).
The :x modifier quotes the substituted words as with :q, but breaks into words at blanks and newlines.
The !-n event designator refers to the current command minus n (the command that was n commands back).
History expansion can be disabled using the +H option to the set builtin command (e.g., 'set +H').
The ^string1^string2^ event designator performs quick substitution. It repeats the previous command, replacing string1 with string2. It is equivalent to '!!:s^string1^string2^'.
When the histreedit shell option is enabled and readline is being used, a failed history substitution will be reloaded into the readline editing buffer for correction.
The -s option to the history builtin command 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.
Yes, history expansion is enabled by default for interactive shells. Non-interactive shells do not perform history expansion by default.
The :G modifier applies the following 's' or '&' modifier once to each word in the event line.
The $ word designator refers to the last word. This is usually the last argument, but will expand to the zeroth word if there is only one word in the line.
Using History Interactively > History Modification
45 questionsThe :x modifier quotes the substituted words similar to :q, but it breaks the words at whitespace and quotes each word separately. This is useful when you want to split a single argument into multiple quoted arguments.
The :g& modifier applies the previous substitution globally to all occurrences in the line, not just the first occurrence.
fc -l lists the last 16 commands in history (or fewer if there aren't 16 commands in the history).
fc 100 with a single argument selects and edits only command 100 from the history.
Use !150:2 to get the second argument from command number 150. Arguments are 0-indexed where 0 is the command name.
Yes, fc can accept string arguments. fc gcc would select the most recent command starting with 'gcc'. If two strings are provided like fc cat gcc, it selects the range from the most recent command starting with 'cat' to the most recent command starting with 'gcc'.
Use fc -s foo=bar to replace the first occurrence of 'foo' with 'bar' in the previous command and execute it.
If the first number is greater than the second, the commands are listed or edited in reverse order. The range is still valid, just processed backwards.
The :p modifier causes the history expansion to be printed but not executed. This is useful for previewing what the expanded command will look like before actually running it.
The :q modifier quotes the substituted words to protect them from further expansion. Each word is individually quoted as if it were enclosed in double quotes.
fc -e vi explicitly uses vi as the editor instead of checking the FCEDIT or EDITOR variables. Without -e, fc checks FCEDIT first, then EDITOR, then defaults to /bin/ed.
The -n option suppresses command numbers when listing commands with fc -l, displaying only the command text without line numbers.
Use fc 100 150 to edit and execute commands 100 through 150. The first argument is the starting command number and the second is the ending command number.
The :e modifier removes everything except the extension. For example, !!:e on file.txt results in .txt (including the dot).
Use !n where n is the command number. For example, !150 executes command number 150 from the history list.
Yes, when you use fc -s to re-execute a command, the re-executed command is added to the history list as a new entry.
A negative number refers to a relative position in history. fc -20 means the 20th previous command (counting backward from the current position).
The :r modifier removes the filename extension (suffix). For example, !!:r on file.txt results in file.
Use !?string? where string is anywhere in the command. For example, !?file? executes the most recent command containing the word 'file' anywhere in it.
Use !!:2-* or !!:2- to get arguments from 2 through the end of the command.
fc -s re-executes the command without invoking an editor. It's a shortcut to recall and re-run a previous command directly.
Commands executed via fc are added to the history list after the fc command itself. The original command remains in history along with the executed result.
The :t modifier removes all leading path components, leaving only the filename (basename). For example, !!:t on /home/user/file.txt results in file.txt.
The :h modifier removes the trailing filename component, leaving only the directory path. For example, !!:h on /home/user/file.txt results in /home/user.
The ^old^new^ syntax is a quick substitution that replaces the first occurrence of 'old' with 'new' in the previous command and executes it. This is equivalent to !!:s/old/new/.
Both achieve the same result. fc -e - uses a dash as the editor name, which is a special value that means 'no editor' (re-execute directly). fc -s is a more readable shorthand for the same behavior.
Use !!:gs/old/new/ where the g modifier performs a global substitution, replacing all occurrences of 'old' with 'new' instead of just the first one.
Use !-n where n is how many commands back to go. For example, !-3 executes the 3rd previous command.
When histverify is enabled and history expansion is used, Bash displays the expanded command line for review instead of immediately executing it. You can then modify the line or press Enter to execute it.
fc -l -10 lists the last 10 commands in the history (commands from history position -10 to the current command).
Use !:0 to get the command name (the 0th word) from the previous command.
The -r option reverses the order of the commands listed, showing them in reverse chronological order (oldest first instead of newest first).
Multiple modifiers are applied left to right. !!:h:t first applies :h (remove filename), then :t (remove path), which effectively gives you the parent directory name. Modifiers are processed sequentially.
Use !^ to get the first argument (argument 1, not the command name) of the previous command.
!! expands to the previous command (the entire command line). It's equivalent to !-1.
Use shopt -s histverify to enable the option. To disable it, use shopt -u histverify.
The :& modifier repeats the previous substitution. For example, after using !!:s/foo/bar/, using !!:& will apply the same foo→bar substitution again.
FCEDIT takes precedence over EDITOR. If FCEDIT is set, it will be used regardless of the EDITOR value.
fc is a built-in command that allows you to edit commands from history before executing them, using an editor. The history expansion feature !cmd directly recalls and executes commands from history without editing (though you can use modifiers like :s for substitution). fc is more suitable for complex edits while history expansion is quicker for simple recalls.
Use !string where string is the prefix. For example, !git executes the most recent command that started with 'git'.
Bourne Shell Builtins > Signal and Event Handling
43 questionsIf job control is in effect, bash ignores SIGTTIN, SIGTTOU, and SIGTSTP.
If arg is not present and -p has been supplied, then the trap commands associated with each sigspec are displayed. If no arguments are supplied or if only -p is given, trap prints the list of commands associated with each signal.
The -r option without a jobspec argument restricts operation to running jobs.
The -p option lists only the process ID of the job's process group leader.
If no jobspec is supplied, the -a option means to remove or mark all jobs.
The ERR trap is not executed if the failed command is part of the command list immediately following a while or until keyword, part of the test in an if statement, part of a command executed in a && or || list except the command following the final && or ||, any command in a pipeline but the last, or if the command's return value is being inverted using !.
If arg is the null string, the signal specified by each sigspec is ignored by the shell and by the commands it invokes.
If arg is absent (and there is a single sigspec) or -, each specified signal is reset to its original disposition (the value it had upon entrance to the shell).
The -l option causes the shell to print a list of signal names and their corresponding numbers.
If the -h option is given, each jobspec 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 the -r option is supplied, the current job is used.
If id specifies a non-existent process or job, the return status is 127.
If id is not given, wait waits for all running background jobs and the last-executed process substitution, if its process id is the same as $!, and the return status is zero.
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.
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). In all cases, bash ignores SIGQUIT.
Trapped signals that are not being ignored are reset to their original values in a subshell or subshell environment when one is created.
If none of the supplied arguments is a child of the shell, or if no arguments are supplied and the shell has no unwaited-for children, the exit status is 127.
If the -n option is supplied, wait waits for a single job from the list of ids or, if no ids are supplied, any job, to complete and returns its exit status.
If a sigspec is ERR, the command arg is executed whenever a pipeline (which may consist of a single simple command), a list, or a compound command returns a non-zero exit status.
Commands run as a result of command substitution ignore the keyboard-generated job control signals SIGTTIN, SIGTTOU, and SIGTSTP.
An argument of -l 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 0.
The return status is 0 unless an invalid option is encountered or an invalid jobspec is supplied.
If a sigspec is RETURN, the command arg is executed each time a shell function or a script executed with the . or source builtins finishes executing.
If the -p option is supplied, the process or job identifier of the job for which the exit status is returned is assigned to the variable varname named by the option argument. The variable will be unset initially, before any assignment. This is useful only when the -n option is supplied.
No, signals ignored upon entry to the shell cannot be trapped or reset.
Supplying the -f option, when job control is enabled, forces wait to wait for id to terminate before returning its status, instead of returning when it changes status.
To prevent the shell from sending the signal to a particular job, it should be removed from the jobs table with the disown builtin or marked to not receive SIGHUP using disown -h.
The return status is false if any sigspec is invalid; otherwise trap returns true.
If wait is interrupted by a signal, the return status will be greater than 128.
The -n option displays information only about jobs that have changed status since the user was last notified of their status.
If a sigspec is EXIT (0) the command arg is executed on exit from the shell.
If a sigspec is DEBUG, the command arg is executed before every simple command, for command, case command, select command, every arithmetic for command, and before the first command executes in a shell function.
When job control is not in effect, asynchronous commands ignore SIGINT and SIGQUIT in addition to the inherited handlers.
Without options, disown removes each jobspec from the table of active jobs.
Modifying Shell Behavior > Job Control and Process Management
43 questionsThe job specification '%-' refers to the second most recent background job (the previous job).
The 'jobs -l' option lists all active jobs and additionally displays the process ID (PID) of each job's process group leader.
When given a job specification like 'kill %1', the kill command sends the specified signal (default SIGTERM) to the process group representing that job. This affects all processes in the job's pipeline.
Without arguments, 'wait' waits for all background jobs to complete. It returns an exit status of zero once all background processes have terminated.
SIGINT is signal number 2. It is generated when the user presses Ctrl+C and typically interrupts the current process.
The 'bg' command resumes a suspended job in the background. Syntax: 'bg [job_spec]'. If no job_spec is provided, it uses the current job. The job must have been previously suspended (typically with Ctrl+Z) to be resumed in the background.
Without options, 'disown' removes the specified jobs from the shell's job table. If no job_spec is provided, it disowns the current job. This means the shell will no longer track the job and will not send SIGHUP to it when the shell exits.
The 'disown -a' option removes all jobs from the job table, effectively disowning every active or stopped job managed by the shell.
SIGHUP is signal number 1. It is typically sent when a controlling terminal is closed and traditionally causes processes to terminate.
SIGSTOP is signal number 19. It stops a process and cannot be caught or ignored. Unlike SIGTSTP (Ctrl+Z), SIGSTOP cannot be handled by the process.
The 'set -o notify' option (equivalent to 'set -b') causes Bash to report the termination status of background jobs immediately, rather than waiting until the next prompt is displayed.
If multiple jobs match a job specification by name, Bash reports an error and the operation fails. You must be more specific or use job numbers instead.
The job specification '%+' or '%%' refers to the most recent background job (the current job). If multiple jobs are referenced, '%+' refers to the most recent one.
SIGSTOP (signal 19) cannot be caught or ignored by a process, while SIGTSTP (signal 20, typically sent by Ctrl+Z) can be caught and handled by the process. Both signals stop a process, but SIGTSTP gives the process a chance to clean up.
The 'fg' command resumes a suspended job in the foreground, or brings a background job to the foreground. Syntax: 'fg [job_spec]'. If no job_spec is provided, it uses the current job (the last job stopped in the background or started in the background).
The 'suspend' command suspends the execution of the shell until it receives a SIGCONT signal. Syntax: 'suspend [-f]'. The -f option forces the suspend even if the shell is a login shell.
After 'wait' completes, the $? variable contains the exit status of the waited-for job. If multiple jobs were waited for, $? contains the exit status of the last one.
The 'disown -r' option removes only running jobs from the job table, leaving stopped jobs unaffected.
The 'monitor' option is OFF by default in non-interactive shells (shell scripts). Job control is not active in scripts unless explicitly enabled with 'set -m'.
The 'jobs -s' option restricts the output to show only stopped jobs, excluding running or completed jobs.
The 'set -m' option enables job control (monitor mode). When enabled, Bash places each pipeline or command in its own process group, allowing job control commands like bg, fg, and jobs to function. This is the default behavior for interactive shells.
Use '%?string' or '%string' where string is a substring of the command name. '%?string' matches any job whose command contains string, while '%string' matches jobs whose command begins with string.
The 'jobs -r' option restricts the output to show only running jobs, excluding stopped or completed jobs.
When given a job specification (e.g., 'wait %1' or 'wait 1234'), 'wait' waits for that specific job or process ID to complete and returns its exit status. Multiple jobs/PIDs can be specified, and wait will wait for all of them to complete.
The 'monitor' option (enabled with 'set -m') is ON by default in interactive shells. This enables job control automatically when you start an interactive Bash session.
The 'set +m' option disables job control. When disabled, background jobs run in the same process group as the shell, and job control features become unavailable.
Yes, 'wait' accepts both process IDs and job specifications. You can use 'wait %1' to wait for job number 1, or 'wait 1234' to wait for a specific process ID.
When given multiple jobs or PIDs, 'wait' returns the exit status of the last job or PID waited for. If any job terminates abnormally, wait returns a non-zero status.
SIGCONT is signal number 18. It resumes a stopped process. If the process was stopped, this signal causes it to continue execution.
The 'huponexit' option is OFF by default. This means that by default, Bash does NOT send SIGHUP to jobs when an interactive login shell exits. However, the operating system may still send SIGHUP when the terminal closes.
The 'jobs -x' option executes the specified command replacing any job specification found in command arguments with the corresponding process group ID. For example: 'jobs -x kill %1' would replace %1 with the process group ID before executing kill.
The $! variable expands to the process ID (PID) of the most recently executed background (asynchronous) command. This allows you to reference the background job in other commands like 'wait $!' or 'kill $!'.
No, by default the 'suspend' command refuses to suspend a login shell for safety reasons. You must use the '-f' flag (force) to suspend a login shell: 'suspend -f'.
The 'huponexit' shell option (set with 'shopt -s huponexit') controls whether Bash sends SIGHUP to all jobs when an interactive login shell exits. It is off by default.
The 'jobs -p' option displays only the process ID (PID) of the process group leader for each job, without showing the job status or command.
Without options, the 'jobs' command lists all active jobs in the current shell. It shows the job number, status (Running/Stopped/Done), and the command that started the job.
SIGTERM is signal number 15. It is the default signal sent by the kill command and requests a process to terminate gracefully.
The exit status returned by 'wait' can range from 0 to 255. If a job exits with a status greater than 255, the value is truncated modulo 256. Values 128 and above typically indicate the job was terminated by a signal (signal number + 128).
Use '%n' where n is the job number. For example, '%1' refers to job number 1, '%2' refers to job number 2, etc. Job numbers are assigned sequentially starting from 1.
Ctrl+Z sends SIGTSTP (signal 20) to the foreground process group, causing the foreground job to suspend (stop). The shell then displays a job number and the '[1]+ Stopped' message, and returns to the prompt.
The 'disown -h' option marks each job_spec so that SIGHUP is not sent to the job if the shell receives a SIGHUP (e.g., when the terminal closes). The job remains in the job table but is marked to not receive hangup signals.
SIGKILL is signal number 9. It cannot be caught or ignored by a process and forces immediate termination.
By default, Bash sends SIGHUP (hangup signal) to all jobs when an interactive login shell exits. This causes background jobs to terminate unless they have been disowned or started with nohup.
Major Differences From The Bourne Shell
43 questionsBash supports $((expression)) for arithmetic expansion and (( )) for arithmetic evaluation. The Bourne shell requires using the external expr command for arithmetic operations.
Bash supports ${var^^} to convert variable contents to uppercase and ${var,,} to convert to lowercase. For example: name='foo'; echo ${name^^} outputs 'FOO'. The Bourne shell does not support this case modification parameter expansion.
No. Bash supports ${var@Q} which expands to a value that can be reused as input, escaping special characters as needed. For example, if var='hello$world', then ${var@Q} expands to 'hello$world'. This is not available in Bourne shell.
Bash supports $'...' quoting which interprets backslash escape sequences within the string. For example: echo $'Hello\nWorld' prints Hello and World on separate lines. The Bourne shell does not support this syntax.
No. The Bourne shell does not maintain command history. Bash maintains a command history list accessible through the history built-in, !! (last command), !n (command number n), and !string (most recent command starting with string).
No. Bash 4.3+ supports nameref variables with declare -n that create a reference to another variable (similar to pointers). For example: declare -n ref=var; ref=value actually assigns to var. The Bourne shell does not support namerefs.
No. Associative arrays (also called hash tables or dictionaries) using declare -A arr are a Bash 4.0+ feature. The Bourne shell has no support for associative arrays.
Bash maintains LINENO as the line number of the currently executing script or function, useful for debugging. The Bourne shell does not have a LINENO variable.
No. Bash supports [n]<|word syntax (available in certain configurations) for duplicating input from a coprocess or other special sources. The Bourne shell does not have this redirection syntax.
Bash correctly interprets ${10} as positional parameter 10. The original Bourne shell requires braces for any positional parameter beyond 9, but some implementations mishandle ${10} without proper braces. Bash always handles ${10} and higher correctly.
In Bash, ${var:=word} assigns word to var if var is unset or null, but this behaves differently when set -u (nounset) is enabled. Bash treats unset and null variables differently with set -u, while Bourne shell behavior varies more by implementation.
Bash provides the 'type' built-in command to display how a command name would be interpreted (including shell functions). The Bourne shell does not have an equivalent built-in for this purpose.
In Bash, the default value of IFS is
No. Bash provides PIPESTATUS, an array variable that contains the exit status of each command in the most recent foreground pipeline (index 0 is the leftmost command). The Bourne shell only has $? for the last command's status.
Bash supports both function name() { commands; } and function name { commands; } syntax. The Bourne shell only supports the name() { commands; } syntax. Additionally, Bash functions support local variables via the 'local' keyword, while Bourne shell functions do not have a local keyword.
No. The parameter expansion operators ${var#pattern}, ${var##pattern}, ${var%pattern}, and ${var%%pattern} for removing patterns from the beginning or end of variables are Bash extensions not available in the original Bourne shell.
Bash provides pushd, popd, and dirs built-in commands for maintaining a directory stack. The Bourne shell does not have these commands built-in.
No. Bash's read built-in supports -t seconds for timeout, -n chars for character count, -s for silent input, -d delim for custom delimiter, and more. The Bourne shell's read command is more limited and does not support these options.
Bash supports here strings with the <<< operator, allowing a string to be used as standard input. For example: wc -w <<< 'hello world'. The Bourne shell does not support here strings.
No. The =~ operator for matching strings against extended regular expressions is only available in Bash's [[ ]] compound command. The Bourne shell does not support this operator.
No. The substring extraction syntax ${var:offset:length} is a Bash extension. The Bourne shell only supports basic parameter expansion like ${var} and ${var:-default}.
No. The shopt built-in command for setting and unseting shell options (like extglob, nocaseglob, dotglob, etc.) is a Bash-specific command. The Bourne shell does not have an equivalent command.
Bash supports extended globbing with shopt -s extglob: ?(pattern) matches zero or one, (pattern) matches zero or more, +(pattern) matches one or more, @(pattern) matches exactly one, and !(pattern) matches anything except the pattern. The Bourne shell only supports standard globbing (, ?, [...]).
No. Each time $RANDOM is referenced in Bash, it generates a random integer between 0 and 32767. The Bourne shell does not have a RANDOM variable.
By default, Bash's echo interprets escape sequences like \n, \t, \b unless the -E flag is used. The Bourne shell's echo behavior varies by implementation but generally does not interpret escape sequences by default. This is why portable scripts should use printf instead.
No. Job control with commands like fg, bg, jobs, and disown is not available in the Bourne shell. This is a feature of Bash and other modern shells.
No. Bash supports command -v to show the command or function name, and command -V for a more verbose description. The Bourne shell's command built-in does not have these options.
No. Bash's SECONDS variable expands to the number of seconds since the shell was started. Assigning to SECONDS resets the counter. The Bourne shell does not have this variable.
Bash supports coprocs with coproc NAME { command; } or coproc command for asynchronous commands that can communicate with the shell. This feature, introduced in Bash 4.0, is not available in the Bourne shell.
No. The Bourne shell does not support arrays. Bash supports both indexed arrays (arr=(element1 element2)) and associative arrays (declare -A arr).
No. Brace expansion, which generates arbitrary strings like {a,b,c} expanding to 'a b c' or file{1,2,3}.txt expanding to 'file1.txt file2.txt file3.txt', is a Bash-specific feature not available in the Bourne shell.
Bash supports ${var@operator} where operator can be: U (uppercase), u (lowercase), L (lowercase all chars), Q (quote), E (escape with $'...'), P (prompt string expansion), A (assignment statement), K (associative array keys), and more. The Bourne shell does not support these transformations.
After a successful =~ regex match in Bash, $BASH_REMATCH is an array variable containing the full match in index 0 and captured groups in indices 1-9. The Bourne shell does not support this variable.
No. Bash supports |= for bitwise OR assignment (e.g., (( var |= mask ))). The Bourne shell does not support compound assignment operators like |=, &=, ^=, <<=, >>=.
No. Bash provides compgen, complete, and compopt built-ins for programmable command-line completion. The Bourne shell does not have any programmable completion features.
No. Bash supports the [n]<&word- and [n]>&word- syntax for moving file descriptors (closing the original). For example: 2>&1- moves fd 2 to fd 1 and closes the original fd 2. The Bourne shell does not support the move syntax with the trailing -.
No. The [[ ]] compound command is a Bash-specific feature that provides more powerful conditional testing with support for &&, ||, <, >, and regex matching with =~. The Bourne shell only supports the [ ] test command (which must use -a and -o instead of && and ||).
No. Bash's lastpipe option (set with shopt -s lastpipe) runs the last command of a pipeline in the current shell context, allowing variables set in the last pipeline command to persist. The Bourne shell does not support this option.
No. Indirect expansion using ${!prefix*} or ${!name@} to expand variable names whose values begin with prefix is a Bash-specific feature not available in the Bourne shell.
No. Bash supports &> and &>> for redirecting both stdout and stderr to the same file (e.g., command &> file). The Bourne shell requires the longer syntax command > file 2>&1 to achieve the same result.
In Bash, readonly and export can be used with the -a flag to operate on arrays, and with -f to operate on functions. The Bourne shell versions of these built-ins are more limited and do not support array operations.
No. The Bourne shell does not support command-line editing. Only Bash (and other modern shells) support command-line editing through the readline library, allowing arrow keys, Ctrl+A, Ctrl+E, and other editing shortcuts.
No. The select construct for creating simple menus is a Bash-specific feature and is not available in the Bourne shell.
Using History Interactively > History Manipulation Commands
42 questionsThe default value of HISTSIZE is 500. This is set by the shell after reading any startup files.
The history -d start-end option deletes the range of history entries between positions start and end, inclusive. Positive and negative values for start and end are interpreted as offsets from the current command.
The history -s option stores the args in the history list as a single entry. The last command in the history list is removed before the args are added.
When not listing (editing or executing), 0 is equivalent to -1 and -0 is invalid.
When HISTSIZE is set to a negative numeric value, every command is saved on the history list with no limit.
The history -r option reads the contents of the history file and appends them to the current history list.
When using fc for listing without specifying last, it defaults to the current command.
fc checks the FCEDIT variable first, then the EDITOR variable if FCEDIT is not set. If neither variable is set, vi is used as the default editor.
The erasedups value causes all previous lines matching the current line to be removed from the history list before that line is saved.
When using fc for editing without specifying last, it defaults to first.
The shell sets the default value of HISTFILESIZE to the value of HISTSIZE after reading any startup files.
If HISTTIMEFORMAT is set and not null, its value is used as a format string for strftime(3) to print the timestamp associated with each history entry displayed by the history builtin. When set, timestamps are written to the history file to be preserved across shell sessions.
The history -w option writes the current history list to the history file, overwriting the history file's contents.
The history -n option reads 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 bash session.
When HISTFILESIZE is set to a negative numeric value or a non-numeric value, truncation is inhibited (the history file is not truncated).
When listing, -0 is equivalent to the current command (usually the fc command itself).
If HISTFILE is unset, the command history is not saved when a shell exits.
The fc (fix command) builtin is used to list, edit, and re-execute commands from the command history.
When using fc for editing without specifying first, the default is the previous command.
You can specify a string to fc to locate the last command beginning with that string.
The history -d offset option deletes the history entry at position offset. If offset is negative, it is interpreted as relative to one greater than the last history position (negative indices count back from the end). An index of -1 refers to the current history -d command.
When HISTFILESIZE is set to 0, the history file is truncated to zero size.
The history -c option clears the history list by deleting all the entries.
The ignoredups value causes lines matching the previous history entry to not be saved.
The history -p option performs history substitution on the following args and displays the result on standard output. It does not store the results in the history list. Each arg must be quoted to disable normal history expansion.
The history -a option appends the 'new' history lines to the history file. These are history lines entered since the beginning of the current bash session, but not already appended to the history file.
The ignorespace value causes lines which begin with a space character to not be saved in the history list.
HISTIGNORE accepts a colon-separated list of patterns. Each pattern is anchored at the beginning of the line and must match the complete line (no implicit '*' is appended). Patterns are tested after HISTCONTROL checks are applied.
When using fc for listing without specifying first, the default is -16.
Negative numbers are used as an offset from the current command number.
Timestamps are written to the history file marked with the history comment character. When the history file is read, lines beginning with the history comment character followed immediately by a digit are interpreted as timestamps for the following history entry.
If an invalid option is encountered with fc, or first or last specify history lines out of range, the return value is 0 for the first form (indicating an error condition).
When using the second form (fc -s), the return status is that of the command re-executed, unless cmd does not specify a valid history line, in which case fc returns failure.
The fc -s option re-executes a command. Each instance of pat is replaced by rep (if pat=rep is specified), and the command is re-executed without editing.
The second and subsequent lines of a multi-line compound command are not tested, and are added to the history regardless of the values of HISTCONTROL or HISTIGNORE.
The -n option suppresses the command numbers when listing history commands.
The manual suggests the alias 'r="fc -s"' so that typing 'r cc' runs the last command beginning with 'cc' and typing 'r' re-executes the last command.
Shell Expansions > Path Expansions
42 questionsA sequence expression takes the form {x..y[..incr]}, where x and y are either integers or letters, and incr, an optional increment, is an integer. The default increment is 1 or -1 as appropriate. Both x and y must be of the same type (integer or letter).
To match a '-', include it as the first or last character in the set. To match a ']', include it as the first character in the set.
The extglob option changes the behavior of the parser, since the parentheses are normally treated as operators with syntactic meaning. To ensure that extended matching patterns are parsed correctly, make sure that extglob is enabled before parsing constructs containing the patterns, including shell functions and command substitutions.
If the globskipdots shell option is enabled, the filenames '.' and '..' are never matched, even if the pattern begins with a '.'. This option is enabled by default.
To avoid conflicts with parameter expansion, the string '${' is not considered eligible for brace expansion and inhibits brace expansion until the closing '}'.
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 following the tilde are treated as a possible login name.
If the nullglob shell option is set, filename expansion patterns which match no files expand to nothing and are removed, rather than expanding to themselves (the literal pattern string).
Brace expansion is performed before any other expansions. Any characters special to other expansions are preserved in the result. Brace expansion is strictly textual - Bash does not apply any syntactic interpretation to the context of the expansion or the text between the braces.
No, the results of each expanded string are not sorted - left to right order is preserved. For example, 'echo a{d,c,b}e' outputs 'ade ace abe' (not alphabetically sorted).
When matching a filename, the slash character must always be matched explicitly by a slash in the pattern, but in other matching contexts it can be matched by a special pattern character.
Yes, brace expansions may be nested. For example, 'chown root /usr/{ucb/{ex,edit},lib/{ex?.?*,how_ex}}' demonstrates nested brace expansion.
If the dotglob shell option is set, Bash includes filenames beginning with a '.' in the results of filename expansion. The filenames '.' and '..' must always be matched explicitly, even if dotglob is set.
Yes, when a word is regarded as a pattern during pathname expansion, it is replaced with an alphabetically sorted list of filenames matching the pattern.
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.
After word splitting, unless the -f option has been set (see The Set Builtin), Bash scans each word for the characters '*', '?', and '[' to perform pathname expansion. The -f option disables pathname expansion.
After word splitting, unless the -f option has been set, Bash scans each word for the characters '*', '?', and '['. If one of these characters appears, and is not quoted, then the word is regarded as a pattern and replaced with an alphabetically sorted list of filenames matching the pattern.
The '' pattern matches any string, including the null string. When the globstar shell option is enabled and '' is used in a filename expansion context, two adjacent '*'s used as a single pattern match all files and zero or more directories and subdirectories.
When integers are supplied in a brace expansion sequence, they may be prefixed with '0' to force each term to have the same width. When either x or y begins with a zero, the shell attempts to force all generated terms to contain the same number of digits, zero-padding where necessary.
Within a bracket expression, character classes can be specified using the syntax [:class:], where class is one of: alnum, alpha, ascii, blank, cntrl, digit, graph, lower, print, punct, space, upper, word, or xdigit. The 'word' character class matches letters, digits, and the character '_'.
The GLOBIGNORE shell variable may be used to restrict the set of file names matching a pattern. If GLOBIGNORE is set, each matching file name that also matches one of the patterns in GLOBIGNORE is removed from the list of matches. The filenames . and .. are always ignored when GLOBIGNORE is set and not null. However, setting GLOBIGNORE to a non-null value has the effect of enabling the dotglob shell option.
When the extglob shell option is enabled, Bash recognizes: ?(pattern-list) for zero or one occurrence, *(pattern-list) for zero or more occurrences, +(pattern-list) for one or more occurrences, @(pattern-list) for exactly one of the given patterns, and !(pattern-list) for anything except one of the given patterns.
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. If the tilde-prefix, sans the tilde, consists of a number without a leading '+' or '-', '+' is assumed.
Yes, the special pattern characters (*, ?, [, etc.) must be quoted if they are to be matched literally. A backslash escapes the following character; the escaping backslash is discarded when matching.
Any incorrectly formed brace expansion is left unchanged. A correctly-formed brace expansion must contain unquoted opening and closing braces, and at least one unquoted comma or a valid sequence expression.
Only brace expansion, word splitting, and filename expansion can increase the number of words of the expansion. Other expansions expand a single word to a single word, with the exceptions of "$@" and $* (special parameters), and "${name[@]}" and ${name[*]} (arrays).
The NUL character may not occur in a pattern. Any character that appears in a pattern, other than the special pattern characters, matches itself.
If the globstar shell option is set, the pattern '**' used in a filename expansion context will match all files and zero or more directories and subdirectories. If the pattern is followed by a '/', only directories and subdirectories match.
If the globasciiranges shell option is set, range expressions used in pattern matching bracket expressions behave as if in the traditional C locale when performing comparisons. Pattern matching does not take the current locale's collating sequence into account, so 'b' will not collate between 'A' and 'B', and upper-case and lower-case ASCII characters will collate together.
Each variable assignment is checked for unquoted tilde-prefixes immediately following a ':' or the first '='. In these cases, tilde expansion is also performed. Consequently, one may use filenames with tildes in assignments to PATH, MAILPATH, and CDPATH, and the shell assigns the expanded value.
By default, if no matching filenames 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 failglob shell option is set and no matches are found, an error message is printed and the command is not executed.
If the login name is invalid, or the tilde expansion fails, the word is left unchanged.
If the first character following the '[' is a '!' or a '^', then any character not within the range matches. For example, '[!abc]' or '[^abc]' matches any character except 'a', 'b', or 'c'.
If the nocaseglob shell option is enabled, the match is performed without regard to the case of alphabetic characters during filename expansion.
Each variable assignment is checked for unquoted tilde-prefixes immediately following a ':' or the first '='. In these cases, tilde expansion is also performed. This special behavior allows convenient usage like PATH=~/bin:/usr/bin where each tilde after a colon is also expanded.
The sorting order of characters in range expressions and the characters included in the range are determined by the current locale and the values of the LC_COLLATE and LC_ALL shell variables. In the default C locale, '[a-dx-z]' is equivalent to '[abcdxyz]'. Many locales sort characters in dictionary order, where '[a-dx-z]' might be equivalent to '[aBbCcDdxYyZz]'.
If the login name after tilde 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.
When a pattern is used for filename expansion, the character '.' at the start of a filename or immediately following a slash must be matched explicitly, unless the shell option dotglob is set. In order to match the filenames '.' and '..', the pattern must begin with '.' (for example, '.?'), even if dotglob is set.
The default increment in a brace expansion sequence is 1 or -1 as appropriate (depending on whether the sequence is ascending or descending). When the increment is supplied, it is used as the difference between each term.
Bash also performs tilde expansion on words satisfying the conditions of variable assignments when they appear as arguments to simple commands. Bash does not do this, except for the declaration commands listed above, when in POSIX mode.
The shell options that control pathname expansion behavior include: dotglob (include filenames beginning with '.'), nocaseglob (case-insensitive matching), nullglob (remove non-matching patterns), failglob (error on non-matching patterns), globstar (enable '**' recursive matching), globskipdots (never match '.' and '..'), and globasciiranges (use C locale for range expressions).
If the failglob shell option is set, patterns which fail to match filenames during filename expansion result in an expansion error (an error message is printed and the command is not executed).
Bash POSIX Mode
41 questionsIn POSIX mode, the type builtin behavior is more limited. The -t, -p, -P, and -f options are Bash extensions and may not be available.
The =~ operator for regular expression matching is not available in POSIX mode since the [[ construct that contains it is disabled.
In POSIX mode, echo does not interpret escape sequences by default unless the -e option is specified.
In POSIX mode, redirection errors may not cause the shell to exit with non-zero status when using the set -e option, following POSIX behavior.
The local keyword for creating local variables in functions is available in POSIX mode, though it's not part of the POSIX standard—Bash maintains it for compatibility.
In POSIX mode, wait follows POSIX specifications with limited options compared to Bash mode, and job ID notation may be more restricted.
No, the select compound command for creating menus is a Bash extension and is not available in POSIX mode.
In POSIX mode, programmable completion using the complete and compgen builtins is disabled as these are Bash extensions.
In POSIX mode, ulimit follows POSIX specifications with limited options compared to Bash mode.
Use the command set -o posix to enable POSIX mode in a running shell or script.
Process substitution using <(command) and >(command) syntax is disabled in POSIX mode.
In POSIX mode, when using $@ and $* without quotes, the behavior matches POSIX standard where they may undergo different expansion rules compared to default Bash mode.
Invoke bash with the --posix option (e.g., bash --posix) or set the POSIXLY_CORRECT environment variable before starting bash.
In POSIX mode, printf follows POSIX specifications and may not support Bash-specific format specifiers or extensions.
No, the &> and >& redirection operators for redirecting both stdout and stderr together are Bash extensions and are not available in POSIX mode.
Setting the POSIXLY_CORRECT environment variable to any value causes bash to behave more strictly POSIX-compliant even before POSIX mode is formally enabled.
In POSIX mode, the read builtin does not support the -e option for readline editing, -u for file descriptors, or other Bash-specific extensions like -a for arrays.
Extended pattern matching features like ?(pattern), *(pattern), +(pattern), @(pattern), and !(pattern) are disabled in POSIX mode.
In POSIX mode, time is treated as a reserved word and pipelines involving time have different behavior than in non-POSIX mode.
In POSIX mode, special patterns like [a-z] follow POSIX collation order rather than the current locale's ordering, which may differ from default Bash behavior.
This is not applicable in POSIX mode since [[ is disabled entirely. The != operator in single-bracket [ tests performs string comparison.
No, here-strings using the <<< operator are a Bash extension and are not available in POSIX mode.
In POSIX mode, cd does not support the -e option to verify successful directory changes, and behavior with $CDPATH follows POSIX standards more strictly.
ANSI-C quoting $'...' and localization quoting $"..." are Bash extensions and are not available in POSIX mode.
In POSIX mode, the command builtin conforms to POSIX specifications and does not support the -p option to use a default value for PATH.
The -n test for non-zero strings works in POSIX mode using the single-bracket [ test command, as it's part of the POSIX standard.
In POSIX mode, the default value of IFS is
In POSIX mode, function names must be valid shell identifiers and the function keyword is not recognized. Functions must be defined as name() { ... } without the function keyword.
In POSIX mode, the hash builtin follows POSIX behavior with more limited options compared to Bash's extended hash command.
Arithmetic expansion using $((...)) is available in POSIX mode as it's part of the POSIX standard, but some Bash-specific arithmetic features may be disabled.
No, history expansion using ! is not a POSIX feature and its behavior in POSIX mode depends on whether history expansion is enabled.
No, the source builtin is not available in POSIX mode. You must use . (dot) command instead.
In POSIX mode, the trap builtin follows POSIX behavior where signal numbers without a SIG prefix are treated differently, and debugging traps may not be available.
No, coprocesses using the coproc keyword are a Bash extension and are not available in POSIX mode.
Yes, job control builtins like disown are Bash extensions and may have restricted or unavailable functionality in POSIX mode.
No, the [[ compound command is not available in POSIX mode. You must use the single bracket [ test command instead.
No, the += assignment operator for appending to variables is a Bash extension and is not available in POSIX mode.
Yes, the <<- here-document syntax that strips leading tabs is available in POSIX mode as it's part of the POSIX standard.
Special variables like RANDOM, LINENO, SECONDS, and other Bash-specific variables may not be available or may have limited functionality in POSIX mode.
Invoking Bash > Shell Execution Modes
41 questionsThe shell sets the default HISTFILESIZE value to the value of HISTSIZE after reading any startup files.
In POSIX mode (started with --posix option), interactive shells expand the ENV variable and read commands from the file whose name is the expanded value. No other startup files are read.
Bash is interactive if: (1) it is started without non-option arguments (unless -s is specified) AND without the -c option, AND (2) its standard input and standard error are both connected to terminals (as determined by isatty(3)), OR (3) it was explicitly started with the -i option.
The -D option prints a list of all double-quoted strings preceded by $ on standard output. These are strings subject to language translation when the current locale is not C or POSIX. This implies the -n option, so no commands are actually executed.
When invoked as 'sh', Bash mimics historical sh behavior: (1) For login shells, it reads /etc/profile and ~/.profile (not ~/.bash_profile), (2) For interactive shells, it looks for ENV variable (not BASH_ENV) and reads that file, (3) It does NOT read /etc/bash.bashrc or ~/.bashrc, (4) After startup files are read, Bash enters POSIX mode.
Bash attempts to determine when it is being run with standard input connected to a network connection (e.g., by rshd or sshd). If Bash determines it is being run non-interactively this way, it reads and executes commands from /etc/bash.bashrc and ~/.bashrc if these files exist and are readable. It will NOT do this if invoked as sh.
If arguments remain after option processing, and neither -c nor -s was supplied, the first argument is assumed to be the name of a file containing shell commands. $0 is set to the name of the file, and positional parameters are set to remaining arguments. Bash reads and executes commands from this file, then exits. The file is first searched in the current directory, then in PATH if not found.
The --debugger option arranges for the debugger profile to be executed before the shell starts and turns on extended debugging mode (extdebug option to shopt builtin). This option must appear on the command line before single-character options to be recognized.
The --noediting option prevents bash from using the GNU readline library to read command lines when the shell is interactive.
The -x option causes bash to print commands and their arguments as they are executed.
The -O shopt_option sets the value of a shell option accepted by the shopt builtin. The +O shopt_option unsets it. If shopt_option is not supplied, the names and values of shell options are printed. If +O is used without shopt_option, output is displayed in a format that may be reused as input.
Check if the 'i' character is present in the $- variable, or if PS1 is set. The command 'echo $-' will include 'i' if the shell is interactive.
When an interactive login shell exits (or a non-interactive login shell executes the exit builtin command), Bash reads and executes commands from ~/.bash_logout, if it exists.
The --posix option changes the behavior of bash where the default operation differs from the POSIX standard to match the standard (POSIX mode). This affects startup file behavior and many other shell behaviors.
If the -i option is present, the shell is forced to run in interactive mode. This sets PS1 and includes 'i' in the $- variable, even if stdin/stdout are not connected to a terminal.
When Bash is started non-interactively, it checks for the BASH_ENV environment variable, expands its value, and uses the expanded value as the name of a file to read and execute. Bash behaves as if 'if [ -n "$BASH_ENV" ]; then . "$BASH_ENV"; fi' were executed. The PATH variable is NOT used to search for the filename.
The --help option displays a usage message on standard output and exits successfully.
If the -s option is present, or if no arguments remain after option processing, commands are read from the standard input. This option allows the positional parameters to be set when invoking an interactive shell or when reading input through a pipe.
A -- signals the end of options and disables further option processing. Any arguments after the -- are treated as filenames and arguments. An argument of - is equivalent to --.
The -l option makes bash act as if it had been invoked as a login shell, causing it to read /etc/profile and the first found of ~/.bash_profile, ~/.bash_login, or ~/.profile.
No. When a command found to be a shell script is executed, rbash turns off any restrictions in the shell spawned to execute the script.
If the shell is started with effective user (group) ID not equal to the real user (group) ID, and the -p option is NOT supplied: (1) no startup files are read, (2) shell functions are not inherited from the environment, (3) SHELLOPTS, BASHOPTS, CDPATH, and GLOBIGNORE environment variables are ignored, and (4) the effective user ID is set to the real user ID.
The --rcfile file option forces Bash to read and execute commands from the specified file instead of /etc/bash.bashrc and ~/.bashrc, but only if the shell is interactive.
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.
No. When Bash executes the file specified by BASH_ENV in non-interactive mode, the value of the PATH variable is NOT used to search for the filename.
Multi-character options (like --debugger, --login, --posix) must appear on the command line BEFORE the single-character options (like -l, -i, -c) to be recognized.
Bash reads and executes commands from /etc/bash.bashrc and ~/.bashrc, if these files exist. This can be inhibited using the --norc option, or a different file can be specified using --rcfile.
The -v option causes bash to print shell input lines as they are read.
The --noprofile option inhibits reading of /etc/profile and any of the personal initialization files (~/.bash_profile, ~/.bash_login, or ~/.profile) when the shell is started as a login shell.
Restricted shell restrictions are enforced AFTER any startup files are read. This means startup files can execute operations that would later be forbidden.
After reading any startup files, the shell sets the default HISTSIZE value to 500.
The --dump-po-strings option is equivalent to -D, but the output is in the GNU gettext po (portable object) file format instead of plain text.
If the -c option is present, commands are read from the first non-option argument command_string. If there are arguments after the command_string, the first argument is assigned to $0 and any remaining arguments are assigned to the positional parameters ($1, $2, etc.).
Bash becomes a restricted shell if: (1) it is started with the name 'rbash', or (2) the -r option is supplied at invocation (equivalently, --restricted).
The --version option shows version information for this instance of bash on the standard output and exits successfully.
Bash reads: (1) /etc/profile first, then (2) 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.
Bash considers itself a login shell if the first character of argument zero ($0) is a '-', or if it was started with the --login option (or -l).
The --init-file file option is an alias for --rcfile. It executes commands from the specified file instead of /etc/bash.bashrc and ~/.bashrc if the shell is interactive.
When -p is supplied at invocation, Bash does NOT reset the effective user ID to the real user ID. However, startup file behavior remains restricted (startup files are still not read when effective ID differs from real ID).
In restricted mode, the following are disallowed: (1) changing directories with cd, (2) setting/unsetting SHELL, PATH, HISTFILE, ENV, or BASH_ENV, (3) specifying command names containing /, (4) specifying filenames containing / to ., history, or hash -p builtins, (5) importing function definitions from environment at startup, (6) parsing SHELLOPTS from environment at startup, (7) redirecting output using >, >|, <>, >&, &>, and >> operators, (8) using exec to replace the shell, (9) adding/deleting builtins with enable -f/-d, (10) enabling disabled builtins with enable, (11) using command -p, (12) turning off restricted mode with set +r or shopt -u restricted_shell.
The --norc option inhibits reading of /etc/bash.bashrc and ~/.bashrc if the shell is interactive. This option is on by default if the shell is invoked as sh.
Executing Commands > Command Expansion and Preparation
41 questionsOnly brace expansion, word splitting, and pathname expansion can increase the number of words. Other expansions expand a single word to a single word, with exceptions for "$@" and "${name[@]}", and in most cases $* and ${name[*]}.
GLOBIGNORE restricts the set of filenames matching a pattern. If set, each matching filename that also matches a pattern in GLOBIGNORE is removed from the list. Setting GLOBIGNORE to a non-null value enables the dotglob option.
If the expression is invalid, bash prints a message indicating failure and no substitution occurs.
All characters preceding the first unquoted slash (or all characters if no slash) in a word beginning with an unquoted tilde (~). If none are quoted, characters following the tilde are treated as a possible login name.
If the tilde-prefix is '~-', it is replaced with the value of the shell variable OLDPWD (previous working directory), if set.
${parameter:=word} assigns default values. If parameter is unset or null, the expansion of word is assigned to parameter, and the value is then substituted. Positional parameters and special parameters cannot be assigned this way.
If command substitution appears within double quotes, word splitting and pathname expansion are NOT performed on the results.
There are two forms: $(command) (modern, recommended) and command (legacy/backtick form). Both execute command in a subshell and replace the substitution with standard output, with trailing newlines deleted.
The string '${' is not considered eligible for brace expansion and inhibits brace expansion until the closing '}'. This avoids conflicts with parameter expansion.
Process substitution is supported on systems that support named pipes (FIFOs) or the /dev/fd method of naming open files.
Any incorrectly formed brace expansion is left unchanged. A correctly-formed brace expansion must contain unquoted opening and closing braces and at least one unquoted comma or a valid sequence expression.
Sequence expressions take the form {x..y[..incr]}, where x and y are integers or single letters, and incr is an optional integer increment. Default increment is 1 or -1. Integers can be prefixed with 0 to force equal width. Example: {1..5} expands to '1 2 3 4 5'.
Bash performs seven kinds of expansion: brace expansion, tilde expansion, parameter and variable expansion, command substitution, arithmetic expansion, word splitting, and pathname expansion.
Brace expansion generates arbitrary strings that need not exist as files. Patterns take the form: optional preamble + {comma-separated strings OR sequence expression} + optional postscript. For example: a{d,c,b}e expands to 'ade ace abe'. Results are not sorted; left-to-right order is preserved.
By default (if nullglob is not enabled), the word is left unchanged. If nullglob is set, the word is removed. If failglob is set, an error message is printed and the command is not executed.
The faster equivalent is $(< file), which reads the file directly without spawning a cat command.
Trailing newlines are deleted from the command output. Embedded newlines are not deleted but may be removed during word splitting.
Braces are required when parameter is a positional parameter with more than one digit (e.g., ${12}), or when parameter is followed by a character that should not be interpreted as part of its name.
If IFS is unset or its value is exactly
Yes, command substitutions may be nested. When using $(command) form, nesting works naturally. When using backquoted form, escape inner backquotes with backslashes.
If the tilde-prefix is '~+', it is replaced with the value of the shell variable PWD (current working directory).
The order is: 1) brace expansion; 2) tilde expansion, parameter and variable expansion, arithmetic expansion, and command substitution (done left-to-right); 3) word splitting; 4) pathname expansion. Quote removal occurs after all expansions.
The format is $((expression)). The old format $[expression] is deprecated and will be removed in upcoming versions.
When globstar is enabled, two adjacent * characters used as a single pattern will match all files and zero or more directories and subdirectories. If followed by a /, it will match only directories and subdirectories.
Tilde expansion, parameter and variable expansion, arithmetic expansion, and command substitution are all performed in a left-to-right fashion.
Brace expansion can be disabled with the +B option to the set command, or by starting bash with the +B option. This provides strict compatibility with historical sh versions.
${parameter:-word} uses default if parameter is unset OR null. ${parameter-word} (omitting the colon) uses default only if parameter is unset, not if it's null (empty string).
Bash scans each word for the characters *, ?, and [. If one appears and is not quoted, the word is treated as a pattern and replaced with an alphabetically sorted list of matching filenames.
In backtick form, backslash retains literal meaning except when followed by $, `, or . In $(command) form, all characters between parentheses make up the command; none are treated specially.
No, if no expansion occurs, no splitting is performed. Word splitting only applies to results of parameter expansion, command substitution, and arithmetic expansion that did not occur within double quotes.
Process substitution allows a process's input or output to be referred to using a filename. It takes the form <(list) for input or >(list) for output. The process list runs asynchronously, and its input/output appears as a filename.
The exclamation point introduces indirect expansion. Bash uses the value formed by expanding the rest of parameter as the new parameter; this is then expanded. For nameref parameters, it expands to the name of the parameter referenced.
After all preceding expansions, all unquoted occurrences of the characters , ', and " that did not result from expansions are removed.
Explicit null arguments ("" or '') are retained and passed to commands as empty strings. Unquoted implicit null arguments from parameters with no values are removed.
Process substitution is performed simultaneously (at the same time) with tilde expansion, parameter and variable expansion, arithmetic expansion, and command substitution.
${parameter-word} substitutes word only if parameter is unset. ${parameter:-word} substitutes word if parameter is unset OR null (empty). The colon checks for both unset and null conditions.
If the first character following [ is ! or ^, then any character NOT enclosed is matched. Example: [^abc] or [!abc] matches any character except a, b, or c.
When dotglob is set, the character '.' at the start of a name or following a slash does not need to be matched explicitly. However, '.' and '..' must still match a pattern beginning with '.' unless globskipdots is enabled.
Readline vi Mode
41 questionsYanks (copies) the last word from the previous command and inserts it at the current cursor position.
Moves to the first line in the command history (the oldest command). Unlike vi editor, this doesn't go to a specific line number.
Use the format: '\e[key: command'. For example: '\e[A: previous-history' binds Escape+[A to previous history. For vi-specific bindings, use 'set keymap vi-insert' or 'set keymap vi-command' before the bindings.
Press 'C-c' (Ctrl-c) in either insert or command mode to abort the current command line and start fresh.
There is no '>>' command in Bash Readline vi mode. Unlike the full vi editor, Bash Readline vi mode has a limited subset of commands.
Press 'y' followed by a motion command. For example, 'y$' yanks from cursor to end of line, 'y0' yanks from cursor to beginning of line.
Add 'set editing-mode vi' to your ~/.inputrc file. This affects all Readline-enabled programs, not just Bash.
In command mode, 'i' enters insert mode at the current cursor position, while 'a' enters insert mode after the current cursor position (append).
Comments out the current line by inserting '#' at the beginning and executes it (which effectively does nothing, allowing you to save the command in history without running it).
Run 'set -o vi' to switch to vi mode or 'set -o emacs' to switch to emacs mode. This changes the mode for the current shell session.
'h' moves left one character, 'l' moves right one character, 'k' moves backward through command history (up), and 'j' moves forward through command history (down).
Press 'p' in command mode to paste the most recently deleted or yanked text after the cursor position.
Press 'u' in command mode to undo the last change. Press 'U' to undo all changes to the current line.
Press 'f' followed by a character to move forward to the next occurrence of that character. Press 'F' followed by a character to move backward to the previous occurrence. Press 't' to move forward to just before the character, or 'T' to move backward to just after it.
Deletes all text inside the nearest parentheses, without deleting the parentheses themselves.
The bell-style determines behavior on errors. Options are 'none' (silent), 'visible' (flash screen), or 'audible' (beep, default). Set with 'set bell-style visible' in .inputrc.
Deletes all text from the cursor position to the end of the line and enters insert mode.
Press 'w' to move forward to the beginning of the next word, or 'b' to move backward to the beginning of the previous word. Press 'e' to move forward to the end of the current word.
Emacs mode is the default editing mode unless vi mode is explicitly enabled with 'set -o vi' or the 'editing-mode' variable is set to 'vi' in .inputrc.
Changes (deletes and enters insert mode) all text inside the nearest double quotes, without deleting the quotes themselves.
Moves to the most recent command in the history (the newest command). This is opposite to the behavior of 'G'.
When set to 'on' in .inputrc, it displays '@' or '+' to indicate insert mode, and ':' or '-' to indicate command mode. The actual characters can be customized with 'vi-ins-mode-string' and 'vi-cmd-mode-string' variables.
Replaces the character under the cursor with the next character typed.
In command mode (after ESC), press '/' to search forward through command history, or '?' to search backward. Press 'n' to repeat the search in the same direction, or 'N' to reverse direction.
Press '.' (period) in command mode to repeat the last text modification (delete, change, yank, etc.).
The default timeout is 500 milliseconds (0.5 seconds). This can be changed with 'set keyseq-timeout N' in .inputrc where N is in milliseconds.
In command mode, pressing 'v' opens the current command in your default editor (defined by $VISUAL or $EDITOR). When you save and exit the editor, the command is executed.
Press ESC to switch from insert mode to command mode. Press 'i', 'a', 'I', or 'A' in command mode to return to insert mode.
The 'dd' command deletes the entire current line and places it in the kill ring (paste buffer).
Toggles the case of the character under the cursor (uppercase to lowercase or vice versa) and moves the cursor forward.
There is no visual indicator by default. However, you can configure a mode indicator by modifying the PS1 prompt to check the mode, or by using 'set show-mode-in-prompt on' in .inputrc which shows '(ins)' or '(cmd)' in the prompt.
Run 'set -o vi' in the current shell, or add it to ~/.bashrc for permanent configuration. This switches Readline from the default emacs mode to vi mode.
Press '(' to move backward to the beginning of the previous sentence, or ')' to move forward to the beginning of the next sentence. Sentences are defined as text followed by '.', '!', or '?' followed by a space.
Vi-insert-mode keymap bindings apply when in insert mode (typing text), while vi-command-mode keymap bindings apply when in command mode (navigating/editing after pressing ESC). These can be customized separately in .inputrc using 'set keymap vi-insert' or 'set keymap vi-command'.
In command mode, press 'ZZ' (shift-z-z) to execute the current command. Alternatively, press Enter in either insert or command mode.
In command mode, press '/' followed by a pattern, then press Enter. Use 'n' to cycle through matching commands or 'N' to go in reverse direction.
The 'cc' command deletes the entire current line and enters insert mode, allowing you to type a replacement for the entire line.
Shell Arithmetic > Conditional Operations
40 questionsBitwise AND (&) has higher precedence than bitwise XOR (^), which has higher precedence than bitwise OR (|).
Exponentiation (**) has higher precedence than multiplication (*, /, %).
The for arithmetic loop terminates when expr2 evaluates to zero. The loop continues as long as expr2 evaluates to a non-zero value.
The return status is 1 when the expression value is zero, and 0 when the expression value is non-zero.
If any expression is omitted in a for ((expr1; expr2; expr3)) loop, it behaves as if it evaluates to 1.
Yes, sub-expressions in parentheses are evaluated first and may override the precedence rules.
If the last argument evaluates to a non-zero value, let returns 0.
Comparison operators (<= >= < >) have higher precedence than equality operators (== !=).
The comma operator (,) is left-to-right associative and has the lowest precedence of all operators.
The expression undergoes the same expansions as if it were within double quotes (tilde expansion, parameter and variable expansion, arithmetic expansion, command substitution, process substitution, and quote removal), but double quote characters in expression are not treated specially and are removed.
When specifying n in [base#]n format, if a non-digit is required, the digits greater than 9 are represented by the lowercase letters, the uppercase letters, @, and _, in that order.
If the last argument evaluates to 0, let returns 1; otherwise it returns 0.
The return status is 0 when the expression value is non-zero, and 1 when the expression value is zero.
Evaluation is done in fixed-width integers with no check for overflow, though division by 0 is trapped and flagged as an error.
The old format $[expression] is deprecated and will be removed in upcoming versions of bash.
A shell variable that is null or unset evaluates to 0 when referenced by name without using the parameter expansion syntax.
If the expression is invalid, bash prints a message indicating failure and no substitution occurs.
When used with the [[ command, arg1 and arg2 are evaluated as arithmetic expressions before comparison.
Yes, if base is less than or equal to 36, lowercase and uppercase letters may be used interchangeably to represent numbers between 10 and 35.
The exponentiation operator () is right-to-left associative, meaning 232 = 2(32) = 512, not (23)**2 = 64.
The shell performs tilde expansion, parameter and variable expansion, arithmetic expansion, command substitution, process substitution, and quote removal on words between [[ and ]] (the expansions that would occur if the words were enclosed in double quotes).
Numbers take the form [base#]n, where the optional 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, base 10 is used.
The test command sorts using ASCII ordering for < and > string comparison.
When used with [[, the < and > operators sort lexicographically using the current locale.
Yes, a shell variable need not have its integer attribute turned on to be used in an arithmetic expression.
The arithmetic binary operators are: -eq (equal to), -ne (not equal to), -lt (less than), -le (less than or equal to), -gt (greater than), -ge (greater than or equal to).
Within ((expression)), you can use <= (less than or equal), >= (greater than or equal), < (less than), > (greater than), == (equality), and != (inequality) for comparison.
No, the words between the [[ and ]] do not undergo word splitting and pathname expansion.
No, bash performs arithmetic evaluation in fixed-width integers with no check for overflow.
Assignment operators (=, *=, /=, %=, +=, -=, <<=, >>=, &=, ^=, |=) are right-to-left associative.
The conditional operator (expr?expr:expr) is right-to-left associative.
No, conditional operators such as -f must be unquoted to be recognized as primaries within [[ ]] expressions.
Bourne Shell Builtins > Testing and Parsing
40 questionsThe echo builtin returns 0 (success) if all arguments are successfully written. It returns non-zero only if there's a write error. The return value is not typically checked since echo is used for output, not testing.
The -f file test operator returns true if the file exists and is a regular file. Use '-e' to check for existence (any file type), '-f' for regular files specifically, and '-d' for directories.
The -t option to read builtin causes read to time out and return failure if a complete line of input is not read within TIMEOUT seconds. The timeout value is specified as an integer after -t. If timeout is reached, read returns exit status 1 and the variable is not set.
Parentheses in let builtin expressions are used to group sub-expressions and control operator precedence, just like in C. For example: let 'x = (5 + 3) * 2' evaluates to 16. The parentheses force the addition to happen before multiplication.
The -e option to read builtin enables readline to read the line. This gives the user full line-editing capabilities including command history, cursor movement, and readline editing features similar to interactive shell input. This is only available when bash is compiled with readline support.
The -p option to read builtin displays PROMPT as a prompt before reading input, without a trailing newline. For example: read -p 'Enter name: ' name displays 'Enter name: ' and waits for user input.
The -d option to read builtin changes the delimiter character from newline to the first character of DELIM. The read command reads until the specified delimiter instead of newline. For example: read -d ';' reads input until a semicolon is encountered.
The -u option to read builtin reads input from file descriptor FD instead of standard input. For example: read -u 3 line reads from file descriptor 3. This is useful for reading from files opened with exec commands.
The default value of IFS in bash is
The let builtin returns 1 (failure) when the last expression evaluates to 0. It returns 0 (success) when the last expression evaluates to a non-zero value.
The -E option to echo builtin explicitly disables interpretation of backslash escape sequences. This is actually the default behavior in bash, but -E can be used to override the xpg_echo shell option or to be explicit. Use -e to enable escape interpretation.
The -u option to read builtin causes read to treat backslashes as escape characters only when followed by a valid escape character. Without -u (and with -r), backslashes are treated literally. This option was added in bash 5.1 to provide more precise control over backslash handling.
The -ef (equal files) file test operator returns true if file1 and file2 refer to the same device and inode numbers (i.e., they are hard links to the same file). Usage: [ file1 -ef file2 ].
The =~ operator performs regular expression matching in bash within [[ ]] conditional expressions. The string to the right of =~ is considered an extended regular expression and matched against the string on the left. Captured groups are stored in BASH_REMATCH array. For example: [[ $string =~ ^[0-9]+$ ]] matches if string contains only digits.
The printf builtin provides formatted output similar to C's printf, with format specifiers like %s, %d, %f, etc. It doesn't interpret escape sequences by default (requires explicit format). The echo builtin simply outputs its arguments separated by spaces, with behavior regarding escape sequences (-e/-E options) varying between implementations. printf is more portable and predictable.
The -nt (newer than) file test operator returns true if file1 is newer (has a more recent modification timestamp) than file2, or if file1 exists and file2 does not. Usage: [ file1 -nt file2 ].
The -x file test operator returns true if the file exists and has execute permission. For directories, this tests if the directory can be searched (entered). The check is performed against the current user's effective permissions.
There is no -a or -A option to the echo builtin. The -a option is used with read builtin to read words into an indexed array. The echo builtin has -n (suppress trailing newline), -e (enable backslash escape interpretation), and -E (disable backslash escape interpretation, which is default) options.
The -n option to echo builtin suppresses the trailing newline that echo normally adds to output. This allows multiple echo statements to output on the same line. For example: echo -n 'Prompt: '; read response displays 'Prompt: ' and waits for input on the same line.
The let builtin supports standard C-style comparison operators: < (less than), <= (less than or equal), > (greater than), >= (greater than or equal), == (equal), and != (not equal). These return 1 for true and 0 for false when used in arithmetic expressions.
The -a option to read builtin reads words into an indexed array variable starting at index 0. Each word from the input (split by IFS) becomes an array element. For example: read -a arr reads space-separated words into the arr array.
The single bracket [ is a POSIX builtin command (test), while [[ is a bash keyword that provides enhanced functionality. Within [[ ]], word splitting and pathname expansion are disabled, && and || have higher precedence than -a and -o, and pattern matching with == and != is supported. Variables inside [[ ]] don't require quoting.
The -n test operator returns true if the length of the string is non-zero (not empty). For example: [ -n "$string" ] is true if string is not empty. This is the opposite of -z which returns true if the string has zero length.
The -r option to read builtin prevents backslash from acting as an escape character. This is 'raw mode' which preserves backslashes literally in the input. This is typically recommended for reading input to avoid unexpected behavior with backslashes.
The -L file test operator returns true if the file exists and is a symbolic link. The -h operator is a synonym for -L. Both test for symbolic links, following the link only if the file test operator requires examining the target.
The -ot (older than) file test operator returns true if file1 is older (has an older modification timestamp) than file2, or if file2 exists and file1 does not. Usage: [ file1 -ot file2 ].
The -e option to echo builtin enables interpretation of backslash escape sequences. Recognized escapes include: \a (alert/bell), \b (backspace), \c (truncate output, suppress trailing newline), \e (escape), \f (form feed), \n (newline), \r (carriage return), \t (horizontal tab), \v (vertical tab), \ (backslash), ' (single quote), \nnn (octal byte), \xHH (hex byte).
The -n option to read builtin reads exactly NCHARS characters rather than a full line. After reading N characters, read returns immediately without waiting for a newline. For example: read -n 1 key reads a single keystroke.
When IFS is set to an empty string (IFS=), no word splitting occurs. This is commonly used with read to preserve leading and trailing whitespace: IFS= read -r line reads the entire line exactly as input.
The -eq operator performs integer (numeric) comparison, while = performs string comparison. Use -eq, -ne, -gt, -ge, -lt, -le for numbers, and =, !=, <, > for strings. For example: [ 5 -eq 05 ] is true (numeric), but [ 5 = 05 ] is false (string comparison).
The -z test operator returns true if the length of the string is zero (empty). For example: [ -z "$string" ] is true if string is empty. This is the opposite of -n which returns true if the string has non-zero length.
Both let and (( evaluate arithmetic expressions, but let is a builtin command while (( is a keyword. The let command syntax is: let 'expression', while (( syntax is: (( expression )). The let command returns 1 if the last expression is 0, while (( can be used directly in conditionals. For example: let x++ vs ((x++)). Both perform the same operation but with different syntax.
The test builtin returns exit status 0 when the test condition is true, and exit status 1 when the test condition is false. Exit status 2 is returned if there's an error in usage.
There is no -N option to the read builtin in standard bash. You may be confusing it with the -n option which reads exactly N characters. The read builtin options are: -a array, -d delim, -e, -i text, -n nchars, -N nchars (bash 5.1+), -p prompt, -r, -s, -t timeout, -u fd.
The read builtin returns exit status 1 when it reaches end-of-file without reading a complete line. It returns 0 on successful input. If the -t timeout option is used and timeout occurs, it also returns exit status 1.
When no variable names are provided to the read builtin, it stores the input in the REPLY variable by default. For example: read stores input in $REPLY.
Both = and == perform string equality comparison in bash. The = operator is POSIX standard, while == is a bash extension. Within double brackets [[ ]], == supports pattern matching with wildcards, but within single brackets [ ] they are functionally identical for string comparison.
The -s option to read builtin puts it into silent mode, where input is not echoed to the terminal. This is commonly used for password input: read -s -p 'Password: ' password. The input is still stored in the variable, just not displayed as it's typed.
The -i option to read builtin places the initial text value into the input buffer before reading begins. It requires the -e option (readline mode). For example: read -e -i 'default' var will pre-fill the input buffer with 'default' which the user can then edit.
The -S file test operator returns true if the file exists and is a socket. This is one of the special file type tests along with -f (regular file), -d (directory), -L (symbolic link), -b (block device), -c (character device), and -p (named pipe/FIFO).
Redirections > Basic Stream Redirection
40 questionsWhen 'set -o noclobber' or 'set -C' is enabled, using '>' will not overwrite an existing file. The shell will refuse the redirection and display an error. Use '>|' to force overwriting even with noclobber enabled.
Redirects both stdout and stderr to file, appending to the file if it exists. Equivalent to '>> file 2>&1'.
Redirects both standard output and standard error to the same file, appending to the file if it exists. This is equivalent to '>> file 2>&1'. Introduced in Bash 4.0.
Closes file descriptor n for output. For example, '1>&-' closes stdout.
Redirects output from file descriptor n to a file. For example, '3>' redirects output from file descriptor 3 to a file.
Redirects standard error (file descriptor 2) to a file, appending to the end of the file if it exists.
A here-string redirects a single string to standard input. It uses '<<<' followed by a string (which can undergo expansion). The string is expanded and supplied to the command's standard input, with a trailing newline automatically appended.
This is a here-document with leading tab removal. All leading tab characters are stripped from input lines before they are processed by the command.
The redirection fails and Bash displays an error message like 'cannot create file: Permission denied'. The command may still execute if it can run without that redirection.
No, redirections are processed by the shell before the command is executed. The redirections are set up and then the command runs with those redirections in place.
Yes, use '<<<$(command)' or '<<<"$(command)"'. The command substitution is expanded first, then the result is passed as a here-string.
Redirects standard error (file descriptor 2) to the same destination as standard output (file descriptor 1). This merges stderr into stdout.
/dev/tty refers to the controlling terminal of the current process. It's used to read from or write to the terminal regardless of I/O redirection.
A here-document is a special form of redirection that allows you to pass multiple lines of input to a command. It uses '<<' followed by a delimiter, then all lines until the delimiter appears on a line by itself become the command's input.
Redirects standard output (file descriptor 1) to the same destination as standard error (file descriptor 2). This merges stdout into stderr.
Redirects standard output (file descriptor 1) to a file, overwriting the file if it already exists. If the file does not exist, it creates it.
File descriptor 1 (standard output). When you use '>' or '>>' without a number, it defaults to redirecting stdout.
/dev/null is a special device file that discards all data written to it. It's commonly used to suppress output.
The '>&' operator duplicates an output file descriptor when the right side is a single digit. If the right side is not a single digit, it redirects to a file. '>file' always redirects to a file.
Redirects standard output (file descriptor 1) to a file, appending to the end of the file if it exists. If the file does not exist, it creates it.
Redirects input to file descriptor n from a file. For example, '3<' reads from a file and makes it available on file descriptor 3.
Use 'command > /dev/null 2>&1' or 'command &> /dev/null'. This discards all output from the command.
0 for stdin (standard input), 1 for stdout (standard output), and 2 for stderr (standard error).
In 'command > file 2>&1', stdout goes to file, then stderr also goes to file (both go to file). In 'command 2>&1 > file', stderr goes to wherever stdout was going (terminal), then stdout goes to file (stderr goes to terminal, stdout goes to file). Order matters in redirections.
File descriptor 0 (standard input). When you use '<' without a number, it defaults to redirecting stdin.
Duplicates input file descriptor n from the file descriptor specified by 'word'. If 'word' is not a number, it redirects input from that file. If 'word' is '-', file descriptor n is closed.
No, redirections themselves do not affect the exit status of a command. If a redirection fails (e.g., permission denied), the shell will report an error and may not execute the command, but this is separate from the command's exit status.
When the here-document delimiter is quoted (single or double quotes), parameter expansion, command substitution, and arithmetic expansion are disabled within the here-document body. The content is treated literally.
Use 'command >stdout_file 2>stderr_file'. This redirects stdout to stdout_file and stderr to stderr_file separately.
Use the '>|' operator instead of '>'. This overrides the noclobber option and forces the file to be overwritten.
Yes, trailing spaces after the delimiter are significant. The delimiter must appear exactly on a line by itself with no trailing spaces for the here-document to end properly.
Duplicates output file descriptor n by redirecting it to the file descriptor specified by 'word'. If 'word' is not a number, it redirects from that file. If 'word' is '-', file descriptor n is closed.
Redirects standard error (file descriptor 2) to a file, overwriting the file if it exists.
Yes, you can open multiple file descriptors for writing using 'exec n>file' where n is the file descriptor number. For example, 'exec 3>output.txt' opens file descriptor 3 for writing.
File descriptors 0, 1, and 2 are reserved for stdin, stdout, and stderr respectively. File descriptors 3 and above are available for custom use.
Redirects standard input (file descriptor 0) from a file, allowing the command to read from the file rather than the keyboard.
The command receives an empty input (just a newline). This is valid and the command will receive EOF immediately.
Redirects both standard output and standard error to the same file. This is equivalent to '> file 2>&1'. This operator is specific to Bash 4.0 and later.
Pipes both standard output and standard error to the next command. This is equivalent to '2>&1 |'. Introduced in Bash 4.0.
Using History Interactively > History Expansion Syntax
39 questionsThe :g modifier causes changes to be applied over the entire event line. This is used in conjunction with :s (e.g., :gs/old/new/) or :&. If used with :s, any delimiter can be used in place of /, and the final delimiter is optional if it is the last character of the event line. An a may be used as a synonym for g.
The :* word designator selects all of the words but the zeroth (word 0). 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.
History expansion is performed immediately after a complete line is read, before the shell breaks it into words. It is performed on each line individually without taking quoting on previous lines into account.
The set -H option enables ! style history substitution. This option is on by default when the shell is interactive. The synonym histexpand can also be used.
The :0 word designator selects the zeroth word, which is the command word (the command itself).
The x* word designator is an abbreviation for x-$ (from word x to the last word).
The history -p option performs history substitution on the following args and displays the result on standard output. Does not store the results in the history list. Each arg must be quoted to disable normal history expansion.
The :G modifier applies the following :s or :& modifier once to each word in the event line.
The :s/old/new/ modifier substitutes new for the first occurrence of old in the event line. Any character may be used as the delimiter in place of /. The final delimiter is optional if it is the last character of the event line. 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 &. If old is null, it is set to the last old substituted, or, if no previous history substitutions took place, the last string in a !?string[?] search. If new is null, each matching old is deleted.
!string refers to the most recent command preceding the current position in the history list that starts with string.
Use the +H option to the set builtin command (e.g., set +H). This disables history expansion for interactive shells. Non-interactive shells do not perform history expansion by default.
^string1^string2^ is quick substitution. It repeats the previous command, replacing string1 with string2. It is equivalent to !!:s^string1^string2^.
When histverify 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.
The :t modifier removes all leading filename components, leaving the tail (filename only).
!n refers to command line number n in the history list. !-n refers to the command at position current_position minus n (e.g., !-2 is two commands back).
Space, tab, newline, carriage return, =. If the extglob shell option is enabled, ( will also inhibit expansion.
The :% word designator selects the first word matched by the most recent ?string? search, if the search string begins with a character that is part of a word.
A : (colon) separates the event specification from the word designator. It may be omitted if the word designator begins with ^, $, *, -, or %.
The :x modifier quotes the substituted words as with :q, but breaks into words at blanks and newlines. The :q and :x modifiers are mutually exclusive; the last one supplied is used.
The x- word designator abbreviates x-$ like x*, but omits the last word. If x is missing, it defaults to 0.
The :e modifier removes all but the trailing suffix (returns only the file extension).
The default quick substitution character is ^ (controlled by the second character in histchars).
The histchars variable controls two or three characters for history expansion and tokenization. The first character is the history expansion character (default !). The second character is the quick substitution character (default ^). The optional third character is the history comment character (default #).
Words are numbered from the beginning of the line, with the first word being denoted by 0 (zero). The zeroth word is the command word for the shell.
The :$ word designator selects the last word. This is usually the last argument, but will expand to the zeroth word if there is only one word in the line.
The :q modifier quotes the substituted words, escaping further substitutions.
The x-y word designator selects a range of words from x through y. The abbreviation -y expands to 0-y.
The :r modifier removes a trailing suffix of the form .xxx, leaving the basename (filename without extension).
The default history expansion character is ! (exclamation mark). It signals the start of a history expansion.
Only backslash (\) and single quotes (') can quote the history expansion character. The history expansion character is also treated as quoted if it immediately precedes the closing double quote in a double-quoted string.
The :h modifier removes a trailing filename component, leaving only the head (directory path).
The history -s option stores the args in the history list as a single entry. The last command in the history list is removed before the args are added.
When histreedit is enabled and readline is being used, a failed history substitution will be reloaded into the readline editing buffer for correction.
Controlling the Prompt > Location Context
39 questionsPROMPT_COMMAND is a variable that, if set, contains a command to execute before printing each primary prompt (PS1).
In Bash, you can include command substitution in prompts using $(command) syntax or command backticks, which allows dynamic prompt content based on command output.
The \V escape sequence displays the release of Bash, including version + patch level (e.g., '5.1.16').
The $ escape sequence displays '#' if the effective UID is 0 (root user), otherwise it displays '$' for regular users.
The \D{format} escape sequence allows you to use a custom format string passed to strftime(3) to display the date and time. For example, \D{%Y-%m-%d} would display the date as '2025-01-21'.
The # escape sequence displays the command number of the current command. This increments with each command executed in the current shell session.
The \n escape sequence inserts a newline, causing the prompt to continue on the next line.
The \L escape sequence displays the basename of the shell's terminal device name, converting it to lowercase if it contains uppercase characters.
The \H escape sequence displays the full hostname, including all domain components. For example, if the hostname is 'server.example.com', \H displays 'server.example.com' in full.
The \e escape sequence represents the ASCII escape character (octal 033), used for beginning ANSI escape sequences for colors and other terminal effects.
PS4 is the prompt displayed before each command during execution tracing (when using 'set -x' for debugging). The default value is '+ '.
The ! escape sequence displays the history number of the current command.
The \r escape sequence inserts a carriage return, moving the cursor to the beginning of the current line.
The \t escape sequence displays the current time in 24-hour HH:MM:SS format. For example, it shows '14:30:45' for 2:30:45 PM.
[ and ] delimit a sequence of non-printing characters in the prompt. Bash does not count characters between these delimiters when calculating the prompt width, which is essential for proper line wrapping when using ANSI color codes.
The \nnn escape sequence displays the character whose ASCII code is the octal value nnn. For example, \101 displays 'A'.
The \T escape sequence displays the current time in 12-hour HH:MM:SS format.
If ANSI escape codes are not enclosed in [ and ], Bash will count them as printable characters when calculating prompt width, causing the prompt to display incorrectly and lines to wrap prematurely.
Non-printing characters (like ANSI escape codes for colors) must be enclosed in [ and ] to tell Bash not to count them when calculating the prompt width. Without these, the prompt may cause display issues with line wrapping.
\w displays the full current working directory path (with $HOME abbreviated as ~), while \W displays only the basename (the last component) of the current working directory. For /home/user/projects/bash, \w shows ~/projects/bash and \W shows 'bash'.
The \l escape sequence displays the basename of the shell's terminal device name (e.g., 'tty1', 'pts/0').
The @ escape sequence displays the current time in 12-hour AM/PM format. For example, it shows '10:30 AM' or '2:45 PM'.
The \w escape sequence displays the current working directory, with $HOME abbreviated with a tilde (~). For example, if you are in /home/user/documents, it shows ~/documents.
The \A escape sequence displays the current time in 24-hour HH:MM format (seconds are not shown). For example, '14:30' for 2:30 PM.
PS1 is the primary prompt string, which is displayed before each command is executed. It is the main prompt you see when using Bash interactively.
The \s escape sequence displays the name of the shell, which is typically 'bash' when running Bash.
The \d escape sequence displays the date in 'Weekday Month Date' format. For example, 'Tue May 26'.
The default value of PS1 is '\s-\v$ ', which displays the shell name, version, and a $ or # prompt character (e.g., 'bash-5.1$ ').
Use \ (double backslash) to include a literal backslash in the prompt string.
PS3 is the value of the prompt for the select command. The default value is '#? '.
PS2 is the secondary prompt string, which is displayed when Bash needs more input to complete a command. The default value is '> '.
The \h escape sequence displays the hostname up to the first '.'. For example, if the full hostname is 'server.example.com', \h displays only 'server'.
The \W escape sequence displays the basename of the current working directory, with $HOME abbreviated with a tilde (~). For example, if you are in /home/user/documents, it shows only 'documents', not the full path.
PROMPT_COMMAND is executed BEFORE printing each primary prompt (PS1). It runs before the prompt is displayed, not after.
Using History Interactively > Word Extraction
38 questions!:1- extracts from word 1 through the second-to-last word (excluding the last word), while !:1* extracts from word 1 through the last word (including the last word).
histexpand (or -H). When enabled with set -H or set -o histexpand, history expansion occurs. Disabled with set +H or set +o histexpand.
The :p modifier (print). It displays the expanded command without executing it.
The :s/old/new/ modifier. For example, !!:s/foo/bar/ replaces the first occurrence of 'foo' with 'bar' in the previous command.
!string:word_designator. For example, !grep:$ extracts the last word from the most recent command starting with 'grep'.
The :gs/old/new/ modifier where g means global substitution. The :& modifier repeats the last substitution performed.
Bash will produce an error or the expansion will fail. For example, if the previous command had only 3 words and you try !:5, bash will report a 'bad word specifier' error.
!n:word_designator where n is the history command number. For example, !42:$ extracts the last word from history command 42.
The :p modifier causes the history expansion to be printed but not executed. This is useful for previewing what the expansion will produce.
Chain them together in the order you want them applied. For example: !$:h:t applies :h first, then :t to the result.
A backslash () before the ! character. For example: echo !literal will print !literal
The entire previous command (all words including the command name and all arguments)
History expansion is performed in double quotes, but NOT in single quotes. Single quotes treat everything literally, including ! characters.
set +H or set +o histexpand. To re-enable, use set -H or set -o histexpand.
The :x modifier. It quotes the words as if they were separate, performing word splitting.
Bash uses 0-based numbering where word 0 is the command itself, word 1 is the first argument, word 2 is the second argument, etc.
All words from the nth word to the end (where n is a number). For example, !!:2* extracts from word 2 through the last word.
The entire command line typed so far in the current command (useful for repeating portions of the current command while still typing it)
The :e modifier (extension). For example, if !$ is file.txt, then !$:e extracts .txt
!?string?:word_designator. For example, !?file?:^ extracts the first argument from the most recent command containing 'file'.
All words from the nth word to the word before the last. For example, !!:1- extracts from word 1 through the second-to-last word.
The :t modifier (tail). For example, if !$ is /path/to/file.txt, then !$:t extracts file.txt
The :r modifier (root). For example, if !$ is file.txt, then !$:r extracts file
The :h modifier (head). For example, if !$ is /path/to/file.txt, then !$:h extracts /path/to
The :q modifier. It quotes the substituted words to protect them from further expansion.
The :& modifier. It repeats the last :s/old/new/ substitution. For example, after !!:s/foo/bar/, using !!:& applies the same substitution again.
Use the syntax !:n-m where n is the starting word number and m is the ending word number. For example: !!:2-4 extracts words 2 through 4.
The nth word from the previous command (0-indexed, where 0 is the command name)
!-2:n where -2 refers to two commands back and n is the word number. For example: !-2:1 extracts the first argument from the command two back.
Shell Scripts
38 questions- The conditional expression returns 2 if the regular expression is syntactically incorrect.
When invoked as sh for an interactive login shell, Bash reads /etc/profile first, then ~/.profile (in that order). It does not read .bash_profile or .bash_login.
The exit status of the last command in the pipeline, unless the pipefail option is enabled.
Bash first attempts to open the file in the current directory. If no file is found there, it searches the directories in PATH for the script.
A word consisting only of alphanumeric characters and underscores, and beginning with an alphabetic character or an underscore.
The following characters are metacharacters when unquoted: | & ; ( ) < > space tab newline
0 (zero). If no commands are executed in a script, Bash returns an exit status of 0.
! case coproc do done elif else esac fi for function if in select then until while { } time [[
None. A non-interactive shell invoked with the name sh does not attempt to read any startup files.
The value of PS3. The select command displays the PS3 prompt and reads a line from standard input.
lastpipe. When the lastpipe option is enabled using shopt and job control is not active, the last element of a pipeline may be run by the shell process.
The value of the last (rightmost) command to exit with a non-zero status, or zero if all commands exit successfully.
(list) executes in a subshell where variable assignments and builtin commands affecting the shell environment do not remain after completion. { list; } executes in the current shell environment.
It connects command1's standard error, in addition to its standard output, to command2's standard input. It is shorthand for 2>&1 |.
Using ;;& causes the shell to test the next pattern list in the statement and execute any associated list on a successful match, continuing the case statement execution as if the previous pattern list had not matched.
Using ;& in place of ;; causes execution to continue with the list associated with the next set of patterns (fall-through), whereas ;; terminates pattern matching after the first match.
ENV. In POSIX 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.
Bash's exit status is the exit status of the last command executed in the script.
BASH_ENV. Bash looks for the BASH_ENV variable in the environment, expands its value, and uses it as the name of a file to read and execute. The behavior is equivalent to: if [ -n "$BASH_ENV" ]; then . "$BASH_ENV"; fi
Bash attempts to determine when it is being run with its standard input connected to a network connection. If determined, it reads and executes commands from /etc/bash.bashrc and ~/.bashrc if they exist and are readable, unless invoked as sh.
BASH_REMATCH. The element with index 0 contains the portion matching the entire regular expression, and subsequent indices contain parenthesized subexpressions.
The -c option. When -c is present, commands are read from the first non-option argument command_string.
No startup files are read, shell functions are not inherited from the environment, the SHELLOPTS, BASHOPTS, CDPATH, and GLOBIGNORE variables are ignored if they appear in the environment, and the effective user ID is set to the real user ID.
Tilde expansion, parameter and variable expansion, arithmetic expansion, command substitution, process substitution, and quote removal. They do NOT undergo word splitting and pathname expansion.
First /etc/profile, then the first existing and readable file of ~/.bash_profile, ~/.bash_login, or ~/.profile (in that order).
&& and || have equal precedence, followed by ; and &, which have equal precedence.
ENV. When invoked as an interactive shell with the name sh, Bash looks for the ENV variable, expands its value if defined, and uses it as the name of a file to read and execute.
0 (zero). The shell does not wait for the command to finish and returns status 0.
Using History Interactively > History Storage and Management
38 questionsIf set, the history list is appended to the history file rather than overwriting it when the shell exits
fc stands for 'fix command' - it lists, edits, and re-executes commands from the history list
history displays the history list with line numbers, while 'fc -l' lists commands from the history list (fc -l also accepts a range of history numbers)
Bash stores each line of the multi-line command as a separate history entry with the same history number
!^# (where ! initiates history expansion, ^ is the quick substitution character, and # is the comment character)
HISTSIZE (when HISTFILE is unset, the shell will not save history to a file, but HISTSIZE still limits the in-memory history)
history -w overwrites the history file with the current history list, while history -a appends new history lines to the history file
Modifying Shell Behavior > History Management
37 questionshistchars (the first character is the history comment character, default #)
There is no hard maximum in Bash; it's limited only by available memory
A colon-separated list of patterns to decide which commands should be saved in the history list (e.g., HISTIGNORE='ls:pwd:exit')
By default, when an interactive shell exits, unless shopt -s histappend is set
ignoredups prevents saving a line that matches the immediate previous line; erasedups removes all previous lines matching the current line before it is saved
No, history expansion is performed only in interactive shells by default
If set, the history list is appended to the history file rather than overwriting it when the shell exits
If set, Bash attempts to save all lines of a multiple-line command in the same history entry
It causes the history list to be saved with timestamps; the format string is passed to strftime(3). If unset, commands are not timestamped.
PROMPT_COMMAND is executed before each primary prompt; it's commonly used to execute 'history -a' to save commands immediately rather than on shell exit
Yes, by separating them with colons (e.g., HISTCONTROL=ignoredups:erasedups)
If set, and cmdhist is enabled, multi-line commands are saved to the history with embedded newlines rather than using semicolons
Interactive Shells > Error and Exit Behavior
37 questionsSIGQUIT is ignored by default in interactive shells. This prevents the core dump behavior typically associated with SIGQUIT when Ctrl+\ is pressed.
When set -u is enabled in an interactive shell, accessing an unset variable displays an error message but does NOT exit the shell. This differs from non-interactive shells where set -u with set -e would cause exit.
SIGWINCH (window size change) is caught by interactive shells and causes bash to update its understanding of the terminal dimensions. The shell does not exit; it continues normally.
The interrupted command returns exit status 130 (128 + 2, where 2 is SIGINT's signal number). The shell itself does not exit and displays a new prompt.
Both cause shell exit and execute the EXIT trap. However, 'exit' can specify an exit status, while EOF always exits with the status of the last command (or 0 if set -e is on). With IGNOREEOF set, EOF characters are ignored until the threshold is reached.
Jobs that have been disowned are not affected by SIGHUP when the shell exits. They continue running regardless of the huponexit setting. Disowned jobs are removed from the job table.
Login shells source /etc/profile and ~/.bash_profile or ~/.profile on exit if they exist. Non-login interactive shells only execute the EXIT trap. Both types behave similarly regarding signal handling.
By default with huponexit disabled, jobs continue running after an interactive shell exits normally. They become orphaned processes adopted by init (PID 1) or the system's init system.
Yes. The EXIT trap executes when the shell exits via EOF (Ctrl+D), just as it would with the 'exit' command or SIGHUP.
Yes. Interactive bash shells ignore SIGTERM by default so that shell sessions are not accidentally terminated by background job cleanup or other processes sending SIGTERM.
- The exit builtin's argument becomes the shell's exit status. If no argument is given, the exit status is that of the last executed command.
No. An interactive shell does not exit when a command fails. The shell continues running and displays the next prompt. This behavior is different from non-interactive shells with 'set -e' enabled.
SIGTTIN (background read) and SIGTTOU (background write) are ignored by interactive shells when job control is enabled. This prevents the shell from being stopped when attempting to read from or write to the terminal while in the background.
The huponexit option (shopt -s huponexit) controls whether bash sends SIGHUP to all jobs when an interactive login shell exits. The default is disabled (off), meaning jobs are not automatically killed on shell exit.
By default, bash sends SIGHUP to all jobs when the shell itself receives SIGHUP. Background jobs that do not trap or ignore SIGHUP will terminate.
The ignoreeof option prevents EOF (Ctrl+D) from exiting the shell. You must use 'exit' or 'logout' to terminate the shell. This is equivalent to setting IGNOREEOF=10.
In interactive shells, set -e does NOT cause the shell to exit when commands within command substitution fail. Interactive mode fundamentally ignores errexit for most command failures.
The default value is unset (0), meaning EOF (typically Ctrl+D) will immediately exit the shell. When set to a number N, the shell must receive N consecutive EOF characters before exiting.
By default, SIGUSR1 and SIGUSR2 are ignored in interactive bash shells unless a trap is explicitly set for them. The shell continues running.
If there are stopped jobs when you attempt to exit an interactive shell, bash displays a warning message and does NOT exit. You must either 'bg' the jobs to background them or 'kill' them before exiting.
The logout command exits a login shell. If used in a non-login shell, it displays an error message. The EXIT trap executes before the shell terminates.
In interactive shells, set -e has limited effect. The shell will NOT exit if a command fails, except when reading EOF (end-of-file) on input. The errexit option is primarily effective in non-interactive shells.
In an interactive shell with set -e enabled, EOF on input causes the shell to exit. The exit status is 0 unless a command previously failed, in which case it's the status of that failed command.
No. SIGKILL (signal 9) cannot be caught or ignored, so EXIT traps do NOT execute when bash receives SIGKILL. The shell terminates immediately.
A command terminated by SIGTERM returns exit status 143 (128 + 15). In an interactive shell, this does not cause the shell itself to exit.
In interactive shells, the shell does not exit on pipeline failures. The exit status of the pipeline is the exit status of the last command in the pipeline, unless pipefail is set.
In interactive shells, set -e is largely ineffective. Commands failing within compound structures like if/while do not cause shell exit. The shell always continues to the next prompt.
When an interactive shell receives SIGHUP, it sends SIGHUP to all job control subprocesses before executing the EXIT trap and exiting.
The shell exits after receiving 10 consecutive EOF characters. Each Ctrl+D before the 10th is ignored and the shell continues running with a new prompt.
SIGINT interrupts the current command but does NOT terminate the shell itself. The interactive shell catches SIGINT, displays a new prompt, and continues running.
The pipeline returns the exit status of the rightmost command that failed. The interactive shell does NOT exit despite the failure; it displays the new prompt.
When an interactive shell receives SIGHUP, it exits. This happens when the terminal session ends or the controlling terminal is closed. The shell sends SIGHUP to all jobs before exiting.
The 'logout' builtin only works in login shells and will fail in subshells or non-login interactive shells. The 'exit' builtin works in both login and non-login shells. Both trigger the EXIT trap before termination.
With failglob enabled, if no matches are found during filename expansion, an error message is displayed and the command is not executed. However, the interactive shell does NOT exit; it displays a new prompt.
The ERR trap can execute in interactive shells when a command fails, but only if the trap is set. However, unlike in scripts with set -e, the shell continues running after the ERR trap completes.
Yes. When an interactive shell receives SIGHUP, it executes the EXIT trap (if set) before terminating. The EXIT trap runs before the shell sends SIGHUP to its jobs.
Ctrl+Z sends SIGTSTP (signal 20). In an interactive shell, this typically stops the foreground command (not the shell itself) and returns control to bash, which displays a job control message and a new prompt.
Shell Variables > Special Parameters
36 questionsAt shell initialization, $_ expands to the absolute pathname of the shell or script being executed.
After executing a command, $_ expands to the last argument of that command.
The current option flags as specified upon invocation, by the set builtin command, or those set by the shell itself (such as the -i flag).
Assignment to special parameters is not allowed and will result in an error.
After command substitution $(command), $_ contains the output of that command, not the last argument of the command itself.
The exit status of the most recently executed foreground pipeline. By convention, 0 indicates success and non-zero indicates failure.
The default IFS (Internal Field Separator) value consists of space, tab, and newline characters (
During parameter expansion and assignment, $_ expands to the name of the variable being assigned.
After a function call, $? contains the return status of the last command executed within the function, or the value returned by the function's return statement.
For an interactive login shell, $- typically contains 'himBH' where h=hashall, i=interactive, m=monitor, B=braceexpand, H=histexpand.
In a non-interactive shell before any command is executed, $_ is unset or empty depending on how the shell was invoked.
Exit status values range from 0 to 255, where 0 indicates success. Exit statuses above 255 are automatically modulo 256.
After a conditional test ([[ ]] or [ ]), $? contains the exit status of the test (0 for true/condition met, 1 for false/condition not met, 2 for syntax errors).
After a mail check command, $_ expands to the name of the mail file currently being checked.
If no background command has been executed, $! expands to zero or an empty string depending on context.
Without pipefail, $? contains the exit status of the last command in the pipeline, not the exit status of all commands.
When quoted, "$*" expands to a single word containing all positional parameters, separated by the first character of IFS (Internal Field Separator).
Positional parameters beyond $9 must be accessed using braces: ${10}, ${11}, ${12}, etc. Using $10 without braces is interpreted as $1 followed by the literal character '0'.
In a command substitution subshell, $$ returns the PID of the parent shell, not the subshell (because command substitution doesn't fork a new process in the traditional sense).
The process ID (PID) of the current shell. In a subshell, it expands to the process ID of the current shell, not the parent shell.
When IFS=':', "$*" expands all positional parameters into a single word separated by colons instead of spaces.
The command 'set --' with no arguments following clears all existing positional parameters. If arguments follow '--', they become the new positional parameters.
The name of the shell or shell script. This is set at shell initialization.
Bash supports positional parameters up to at least ${99999}, with the practical limit determined by system resources (maximum argument length and stack size).
No, $0 cannot be directly assigned or modified within a running script. It can only be set when invoking the script or using exec.
When running a script, $0 is the script name/path. When invoked with bash -c 'commands', $0 is set to the first argument after commands, or 'bash' if no argument is provided.
When quoted, "$@" expands to each positional parameter as a separate word, preserving arguments with spaces exactly as they were passed. This is functionally equivalent to "$1" "$2" "$3" ...
The shift command discards positional parameter $1 and renumbers the remaining parameters ($2 becomes $1, $3 becomes $2, etc.). $# decreases by 1.
If there are no positional parameters ($# is 0), shift returns a non-zero exit status and does nothing.
When unquoted, $* expands to all positional parameters, starting from $1.
When there are no positional parameters, "$@" expands to nothing (no words at all).
The process ID (PID) of the most recently executed background (asynchronous) command.
When unquoted, $@ expands to all positional parameters, starting from $1.
When IFS is null, "$*" expands to all positional parameters concatenated without any separators.
Command Line Editing > Text Manipulation
36 questionsCtrl+R (Control-R) starts an incremental backward search through the command history.
The readline 'overwrite-mode' command (bound to Insert by default) toggles between overwrite mode and insert mode. In overwrite mode, typed characters replace existing characters instead of inserting.
Press the ESC key to switch from insert mode to command mode in vi editing mode.
Ctrl+U (Control-U) kills (cuts) text from the cursor to the beginning of the line and stores it in the kill-ring.
Alt+T (or ESC T) transposes the word before the cursor with the word after the cursor, moving the cursor forward one word.
The 'convert-meta' variable (default is 'on') controls whether readline converts characters with the eighth bit set to ASCII key sequences by stripping the eighth bit and prefixing with ESC.
Alt+L (or ESC L) converts the current word to lowercase, moving to the end of the word.
Alt+C (or ESC C) capitalizes the current word (makes the first character uppercase and the rest lowercase), moving to the end of the word.
Ctrl+G (Control-G) aborts the current incremental search and returns to the original command line.
Alt+D (or ESC D on some terminals) kills from the cursor to the end of the current word.
Alt+Backspace (or ESC Backspace on some terminals) kills the word before the cursor, using whitespace as the word boundary.
The 'completion-ignore-case' variable (default is 'off') controls whether case is ignored during completion. Set to 'on' to make completion case-insensitive.
Ctrl+T (Control-T) transposes the character before the cursor with the character at the cursor, moving the cursor forward one character.
Ctrl+Q (Control-Q) or Ctrl+V (Control-V) quotes the next character typed, allowing insertion of literal control characters.
Ctrl+H (Control-H) or Backspace deletes the character before the cursor.
The 'completer-word-break-characters' variable defines the set of characters that separate words for word operations like forward-word, backward-word, kill-word, etc. The default includes space, tab, newline, and certain punctuation characters.
Ctrl+K (Control-K) kills (cuts) text from the cursor to the end of the line and stores it in the kill-ring.
There is no default redo binding in Bash readline. The 'redo' command can be bound to a custom key if needed.
The 'enable-meta-key' variable controls whether readline will attempt to enable the meta flag. The default is 'on'.
The 'echo-control-characters' variable (default is 'on') controls whether control characters are echoed as '^A', '^B', etc. in emacs mode.
Ctrl+_ (Control-Underscore) or Ctrl+X Ctrl+U can be used for incremental undo to revert changes in the command line.
Run 'set -o vi' to enable vi editing mode, or add it to ~/.bashrc to make it permanent.
The 'bell-style' variable controls what happens when readline wants to ring the terminal bell. Valid values are 'none', 'visible', 'audible', or 'visible-if-not-terminal'. The default is 'audible'.
Alt+U (or ESC U) converts the current word to uppercase, moving to the end of the word.
Press Tab twice (double-tab) to display all possible completions for the current word. This is controlled by the 'show-all-if-ambiguous' readline variable.
After yanking with Ctrl+Y, press Alt+Y (or ESC Y) to cycle through previous items in the kill-ring.
Ctrl+Y (Control-Y) yanks (pastes) back the last killed text from the kill-ring.
Emacs mode is the default editing mode in Bash. You can switch to vi mode using 'set -o vi'.
Ctrl+L (Control-L) clears the screen and redisplays the current line at the top.
Ctrl+D (Control-D) deletes the character under the cursor. If the line is empty, it exits the shell.
Shell Syntax > Command Structures
36 questionsWhen a command is terminated by signal n, bash returns exit status 128+n. For example, SIGKILL (signal 9) results in exit status 137, and SIGTERM (signal 15) results in exit status 143.
The '&&' (AND) operator executes command2 only if command1 returns an exit status of zero (success). This is called an AND list.
Brace expansion generates arbitrary strings. It takes the form of an optional preamble, followed by comma-separated strings or a sequence expression {x..y[..incr]} between braces, followed by an optional postscript. Example: a{d,c,b}e expands to 'ade ace abe'.
Brace expansion is performed before any other expansions. Any characters special to other expansions are preserved in the result. It is strictly textual and bash does not apply syntactic interpretation to the context.
A simple command is a sequence of words separated by blanks (spaces/tabs), terminated by one of the shell's control operators. The first word typically specifies the command to execute, and the remaining words are arguments to that command.
Trailing newlines are deleted from the output of command substitution. Embedded newlines are not deleted but may be removed during word splitting. The command substitution $(cat file) can be replaced by the equivalent but faster $(< file).
The standard modern form is $(command). The deprecated form uses backticks: command. Both execute the command in a subshell environment and replace the substitution with the command's standard output, with trailing newlines deleted.
If a word begins with an unquoted tilde (), all characters up to the first unquoted slash (or all characters if no slash) are considered a tilde-prefix. If the tilde-prefix is null (just ''), it's replaced with the value of the HOME shell variable (or the executing user's home directory if HOME is unset).
When pipefail is enabled using 'set -o pipefail', the pipeline's return status is the value of the last (rightmost) command to exit with a non-zero status, or zero if all commands exit successfully.
The 'lastpipe' option, when enabled via 'shopt -s lastpipe', causes the last element of a pipeline to be run by the shell process (not a subshell) when job control is not active. This allows variable assignments in the last pipeline command to persist in the current shell.
Arithmetic expansion uses the format $(( expression )). The expression undergoes the same expansions as if within double quotes, but double quote characters in the expression are not treated specially and are removed. All tokens undergo parameter and variable expansion, command substitution, and quote removal.
A list is a sequence of one or more pipelines separated by one of the operators ';', '&', '&&', or '||', and optionally terminated by ';', '&', or a newline.
PIPESTATUS is an array variable that holds the exit status of each command in the most recently executed foreground pipeline. ${PIPESTATUS[0]} is the first command's status, ${PIPESTATUS[1]} is the second, etc.
The operators '&&' and '||' have equal precedence (higher), followed by ';' and '&' which have equal precedence (lower). All AND and OR lists are executed with left associativity.
The '|&' operator connects command1's standard error (in addition to standard output) to command2's standard input through the pipe. It is shorthand for '2>&1 |'. This implicit redirection of stderr to stdout occurs after any redirections specified by command1.
The reserved word 'time' causes timing statistics to be printed for the pipeline once it finishes. Statistics include elapsed (wall-clock) time and user and system time consumed by command execution. The -p option changes output format to POSIX standard. The TIMEFORMAT variable may be set to customize the display format.
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.
The tilde-prefix '+' expands to the value of the shell variable PWD. The tilde-prefix '-' expands to the value of the shell variable OLDPWD (if set).
Bash provides two ways: (list) - parentheses create a subshell and execute commands in that subshell environment; { list; } - curly braces execute commands in the current shell environment (no subshell).
When a command is terminated by '&', the shell executes it asynchronously in a subshell (background). The shell does not wait for the command to finish, and the return status is 0 (true). When job control is not active, the standard input for asynchronous commands is redirected from /dev/null in the absence of explicit redirections.
Process substitution takes the form <(list) or >(list). The process list is run asynchronously, and its input or output appears as a filename passed as an argument to the current command. No space may appear between the '<' or '>' and the left parenthesis, otherwise it's interpreted as redirection.
Brace expansion sequences support an optional increment: {x..y..incr} where x and y are integers or letters, and incr is an integer. When x or y begins with '0', the shell zero-pads to force equal width. Default increment is 1 or -1 as appropriate.
Yes, a sequence of one or more newlines may appear in a list to delimit commands, equivalent to a semicolon.
Enclosing characters in double quotes (") preserves the literal value of all characters within quotes, except for '$', '', '\', and (when history expansion is enabled) '!'. The characters '$' and '' retain their special meaning within double quotes. The backslash retains its special meaning only when followed by one of: '$', '`', '"', '', or newline.
By default (when pipefail is not enabled), the exit status of a pipeline is the exit status of the last command in the pipeline.
A pipeline is a sequence of one or more commands separated by the control operators '|' (pipe) or '|&' (pipe and stderr). The format is: [time [-p]] [!] command1 [ | or |& command2 ] …
When the reserved word '!' precedes a pipeline, the exit status is the logical negation of the pipeline's exit status as described above. The shell waits for all commands in the pipeline to terminate before returning this negated value.
The '||' (OR) operator executes command2 only if command1 returns a non-zero exit status (failure). This is called an OR list.
Using 'time' as a reserved word permits timing of shell builtins, shell functions, and pipelines. An external time command cannot easily time these constructs.
Bash reserved words include: !, case, do, done, elif, else, esac, fi, for, function, if, in, select, then, until, while, {, }, [[, ]], and time. Reserved words have special meaning and are used to begin/end compound commands.
Curly braces {} are reserved words, so they must be separated from the list by blanks or other shell metacharacters. Parentheses () are operators and are recognized as separate tokens even without whitespace separation.
With the backquote form, backslash retains its literal meaning except when followed by '$', '`', or ''. With $(command) form, all characters between parentheses make up the command; none are treated specially. The $(command) form is preferred and can nest without escaping.
Yes, the semicolon (or newline) following the list in curly braces {} is required. For example: '{ command1; command2; }' - note the final semicolon before the closing brace.
ANSI-C quoting uses the syntax $'string' and treats string as a special kind of single quotes. It expands string with backslash-escaped characters replaced according to ANSI-C standards (e.g., \n for newline, \t for tab, ' for single quote).
Yes, each command in a multi-command pipeline (where pipes are created) is executed in its own subshell, which is a separate process. Exception: if the 'lastpipe' option is enabled using 'shopt' and job control is not active, the last element may run in the current shell process.
Bourne Shell Builtins > Directory and Path Management
35 questionsThe -P option prints the physical directory path without symbolic links (resolves all symlinks), while -L prints the logical path which may include symbolic links.
The -e option causes cd to return a failure status if the current directory cannot be determined or cannot be reached after successfully changing the directory.
DIRSTACK is an array variable that holds the contents of the directory stack. It is set by pushd and popd, and cannot be set directly.
The dirs -l option produces a longer listing with the full pathnames instead of using ~ for the home directory.
The hash -p option uses pathname as the full path of command, adding it to the hash table.
By default, dirs uses tilde (~) to represent the home directory. The -l option displays the full pathname instead.
By default, dirs displays the contents of the directory stack with one entry per line.
By default (with -L behavior), cd follows the symbolic link. With -P, cd uses the physical directory structure and does not follow symlinks.
The hash -l option displays the contents of the hash table in a format that can be reused as input.
The pushd +n command rotates the stack so that the nth directory (counting from zero starting at the left) is at the top.
When CDPATH is set, cd searches each colon-separated directory in CDPATH for the target directory before using the path as-is.
The hash -r option clears the hash table, forgetting all remembered command locations.
When cd is called without arguments, it changes to the home directory specified by the HOME environment variable.
There is no fixed limit on the directory stack size in bash. It can grow as needed limited only by available memory.
The OLDPWD variable stores the previous working directory, which is set by the cd command.
The hash -t option prints the remembered pathname for each specified command, or all remembered commands if none specified.
The -n option suppresses the normal directory change when adding directories to the stack, so the current working directory is not changed.
cd sets the PWD environment variable to the new current working directory and sets OLDPWD to the previous working directory.
The dirs -c option clears the directory stack by deleting all of its entries.
The -P option uses the physical directory structure without following symbolic links, while -L (the default) uses the logical directory structure and follows symbolic links.
Using cd does not modify the directory stack. The directory stack is only modified by pushd and popd commands.
The command 'cd -' changes to the previous working directory (the value of OLDPWD).
The popd +n command removes the nth directory (counting from zero starting at the left) from the stack.
The popd -n command (where n is a number) removes the nth directory (counting from zero from the right) from the stack.
By default, pwd prints the current working directory with -L semantics, which may include symbolic links in the path.
The -n flag for popd suppresses the normal directory change when removing entries from the directory stack.
The hash command remembers the full pathnames of commands, storing them in a hash table for faster lookup.
The pushd -n command (where n is a number) rotates the stack so that the nth directory (counting from zero from the right) is at the top.
When popd is called without arguments, it removes the top directory from the stack and changes to the new top directory.
The dirs -p option outputs the directory stack with one entry per line.
cd returns a non-zero exit status if the directory doesn't exist or if the user doesn't have permission to access it.
The hash -d option forgets the remembered location of each specified command (or all commands if none specified).
pwd continues to print the path stored in PWD, but the -P option may fail if the directory no longer exists in the filesystem.
When pushd is called with no arguments, it exchanges the top two directories on the stack and makes the new top directory the current working directory.
The dirs -v option outputs the directory stack with one entry per line, prefixing each entry with its index in the stack.
Interactive Shells > Signal Handling
35 questionsBackground processes which attempt to read from the terminal are sent a SIGTTIN signal by the kernel's terminal driver, which, unless caught, suspends the process.
Background processes which attempt to write to the terminal when 'stty tostop' is in effect are sent a SIGTTOU signal by the kernel's terminal driver, which, unless caught, suspends the process.
When bash is running without job control enabled and receives SIGINT while waiting for a foreground command, it waits until that foreground command terminates and then decides: 1) If the command terminates due to the SIGINT, bash acts on the SIGINT (e.g., by running a SIGINT trap or exiting itself); 2) If the command does not terminate due to SIGINT (the program handled it), bash does not treat SIGINT as a fatal signal, but will still run any trap set on SIGINT.
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.
Trapped signals that are not being ignored are reset to their original values in a subshell or subshell environment when one is created.
The disown command with the -h option marks each jobspec so that SIGHUP is not sent to the job if the shell receives a SIGHUP. The job is not removed from the table.
If job control is in effect, bash ignores SIGTTIN, SIGTTOU, and SIGTSTP.
Any trap on SIGCHLD is executed for each child that exits. The shell learns immediately whenever a job changes state, but normally waits until it is about to print a prompt before reporting changes in job status unless the -b option is enabled.
When job control is not in effect, asynchronous commands ignore SIGINT and SIGQUIT in addition to the signal handlers inherited by the shell from its parent.
Without options, disown removes each jobspec from the table of active jobs. If jobspec is not present and neither -a nor -r is supplied, the current job is used.
No, the ERR trap is not inherited by shell functions, command substitutions, and commands executed in a subshell environment by default. The -E option (errtrace) must be set for the ERR trap to be inherited in these cases.
If arg is absent (and there is a single sigspec) or -, each specified signal is reset to its original disposition (the value it had upon entrance to the shell).
If a sigspec is DEBUG, the command arg is executed before every simple command, for command, case command, select command, every arithmetic for command, and before the first command executes in a shell function.
The RETURN trap command is executed each time a shell function or a script executed with the . or source builtins finishes executing. Any command associated with the RETURN trap is executed before execution resumes after the function or script.
If arg is the null string, the signal specified by each sigspec is ignored by the shell and by the commands it invokes.
Without job control, the shell and foreground command are in the same process group as the terminal, so keyboard-generated signals like SIGINT (usually ^C) are sent to both. Bash waits for the command to terminate, then decides based on whether the command terminated due to SIGINT or handled it itself.
The checkjobs shell option is disabled by default. When set, bash lists the status of any stopped and running jobs before exiting an interactive shell. If any jobs are running, this causes the exit to be deferred until a second exit is attempted without an intervening command.
If the huponexit shell option has been set with shopt, bash sends a SIGHUP to all jobs when an interactive login shell exits.
No. The huponexit shell option must be set for bash to send SIGHUP to all jobs when an interactive login shell exits. Additionally, the shell always resends SIGHUP to jobs when it receives an external SIGHUP, regardless of huponexit.
No, the DEBUG and RETURN traps are not inherited by shell functions, command substitutions, and commands executed in a subshell environment by default. The -T option (functrace) must be set for these traps to be inherited.
If bash is waiting for a command to complete and receives a signal for which a trap has been set, the trap will not be executed until the command completes.
When bash is waiting for an asynchronous command via the 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.
Signals ignored upon entry to the shell cannot be trapped or reset.
When bash is waiting via the wait builtin and receives a signal for which a trap has been set, the wait builtin returns immediately with an exit status greater than 128, then the trap is executed.
SIGINT is caught and handled, which makes the wait builtin interruptible. The shell catches and handles SIGINT but does not ignore it.
Commands run as a result of command substitution ignore the keyboard-generated job control signals SIGTTIN, SIGTTOU, and SIGTSTP.
When bash is interactive, in the absence of any traps, it ignores SIGTERM and SIGQUIT. SIGTERM is ignored so that 'kill 0' does not kill an interactive shell.
The return value of a simple command is its exit status, or 128+n if the command is terminated by signal n.
If an attempt to exit bash is made while jobs are stopped, the shell prints a warning message. If a second attempt to exit is made without an intervening command, the shell does not print another warning, and any stopped jobs are terminated.
If a sigspec is EXIT (0), the command arg is executed on exit from the shell.
Typing the suspend character (typically ^Z, Control-Z) while a process is running causes that process to be stopped and returns control to bash. The ^Z takes effect immediately and has the additional side effect of causing pending output and typeahead to be discarded.
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 or marked to not receive SIGHUP using 'disown -h'.
The -b option causes bash to report job status changes immediately instead of waiting until it is about to print a prompt. This is effective only when job control is enabled.
Programmable Completion > Result Filtering and Processing
35 questionsThe -D option in compopt indicates that other supplied options should apply to the 'default' command completion - that is, completion attempted on a command for which no completion has previously been defined.
Yes. If the nocasematch shell option is enabled, the -X filterpat pattern match is performed without regard to the case of alphabetic characters.
The -o default option uses readline's default filename completion if the compspec generates no matches. This is different from bashdefault as it uses readline's completion rather than bash's default completions.
An exit status of 124 from a shell function causes completion to be retried. The function must also change the compspec associated with the command. Programmable completion then restarts from the beginning with an attempt to find a new compspec.
No filtering of the generated completions against the word being completed is performed for -F functions or -C commands. The function or command has complete freedom in generating the matches.
A -F function receives three arguments: $1 is the name of the command whose arguments are being completed, $2 is the word being completed, and $3 is the word preceding the word being completed on the current command line.
The -X filter is applied AFTER all possible completions are generated (including -F functions, -C commands, -G patterns, -W wordlist) but BEFORE -P prefix and -S suffix are added. This is the final filtering step before prefix/suffix modification.
Yes. If no name arguments are supplied to compopt, it modifies completion options for the currently-executing completion. This allows dynamic modification of completion behavior from within a completion function.
The -o plusdirs option causes directory name completion to be attempted AFTER any matches defined by the compspec are generated, and any directory matches are added to the results of the other actions (in addition to, not replacing them).
The -X filterpat option applies a pattern (used for pathname expansion) to filter completions. Each completion matching filterpat is removed from the list of possible completions. The filter is applied after all possible completions have been generated by preceding options and arguments.
Any function specified with -F is invoked FIRST. Next, any command specified with -C is invoked. The -F function runs before -C commands in the completion processing order.
The FIGNORE shell variable is used to filter matches when using the -f (filename) or -d (directory) options. FIGNORE is a colon-separated list of suffixes to ignore when performing filename completion.
The -E option in compopt indicates that other supplied options should apply to 'empty' command completion - that is, completion attempted on a blank line.
The -W wordlist string is first split using characters in IFS as delimiters (shell quoting is honored). Each word is then expanded using brace expansion, tilde expansion, parameter/variable expansion, command substitution, and arithmetic expansion. Results are split using Word Splitting rules, then prefix-matched against the word being completed.
The -P prefix and -S suffix are applied FINALLY, after all completion generation and filtering (including -X filterpat) is complete. They are added to each member of the completion list just before returning results to readline.
The -o filenames option tells readline that the compspec generates filenames, so it can perform any filename-specific processing such as adding a slash to directory names, quoting special characters, or suppressing trailing spaces. This is intended to be used with shell functions.
When a compspec indicates that directory name completion is desired, programmable completion forces readline to append a slash to completed names which are symbolic links to directories, subject to the value of mark-directories, regardless of the setting of mark-symlinked-directories.
In the -X filterpat pattern, a & is replaced with the text of the word being completed. A literal & can be escaped with a backslash; the backslash is removed before attempting a match.
The -I option in compopt indicates that other supplied options should apply to completion on the initial non-assignment word on the line, or after a command delimiter such as ; or |, which is usually command name completion.
The -o nosort option tells readline not to sort the list of possible completions alphabetically. Without this option, completions are sorted by default.
The -o noquote option tells readline not to quote the completed words if they are filenames. Quoting filenames is the default behavior.
If multiple options are supplied, the -D option takes precedence over -E, and both take precedence over -I. If any of -D, -E, or -I are supplied, any other name arguments are ignored.
A command specified with -C is invoked in an environment equivalent to command substitution. It should print a list of completions, one per line, to standard output. Backslash may be used to escape a newline if necessary.
By default, if a compspec is found, whatever it generates is returned as the full set of possible completions. The default bash completions are NOT attempted, and the readline default of filename completion is disabled unless -o bashdefault or -o default is specified.
Yes. The compopt command accepts both -o option (to set an option) and +o option (to unset/remove an option) syntax, similar to other bash builtins like set.
A leading ! in filterpat negates the pattern. In this case, any completion NOT matching filterpat is removed from the list instead of completions that do match.
When -F or -C handlers are invoked, COMP_LINE, COMP_POINT, COMP_KEY, and COMP_TYPE variables are assigned values. For shell functions (-F only), COMP_WORDS and COMP_CWORD variables are also set.
The -o bashdefault option performs the rest of the default bash completions if the compspec generates no matches. This falls back to standard bash completion behavior when custom completion produces nothing.
The -o dirnames option performs directory name completion if the compspec generates no matches. This is a fallback behavior only, unlike plusdirs which always adds directory matches.
A completion function specified with -F must put the possible completions in the COMPREPLY array variable, with one completion per array element.
The -o nospace option tells readline not to append a space (which is the default behavior) to words completed at the end of the line.
FIGNORE is a colon-separated list of suffixes. A filename whose suffix matches one of the entries in FIGNORE is excluded from the list of matched filenames. A sample value is '.o:~'.
No. The words generated by the -G pathname expansion pattern need NOT match the word being completed. They are generated unconditionally, unlike some other completion methods that apply prefix matching.
No. The GLOBIGNORE shell variable is NOT used to filter matches generated by -G pathname expansion patterns. However, the FIGNORE variable is used instead for -G option matches.
-o dirnames attempts directory completion only if the compspec generates NO matches (fallback). -o plusdirs ALWAYS attempts directory completion and adds matches to results from other actions (in addition).
Executing Commands > Command Location and Invocation
34 questions'command' suppresses shell function lookup. If you have a function named 'cd', running 'cd' calls your function, but 'command cd' bypasses the function and calls the builtin directly. This applies to all commands, not just builtins.
In POSIX mode, 'command -v' is the POSIX-standard way to get command information. Bash's 'type' builtin is similar but not POSIX compliant. Use 'command -v' for portable scripts.
'type -p commandname' returns the name of the disk file that would be executed, or nothing if the command is not a file (i.e., it's an alias, function, or builtin). This is similar to the 'command -p' or 'which' command behavior.
The PATH_SEPARATOR is a colon (':') on Unix/Linux systems. It separates directories in the PATH environment variable. On Windows (when using Bash via WSL or Cygwin), it may be semicolon (';') depending on the build.
When PATH is empty or unset, Bash only searches the current directory for commands (plus builtins, functions, aliases). This is a security consideration, as it differs from the default behavior of searching standard system directories.
The 'hash -r' command clears the entire hash table, forcing Bash to search the PATH again for all subsequent commands. This is useful when you've moved executables or updated your PATH.
No, Bash does NOT cache command lookup failures. If a command is not found, Bash will search PATH again each time you invoke it, rather than remembering that it doesn't exist.
PATH is a colon-separated list of directories. Example: '/usr/local/bin:/usr/bin:/bin:/usr/sbin:/sbin'. Empty entries in PATH represent the current directory (e.g., '/usr/bin::/bin' has an empty entry representing '.').
Hashing improves performance by avoiding repeated filesystem searches. However, if you install a new version of a program in a PATH directory that appears earlier than the hashed location, Bash will still use the old hashed location unless you run 'hash -r' or restart the shell.
Bash uses command hashing by default. When the shell finds a command in the PATH, it remembers its location in a hash table. Subsequent executions of the same command use the hashed location instead of searching PATH again. The hash table is cleared when you start a new shell.
'command commandname' runs the specified command, bypassing any shell functions with the same name. This allows you to execute the actual external command or builtin even if a function shadows it.
When called without arguments, 'hash' displays the current hash table showing the remembered locations of commands that have been found through PATH searches.
'type' is a Bash builtin that understands shell functions, aliases, keywords, and builtins. 'which' is typically an external command (on some systems it's also a builtin) that only searches PATH for executable files. 'type' is more comprehensive and shell-aware.
Bash searches PATH directories from left to right (in the order they appear in the PATH variable, separated by colons). It stops at the first match found and executes that file. The search is NOT recursive within directories.
'command -V commandname' returns a more verbose description of the command, similar to 'type commandname'. It shows whether it's an alias, function, builtin, or file with more detailed output.
'enable -a' displays all enabled and disabled shell builtins, showing which are currently active and which have been disabled.
The 'hash -d commandname' command removes the specified command from the hash table, causing Bash to search PATH again for that specific command on the next invocation.
'command -p commandname' uses a default value for PATH that guarantees it finds all standard utilities. This ensures the command is found even if the current PATH has been modified. The default PATH is '/bin:/usr/bin' on most systems (implementation dependent).
If a command name contains a slash ('/'), Bash does NOT search PATH. It treats it as a pathname (relative or absolute) and attempts to execute that specific file directly. If the file doesn't exist or isn't executable, Bash returns an error.
'enable -n commandname' disables the specified builtin command, allowing an external command with the same name to be executed without using the full path. Use 'enable commandname' to re-enable the builtin.
If 'command_not_found_handle' returns a non-zero exit status, Bash displays the standard 'command not found' error message. If it returns 0 (success), Bash does not display any additional error message.
'enable -s' enables only the specified dynamic loadable builtins (if Bash was compiled with support for dynamic loading of builtins). Without arguments, 'enable -s' lists all currently enabled dynamic builtins.
'hash -l' displays the hash table in a format that can be reused as input. The output shows commands and their full paths, useful for saving and restoring the hash table state.
'type -t commandname' returns a single word indicating the command type: 'alias', 'keyword', 'function', 'builtin', or 'file'. If the command is not found, it returns nothing.
When a command is not found, Bash executes the function named 'command_not_found_handle' if it exists. This function receives the command name and arguments as parameters. If not defined, Bash prints an error message. This is a Bash extension, not POSIX.
Bash searches for commands in the following order: 1) Aliases, 2) Shell reserved words (keywords), 3) Shell functions, 4) Builtin commands, 5) Executable files found in directories listed in the PATH environment variable (searched left-to-right).
Using './commandname' explicitly tells Bash to execute 'commandname' from the current directory. The './' prefix bypasses PATH searching entirely and directly accesses the file. This is required for executables in the current directory when '.' is not in PATH.
'command -v commandname' returns a description of the command similar to 'type', but without executing it. Returns the path or alias/function definition. Returns failure status if command not found.
Bash automatically updates the hash table when it successfully finds a command in PATH. It also updates the table if PATH is changed. However, if a command is moved or deleted, Bash won't know until you run 'hash -r' or the lookup fails.
'type commandname' shows how the command name would be interpreted if typed, while 'type -a commandname' shows ALL locations where the command appears, including aliases, functions, and every match in PATH directories.
CDPATH is used by the 'cd' builtin command to search for the target directory. It works like PATH but for directory changes. If the directory argument to 'cd' doesn't start with '/', Bash searches directories listed in CDPATH (colon-separated).
'type -P commandname' forces a PATH search even if the command is a builtin, alias, or function. It returns the disk file path or nothing if no file is found in PATH. This is useful when you specifically want the external command location.
'enable -p' displays only the disabled shell builtins, showing which builtin commands have been turned off and can be shadowed by external commands.
Use 'set +h' or 'set +o hash' to disable command hashing. With hashing disabled, Bash searches the PATH directories on every command invocation. To re-enable hashing, use 'set -h' or 'set -o hash'.
Bourne Shell Builtins > Flow Control
34 questionsYes, shift is a Bourne Shell builtin that shifts positional parameters to the left by n (default 1). Parameters from $n+1...$# are renamed to $1...$#-n, and parameters $1...$n are unset. shift returns 0 if n is in range, or 1 if n is greater than $#.
The wait builtin waits for each specified background process to complete and returns the exit status of the last awaited command. If no jobspec is specified, it waits for all currently active child processes and returns the exit status of the last command to finish.
Yes, both break and continue accept an optional numeric argument N. break N breaks out of N enclosing loops, and continue N skips to the next iteration of the N-th enclosing loop. The default value for N is 1.
If return is used outside a function but during script execution with the . (source) builtin, it causes the shell to stop executing that script and return to the calling script or interactive shell.
The ERR signal with trap causes the command to be executed whenever the shell would exit if a pipeline or command list returns 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 except the command following the final || or &&, or if the command's return status is being inverted with !.
Bash ignores SIGQUIT and SIGTERM by default when started without job control enabled. These signals can still be caught and handled using trap.
The default value for N in break [n] is 1, meaning it breaks out of the innermost enclosing loop when no argument is specified.
The default value for N in continue [n] is 1, meaning it continues to the next iteration of the innermost enclosing loop when no argument is specified.
If continue is used outside of a for, while, until, or select loop, the shell will produce an error message and return a non-zero exit status.
The local builtin creates local variables within a function. Variables declared with local are visible only within the function and its children. When the function returns, the previous value (if any) is restored. local can only be used within functions.
When used with trap, the EXIT signal (sigspec) causes the command to be executed when the shell exits. This is commonly used for cleanup tasks that should run regardless of how the script exits.
trap -l displays a list of signal names and their corresponding numbers. The output is similar to kill -l.
The false builtin does nothing unsuccessfully and returns an exit status of 1. It is typically used to force a loop exit condition or to fail a test condition.
The let builtin evaluates each arithmetic expression argument. If the last expression evaluates to 0, let returns 1; otherwise it returns 0. Each expression is evaluated as a shell arithmetic expression.
If break is used outside of a for, while, until, or select loop, the shell will not exit but will produce an error message and return a non-zero exit status.
trap -p displays a list of currently set traps in a form that can be reused as shell input. If sigspec is supplied, only the traps for those signals are displayed.
The eval builtin reads its arguments, concatenates them with spaces, and evaluates the resulting string as bash commands. The resulting command is then read and executed by the shell, and its exit status is returned as the exit status of eval.
The true builtin does nothing successfully and returns an exit status of 0. It is typically used in infinite loops with while.
The continue builtin skips the remaining commands in the current loop iteration and begins the next iteration. If N is specified, it resumes with the N-th enclosing loop. The default value for N is 1.
The return builtin causes a function to exit with a specified return status (n). If n is not supplied, the return status is that of the last command executed within the function. If used outside a function, but during script execution with the . or source builtin, it causes the shell to stop executing that script and return to the calling context.
The exit builtin causes the shell to exit with a given status. If n is omitted, the exit status is that of the last command executed. When used in a subshell, only the subshell exits.
The . builtin (source) reads and executes commands from the filename argument in the current shell context. If filename does not contain a slash, the PATH variable is used to find the file. The return status is the exit status of the last command executed, or 0 if no commands were executed.
break exits from loops (for, while, until, select), while return is used to exit from a function with a return status. When used outside a function but during a script executed with . or source, return causes the shell to stop executing that script.
There is no functional difference. source is a synonym for .. Both execute commands from a file in the current shell context rather than in a subshell.
When used with trap, the RETURN signal causes the command to be executed each time a shell function or a script executed with the . or source builtin finishes executing.
The return builtin returns the exit status of the last executed command if n is not supplied. If n is supplied, it must be in the range 0-255. Values outside this range will be modulo 256.
The times builtin prints the accumulated user and system times for the shell and for processes run from the shell. The return status is 0.
The : builtin is a null command that does nothing and returns a successful exit status (0). It expands arguments and performs redirections, but executes no commands. Commonly used as a placeholder in while loops or for evaluating conditions without side effects.
When used with trap, the DEBUG signal causes the command to be executed before every simple command. This is useful for debugging scripts.
If shift n is called where n is greater than $# (the number of positional parameters), shift returns an exit status of 1 and does not change the positional parameters.
exit terminates the entire shell or subshell session, while return exits from a function (or a sourced script) and returns to the caller. exit ends execution completely, return continues execution in the calling context.
The trap builtin allows you to specify commands that will be executed when the shell receives signals. Syntax: trap [-lp] [[arg] sigspec ...]. If arg is absent, all signals specified are reset to their original values. If arg is -, each specified signal is set to its original disposition.
The exec builtin replaces the shell with a given command without creating a new process. If command is specified, it replaces the shell. If no command is specified, any redirections take effect in the current shell. Commonly used to redirect file descriptors or change the shell's standard input/output.
The break builtin exits from a for, while, until, or select loop. If N is specified, it breaks out of N enclosing loops. The default value for N is 1.
Executing Commands > Signal Processing
34 questionsThe 'wait -n' option (available in bash 4.3+) waits for any single background job to complete and returns its exit status. When multiple jobs are specified, it returns the exit status of the next job that completes.
The RETURN pseudo-signal. When a function or script executed with the . or source builtins finishes executing, trap executes the command associated with RETURN.
If no jobs are specified and all background jobs have already terminated or there are no background jobs, 'wait' returns exit status 0.
The 'trap -l' command causes the shell to print a list of signal names and their corresponding numbers.
If the first argument is a single dash ('-'), the signal handling for each specified sigspec is reset to the default disposition.
Yes. The 'disown' builtin removes jobs from the shell's job table. Jobs that have been disowned are no longer subject to 'wait' and will not be reported by the shell when they terminate. The shell does not send SIGHUP to disowned jobs when the shell exits.
The DEBUG pseudo-signal. When a shell executes a simple command, trap executes the command associated with DEBUG before the simple command runs.
When a DEBUG trap is executed, the variable 'BASH_ARGC' contains the number of parameters to the current function call, 'BASH_ARGV' contains the arguments, 'BASH_SOURCE' contains the source filename, 'BASH_LINENO' contains line numbers, and 'LINENO' contains the current line number.
The 'disown -a' option removes all jobs from the job table (both running and stopped).
If a signal for which a trap has been set is received while the shell is waiting for an asynchronous command to finish, the trap will not be executed until the command completes.
The 'trap -p' command causes the shell to display the trap commands associated with each sigspec. If no sigspec is supplied, 'trap -p' prints all of the traps currently set.
On Linux: SIGINT is signal 2, SIGTERM is signal 15, and SIGKILL is signal 9.
While a trap is being executed, signals received are queued and handled after the current trap completes. However, if the signal being received is the same as the trap currently being executed, the behavior varies by system; on most systems, it is queued.
The EXIT pseudo-signal. When a shell exits, trap executes the command associated with EXIT. This is useful for cleanup operations.
When a script is sourced using the '.' or 'source' builtin, the traps set in the sourced script are visible in the calling shell. Traps are not reset when the sourced script finishes.
The ERR pseudo-signal. When a pipeline command (which may be a simple command, a compound command, or a function) returns a non-zero exit status, trap executes the command associated with ERR. However, ERR is not triggered if the failed command is part of a command list immediately following an 'if', 'elif', 'while', or 'until' keyword, part of a test in an 'if' statement, part of an '&&' or '||' list where the command following failed, or if the command's return status is being inverted with '!'
Use 'shopt -s inherit_errexit' to enable it. This option causes command substitutions to inherit the errexit setting, meaning they will exit on error if errexit is set. This affects error handling in subshells and command substitutions.
No. SIGKILL and SIGSTOP cannot be caught, blocked, or ignored. This is a system-level restriction, not specific to bash.
Yes. Bash automatically waits for and reaps child processes that have terminated. However, if you need to know when a specific child process exits, you should use 'wait' or trap SIGCHLD.
When wait is interrupted by a signal for which a trap has been set, wait returns exit status 128 plus the signal number, and the trap handler is executed. After the trap completes, wait may still be waiting for jobs.
Traps are reset to the default in subshells. A subshell does not inherit the traps of its parent shell. Each subshell must set its own traps.
The trap builtin has the syntax: trap [-lp] [[arg] sigspec ...]. The 'arg' is the command to execute when the signal 'sigspec' is received. If arg is absent or '-', the signal handling is reset to the default. If arg is the null string, the signal is ignored.
List the signal names after the action: 'trap "command" SIGINT SIGTERM SIGQUIT'. All specified signals will trigger the same command when received.
The ERR trap is triggered when any command returns a non-zero exit status (with exceptions for conditional contexts), while 'set -e' causes the shell to exit immediately when any command exits with a non-zero status. The ERR trap allows you to run cleanup code, whereas errexit terminates execution. Both can be used together.
The 'wait -f' option (available in bash 5.1+) causes wait to wait until all jobs in the job specification have terminated before returning exit status, instead of returning when the status of the last job in the list is known. This option is only effective when job control is enabled.
The default behavior of SIGPIPE is to terminate the process. SIGPIPE is generated when a process writes to a pipe or socket that has no reader. It can be trapped or ignored.
Use 'trap "" SIGQUIT' or 'trap '' SIGQUIT'. The empty string as the action causes the signal to be ignored.
When the huponexit shell option is disabled (the default in bash), the shell does not send SIGHUP to background jobs when it exits. Jobs continue running after the shell terminates.
If the specified job or process ID is unknown or does not exist, 'wait' returns exit status 127.
The 'disown -h' option marks each job so that SIGHUP is not sent to the job if the shell receives a SIGHUP (hangup signal). This prevents the job from being killed when the shell's controlling terminal is closed.
In an interactive shell, SIGINT causes the current command to be terminated and the main prompt to be displayed. The trap for SIGINT can be set to customize this behavior.
When a job is terminated by a signal, 'wait' returns an exit status greater than 128. Specifically, it returns 128 plus the signal number (e.g., if terminated by SIGINT (signal 2), wait returns 130).
If the first argument (action) is an empty string (''), the specified signals are ignored by the shell and the commands it invokes.
Quoting > Extended Quoting Formats
34 questions\UHHHHHHHH represents the Unicode (ISO/IEC 10646) character whose value is the hexadecimal value HHHHHHHH, where HHHHHHHH is one to eight hex digits.
TEXTDOMAINDIR points to the base directory where message catalog files are stored. If you install message files into the system's standard message catalog directory, you don't need to set this variable.
Regular single quotes (') treat everything literally and no escaping is possible. ANSI-C quoting ($') allows backslash escape sequences to be interpreted while still providing strong quoting (no variable or command expansion).
If the current locale is C or POSIX, if there are no translations available, or if the string is not translated, the dollar sign is ignored and the string is treated as a regular double-quoted string.
Bash has two extended quoting formats: ANSI-C Quoting ($'string') and Locale-Specific Translation ($"string"). These are in addition to the basic quoting mechanisms: escape character, single quotes, and double quotes.
Yes, unlike regular single quotes where you cannot escape a single quote, in ANSI-C quoted strings ($'...'), you can use ' to include a literal single quote. For example: $'can't' works correctly.
When the noexpand_translation option is enabled using the shopt builtin, translated strings are single-quoted instead of double-quoted. This prevents variable and command expansion within translated strings.
Use the command: bash --dump-po-strings scriptname > domain.pot. This extracts all strings marked for translation ($"...") and creates a gettext template file.
Users set the LANG or LC_MESSAGES environment variables to select the desired language before running the script.
The ANSI-C quoting syntax ($'...') originated in ksh93 (the KornShell 93) and was adopted by bash. It was part of ksh93's enhanced capabilities including following ANSI C standards.
The noexpand_translation option is disabled (off) by default, as with all shopt options unless otherwise noted. This means translated strings are double-quoted by default.
\uHHHH represents the Unicode (ISO/IEC 10646) character whose value is the hexadecimal value HHHH, where HHHH is one to four hex digits.
Octal escape sequences use the format \nnn where nnn is one to three octal digits, representing an eight-bit character with that octal value.
\cx represents a control-x character, where x is any character. For example, \cM would produce a carriage return (Ctrl-M).
No, ANSI-C quoting is not part of the POSIX standard. It is a bash/ksh93 extension, meaning portable shell scripts should avoid using it for strict POSIX compliance.
Bash locale translation uses the gettext infrastructure which performs lookup and translation using the LC_MESSAGES, TEXTDOMAINDIR, and TEXTDOMAIN shell variables.
Hexadecimal escape sequences use the format \xHH where HH is one or two hexadecimal digits, representing an eight-bit character with that hexadecimal value.
By default, translated strings are double-quoted. Since this is a form of double quoting, the string remains double-quoted whether or not it is translated and replaced.
The expanded result is single-quoted, as if the dollar sign had not been present. This means no further expansion occurs.
\e and \E both represent an escape character (ASCII ESC, 0x1B). This is not in ANSI C but is a Bash extension.
ANSI-C quoting uses the syntax $'string'. Character sequences of this form are treated as a special kind of single quotes where backslash-escaped characters are replaced as specified by the ANSI C standard.
Locale-specific translation uses the syntax $"string". Prefixing a double-quoted string with a dollar sign causes the string to be translated according to the current locale using the gettext infrastructure.
TEXTDOMAIN is the name of your script's message domain. It's an arbitrary string used to identify the files gettext needs, like a package or script name. You use it to name your translation files.
Shell Variables > Execution Context and Debugging
33 questionsWhen you assign a value to SECONDS, the timer resets to that value and continues incrementing from there. Assigning 0 resets the timer.
No, BASH_XTRACEFD must be set to an integer that refers to an already open file descriptor. If set to an invalid file descriptor, Bash will produce an error when debugging is enabled.
The ERR trap is executed whenever a command returns a non-zero exit status, but only if the command is not part of a compound list like && or ||, or part of an if/while/until construct.
BASH_ARGC contains the number of parameters in each stack frame. BASH_ARGC[0] is the total number of parameters for the current subshell, BASH_ARGC[1] for the parent, etc.
FUNCNAME and BASH_SOURCE always have the same number of elements. For each function in the call stack, there is a corresponding element in both arrays.
SHELLOPTS contains enabled shell options as a colon-separated list of option names (e.g., 'braceexpand:emacs:hashall:histexpand:history').
BASH_ARGV contains all the parameters in the current stack frame execution. BASH_ARGV[0] is the last parameter, BASH_ARGV[1] is the second-to-last, and so on.
EPOCHREALTIME contains the time since the epoch in seconds with microsecond precision as a floating-point value (e.g., 1704067200.123456).
BASHOPTS is read-only, like SHELLOPTS. To change options, use the 'shopt' command with -s (enable) or -u (disable) flags.
The last element in the FUNCNAME array is 'main' when the script is executed directly (not sourced).
BASH_REMATCH is populated after a successful match using the =~ conditional operator in [[ ]]. BASH_REMATCH[0] contains the entire match, and BASH_REMATCH[1] through BASH_REMATCH[n] contain captured groups.
BASH_LINENO[$i] contains the line number in the source file ${BASH_SOURCE[$i+1]} where the function ${FUNCNAME[$i]} was called (or ${BASH_LINENO[$i]} if ${BASH_SOURCE[$i+1]} is null).
LINENO defaults to 1. It is incremented each time a script reads a line and resets when the script calls a function.
BASH_EXECUTION_STRING contains the command arguments passed to Bash with the -c option. It holds the exact string that Bash was invoked to execute.
BASH_COMMAND contains the command currently being executed or about to be executed. It's most useful in DEBUG trap functions to show what command triggered the trap.
ENV is used when Bash is started in POSIX mode (with --posix or when invoked as sh), while BASH_ENV is used in standard Bash mode. Both specify files to be read and executed at startup for non-interactive shells.
BASH_SUBSHELL increments by 1 for each subshell level. Starting at 0 in the main shell, it becomes 1 in the first subshell, 2 in a nested subshell, and so on.
The default value of PS4 is '+ ' (plus sign followed by a space). PS4 is used as the prompt for the xtrace (set -x) debugging mode.
The default value of BASH_SUBSHELL is 0 in the main shell. It increments by 1 for each nested subshell level.
${BASH_SOURCE[$i+1]} is the source file where the function ${FUNCNAME[$i]} was called, and ${BASH_LINENO[$i]} is the line number within that file.
BASH_ENV is read and executed when Bash is invoked to execute a shell script in non-POSIX mode, but only if Bash is an interactive shell. It is not executed for login shells or when Bash is started with the --norc option.
BASHOPTS contains enabled shell options in a colon-separated list, similar to SHELLOPTS, but for options controlled by the 'shopt' builtin rather than 'set'.
RANDOM generates a pseudo-random integer between 0 and 32767 each time it is referenced. There is no 'first value' - it returns a different random number on each reference.
BASH_ARGC[$i] contains the number of parameters in stack frame $i, and BASH_ARGV contains all parameters across all stack frames with the current frame's parameters at the start.
When not executing a function, FUNCNAME is unset. FUNCNAME[0] only contains the name of the currently executing function when inside a function call.
SHELLOPTS is a read-only variable. It contains enabled shell options in a colon-separated format and cannot be directly modified. Use 'set -o option' or 'shopt' commands to change options.
EPOCHSECONDS contains the time since the epoch (1970-01-01 00:00:00 UTC) as an integer number of seconds, with no fractional component.
The RETURN trap is executed each time a shell function or script executed with the '.' or 'source' builtin finishes executing.
The DEBUG trap is executed before every simple command in a script, allowing for debugging and tracing execution. The BASH_COMMAND variable shows the command about to execute.
SECONDS defaults to 0 when Bash starts. It increments by 1 each second and can be assigned to reset the counter.
BASH_SOURCE[0] contains the name of the source file that is currently being executed. When a script is sourced, this contains the filename of the script being sourced.
BASH_REMATCH stores up to 9 captured groups (BASH_REMATCH[1] through BASH_REMATCH[9]) plus BASH_REMATCH[0] which contains the entire match.
The BASH_COMMAND variable contains the command currently being executed, which is particularly useful within DEBUG trap functions.
Bash Conditional Expressions > File Comparison Tests
33 questionsThe -f file operator returns true if file exists and is a regular file. This will return false for directories, symbolic links, device files, and other special file types.
The file1 -ot file2 operator returns true if file1 is older than file2 (modification time), or if file2 exists and file1 does not.
Yes, file test operators work with filenames containing whitespace, but proper quoting is required. Use '[ -f "file with spaces.txt" ]' or '[[ -f "file with spaces.txt" ]]' with quotes around the variable or filename.
The -b file operator returns true if file exists and is a block special file (e.g., /dev/sda, /dev/sda1).
For file1 -nt file2: returns true if file1 exists and file2 does not exist. For file1 -ot file2: returns true if file2 exists and file1 does not exist. If both files do not exist, the result is false.
Most Bash file test operators follow symbolic links and test the target file, except for -h and -L which test the symbolic link itself. For example, -f will return true if the symlink target is a regular file, while -L returns true for the symlink itself.
The -G file operator returns true if file exists and its group ID matches the effective group ID of the current process.
The -k file operator returns true if file exists and has its sticky bit set.
The -N file operator returns true if file exists and has been modified since it was last read.
The -s file operator returns true if file exists and has a size greater than zero. This tests for non-empty files.
The -h file operator returns true if file exists and is a symbolic link. This is a synonym for -L.
The file1 -ef file2 operator returns true if file1 and file2 refer to the same device and inode numbers (i.e., they are the same file, including hard links).
The -N operator checks the file's access time (atime) versus modification time (mtime). If the modification time is newer than the access time, the file is considered to have been modified since it was last read. Note that systems with relatime or noatime mount options may affect this behavior.
When the file descriptor argument is omitted, the -t operator defaults to file descriptor 1 (stdout). So 'if [ -t ]' is equivalent to 'if [ -t 1 ]'.
Both -e and -a test if a file exists. However, -e is the primary and recommended operator. The -a operator is effectively its synonym, but -a is also the logical AND operator in some contexts which can cause confusion. The POSIX standard is -e.
The -r file operator returns true if file exists and is readable (has read permission for the current user). This checks effective permissions, not just the permission bits.
The -x file operator returns true if file exists and is executable (has execute/search permission for the current user). For directories, this tests if the directory can be searched (cd into it).
The -e file operator returns true if file exists. This test checks for existence regardless of file type.
The -O file operator returns true if file exists and is owned by the effective user ID of the current process.
The -p file operator returns true if file exists and is a named pipe (FIFO).
The -g file operator returns true if file exists and has its set-group-id flag set.
The -c file operator returns true if file exists and is a character special file (e.g., /dev/tty, /dev/null).
Yes, file comparison operators (-nt, -ot, -ef) work within the [[ compound command just like single-file test operators. They are part of the conditional expressions and can be used in both [ ] and [[ ]].
The -t fd operator returns true if file descriptor fd is open and refers to a terminal. Common values: fd 0 is stdin, fd 1 is stdout, fd 2 is stderr. If fd is omitted, it defaults to 1 (stdout).
The -r, -w, and -x operators check the effective permissions, which considers the real user ID, effective user ID, and group memberships. These operators test whether the current process can actually read, write, or execute the file, not just what the permission bits show. For example, a file owned by root with mode 600 may still show as readable if the current user has appropriate capabilities or group membership.
The -L file operator returns true if file exists and is a symbolic link. This is a synonym for -h.
The -w file operator returns true if file exists and is writable (has write permission for the current user). This checks effective permissions, not just the permission bits.
Both [ ] and [[ ]] work with file test operators. However, [[ ]] is a Bash keyword (not a command) that provides safer parsing, no word splitting on variables, and allows pattern matching. For file tests, both work identically, but [[ ]] is generally recommended in Bash scripts for consistency and safety.
The -u file operator returns true if file exists and has its set-user-id flag set.
The file1 -nt file2 operator returns true if file1 is newer than file2 (modification time), or if file1 exists and file2 does not.
If the file does not exist, all file test operators that require file existence (such as -f, -d, -r, -w, -x, -s, etc.) return false. The operators do not produce an error; they simply return a false result.
Redirections > File Descriptor Operations
33 questionsUse the syntax [n]<&- to close input file descriptor n. For example, 0<&- closes stdin, and 4<&- closes file descriptor 4.
File descriptor 0 is reserved for standard input (stdin), file descriptor 1 is reserved for standard output (stdout), and file descriptor 2 is reserved for standard error (stderr). File descriptors 3-9 are available for general use.
The default file descriptor for input redirection (< word) is 0 (stdin). The default file descriptor for output redirection (> word) is 1 (stdout). For truncating output (>), append output (>>), and read-write (<>), fd 1 is the default.
Use exec 6<&0 to duplicate stdin (fd 0) to fd 6. Later, you can restore it with exec 0<&6 6<&-. For example: exec 6<&0; exec < inputfile; # work with inputfile; exec 0<&6 6<&-; # restore original stdin.
The delimiter can be any word consisting of alphanumeric characters and underscores. It cannot contain whitespace, quotes, or special characters. Common conventions include EOF, END, BLOCK, and similar uppercase words.
There is no functional difference in most cases. 2>&1 explicitly duplicates fd 1 to fd 2. >&1 is an older form where the leading digit is omitted, defaulting to 1, so it means 1>&1 (which redirects stdout to stdout) followed by 2>&1. The explicit 2>&1 form is preferred for clarity.
If word evaluates to '-', the file descriptor n is closed. For example, 1>&- closes stdout, and 3>&- closes file descriptor 3 for output.
If word in [n]>&word or [n]<&word is not a valid file descriptor number, bash attempts to interpret it as a filename. For example, 2>&error tries to redirect stderr to a file named 'error', not to file descriptor 'error'.
You cannot escape the delimiter in here-document content. If the exact delimiter word appears on a line by itself in the body, bash will interpret it as the end marker. To include the delimiter text in content, use a different delimiter or restructure the content.
Bash does not have a <<<<EOF syntax. The available here-document variants are: <<EOF (with expansion), <<'EOF' (literal/quoted), and <<-EOF (strips leading tabs with expansion). To disable parameter/command substitution but allow arithmetic expansion, use <<\EOF or <<"EOF" with appropriately quoted delimiters.
No, [n]<>word does not truncate the file. It opens the file for both reading and writing without truncating, and creates the file if it does not exist.
No, bash only supports file descriptors 0 through 9 for direct redirection syntax. However, file descriptors opened by the operating system (beyond 9) can be accessed indirectly through /dev/fd/N or /proc/self/fd/N.
Bash recognizes /dev/fd/N as file descriptor N, /dev/stdin as fd 0, /dev/stdout as fd 1, and /dev/stderr as fd 2. These can be used in redirections: command < /dev/fd/3 reads from file descriptor 3.
If word evaluates to '-', the file descriptor n is closed. For example, 0<&- closes stdin, and 3<&- closes file descriptor 3 for input.
When redirecting both stdout and stderr, the order is critical. To redirect both to a file: command >file 2>&1 (redirect stdout first, then duplicate it to stderr). The reverse order 2>&1 >file would only redirect stdout, not stderr.
Parameter, command, and arithmetic expansion in here-document bodies happens after the delimiter is read but before the content is passed to the command. The delimiter line itself is never expanded or modified.
Use the syntax [n]>&- to close output file descriptor n. For example, 1>&- closes stdout, and 3>&- closes file descriptor 3.
The syntax is <<< word, introduced in bash 2.05b. It expands word and feeds it to stdin. Unlike here-documents, it automatically adds a trailing newline. Example: wc -w <<< 'count these words'.
The null command : with redirections opens or creates files without executing any command. For example, : >file creates an empty file or truncates an existing one. This is useful for creating zero-length files from within a script.
The syntax is [n]<>word, where n is the file descriptor number (defaults to 0 if omitted) and word is the filename. For example, 3<>data.txt opens data.txt for both reading and writing on file descriptor 3.
The here-string syntax is <<< word. It expands word, supplies the result to the command's standard input (file descriptor 0), and adds a trailing newline. For example: grep 'pattern' <<< 'search this string'.
Bash processes redirections left-to-right. Later redirections override earlier ones for the same file descriptor. For example, in 'command >file1 >file2', the final redirection to file2 takes effect, not file1.
The &>file redirection redirects both stdout (fd 1) and stderr (fd 2) to file. This is equivalent to >file 2>&1. The append form is &>>file, equivalent to >>file 2>&1.
Within a here-document with a quoted delimiter (<<'EOF'), the body is treated literally. No parameter expansion ($VAR remains $VAR), no command substitution ($(cmd) remains $(cmd)), and no arithmetic expansion ($((expr)) remains $((expr)) occurs.
With <<delimiter, the here document content undergoes parameter expansion, command substitution, and arithmetic expansion. With <<'delimiter' (quoted delimiter), the content is treated literally and no expansion is performed on the body text.
The <<-delimiter form strips leading tab characters from each line of the here document body. This allows the here document content to be indented naturally within a script while still maintaining proper formatting.
The syntax is [n]<&word, where n is the file descriptor to duplicate into (defaults to 0 if omitted), and word is the file descriptor to duplicate from. For example, 5<&0 duplicates stdin (fd 0) to file descriptor 5.
Use: command >stdout_file 2>stderr_file. This redirects fd 1 (stdout) to stdout_file and fd 2 (stderr) to stderr_file separately.
Use exec [n]>file or exec [n]<&word without a command. For example, exec 2>error.log redirects all subsequent stderr in the current shell to error.log. exec 3<&0 saves stdin for later use.
The |& operator is shorthand for 2>&1 |. It pipes both stdout and stderr to the standard input of the following command. For example: command1 |& command2 is equivalent to command1 2>&1 | command2.
The redirection 2>&1 duplicates file descriptor 1 (stdout) to file descriptor 2 (stderr), causing stderr to go to the same destination as stdout. The order matters: it must appear after any redirection of fd 1.
No, the here-document delimiter must be a single unquoted word with no whitespace. If quoted (e.g., <<'EOF TEXT'), the quotes are part of the delimiter name. The closing delimiter must match exactly, including any quotes.
The syntax is [n]>&word, where n is the file descriptor to duplicate into (defaults to 1 if omitted), and word is the file descriptor to duplicate from. For example, 2>&1 duplicates stderr (fd 2) to stdout (fd 1).
Shell Commands > Compound Commands
32 questionsThe DEBUG and RETURN traps are not inherited unless the function has been given the 'trace' attribute using 'declare' or the '-o functrace' option has been enabled with 'set'.
The exit status of a function definition is zero unless a syntax error occurs or a readonly function with the same name already exists.
The process ID of the shell spawned to execute the coprocess is available as the value of the variable NAME_PID (or COPROC_PID if using default name).
Yes. The braces are reserved words, so they must be separated from the list by blanks or other shell metacharacters.
Other than those created to execute command and process substitutions, the file descriptors are not available in subshells.
If the regular expression is syntactically incorrect, the conditional expression returns 2.
The syntax is 'coproc [NAME] command [redirections]' where NAME is a shell variable name. If NAME is not supplied, the default name is COPROC.
By default, Bash places no limit on the number of recursive calls. The FUNCNEST variable may be used to limit the depth.
No. Shell functions are executed in the current shell context; there is no new process created to interpret them.
Each clause in a case statement must be terminated with ';;' (terminates after match), ';&' (continues with next clause's command-list), or ';;&' (continues testing patterns in next clause).
If the value of the expression is zero, the return status is 1 (false/failure).
Yes. The semicolon (or newline) following the list is required when using curly braces { } for command grouping.
No. If command is a simple command, NAME is not allowed; this is to avoid confusion between NAME and the first word of the simple command.
The shell performs tilde expansion, parameter and variable expansion, arithmetic expansion, command substitution, process substitution, and quote removal. Word splitting and filename expansion are NOT performed.
The return status is zero if no pattern matches. Otherwise, the return status is the exit status of the last command-list executed.
Yes. If the 'function' reserved word is supplied, the parentheses are optional.
If the value of the expression is non-zero, the return status is 0 (true/success).
The FUNCNEST variable, if set to a numeric value greater than 0, defines a maximum function nesting level. Function invocations that exceed the limit cause the entire command to abort.
No. 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 first element of the FUNCNAME variable is set to the name of the function while the function is executing.
The shell uses dynamic scoping to control a variable's visibility within functions. With dynamic scoping, visible variables and their values are a result of the sequence of function calls that caused execution to reach the current function.
Yes. Command groups are executed in the current shell environment (no subshell is created), so variable assignments remain in effect after the command group completes.
No. Since the list is executed in a subshell environment, variable assignments do not remain in effect after the subshell completes.
No. The words between the [[ and ]] do not undergo word splitting and filename expansion.
The match succeeds if the pattern matches any part of the string. To force the pattern to match the entire string, anchor the pattern using the '^' and '$' regular expression operators.
Since the coprocess is created as an asynchronous command, the coproc command always returns success (exit status 0). The return status of the actual command is separate.
When executed, the exit status of a function is the exit status of the last command executed in the body, unless 'return' supplies a numeric argument.
The array variable BASH_REMATCH records which parts of the string matched the pattern. Index 0 contains the portion matching the entire regex, and indices 1+ contain substrings matched by parenthesized subexpressions.
When using the braces, the list must be terminated by a semicolon, a '&', or a newline.
Special parameter 0 (which contains the name of the shell or script) is unchanged when a function is executed.
The exit status of both ( ) subshell and { } command group constructs is the exit status of the list of commands executed within them.
For historical reasons, in the most common usage the curly braces that surround the body of the function must be separated from the body by blanks or newlines. This is because braces are reserved words.
Shell Functions > Return Values and Exit Status
32 questionsThey are restored to the values they had prior to the function's execution. Bash automatically saves and restores these values when entering and exiting a function.
FUNCNAME is an array variable containing the names of all shell functions currently in the execution call stack. The element with index 0 is the name of the currently-executing shell function. This exists only when a shell function is executing.
Exit status out of range. This should be avoided as a custom return code.
With dynamic scoping, if a variable is declared local in an outer function, that value is visible to called inner functions. When the outer function returns, its local variables are restored to their previous values.
126 indicates the command was found but cannot be executed. 127 indicates the command was not found. These values should be avoided as custom return codes.
$? expands to the exit status of the most recently executed foreground pipeline or function.
'return' exits from a shell function and returns a status code to the caller. 'exit' terminates the entire shell or script. Use 'return' in functions; use 'exit' to terminate the script.
If return is executed during a DEBUG trap, the last command used to determine the status is the last command executed by the trap handler before return was invoked.
The return value wraps around to 0 (256 % 256 = 0). Values >= 256 are truncated using modulo 256 arithmetic.
Bash uses 128+N where N is the fatal signal number. For example, SIGKILL (signal 9) results in exit status 137 (128+9), and SIGINT (signal 2, typically Ctrl-C) results in exit status 130 (128+2).
The return status is non-zero. Return is designed for use within shell functions or scripts executed by the source (.) command.
If a command fails because of an error during expansion or redirection, the exit status is greater than zero.
Bash returns the exit status of the last command executed in the script, unless a syntax error occurs (in which case it exits with a non-zero value). If no commands are executed, the exit status is 0.
Bash does not accept negative arguments to the return statement. If you pass a negative value to return, it's treated as an error. However, exit status 255 may sometimes appear from negative values due to unsigned integer wrapping.
Indicates the script was terminated by Control-C (SIGINT signal: 128+2=130).
The exit status of the last command executed before the return statement. If return is used without an argument, it defaults to the last command's exit status.
Set the FUNCNEST variable to a numeric value greater than 0. Function invocations that exceed this limit cause the entire command to abort.
Misuse of shell builtins (according to common bash conventions). This should be avoided as a custom return code.
Any command associated with the RETURN trap is executed before execution resumes with the next command after the function call.
If pipefail is enabled, the pipeline's return status is the value of the last (rightmost) command to exit with a non-zero status, or zero if all commands exit successfully. By default (without pipefail), the pipeline's return status is the exit status of the last command.
All shell builtin commands return an exit status of 2 to indicate incorrect usage (generally invalid options or missing arguments).
The return value becomes 1 (257 % 256 = 1). Values >= 256 are truncated using modulo 256 arithmetic.
The exit status of the last command executed in the function body. This is the default behavior if no return statement is present.
You cannot use the return statement for values > 255. Instead, use stdout with echo/printf and capture via command substitution: 'result=$(my_function)', or use a global variable.
Bash functions can only return numeric exit codes (0-255) via the return statement. To return strings or other data, you must use alternative methods: global variables, command substitution (capturing stdout), or output redirection.
The local command itself returns exit status 0, which overwrites the exit status of the command in $?. To preserve the exit status, separate the declaration and assignment: 'local var; var=$(command)'
Local variables declared with 'local' cease to exist when the function returns. The global variable that was shadowed by the local variable becomes visible again once the function returns.
0 to 255 (8-bit unsigned integer). Return values outside this range will be truncated using modulo 256 arithmetic.
There is no default limit. By default, bash places no limit on the number of recursive calls. However, you can set FUNCNEST to a numeric value greater than 0 to define a maximum function nesting level.
No, return is designed to terminate execution of a function or sourced file. Using return outside of these contexts results in a non-zero exit status.
Use the special parameter $? immediately after the function call. This expands to the exit status of the most recently executed command or function.
Bash Builtin Commands > Special Builtins
32 questionsIf no options are supplied to unset, each name refers to a variable; if there is no variable by that name, a function with that name, if any, is unset.
The command enable -s restricts the output to the POSIX special builtins.
Syntax: break [n]. Exits from within a for, while, until, or select loop. If n is specified, break n levels. n must be ≥ 1. If n is greater than the number of enclosing loops, all enclosing loops are exited. Returns 0 unless n is not greater than or equal to 1.
The -a option causes the shell to pass name as the zeroth argument to the executed command.
If n is greater than $#, the positional parameters are not changed. n must be a non-negative number less than or equal to $#.
The colon (:) builtin command returns exit status 0 (zero). It does nothing beyond expanding arguments and performing any specified redirections.
If arg is absent (and there is a single sigspec) or -, each specified signal is reset to its original disposition (the value it had upon entrance to the shell).
If a sigspec is RETURN, the command arg is executed each time a shell function or a script executed with the . or source builtins finishes executing.
If the -T option is enabled, . inherits any trap on DEBUG; if it is not, any DEBUG trap string is saved and restored around the call to ., and . unsets the DEBUG trap while it executes.
If command cannot be executed for some reason, a non-interactive shell exits, unless the execfail shell option is enabled. In that case, it returns failure.
If 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.
The -l option supplies a dash at the beginning of the zeroth argument passed to the executed command, simulating what login(1) does.
If return is used outside a function, but during execution of a script by the . (source) command, it causes the shell to stop executing that script and return either n or the exit status of the last command executed within the script as the exit status of the script.
Bash has three categories of builtin commands: 1) Bourne Shell builtins (special builtins with specific POSIX behavior), 2) Bash builtins (regular builtins), and 3) Modified or added commands in Bash.
If n is greater than the number of enclosing loops in continue, the last enclosing loop (the 'top-level' loop) is resumed. n must be ≥ 1.
The ERR trap is not executed if the failed command is: part of the command list immediately following a while or until keyword, part of the test in an if statement, part of a command executed in a && or || list except the command following the final && or ||, any command in a pipeline but the last, or if the command's return value is being inverted using !.
If both -a (indexed arrays) and -A (associative arrays) options are supplied, -A takes precedence.
The -c option causes the executed command to be executed with an empty environment.
The return status of shift is greater than zero if n is greater than $# or less than zero; otherwise 0.
If the -n option is supplied, and name is a variable with the nameref attribute, name will be unset rather than the variable it references. -n has no effect if the -f option is supplied.
If any of BASH_ALIASES, BASH_ARGV0, BASH_CMDS, BASH_COMMAND, BASH_SUBSHELL, BASHPID, COMP_WORDBREAKS, DIRSTACK, EPOCHREALTIME, EPOCHSECONDS, FUNCNAME, GROUPS, HISTCMD, LINENO, RANDOM, SECONDS, or SRANDOM are unset, they lose their special properties, even if they are subsequently reset.
No, readonly variables may not be unset. The exit status is true unless a name is readonly or may not be unset.
If -T is not set, and the sourced file changes the DEBUG trap, the new value is retained when . completes.
If a sigspec is DEBUG, the command arg is executed before every simple command, for command, case command, select command, every arithmetic for command, and before the first command executes in a shell function.
Introduction
32 questionsA process group ID is a unique identifier that represents a process group during its lifetime.
Bash is intended to conform to the IEEE POSIX P1003.2/ISO 9945.2 Shell and Tools standard.
Shells may be used interactively or non-interactively. In interactive mode, they accept input typed from the keyboard. When executing non-interactively, shells execute commands read from a file or a string.
A token is a sequence of characters considered a single unit by the shell. It is either a word or an operator.
Job control is a mechanism by which users can selectively stop (suspend) and restart (resume) execution of processes.
POSIX stands for a family of open system standards based on Unix, and Bash is primarily concerned with the Shell and Utilities portion of the POSIX 1003.1 standard.
A shell is both a command interpreter and a programming language. As a command interpreter, the shell provides the user interface to the rich set of GNU utilities. The programming language features allow these utilities to be combined. Users can create files containing commands that become commands themselves with the same status as system commands in directories such as /bin.
Bash is largely compatible with sh (the Bourne shell) and incorporates useful features from the Korn shell (ksh) and the C shell (csh).
A name is a word consisting solely of letters, numbers, and underscores, and beginning with a letter or underscore. Names are used as shell variable and function names, also referred to as an identifier.
The official documentation is called the 'Bash Reference Manual', which is Edition 5.3, last updated 18 May 2025.
At its base, a shell is simply a macro processor that executes commands. The term macro processor means functionality where text and symbols are expanded to create larger expressions.
A control operator is a token that performs a control function. It is a newline or one of the following: '||', '&&', '&', ';', ';;', ';&', ';;&', '|', '|&', '(', or ')'.
The exit status is the value returned by a command to its caller. The value is restricted to eight bits, so the maximum value is 255.
A metacharacter is a character that, when unquoted, separates words. A metacharacter is a space, tab, newline, or one of the following characters: '|', '&', ';', '(', ')', '<', or '>'.
Bash is the shell, or command language interpreter, for the GNU operating system. It is an sh-compatible shell that incorporates useful features from the Korn shell (ksh) and the C shell (csh), intended to conform to the IEEE POSIX P1003.2/ISO 9945.2 Shell and Tools standard.
Bash incorporates useful features from the Korn shell (ksh) and the C shell (csh), such as command-line editing, unlimited size command history, job control, shell functions and aliases, indexed arrays, and integer arithmetic.
Redirection constructs permit fine-grained control of the input and output of commands through constructs like '>', '<', '>>', and pipe operators.
A process group is a collection of related processes each having the same process group ID.
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.
Shell builtins are commands that are implemented internally by the shell itself, rather than by an executable program somewhere in the file system. Examples include cd, break, continue, and exec which cannot be implemented outside of the shell because they directly manipulate the shell itself.
Whitespace is a character belonging to the 'space' character class in the current locale, or for which isspace() returns true.
Bash is an acronym for 'Bourne-Again SHell', a pun on Stephen Bourne, the author of the direct ancestor of the current Unix shell sh.
While the GNU operating system provides other shells including a version of csh, Bash is the default shell.
A special builtin is a shell builtin command that has been classified as special by the POSIX standard.
Bash offers functional improvements over sh for both programming and interactive use, including command-line editing, unlimited size command history, job control, shell functions and aliases, indexed arrays of unlimited size, and integer arithmetic in any base from two to sixty-four.
A builtin is a command that is implemented internally by the shell itself, rather than by an executable program somewhere in the file system.
A reserved word is a word that has a special meaning to the shell. Most reserved words introduce shell flow control constructs, such as 'for' and 'while'.
Bindable Readline Commands > Commands For Changing Text
31 questionsIn overwrite mode, characters bound to self-insert replace the text at point rather than pushing the text to the right. Characters bound to backward-delete-char replace the character before point with a space.
copy-region-as-kill copies the text in the region to the kill buffer without removing it from the line.
capitalize-word capitalizes the current (or following) word (first character uppercase, rest lowercase). With a negative argument, it capitalizes the previous word but does not move point. Default binding is M-c (Meta-c).
unix-line-discard kills backward from point to the beginning of the line and saves the killed text on the kill-ring. Default binding is C-u (Ctrl-u).
overwrite-mode toggles overwrite mode. With an explicit positive numeric argument, it switches to overwrite mode. With an explicit non-positive numeric argument, it switches to insert mode. This command only affects emacs mode; each call to readline() starts in insert mode by default.
Use tab-insert, which is bound to C-v TAB (press Ctrl-v then Tab). This inserts a literal tab character instead of triggering completion.
kill-region kills the text in the current region (the text between point and mark).
yank pastes the top of the kill ring into the buffer at point (cursor position). Default binding is C-y (Ctrl-y).
The default key binding for backward-delete-char is Rubout (Backspace/Delete key, depending on terminal configuration).
copy-forward-word copies the word following point to the kill buffer without deleting it. The word boundaries are the same as forward-word.
No, overwrite-mode is unbound by default and must be explicitly bound to a key sequence.
upcase-word uppercases the current (or following) word. With a negative argument, it uppercases the previous word but does not move point. Default binding is M-u (Meta-u).
yank-pop rotates the kill ring and yanks (pastes) the new top. It only works following yank or yank-pop. Default binding is M-y (Meta-y).
When Ctrl-d is read when there are no characters on the line and point is at the beginning of the line, readline interprets it as the end of input and returns EOF (end-of-file).
quoted-insert adds the next character typed to the line verbatim (literally), allowing insertion of control characters like C-q. Default key bindings are C-q (Ctrl-q) and C-v (Ctrl-v).
backward-kill-word kills the word behind point. Word boundaries are the same as those used by backward-word. Default binding is M-Rubout (Meta-Backspace).
backward-kill-line kills (cuts) backward from point to the beginning of the line. Default binding is C-x Rubout (Ctrl-x followed by Backspace).
kill-whole-line kills all characters on the current line, no matter where point is located.
shell-kill-word and shell-backward-kill-word use shell word boundaries (same as shell-forward-word and shell-backward-word), while kill-word and backward-kill-word use standard readline word boundaries (same as forward-word and backward-word). Shell word boundaries typically include more characters as part of words.
kill-word kills 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 forward-word. Default binding is M-d (Meta-d).
forward-backward-delete-char deletes the character under the cursor, unless the cursor is at the end of the line, in which case it deletes the character behind the cursor.
unix-filename-rubout kills the word behind point, using white space and the slash character (/) as the word boundaries. The killed text is saved on the kill-ring.
transpose-chars drags the character before point forward over the character at point, moving point forward as well. If point is at the end of the line, it transposes the two characters before point. Negative arguments have no effect. Default binding is C-t (Ctrl-t).
kill-line kills (cuts) the text from point (cursor position) to the end of the line. Default binding is C-k (Ctrl-k).
downcase-word lowercases the current (or following) word. With a negative argument, it lowercases the previous word but does not move point. Default binding is M-l (Meta-l).
When given a numeric argument, backward-delete-char saves the deleted text on the kill ring (clipboard). Without an argument, it simply deletes the character behind the cursor.
copy-backward-word copies the word before point to the kill buffer without deleting it. The word boundaries are the same as backward-word.
self-insert inserts the character typed. It is bound to all printable characters (letters, numbers, symbols, etc.).
transpose-words drags 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, it transposes the last two words on the line. Default binding is M-t (Meta-t or Alt-t).
Shell Commands > Lists
31 questionsUse 'declare -A name' to declare an associative array. Associative arrays were introduced in Bash 4.0 and must be explicitly declared before use.
You can use either explicit key-value syntax 'name=([key1]=value1 [key2]=value2)' or alternating keys and values 'name=(key1 value1 key2 value2)'. Both are treated identically. Keys must not be missing or empty; a final missing value is treated as empty string.
Referencing an array variable without a subscript is equivalent to referencing with a subscript of 0 (the first element).
Bash provides one-dimensional indexed and associative array variables. Indexed arrays are referenced using integers (including arithmetic expressions) and are zero-based. Associative arrays use arbitrary strings as keys.
Use parentheses syntax: 'name=(value1 value2 value3)'. Each value may optionally be of the form '[subscript]=string'. The entire list undergoes all shell expansions.
Use '${!name[@]}' or '${!name[*]}' to expand to the list of array indices (keys) assigned in the array. When within double quotes, '@' expands each key to a separate word.
Use '${#name[@]}' or '${#name[*]}' to get the number of elements in the array.
A negative offset in array slicing is taken relative to one greater than the maximum index of the specified array. You must separate the negative offset from the colon with a space to avoid confusion with the ':-' expansion operator: '${array[@]: -2}' gets the last 2 elements.
Within double quotes, '${array[*]}' expands to a single word with the value of each array member separated by the first character of IFS. '${array[@]}' expands each element to a separate word.
For an associative array, 'unset name[@]' or 'unset name[]' removes the element with key '@' or ''. For an indexed array, it removes all elements but does not remove the array itself.
Use '${#name[subscript]}' to get the length in characters of the element at that index.
Use 'unset name' where name is the array to remove the entire array. Using 'unset name[@]' or 'unset name[*]' on an indexed array removes all elements but does not remove the array itself.
Use the syntax 'name[subscript]=value'. For indexed arrays, the subscript is treated as an arithmetic expression that must evaluate to a number.
Yes, Bash arrays are sparse and there is no requirement that members be indexed or assigned contiguously. You can assign elements to arbitrary indices without requiring them to be sequential.
When assigning to an indexed array, if the name is subscripted by a negative number, that number is interpreted as relative to one greater than the maximum index of the array, so negative indices count back from the end.
Unless otherwise noted, indexed array indices must be non-negative integers. The only exception to this is negative indexing which counts back from the end of the array.
Use '${name[-1]}' to access the last element. Negative indices count back from the end of the array, where -1 is the last element, -2 is second-to-last, etc. This feature was added in Bash 4.2.
Use substring expansion syntax: '${name[@]:offset:length}' to get 'length' elements starting at 'offset'. For example, '${array[@]:1:3}' returns 3 elements starting at index 1. Omit 'length' to get all elements from offset to the end.
No, unsetting an array element does not re-index the array. The array retains gaps in its indices. To get a contiguous array after unsetting, you must rebuild it by copying non-empty elements to a new array.
Indexed arrays in Bash are zero-based, meaning the first element is at index 0.
When assigning to indexed arrays without an optional subscript, the index of the element assigned is the last index assigned to by the statement plus one. Indexing starts at zero.
If both options are supplied to declare, -A takes precedence and the variable is declared as an associative array.
Use '${name[@]}' or '${name[]}' to expand to all members of the array. The difference matters when within double quotes: '${name[]}' expands to a single word with values separated by the first character of IFS, while '${name[@]}' expands each element to a separate word.
Use the '+=' operator with compound assignment syntax: 'name+=(value1 value2)'. This appends the new elements to the array without deleting existing ones.
No, associative arrays must be explicitly declared using 'declare -A' before use. Unlike indexed arrays which can be created implicitly by assignment, associative arrays require explicit declaration.
There is no maximum limit on the size of an array in Bash, nor any requirement that members be indexed or assigned contiguously.
Yes, the braces are required when accessing array elements to avoid conflicts with the shell's filename expansion operators. Use '${name[subscript]}' syntax.
Yes, Bash arrays can contain both numbers and strings in the same array. All values are stored as strings regardless of whether they look like numbers.
Use the 'read' builtin with the '-a' option: 'read -a name' to assign a list of words read from standard input to an array.
Use 'declare -a name' to explicitly declare an indexed array. The syntax 'declare -a name[subscript]' is also accepted but the subscript is ignored.
Use 'unset name[subscript]' to destroy the array element at that index. Negative subscripts are interpreted as counting back from the end. Unsetting does not re-index the array.
Command Line Editing > Killing and Yanking
31 questionsThere is no default keybinding. backward-kill-line kills text from the cursor back to the beginning of the line. It can be bound to a key in .inputrc or via the bind command.
There is no default keybinding. kill-whole-line kills all characters on the current line, no matter where the cursor is positioned. It can be bound to a key in .inputrc or via the bind command.
No. yank-pop (M-y) only works immediately after a yank (C-y). If pressed without a preceding yank in the same command sequence, it has no effect.
DEL (Backspace) or C-h (Ctrl+H). This deletes the character behind the cursor. Unlike kill commands, this does not save to the kill-ring.
There is no default keybinding. This kills (cuts) the text between the cursor and the mark. Requires first setting a mark with set-mark (C-@ or C-SPC). Can be bound via bind command or .inputrc.
C-y (Ctrl+Y). This yanks back the last killed text from the kill-ring at the current cursor position.
No. C-w uses whitespace as the word boundary, while M-DEL uses alphanumeric characters as word boundaries (defined by readline's word characters). For example, in 'foo/bar', C-w would kill 'foo/bar' as one unit, while M-DEL would only kill 'bar'.
C-x C-x (Ctrl+X followed by Ctrl+X). This swaps the cursor position with the mark position.
There is no default keybinding. This deletes all spaces and tabs around the cursor. It can be bound via bind command or .inputrc.
The kill-ring has no fixed maximum size limit by default. It grows as items are killed. The kill-ring preserves previously killed text in order for yanking.
M-d (Meta/Alt+D). This kills (cuts) the word from the cursor position forward to the end of the word.
C-w (Ctrl+W) or M-DEL (Meta/Alt+Backspace). This kills (cuts) the word behind the cursor, using whitespace as the word boundary.
There is no default keybinding. This copies the word before the cursor to the kill-ring without deleting it.
C-k (Ctrl+K). This kills (cuts) all text from the current cursor position to the end of the line and stores it in the kill-ring.
C-d (Ctrl+D). This deletes the character at the cursor. Unlike kill commands, this does not save to the kill-ring unless the character is a EOF at an empty line.
The 'kill-ring' behavior is automatic for kill commands. There is no variable to disable it - all kill commands (kill-line, kill-word, etc.) automatically save to the kill-ring, while delete commands (delete-char, backward-delete-char) do not.
C-d at an empty line sends EOF (End-Of-File) and will exit the shell or terminate the current command (like exit), unless ignoreeof is set. This is different from its behavior when there is text on the line.
M-d (Meta/Alt+D). This kills (cuts) the word from the cursor position forward to the end of the word, using alphanumeric characters as word boundaries.
M-C-y (Meta+Ctrl+Y). This yanks the nth argument from the previous command, prompted by a digit. After entering M-C-y, you type a digit to specify which argument to retrieve (0 for command name, 1 for first argument, etc.).
C-u (Ctrl+U). This kills (cuts) all text from the current cursor position to the beginning of the line and stores it in the kill-ring.
M-DEL (Meta/Alt+Backspace) or M-C-? (Meta+Ctrl+?). This kills (cuts) the word behind the cursor, using alphanumeric characters as word boundaries (not just whitespace like C-w).
There is no default keybinding. This command copies the region (marked text) to the kill-ring without deleting it. It requires setting a mark first with set-mark (C-@ or C-SPC).
C-w (Ctrl+W). This kills (cuts) the word behind the cursor, using whitespace as the word boundary, matching Unix terminal behavior.
kill-word (M-d) considers words as sequences of alphanumeric characters plus underscore (defined by readline's word-characters), while unix-word-rubout (C-w) uses only whitespace as boundaries. For 'hello-world', M-d kills only 'world', while C-w kills 'hello-world'.
M-. (Meta/Alt+Period) or M-_ (Meta/Alt+Underscore). This yanks the last argument from the previous command. Repeated execution cycles backward through the command history.
Use the bind builtin command: 'bind "\C-xk": kill-whole-line' or add to ~/.inputrc: '"\C-xk": kill-whole-line'. The bind command affects the current shell session, while .inputrc affects all readline applications.
There is no default keybinding. This copies the word after the cursor to the kill-ring without deleting it.
M-y (Meta/Alt+Y). This must be used immediately after a yank (C-y) to cycle through previously killed text in the kill-ring. Each M-y replaces the yanked text with the previous item in the kill-ring.
Consecutive kill commands append to the kill-ring entry rather than creating separate entries. For example, pressing M-d multiple times kills multiple words into a single kill-ring entry that can be yanked together.
C-@ (Ctrl+@) or C-SPC (Ctrl+Space). This sets the mark at the current cursor position, used in combination with kill-region or copy-region-as-kill.
C-u (Ctrl+U). This is an alias for killing from the cursor to the beginning of the line, behavior that matches Unix terminal line discipline.
Bourne Shell Builtins > Command Execution
30 questionsIn trap, using an empty string ('') as the action causes the signal to be ignored.
When exec is used with a command, redirections are applied to the new command that replaces the shell. When used without a command, redirections persist in the current shell.
The default value for n in continue [n] is 1, meaning it continues with the next iteration of the immediately enclosing loop.
The trap builtin allows you to specify commands to be executed when the shell receives signals or other events. It can trap signals and execute cleanup handlers.
When exec is called without arguments, it only redirects file descriptors for the current shell without replacing the shell with a new process.
When trap is executed with trap - signal, it resets each signal to the default disposition for the shell.
When return is used outside of a function or script executed with the . or source commands, it has the same effect as exit.
The break builtin exits from a for, while, until, or select loop. If a number n is provided, it breaks out of n enclosing loops.
The eval builtin does not have a -p option. eval only takes arguments to be concatenated and executed as a single command.
The times builtin outputs two lines: the first line shows user and system time for the shell itself, and the second line shows user and system time for all child processes. Times are displayed in minutes and seconds.
The : builtin does nothing and returns a successful exit status (0). It expands arguments but performs no other actions. It is often used as a placeholder in conditional constructs or to provide a successful exit status.
The wait builtin accepts both job IDs (prefixed with %) and process IDs as arguments.
The default value for n in shift [n] is 1, meaning it shifts positional parameters by one position.
The return builtin causes a function to exit with a specified return value. If n is omitted, the return status is that of the last executed command.
When exit is called without an argument, the shell exits with the exit status of the last command executed.
Yes, exec can be used solely for redirection purposes. For example, exec 3<file opens file descriptor 3 for reading without replacing the shell process.
When exec is executed with a command, it replaces the current shell process with the new command without creating a new process. The original shell process is destroyed and does not return.
The exit builtin causes the shell to exit with a given status. If n is omitted, the exit status is that of the last executed command.
The . builtin reads and executes commands from the filename argument in the current shell context. It is equivalent to the source command.
The wait builtin waits for the specified background process(es) to complete and returns their exit status. If no arguments are given, it waits for all currently active child processes.
When wait is used with multiple jobs, it returns the exit status of the last job waited for.
If the file specified in . or source cannot be read, the shell returns a non-zero exit status and an error message is displayed (unless in non-interactive mode with certain options set).
The continue builtin skips the rest of the current loop iteration and begins the next iteration of a for, while, until, or select loop. If n is provided, it resumes with the n-th enclosing loop.
In a shell function, return exits only the function and returns to the calling context, while exit terminates the entire shell session or script.
The default value for n in break [n] is 1, meaning it breaks out of the immediately enclosing loop.
The shift builtin shifts the positional parameters to the left by n positions. The parameter that was $1 is discarded, $2 becomes $1, and so on. Parameters shifted out are deleted.
The . builtin executes commands in the current shell context, not in a subshell. This means variables and functions defined in the sourced file remain available after the command completes.
When shift is executed with n greater than $# (the number of positional parameters), the positional parameters become empty. This is not considered an error.
The eval builtin concatenates its arguments into a single command, then reads and executes the resulting command. This allows for dynamic command construction and execution.
Executing Commands > Exit Status and Return Codes
30 questionsCommands separated by semicolons execute sequentially regardless of exit status. The exit status of the entire list is the exit status of the last command executed.
An if statement returns exit status 0 if no condition matches and no else clause is present. With an else clause, it returns the exit status of the last command executed in the else body.
The && operator executes the second command only if the first command returns an exit status of 0 (success). If the first command fails (non-zero exit), the second command is not executed.
If a script terminates without an explicit exit or return statement, it returns the exit status of the last command executed in the script.
An exit status of 0 indicates successful execution. In Bash, 0 means success while non-zero values (1-255) indicate failure or error conditions.
The return builtin, when used without an argument, returns the exit status of the last executed command. If used in a function, it returns from the function with that status.
The : (colon) null command always returns exit status 0. It does nothing and is often used as a placeholder or to evaluate variables for their side effects.
A for loop returns the exit status of the last command executed in the loop body, or 0 if no commands were executed.
The false command always returns exit status 1. It indicates failure and does nothing.
When a command is terminated by a signal, the exit status is 128 plus the signal number. For example, SIGINT (signal 2) produces exit status 130 (128 + 2), SIGTERM (signal 15) produces exit status 143 (128 + 15).
The test command (or [) returns exit status 0 when the test condition evaluates to true, and exit status 1 when the condition is false.
When a command is found but cannot be executed (e.g., due to missing execute permissions), Bash returns exit status 126.
When exit is called without arguments in a script, it causes the script to exit with the exit status of the last command executed before the exit call.
A case statement returns the exit status of the last command executed in the case body, or 0 if no commands were executed.
Bash exit status values range from 0 to 255. The value is stored in the special parameter $?. Exit status values above 255 are masked modulo 256.
The || operator executes the second command only if the first command returns a non-zero exit status (failure). If the first command succeeds (exit status 0), the second command is not executed.
Both { list; } and ( list ) return the exit status of the last command in the list. The difference is that ( ) creates a subshell while { } does not.
With && and || operators, execution is short-circuited based on exit status. The exit status of the entire expression is the exit status of the last command actually executed.
The trap command returns exit status 0 if successful, and non-zero if an error occurs (e.g., invalid signal specification).
The special parameter $? holds the exit status of the last command executed. It is updated after every command execution, including pipeline commands.
A while loop returns the exit status of the last command executed within the loop body, or 0 if no commands were executed.
When exit is given a negative value, Bash uses the two's complement representation. Exit values are treated as unsigned 8-bit integers, so exit -1 is equivalent to exit 255.
When a command is not found, Bash returns exit status 127. This is the standard exit code for 'command not found' errors.
When exit is used without an argument, it returns the exit status of the last command executed. This preserves the error state of the script.
The ! operator inverts the exit status: if the command returns 0, ! returns 1. If the command returns non-zero, ! returns 0. The actual exit status is 0 if the command was non-zero, and 1 if the command was zero.
When set -o pipefail is enabled, the pipeline returns the last (rightmost) command to exit with a non-zero status, or zero if all commands exit successfully.
An until loop returns the exit status of the last command executed within the loop body, or 0 if no commands were executed.
Without set -o pipefail, the exit status of a pipeline is the exit status of the last command in the pipeline. Earlier command failures are ignored.
The true command always returns exit status 0. It is successful and does nothing.
Reading $? does not modify its value, but executing any command (including even simple commands like echo $?) will update $? to the exit status of that command.
Definitions
30 questionsThe control operators are: newline, ||, &&, &, ;, ;;, ;&, ;;&, |, |&, (, and ). These are tokens that perform a control function.
The case-specific control operators are ;; (terminates a case), ;& (fall through to next case), and ;;& (fall through and test next pattern). These were added in Bash 4.0.
There is no difference - 'return status' is a synonym for 'exit status'. Both refer to the value returned by a command to its caller.
A builtin is a command that is implemented internally by the shell itself, rather than by an executable program somewhere in the file system.
The |& control operator pipes both stdout and stderr to the next command. It is equivalent to 2>&1 |.
A name consists solely of letters, numbers, and underscores, and must begin with a letter or underscore. Names are used as shell variable and function names.
A process group is a collection of related processes each having the same process group ID.
'in' is recognized as a reserved word if it is the third word of a 'case' or 'select' command. 'in' and 'do' are recognized as reserved words if they are the third word in a 'for' command. Otherwise, reserved words are recognized when unquoted and the first word of a command.
An operator is a control operator or a redirection operator. Operators contain at least one unquoted metacharacter.
A token is the broader category - it can be either a word or an operator. A word is a sequence of characters treated as a unit by the shell, and words may not include unquoted metacharacters.
A process group ID is a unique identifier that represents a process group during its lifetime.
No. A name must begin with a letter or underscore, not a number. It can only contain letters, numbers, and underscores after the first character.
The maximum value is 255. The exit status is restricted to eight bits, so values range from 0 to 255.
In Bash, 'name' and 'identifier' are synonyms. Both refer to a word consisting solely of letters, numbers, and underscores, beginning with a letter or underscore.
The reserved words are: !, {, }, case, coproc, do, done, elif, else, esac, fi, for, function, if, in, select, then, until, while, time, [[, ]].
The metacharacters are: space, tab, newline, |, &, ;, (, ), <, and >. When unquoted, these characters separate words.
Since exit status is restricted to eight bits, only the least significant 8 bits are used. For example, exit 3809 would result in exit code 225 (3809 % 256 = 225).
A special builtin is a shell builtin command that has been classified as special by the POSIX standard.
The single ; is a command separator that executes commands sequentially. The double ;; is a case statement terminator that ends a specific case pattern.
A word is a sequence of characters treated as a unit by the shell. Words may not include unquoted metacharacters.
A job is a set of processes comprising a pipeline, and any processes descended from it, that are all in the same process group.
A 'blank' is specifically a space or tab character. 'Whitespace' is any character belonging to the space character class in the current locale, or for which isspace() returns true.
A reserved word is a word that has a special meaning to the shell. Most reserved words introduce shell flow control constructs, such as 'for' and 'while'.
A token is a sequence of characters considered a single unit by the shell. It is either a word or an operator.
POSIX is a family of open system standards based on Unix. Bash is primarily concerned with the Shell and Utilities portion of the POSIX 1003.1 standard.
A signal is a mechanism by which a process may be notified by the kernel of an event occurring in the system.
Job control is a mechanism by which users can selectively stop (suspend) and restart (resume) execution of processes.
A field is 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.
Job Control > Interactive vs Non-Interactive Behavior
30 questionsAn interactive non-login shell reads and executes commands from ~/.bashrc if that file exists.
Interactive shells do not use 'set -e' by default - errors in commands do not cause the shell to exit. Non-interactive shells also do not enable 'set -e' by default, but scripts commonly use it explicitly for error handling.
The 'disown' builtin is not available in non-interactive shells unless job control is enabled with 'set -m'. It removes jobs from the shell's job table, which requires an active job table maintained by job control.
In interactive shells, SIGINT interrupts the current command but not the shell itself, and the shell displays the next prompt. In non-interactive shells, SIGINT typically causes the shell to exit, unless caught in a trap.
No, job control messages like '[1]+ Done command' are not displayed in non-interactive shells. The shell does not report job status changes unless job control is explicitly enabled and the shell has a controlling terminal.
The 'fg', 'bg', 'jobs', 'disown', 'suspend', and 'wait' builtins are unavailable or non-functional when job control is disabled in a non-interactive shell.
An interactive login shell reads and executes commands from /etc/profile, then looks for ~/.bash_profile, ~/.bash_login, or ~/.profile (in that order), and executes the first one that exists and is readable.
Yes, you can force job control in a script by adding 'set -m' at the beginning, or by using the shebang '#!/bin/bash -m', but this is unusual and the script still needs a controlling terminal for full job control functionality.
Yes, job control is enabled by default in interactive shells. The shell starts with job control active when running interactively.
No, the 'suspend' builtin (which suspends the shell until a SIGCONT signal) is not functional in non-interactive shells without a controlling terminal. It requires job control and terminal control to operate.
The '-m' option (monitor mode) or 'set -m' / 'set -o monitor' enables job control in bash.
No, non-interactive shells do not expand aliases by default. Aliases are expanded by default only in interactive shells. The 'expand_aliases' shell option must be set in a non-interactive shell to use aliases.
The 'm' character in the $- special parameter indicates that job control (monitor mode) is enabled. For example, if 'echo $-' shows 'himBH', the 'm' means job control is active.
Bash determines if a shell is interactive by checking: 1) it was started without non-option arguments and without -c, 2) both standard input and standard error are connected to terminals, or 3) it was started with the -i option. It also checks if the 'i' flag in the $- special parameter is set.
When a non-interactive shell exits, background processes started with '&' become orphaned and are typically reparented to init or the system's init process (PID 1). Without job control, the shell does not track or manage these processes.
No, history expansion (using ! to recall previous commands) is disabled by default in non-interactive shells. It is enabled by default only in interactive shells.
A shell has a controlling terminal if it is started with stdin/stdout/stderr connected to a terminal device (tty/pty). Non-interactive shells typically lack a controlling terminal, which prevents full job control operation.
The BASH_ENV environment variable controls startup behavior for non-interactive shells. When set, bash expands its value and uses it as the name of a file to read and execute before running the script.
The 'read' command's -t timeout option works in both interactive and non-interactive shells, but it's primarily useful in interactive shells since non-interactive shells read from scripts or redirected input, not terminals.
Yes, you can enable job control in a non-interactive shell by using 'set -m' or 'set -o monitor', but this is uncommon as script execution typically doesn't involve terminal job control.
Interactive shells ignore SIGTERM and SIGTTIN signals. They also catch and handle SIGINT (Ctrl+C), SIGQUIT, and SIGTSTP (Ctrl+Z) specially to manage job control. Non-interactive shells do not have these special signal handling behaviors.
No, the 'jobs' builtin does not work in a non-interactive shell unless job control is explicitly enabled with 'set -m'. The shell does not maintain a job table without job control active.
A non-interactive shell can use process groups if job control is enabled with 'set -m', but without a controlling terminal, full job control functionality (like foreground/background switching with terminal control) is not available.
No, non-interactive shells do not source ~/.bashrc by default. They look for the environment variable BASH_ENV and if it is set, expands its value and uses it as the name of a file to read and execute.
In a non-interactive shell, commands started with '&' still execute in the background, but the shell does not place them in job control groups, does not track them in a job table, and cannot manipulate them with job control builtins.
Yes, the 'wait' builtin works in non-interactive shells without job control to wait for specific process IDs, but it cannot wait for job specifications (like 'wait %1') without job control maintaining a job table.
No, 'fg' and 'bg' builtins are not functional in non-interactive shell scripts unless job control is explicitly enabled with 'set -m', and even then they require a controlling terminal to function properly.
An interactive shell is one started without non-option arguments and without the -c option, with standard input and error connected to terminals, or one started with the -i option. Interactive shells also have the 'ps1' prompt set.
The 'i' character in the $- special parameter indicates that the shell is interactive. For example, if 'echo $-' shows 'himBH', the 'i' means the shell is in interactive mode.
When job control is not active, background jobs (those started with &) report their job status but the shell does not maintain a job table, and job control builtins like 'fg', 'bg', and 'jobs' are not available.
Shell Arithmetic > Bitwise Operations
30 questionsThe result is 1. Right shifting 8 by 3 positions is equivalent to 8 / 2^3 = 8 / 8 = 1.
Yes, Bash supports hexadecimal notation (0x prefix) with bitwise operations. Example: $((0xA & 0x5)) evaluates to 0 (10 AND 5 = 0).
The & operator performs bitwise AND on individual bits, while && performs logical AND and returns 1 or 0 based on truthiness. $((5 & 3)) = 1, but $((5 && 3)) = 1.
The symbol for right shift in Bash is >> (double greater-than). Example: $((5 >> 1)) evaluates to 2.
The | operator performs bitwise OR on individual bits, while || performs logical OR and returns 1 or 0 based on truthiness. $((5 | 3)) = 7, but $((5 || 3)) = 1.
In Bash, bitwise AND (&) has higher precedence than bitwise XOR (^), which has higher precedence than bitwise OR (|).
The result is -1. Right shifting -1 preserves the sign bit due to arithmetic shift in two's complement.
Bitwise AND (&) has higher precedence than logical AND (&&) in Bash arithmetic expressions.
The result is 8. Left shifting 1 by 3 positions is equivalent to 2^3 = 8.
Bitwise shift operators (<<, >>) have lower precedence than arithmetic operators (+, -, *, /, %) but higher precedence than comparison operators.
No, bitwise operators do not work in [[ ]] or [ ] test constructs. They only work in arithmetic context: $(( )), (( )), or let.
The result is -1. In two's complement representation, inverting all bits of 0 yields -1.
Bash evaluates this as ((2 & 3) | 4) because & has higher precedence than |. This equals (2 | 4) = 6.
The symbol for bitwise OR in Bash is | (single pipe). Example: $((5 | 3)) evaluates to 7.
The result is 15. In binary: 11111111 & 00001111 = 00001111, which equals 15.
Right shifting a negative number performs an arithmetic shift, preserving the sign bit. The result depends on the two's complement representation.
The bitwise NOT operator (~) has higher precedence than other bitwise operators and is evaluated before &, |, ^, <<, and >>.
Yes, bitwise operations can be used with array elements within arithmetic expansion. Example: $((array[i] & mask)).
Yes, Bash supports &=, |=, ^=, <<=, and >>= for bitwise operations. Example: (( x &= mask )) is equivalent to (( x = x & mask )).
Bash supports octal notation (0 prefix) with bitwise operations. Example: $((010 & 007)) involves octal 8 and 7.
The symbol for bitwise NOT in Bash is ~ (tilde). Example: $((~5)) evaluates to -6 due to two's complement representation.
The symbol for bitwise AND in Bash is & (single ampersand). Example: $((5 & 3)) evaluates to 1.
The result is 15 (or 0x0F in hexadecimal). The bitwise AND of 255 (0xFF) and 15 (0x0F) equals 15.
Yes, Bash uses signed 64-bit integers for arithmetic operations on most modern systems, including bitwise operations.
The symbol for bitwise XOR in Bash is ^ (caret). Example: $((5 ^ 3)) evaluates to 6.
Yes, Bash handles negative numbers using two's complement representation. Example: $((~0)) evaluates to -1.
The symbol for left shift in Bash is << (double less-than). Example: $((5 << 1)) evaluates to 10.
Yes, bitwise operations work with let, (( )), and $(( )) syntax. Example: let 'x = 5 & 3' or (( x = 5 | 3 )).
Left shift by n positions is equivalent to multiplying by 2^n. Right shift by n positions is equivalent to integer division by 2^n. Example: $((5 << 2)) equals 20 (5 * 4).
Bitwise XOR (^) has lower precedence than addition (+) and subtraction (-) in Bash arithmetic expressions.
Readline Init File > Init File Structure
29 questionsThe default is ~/.inputrc. If that file does not exist or cannot be read, the ultimate default is /etc/inputrc.
Empty or null values, 'on' (case-insensitive), and '1' are all equivalent to On.
The $include directive takes a single filename as an argument and reads commands and bindings from that file. For example: $include /etc/inputrc
"keyseq":function-name or macro. For example: "\C-u": universal-argument or "\C-x\C-r": re-read-init-file.
Blank lines (ignored), lines beginning with # (comments), lines beginning with $ (conditional constructs), and lines denoting key bindings and variable settings.
keyname:function-name or macro. For example: Control-u: universal-argument. The keyname and function/macro are separated by a colon with no whitespace allowed between the name and colon.
The INPUTRC environment variable specifies the initialization file location. When unset, readline defaults to ~/.inputrc.
The term= test checks against the full terminal name AND the portion of the terminal name before the first hyphen. For example, 'sun' matches both 'sun' and 'sun-cmd'.
Single or double quotes should be used to indicate a macro definition. Unquoted text is assumed to be a function name.
No, symbolic character names are not recognized within double-quoted key sequences. Only GNU Emacs style escape sequences can be used there.
$if (begins conditional test), $else (executes if test fails), $endif (terminates an $if command), $include (reads commands from another file).
Yes, the operator may be separated from the string version and from the version number argument by whitespace.
mode (tests emacs or vi editing mode), term (terminal type), version (readline version comparison), application (application-specific settings), variable (readline variable equality tests).
DEL, ESC, ESCAPE, LFD, NEWLINE, RET, RETURN, RUBOUT, SPACE, SPC, and TAB.
The $ character starts conditional constructs ($if, $else, $endif, $include).
\a (alert/bell), \b (backspace), \d (delete), \f (form feed), \n (newline), \r (carriage return), \t (horizontal tab), \v (vertical tab), \nnn (octal value 1-3 digits), \xHH (hexadecimal value 1-2 digits).
Major version number, an optional decimal point, and an optional minor version (e.g., 7.1). If the minor version is omitted, it is assumed to be 0.
\C- (control prefix), \M- (meta prefix), \e (escape character), \ (backslash), " (literal double quote), ' (literal single quote).
History Expansion > Modifiers
29 questionsWhen applied to a filename without a dot (e.g., 'Makefile'), :r returns the filename unchanged, and :e returns an empty string (as there's no suffix to extract).
When applied to a simple filename without any path (e.g., 'file.txt'), :h returns the filename unchanged (as there's no directory component to remove), and :t also returns the filename unchanged (as there's no path to strip).
There is no :X modifier. The split-and-quote modifier is lowercase :x, not uppercase. The :x modifier quotes words and breaks them at whitespace and tabs.
The :l modifier converts the first character of the word to lowercase. For example, if the history word is 'FILE', then ':l' makes it 'fILE'.
When used with word designators like :*, :g causes the expansion to apply to all words. When used with :s or :&, the :g modifier causes the substitution to be applied to all occurrences of the pattern rather than just the first.
There is no :V modifier in standard bash history expansion. The available modifiers are :h, :t, :r, :e, :p, :s, :&, :g, :a, :q, and :x.
The :e modifier removes all but the trailing suffix (extension). For example, if history contains 'echo file.txt', then 'echo !!:1:e' outputs '.txt'.
The :u modifier converts the first character of the word to uppercase. For example, if the history word is 'file', then ':u' makes it 'File'.
The :a modifier expands each word in the expansion as if it were quoted with $'...' syntax, which allows escape sequences to be preserved.
The :x modifier quotes the substituted words like :q but also breaks them into words at whitespace and tab characters. Each word is quoted separately.
The :h modifier removes a trailing pathname component, leaving only the head (directory portion). For example, if history contains 'echo /usr/local/bin/file', then 'echo !!:1:h' outputs '/usr/local/bin'.
The :U modifier converts the entire word to uppercase. For example, if the history word is 'file', then ':U' makes it 'FILE'.
The :s/old/new/ modifier substitutes the first occurrence of 'old' with 'new'. For example, if history contains 'echo foo bar foo', then '!!:s/foo/baz/' expands to 'echo baz bar foo'.
The :L modifier converts the entire word to lowercase. For example, if the history word is 'FILE', then ':L' makes it 'file'.
There is no :Q modifier. The quoting modifier is lowercase :q, not uppercase. The :q modifier quotes the substituted words to prevent further expansion.
The :r modifier removes only the last suffix. For 'file.tar.gz', :r removes '.gz' resulting in 'file.tar', not 'file'.
The :q modifier quotes the substituted words as needed to prevent further expansion. This protects special characters from being interpreted.
The :g modifier causes changes to be applied globally (to all occurrences) rather than just the first. For example, 'echo foo bar foo' with ':gs/foo/baz/' becomes 'echo baz bar baz'.
If an invalid modifier is specified, bash treats it as a substitution failure. No expansion is performed for that word when histreexp is set, or the expansion is not attempted when histreexp is not set.
Any character can be used as the delimiter in the :s modifier. The delimiter is the first character following 's'. For example, '!!:s|old|new|' or '!!:s:old:new:' are both valid.
The :& modifier requires that a previous substitution has been performed. It repeats the most recent substitution pattern. If no previous substitution exists, it has no effect.
The :p modifier can be combined with other modifiers. When :p is present, the entire history expansion is printed but not executed, regardless of other modifiers applied. For example, '!!:s/foo/bar/:p' prints the substitution result without running it.
There is no :% modifier in bash history expansion. The percent sign (%) is used in the history expansion event designator !% to refer to the most recent command matched by string search, but it is not a word modifier.
The :p modifier causes the history expansion to be printed but not executed. This is useful for previewing what the expanded command will be before running it.
The :G modifier is not a standard bash history expansion modifier. The standard global modifier is lowercase :g which must appear immediately after the colon or just before :s, :&, or :~.
Yes, multiple modifiers can be combined and are applied in order from left to right. For example, '!!:1:r:t' first removes the suffix (:r), then removes leading pathname components (:t).
The :& modifier repeats the previous substitution. For example, if the previous command used :s/foo/baz/, then '!!:&' applies the same foo→baz substitution to the current command.
The :r modifier removes a filename suffix (extension) of the form '.suffix'. For example, if history contains 'echo file.txt', then 'echo !!:1:r' outputs 'file'.
The :t modifier removes all leading pathname components, leaving only the tail (filename portion). For example, if history contains 'echo /usr/local/bin/file', then 'echo !!:1:t' outputs 'file'.
Quoting > Basic Quoting Mechanisms
29 questionsThe expanded result is single-quoted, as if the dollar sign had not been present.
The gettext infrastructure performs the lookup and translation using the LC_MESSAGES, TEXTDOMAINDIR, and TEXTDOMAIN shell variables.
The history expansion character is usually !. When the command history expansion facilities are being used, the history expansion character must be quoted to prevent history expansion.
Backslashes preceding characters without a special meaning are left unmodified (not removed).
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 (see Shell Parameter Expansion for details).
A non-quoted backslash () is the Bash escape character. It preserves the literal value of the next character that follows, removing any special meaning it has, with the exception of newline.
Yes, when history expansion is enabled, ! has special meaning within double quotes and will trigger history expansion unless escaped with a backslash. When the shell is in POSIX mode, ! has no special meaning within double quotes, even when history expansion is enabled.
Character sequences of the form $'string' are treated as a special kind of single quotes. The sequence expands to string, with backslash-escaped characters in string replaced as specified by the ANSI C standard.
The \xHH escape sequence accepts one or two hexadecimal digits and represents the eight-bit character whose value is the hexadecimal value HH.
By default, translated strings remain double-quoted. This is because locale-specific translation is a form of double quoting.
Yes. Within double quotes, backslashes that are followed by one of the special characters ($, `, ", , or newline) are removed.
Each of the shell metacharacters has special meaning to the shell and must be quoted if it is to represent itself.
The \uHHHH escape sequence represents the Unicode character whose value is the hexadecimal value HHHH (one to four hex digits), while \UHHHHHHHH represents the Unicode character whose value is the hexadecimal value HHHHHHHH (one to eight hex digits).
No. A single quote may not occur between single quotes, even when preceded by a backslash.
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.
ANSI-C quoting supports these escape sequences: \a (alert/bell), \b (backspace), \e or \E (escape character), \f (form feed), \n (newline), \r (carriage return), \t (horizontal tab), \v (vertical tab), \ (backslash), ' (single quote), " (double quote), ? (question mark), \nnn (octal value, 1-3 digits), \xHH (hexadecimal value, 1-2 digits), \uHHHH (Unicode character, 4 hex digits), \UHHHHHHHH (Unicode character, 8 hex digits), \cx (control-x character).
Prefixing a double-quoted string with a dollar sign, such as $"hello, world", causes the string to be translated according to the current locale using the gettext infrastructure.
Within double quotes, the characters $, `, \ retain their special meaning. Additionally, ! retains special meaning when history expansion is enabled (except in POSIX mode).
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.
If the current locale is C or POSIX, if there are no translations available, or if the string is not translated, the dollar sign is ignored and the string is treated as double-quoted.
The four quoting mechanisms in Bash are: the escape character, single quotes, double quotes, and ANSI-C quoting (dollar-single quotes). Locale-Specific Translation is also listed as a fifth mechanism in some contexts.
Within double quotes, the backslash retains its special meaning only when followed by one of the following characters: $, `, ", , or newline.
If history expansion is enabled, it will be performed on ! appearing in double quotes unless the ! is escaped using a backslash. The backslash preceding the ! is not removed.
The \cx escape sequence represents a control-x character (for example, \cM is control-M, which is carriage return).
A metacharacter is a character that, when unquoted, separates words. A metacharacter is a space, tab, newline, or one of the following characters: |, &, ;, (, ), <, >.
If the noexpand_translation option is enabled using the shopt builtin, translated strings are single-quoted instead of double-quoted.
The \nnn escape sequence accepts one to three octal digits and represents the eight-bit character whose value is the octal value nnn.
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).
Shell Syntax > Shell Processing Mechanics
29 questionsExit status 127 indicates that a command or file could not be found on the system (not found in PATH or specified path does not exist).
If a command is followed by '&' and job control is not active, the default standard input for the command is the empty file /dev/null. Otherwise, the command inherits the file descriptors of the calling shell as modified by redirections.
Traps caught by the shell are reset to the values inherited from the shell's parent, and traps ignored by the shell are ignored in the separate execution environment.
In POSIX mode, brace expansion is disabled by default. Brace expansion can be controlled with 'set -B' to enable or 'set +B' to disable.
The 'hash -r' command clears the entire hash table. 'hash -d
Only brace expansion, word splitting, and filename expansion can increase the number of words. Other expansions (tilde, parameter, arithmetic, command substitution) expand a single word to a single word. The exceptions are the expansions of "$@" and $, and "${name[@]}" and ${name[]}.
Brace expansion sequence expressions take the form {x..y[..incr]} where x and y are either integers or letters, and incr is an optional integer increment. When integers are supplied, it expands to each number between x and y inclusive. When letters are supplied, it expands to each character lexicographically between x and y inclusive. The default increment is 1 or -1 as appropriate.
The string '${' is not considered eligible for brace expansion and inhibits brace expansion until the closing '}'. This avoids conflicts with parameter expansion.
A subshell is a copy of the shell process. Command substitution, commands grouped with parentheses, asynchronous commands, and builtin commands invoked as part of a pipeline (except possibly the last element with lastpipe option) are invoked in a subshell environment.
Bash uses a hash table to remember the full pathnames of executable files. Once a command is found in PATH, its location is cached. Bash performs a full search of PATH directories only if the command is not found in the hash table.
Quote removal is performed after all other expansions. Quote characters present in the original word are removed unless they have been quoted themselves.
The default value of IFS is
PIPESTATUS is an array variable that contains the exit status of all commands in the last pipeline. PIPESTATUS[0] contains the exit status of the first command, PIPESTATUS[1] the second, and so on.
shopt options are Bash-specific extensions, while set -o options are portable across Bourne-based shells (like ksh, dash). For example, 'set -o vi' works the same in ksh and bash, but 'shopt' options are unique to Bash.
The use of time as a reserved word permits timing of shell builtins, shell functions, and pipelines. An external time command (e.g., /usr/bin/time) cannot easily time these constructs. For example, 'time cmd1 | cmd2' times the entire pipeline when using the reserved word, but '/usr/bin/time cmd1 | cmd2' only times cmd1.
The seven types of shell expansion in order are: 1) Brace expansion, 2) Tilde expansion, 3) Parameter and variable expansion, 4) Arithmetic expansion, 5) Command substitution, 6) Word splitting, 7) Filename expansion. Tilde expansion, parameter/variable expansion, arithmetic expansion, and command substitution are performed in a left-to-right fashion. After all expansions, quote removal is performed. Process substitution is performed at the same time as tilde, parameter, variable, and arithmetic expansion and command substitution.
Bash searches for commands in this order: 1) Aliases (in interactive shells), 2) Shell functions, 3) Shell builtin commands, 4) Hash table (cached executables), 5) Directories in PATH variable (searched left to right). The search stops at the first match.
The 'set -o pipefail' option causes a pipeline to return the exit status of the last command to exit with a non-zero status, or zero if all commands exit successfully. This is available in Bash version 3 and beyond.
POSIX mode can be enabled by starting bash with the --posix command-line option or by using the 'set -o posix' command.
When PATH changes, Bash does not automatically invalidate the hash table. Commands executed after PATH changes may still use cached paths. Use 'hash -r' to clear the hash table and force a new PATH search.
A correctly-formed brace expansion must contain unquoted opening and closing braces, and at least one unquoted comma or a valid sequence expression. Any incorrectly formed brace expansion is left unchanged.
When Bash is in POSIX mode, subshells spawned for command substitution inherit the -e option from the parent shell. When not in POSIX mode, Bash clears the -e option in such subshells. The inherit_errexit shell option controls this behavior when not in POSIX mode.
Brace expansion is performed before any other expansions. Any characters special to other expansions are preserved in the brace expansion result. Brace expansion is strictly textual and Bash does not apply any syntactic interpretation to the text between the braces.
Exit codes above 128 follow the formula 128 + signal_number. For example, if a script is terminated by SIGINT (signal 2), the exit code is 130. If terminated by SIGKILL (signal 9), the exit code is 137.
No, the results of brace expansion are not sorted. Left to right order is preserved.
A simple command other than a builtin or shell function is invoked in a separate execution environment consisting of: the shell's open files plus redirections, the current working directory, the file creation mode mask, exported shell variables and functions, and traps (caught traps reset to inherited values, ignored traps stay ignored).
If the command name contains a slash, Bash does not perform PATH searching. The shell attempts to execute the command directly using the specified path.
Exit status 126 indicates the command was found but cannot be executed (typically due to permission issues or lack of execute permissions).
By default, the exit status of a pipeline is the exit status of the last command in the pipeline.
Controlling the Prompt > System Identity
29 questionsThe ! escape sequence displays the history number of the current command (the index in the command history).
The \d escape sequence displays the date in 'Weekday Month Day' format (e.g., 'Tue May 26').
The \a escape sequence causes the terminal to emit a bell (audible alert) each time the prompt is displayed.
The default value of PS1 is '\s-\v$ ' which displays the shell name (e.g., 'bash'), a hyphen, the version number (e.g., '5.1'), and the prompt character. However, many distributions customize this to '\u@\h:\w$ '.
The \V escape sequence displays the release of Bash with patch level (e.g., '5.1.16').
To include non-printing characters like terminal escape sequences in PS1, wrap them in [ and ] to tell Bash not to count them when calculating the prompt width. Example: PS1='[\033[01;32m]\u@\h[\033[00m]:\w$ '
The \T escape sequence displays the current time in 12-hour HH:MM:SS format (e.g., '10:30:45').
The \r escape sequence displays a carriage return, moving the cursor to the beginning of the line.
The @ escape sequence displays the current time in 12-hour AM/PM format (e.g., '10:30 PM').
The \t escape sequence displays the current time in 24-hour HH:MM:SS format (e.g., '22:30:45').
The \H escape sequence displays the full hostname (fully qualified domain name). For example, if the hostname is 'server.example.com', \H displays 'server.example.com'.
The \j escape sequence displays the number of jobs currently managed by the shell.
The \D{format} escape sequence allows you to display the time using strftime(3) format. For example, \D{%Y-%m-%d} displays the date as '2025-01-21'.
The default value of PS3 is '#? ' which is used as the prompt for the select command in bash scripts.
The \w escape sequence displays the current working directory with full path (e.g., '/home/user/documents').
The $ escape sequence displays '#' if the effective user ID (UID) is 0 (root), and '$' for all other users.
The \e escape sequence represents the ASCII escape character (octal 033), which is used to begin ANSI escape sequences for terminal control.
The default value of PS4 is '+ ' which is displayed before each line of trace output when debugging is enabled with 'set -x'.
The \A escape sequence displays the current time in 24-hour HH:MM format (e.g., '22:30').
The \h escape sequence displays the hostname up to the first dot (short hostname). For example, if the full hostname is 'server.example.com', \h displays 'server'.
The \l escape sequence displays the basename of the shell's terminal device name (e.g., 'pts/0' becomes '0').
The \nnn escape sequence displays the character whose ASCII code is nnn in octal (e.g., \101 displays 'A').
The \W escape sequence displays the basename of the current working directory (e.g., if in '/home/user/documents', it shows 'documents').
The default value of PS2 is '> ' which is displayed as the secondary prompt for multi-line command continuation.
The # escape sequence displays the command number of the current command (incrementing for each command executed).
The \s escape sequence displays the name of the shell (e.g., 'bash' or 'sh').
Arithmetic Expansion
29 questionsBash supports: && (logical AND), || (logical OR), ! (logical NOT). These return 1 for true and 0 for false. For example: $(( 5 > 3 && 2 < 4 )) evaluates to 1 (true). Short-circuit evaluation applies.
The exponentiation operator is ** (two asterisks). For example: echo $((2 ** 8)) outputs 256. Exponentiation is right-associative, so 232 equals 2**(32) = 512, not (23)**2 = 64.
Use the ~ operator. Bitwise NOT flips all bits. For example, on a 64-bit system: echo $((~0)) outputs -1 because ~0 = -1 in two's complement representation (all bits flipped).
When shifting left (<<) beyond the bit width, the result is 0. When shifting right (>>) on negative numbers, the behavior is arithmetic right shift (sign-extending) on most systems. For example: on 64-bit, $((1 << 64)) = 0.
The base can be from 2 to 64. In bases above 10, uppercase letters A-Z represent values 10-35, and lowercase letters a-z represent values 36-61. The @ character represents 62, and _ represents 63. For example: 64#@# = 63.
The sign of the result of the % (modulus) operator follows the sign of the dividend. For example: echo $(( -7 % 3 )) outputs -1, and echo $(( 7 % -3 )) outputs 1. The result has the same sign as the first operand.
For &&: if the left operand is 0 (false), the right operand is not evaluated. For ||: if the left operand is non-zero (true), the right operand is not evaluated. This prevents side effects and errors. For example: $((1 || 1/0)) evaluates to 1 without causing division by zero.
Spaces are allowed anywhere in the expression for readability, including around operators and parentheses. For example: $(( 5 + 3 )) and $((5+3)) are equivalent. This differs from variable assignment outside arithmetic expansion.
Integer overflow in Bash wraps around silently using two's complement arithmetic. For example, on a 64-bit system: echo $((9223372036854775807 + 1)) outputs -9223372036854775808. No warning or error is generated.
Yes, Bash supports both prefix and postfix increment (++) and decrement (--) operators. For example: (( x++ )) increments x after using its value, while (( ++x )) increments before. In $(( )), you can write: echo $((x++)) to output x then increment it.
The $[ ] syntax for arithmetic expansion is deprecated but still supported for backward compatibility. It was the original Korn shell syntax. The $(( )) syntax is the POSIX standard and should be used instead.
The let command evaluates arithmetic expressions but doesn't output the result. Syntax: let 'x=5+3' or let x=5+3 (quotes optional with no spaces). Unlike $(( )), let returns exit status 1 if the last expression evaluates to 0, else 0. $(( )) is generally preferred.
The unary minus operator - negates its operand. For example: $(-x) negates x. The unary plus + is also supported but does nothing. Unary operators have higher precedence than multiplicative operators.
Comparison operators (<, >, <=, >=, ==, !=) have lower precedence than arithmetic operators but higher than logical AND/OR. For example: $((5 + 3 > 2 * 4)) = $((8 > 8)) = 0 (false) because arithmetic is evaluated before comparison.
Division in Bash arithmetic expansion truncates toward zero (integer division). For example: echo $((7 / 3)) outputs 2, and echo $((-7 / 3)) outputs -2 (not -3). This behavior differs from some languages that floor toward negative infinity.
Bash supports: =, +=, -=, *=, /=, %=, **=, <<=, >>=, &=, ^=, |=. These can be used within $(( )) or with (( )) compound command. For example: (( x += 5 )) increments x by 5.
Comparison operators return 1 for true and 0 for false. For example: $((5 > 3)) returns 1, and $((5 == 3)) returns 0. These are integer values that can be used in further calculations.
The ternary operator ? : has very low precedence, just above assignment and comma. It's lower than arithmetic and comparison operators. This means: $(( a + b ? c : d )) is parsed as $(( (a + b) ? c : d )).
Bash supports base prefixes: 0x or 0X for hexadecimal (e.g., 0xFF), 0 for octal (e.g., 077), and 0b or 0B for binary (Bash 4.2+). You can also use base#number notation for any base from 2 to 64, e.g., 16#FF = 255.
Arithmetic expansion uses the syntax $(( expression )) or $[ expression ] (deprecated). The $(( )) form evaluates the expression and expands to the result. For example: echo $((5 + 3)) outputs 8.
The (( )) compound command returns an exit status of 1 (false) if the expression evaluates to zero, and 0 (true) if the expression evaluates to non-zero. This makes it useful for numeric comparisons in if statements: if (( x > 5 )); then echo 'x is greater than 5'; fi
$((expression)) is arithmetic expansion that returns a value and can be used in commands like echo $((x+1)). ((expression)) is an arithmetic compound command that evaluates an expression but doesn't return a value; it sets the exit status based on whether the result is zero (false) or non-zero (true). It's used in conditionals.
On a 64-bit system, Bash uses signed 64-bit integers with a maximum value of 9223372036854775807 (2^63 - 1) and a minimum value of -9223372036854775808 (-2^63). On 32-bit systems, the range is -2147483648 to 2147483647.
Parentheses () override the default operator precedence. Expressions inside parentheses are evaluated first. For example: $((2 + 3 * 4)) = 14, but $(((2 + 3) * 4)) = 20. Nested parentheses are supported.
Bash supports: & (AND), | (OR), ^ (XOR), ~ (NOT), << (left shift), >> (right shift). For example: echo $((5 << 2)) outputs 20 (binary 101 shifted left 2 bits = 10100).
Yes, but it's optional. Inside $(( )), you can write either $((var + 1)) or $(( $var + 1 )). The $ prefix is unnecessary because variable names are automatically recognized as arithmetic variables. However, you need $ for positional parameters: echo $(( $1 + 1 )).
The comma operator , evaluates both operands but returns only the value of the second. For example: $((x=5, y2)) sets x to 5 and returns y2. It's useful for side effects in expressions.
No. Bash arithmetic expansion only supports integer arithmetic. Floating-point operations require external tools like bc, awk, or dc. For example: echo $((5 / 2)) outputs 2, not 2.5.
Yes, array elements can be used directly. For example: arr=(10 20 30); echo $((arr[0] + arr[1])) outputs 30. You can also use arithmetic for the index: echo $((arr[i+1])) accesses the (i+1)th element.
Shell Functions > Function Definition and Syntax
29 questionsWhen bash is in POSIX mode, the function name must be a valid shell name and may not be the same as one of the special builtins (such as break, :, ., continue, eval, exec, exit, export, readonly, return, set, shift, trap, unset).
The first element of the FUNCNAME variable is set to the name of the function while the function is executing.
No, when the function reserved word is used, the parentheses are optional. However, if the function keyword is used but parentheses are not supplied, the braces are recommended.
The FUNCNEST variable, if set to a numeric value greater than 0, defines a maximum function nesting level. Function invocations that exceed the limit cause the entire command to abort. By default, Bash places no limit on the number of recursive calls.
Ordinarily, variables and their values are shared between a function and its caller (global scope). Variables local to the function must be explicitly declared with the local builtin.
Yes, due to dynamic scoping, if a variable is declared as local in one function and that function calls another function, references to that variable made from within the called function resolve to the local variable from the calling function, shadowing any global variable with the same name.
In default mode, a function name can be any unquoted shell word that does not contain the dollar sign ($).
If return is supplied a numeric argument, that becomes the function's return status; otherwise the function's return status is the exit status of the last command executed before the return.
Yes, the body of the function is the compound command, which is usually a list enclosed between { and }, but may be any compound command including subshells (), if/then/else/fi, case/esac, for/do/done, while/do/done, until/do/done, or select/do/done.
The -F option to declare or typeset lists the function names only. With the extdebug shell option enabled, it also optionally shows the source file and line number.
If the builtin command return is executed in a function, the function completes and execution resumes with the next command after the function call. Any command associated with the RETURN trap is executed before execution resumes.
No, the special parameter 0 remains unchanged when a function is executed. It still refers to the shell or script name, not the function name.
Any redirections associated with the shell function are performed when the function is executed, not when it is defined.
By default, Bash places no limit on the number of recursive calls. The FUNCNEST variable can be set to a numeric value greater than 0 to define a maximum function nesting level.
Functions may be exported so that child shell processes (those created when executing a separate shell invocation) automatically have them defined using the -f option to the export builtin: export -f function_name.
Bash supports two function definition syntaxes:
fname () compound-command [ redirections ]function fname [()] compound-command [ redirections ]
In the second syntax, the function reserved word is optional, and if it is supplied, the parentheses are optional.
No, the function reserved word is optional in bash function definitions. If the function reserved word is supplied, the parentheses become optional.
The exit status of a function definition is zero unless a syntax error occurs or a readonly function with the same name already exists.
For historical reasons, the curly braces that surround the body of the function must be separated from the body by blanks or newlines. This is because braces are reserved words and are only recognized as such when separated from the command list by whitespace or another shell metacharacter.
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.
The -f option to the declare (or typeset) builtin command lists function names and definitions: declare -f.
When a function is executed, the arguments to the function become the positional parameters during its execution. The special parameter # is updated to reflect the new set of positional parameters.
When executed, the exit status of a function is the exit status of the last command executed in the body.
Function definitions are deleted using the -f option to the unset builtin: unset -f function_name.
Yes, functions may be recursive. The FUNCNEST variable may be used to limit the depth of the function call stack and restrict the number of function invocations.
The ERR trap is not inherited by functions unless the -o errtrace shell option has been enabled.
No, shell functions are executed in the current shell context; there is no new process created to interpret them.
The DEBUG and RETURN traps are not inherited by functions unless the function has been given the trace attribute using the declare builtin or the -o functrace option has been enabled with the set builtin (in which case all functions inherit the DEBUG and RETURN traps).
When using curly braces, the list must be terminated by a semicolon, an ampersand (&), or a newline.
Using History Interactively > Event Selection
28 questionsThe ':p' modifier causes the history expansion to be printed but not executed. This is useful for previewing what the expanded command will be.
Yes, if a word designator is used with the ':s' modifier, the modification is applied only to the selected word(s). For example, '!!:3:s/foo/bar/' modifies only the third argument.
The '!#' designator expands to all of the words typed so far in the current command, allowing you to repeat what you've already typed in the same command line.
The ':e' modifier removes all but the trailing suffix (file extension). For example, '!!:1:e' applied to 'file.txt' gives '.txt'.
When n is a positive integer, '!n' refers to command line n in the history list.
The '!#' designator refers to the entire command line typed so far in the current command.
When no event specification is given (e.g., just ':^' or ':*'), the previous command is used as the default event.
The '!string' designator refers to the most recent command in the history list that starts with the specified string.
The word designator '$' refers to the last argument of the referenced command. For example, '!!:$' gives the last argument of the previous command.
Add the 'g' modifier before any substitution modifier. For example, '!!:gs/old/new/' replaces ALL occurrences of 'old' with 'new' in the previous command.
The ':h' modifier removes a trailing pathname component, leaving the head of the path. For example, '!!:0:h' applied to '/usr/bin/ls' gives '/usr/bin'.
The word designator 'x*' specifies words from the xth through the last word. For example, '!!:3*' gives words 3 through the end.
Words are indexed from 0, where word 0 is the command name and subsequent words are the arguments.
The ':r' modifier removes a trailing suffix (file extension) of the form '.xxx'. For example, '!!:1:r' applied to 'file.txt' gives 'file'.
The ':q' modifier quotes the substituted words to prevent further expansion. This protects special characters from being interpreted.
The ':t' modifier removes all leading pathname components, leaving the tail (filename). For example, '!!:0:t' applied to '/usr/bin/ls' gives 'ls'.
The '!!' event designator is a synonym for '!-1', which refers to the previous command in the history list.
The ':x' modifier quotes the substituted words as if they were separate words, breaking them at whitespace and quoting each part individually.
The '^string1^string2^' designator repeats the last command, replacing the first occurrence of string1 with string2. This is equivalent to '!!:s/string1/string2/'.
The word designator '%' refers to the word matched by the most recent '?string?' search. This is only meaningful when used after a '!?string?' event designator.
When n is a positive integer, '!-n' refers to the current command line minus n (i.e., the command n lines back in history).
The 'histexpand' shell option (or '-H' for shorthand) enables history expansion. It can be disabled with 'set +H' or 'set +o histexpand'.
The '!?string[?]' designator refers to the most recent command in the history list that contains the specified string anywhere in the command line. The trailing '?' is optional if the string is followed immediately by a newline.
The '!' character starts history expansion in bash. It can be escaped with a backslash ('!') or single quotes to prevent expansion.
The word designator '^' is equivalent to ':1' (the first argument) and can be used without the colon prefix, like '!!^' to get the first argument of the previous command.
The syntax is '!!:s/old/new/' which substitutes the first occurrence of 'old' with 'new' in the previous command. The 'g' modifier can be added for global substitution: '!!:gs/old/new/'.
When history expansion fails to find a matching event, bash displays an error message and does not execute the command. The shell treats the failed expansion as an error.
The word designator '' refers to all words except the 0th (command name). For example, '!!:' gives all arguments of the previous command.
Shell Arithmetic > Arithmetic Operations
28 questionsThe exponentiation operator is ** (two asterisks). For example, $((2**3)) evaluates to 8.
The modulus operator is %. The result has the same sign as the dividend. For example, $((7 % 3)) is 1, but $((-7 % 3)) is -1.
When shifting left (<<) by 32 or more bits on a 32-bit system, or 64 or more bits on a 64-bit system, the result is 0. Right shifting by more bits than the width yields -1 for negative numbers (sign extension) or 0 for non-negative numbers.
The syntax for arithmetic expansion is $(( expression )) or $[ expression ] (deprecated). The $(( )) form is the preferred and portable way to perform arithmetic expansion.
In Bash arithmetic, = is the assignment operator while == is the equality comparison operator. Both return 1 (true) or 0 (false) as the result of the comparison.
The logical AND (&&) and OR (||) operators return 0 or 1. For &&: returns 1 only if both operands are non-zero. For ||: returns 1 if either operand is non-zero. These operators short-circuit evaluation.
Bash supports == (equal), != (not equal), < (less than), > (greater than), <= (less than or equal), and >= (greater than or equal). All return 1 for true, 0 for false.
The base specifier 10# forces interpretation as base 10. For example, $((10#010)) equals 10 (not 8), ignoring the leading zero's octal interpretation.
Parentheses () override default precedence. Expressions inside parentheses are evaluated first. For example, $(((2 + 3) * 4)) evaluates to 20, while $((2 + 3 * 4)) evaluates to 14.
No, variable names cannot contain spaces. However, you can use parameter expansion to reference variables with special names or to avoid ambiguity.
Yes, array elements can be used in arithmetic expansion. Use ${array[index]} syntax. For example, if arr=(10 20 30), then $((arr[0] + arr[1])) evaluates to 30.
An unset variable in arithmetic expansion evaluates to 0. Therefore, $((-unset_var)) evaluates to 0, and $((unset_var + 5)) evaluates to 5.
The ternary operator follows the syntax: condition ? value_if_true : value_if_false. For example, $((x > 5 ? 10 : 20)) returns 10 if x is greater than 5, otherwise returns 20.
Bash supports =, +=, -=, *=, /=, %=, &=, |=, ^=, <<=, >>=, and **=. For example, $((x += 5)) adds 5 to x and assigns the result back to x.
Bash interprets numbers starting with 0 as octal and numbers starting with 0x or 0X as hexadecimal. For example, $((010)) equals 8 (decimal) and $((0x10)) equals 16.
Bash supports the following bitwise operators: & (AND), | (OR), ^ (XOR), ~ (NOT), << (left shift), and >> (right shift).
Use the base#value syntax where base is between 2 and 64. For example, $((2#1010)) is binary for decimal 10, and $((36#zz)) is decimal 1295.
The comma operator (,) evaluates both operands but returns only the value of the second operand. For example, $((x=5, y=10)) evaluates x=5, then y=10, and returns 10.
The logical NOT operator is !. It returns 1 if the operand is 0 (false), and returns 0 if the operand is non-zero (true). For example, $((!0)) is 1, and $((!5)) is 0.
No, Bash arithmetic expansion only supports integer arithmetic. All numbers are treated as signed 64-bit integers (or at least signed long integers on the platform). For floating-point arithmetic, you must use external commands like bc or awk.
Multiplication (*), division (/), and modulus (%) have higher precedence than addition (+) and subtraction (-). For example, $((2 + 3 * 4)) evaluates to 14 (not 20), because multiplication happens first.
The exponentiation operator ** has lower precedence than unary operators (+, -, !, ~). This means $((-22)) evaluates to -4 (not 4), because it's parsed as -(22).
Integer division in Bash truncates toward zero. For example, $((7/3)) evaluates to 2, and $((-7/3)) evaluates to -2.
Bash supports bases from 2 to 64. In bases above 10, digits are 0-9, lowercase a-z, uppercase A-Z, @, and _ representing values 0-63.
let evaluates expressions but doesn't output the result; it only sets the exit status based on whether the result is non-zero. $(( )) evaluates and substitutes the result. Also, let requires quotes around expressions with spaces, while $(( )) does not.
Division by zero in Bash arithmetic expansion results in an error and causes the shell to exit with a non-zero status. The error message is 'division by 0'.
The let command evaluates arithmetic expressions. Syntax: 'let expression' or 'let "expression"'. The return status is 0 if the result is non-zero, 1 if zero. Variables don't need $ prefix. Example: 'let x=5+3' sets x to 8.
Bash supports both prefix and postfix increment (++) and decrement (--) operators. The prefix form (++x) modifies the variable before evaluating, while the postfix form (x++) modifies after evaluating.
Modifying Shell Behavior > Debugging and Tracing
28 questionsBASH_ARGC and BASH_ARGV are updated as described in their descriptions. These variables are set only when in extended debugging mode, and setting extdebug after the shell has started may result in inconsistent values.
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.
If return is executed during a DEBUG trap, the last command used to determine the status is the last command executed by the trap handler before return was invoked.
Setting BASH_XTRACEFD to 2 (the standard error file descriptor) and then unsetting it will result in the standard error being closed.
Using + rather than - causes options to be turned off. For example, set +x disables xtrace, and set +v disables verbose mode.
If set to an integer corresponding to a valid file descriptor, bash will write the trace output generated when set -x is enabled to that file descriptor. The file descriptor is closed when BASH_XTRACEFD is unset or assigned a new value.
If the command run by the DEBUG trap returns a non-zero value, the next command is skipped and not executed.
set -o verbose is the same as set -v - it prints shell input lines as they are read.
After expanding each simple command, for command, case command, select command, or arithmetic for command, display the expanded value of PS4, followed by the command and its expanded arguments or associated word list. This is commonly called xtrace or execution tracing.
The debugging options (-x, -v, -n) are off by default unless otherwise noted. Using + rather than - causes these options to be turned off.
Using - with no arguments signals the end of options, causes all remaining args to be assigned to the positional parameters. The -x and -v options are turned off. If there are no args, the positional parameters remain unchanged.
set -o xtrace is the same as set -x - it enables execution tracing that displays the expanded value of PS4 followed by commands and their expanded arguments.
If -T is not set, any DEBUG trap string is saved and restored around the call to ., and . unsets the DEBUG trap while it executes. If the sourced file changes the DEBUG trap, the new value is retained when . completes.
If the command run by the DEBUG trap returns a value of 2, and the shell is executing in a subroutine (a shell function or a shell script executed by the . or source builtins), the shell simulates a call to return.
When extdebug is enabled, function tracing is enabled: command substitution, shell functions, and subshells invoked with ( command ) inherit the DEBUG and RETURN traps.
Arranges for the debugger profile to be executed before the shell starts. Turns on extended debugging mode (see the description of the extdebug option to the shopt builtin).
The first character of the expanded value of PS4 is replicated multiple times, as necessary, to indicate multiple levels of indirection.
Unsetting BASH_XTRACEFD or assigning it the empty string causes the trace output to be sent to the standard error.
BASH_COMMAND contains the command currently being executed or about to be executed, unless the shell is executing a command as the result of a trap, in which case it is the command executing at the time of the trap.
If set, any trap on ERR is inherited by shell functions, command substitutions, and commands executed in a subshell environment. The ERR trap is normally not inherited in such cases.
The value of PS4 is expanded as with PS1 and the value is printed before each command bash displays during an execution trace.
If set, any traps on DEBUG and RETURN are inherited by shell functions, command substitutions, and commands executed in a subshell environment. The DEBUG and RETURN traps are normally not inherited in such cases.
If set at shell invocation, or in a shell startup file, arrange to execute the debugger profile before the shell starts, identical to the --debugger option.
When extdebug is enabled, error tracing is enabled: command substitution, shell functions, and subshells invoked with ( command ) inherit the ERR trap.
When extdebug is set after invocation, the -F option to the declare builtin displays the source file name and line number corresponding to each function name supplied as an argument.
Bash Builtin Commands > Directory Stack Builtins
28 questionsThe -n option suppresses the normal change of directory when removing directories from the stack, so only the stack is manipulated without changing the current working directory.
The -n option suppresses the normal change of directory when adding directories to the stack, so only the stack is manipulated without changing the current working directory.
pushd returns failure (non-zero) if an invalid argument is supplied or if the directory change fails.
The -N argument 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' removes the next to last.
The +N argument displays the Nth entry counting from the left of the list shown by dirs when invoked without options, starting with zero.
The -N argument 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.
The default index numbering starts at zero for -N notation, counting from the right of the list shown by dirs when invoked without options.
popd returns failure (non-zero) if an invalid argument is supplied or if the directory change fails.
When popd succeeds without arguments, it removes the top directory from the stack and changes to the new top directory.
When called without arguments, pushd exchanges the top two directories on the stack and makes the new top of the stack the current working directory.
The -l option produces a longer listing format without using tilde (~) notation to display directories relative to your home directory.
The default index numbering starts at zero for +N notation, counting from the left of the list shown by dirs when invoked without options.
When called without arguments, popd removes the top directory from the stack and changes to the new top directory.
The +N argument 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.
When using popd -n, the current working directory does not change - only the stack is manipulated. This allows you to remove directories from the stack without changing your current location.
When using pushd -n, the current working directory does not change - only the stack is manipulated. This allows you to add directories to the stack without changing your current location.
Both dirs -p and dirs -v print the directory stack with one entry per line, but dirs -v includes an index number prefix for each entry while dirs -p does not.
The -c option clears the directory stack by deleting all of the elements.
The three directory stack builtins are: dirs (display the directory stack), pushd (add directories to the stack), and popd (remove directories from the stack).
The +N argument 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' removes the second.
When called without arguments, dirs displays the list of currently remembered directories in the directory stack.
dirs returns failure (non-zero) if an invalid option is supplied or an error occurs.
When given a directory argument (dir), pushd adds that directory to the directory stack at the top, making it the new current working directory.
When pushd succeeds (without -n), it makes the new top of the stack the current working directory.
The -N argument displays the Nth entry counting from the right of the list shown by dirs when invoked without options, starting with zero.
The -v option prints the directory stack with one entry per line, prefixed with its position in the stack.
Filename Expansion > Shell Options for Globbing Behavior
28 questionsNo. When dotglob is enabled, it includes filenames beginning with . in filename expansion results, but explicitly excludes the special directory entries . (current directory) and .. (parent directory). These are never matched by glob patterns.
Yes. When globstar is enabled, the ** pattern recursively matches directories and their subdirectories regardless of filesystem boundaries. It will descend into mounted filesystems unless restricted by other means.
No. The nocaseglob option only affects filename expansion (globbing). It does not affect case sensitivity in the [[ compound command's pattern matching with == or =. For case-insensitive string matching in [[, you must use the ~~ operator with shopt -s nocasematch or convert strings to the same case.
The !(pattern-list) operator matches anything except one of the given patterns. For example, !(*.txt) matches any filename that does not end with .txt.
The -p flag for shopt displays each option's current setting in a format that can be reused as input to shopt. This outputs shopt -s optionname for enabled options and shopt -u optionname for disabled options.
The extglob option enables five extended pattern matching operators: ?(pattern-list) matches zero or one occurrence, *(pattern-list) matches zero or more occurrences, +(pattern-list) matches one or more occurrences, @(pattern-list) matches exactly one occurrence, and !(pattern-list) matches anything except the pattern-list.
The shopt builtin command is used to set and unset bash-specific shell options. Use shopt -s option_name to enable and shopt -u option_name to disable an option.
There is no flag to restrict display to settable options. All options displayed by shopt are settable; some options are read-only and are controlled differently. The -o flag allows access to POSIX options via shopt, but options controlled by shopt are all bash-specific and settable.
The -u flag for shopt displays only those shell options that are currently unset (disabled). This is useful for seeing which optional behaviors are not active.
The nocasematch shell option controls case sensitivity for pattern matching in the [[ compound command and case statements. When enabled with shopt -s nocasematch, pattern matching becomes case-insensitive. This is separate from nocaseglob, which only affects filename expansion.
The default status of extglob varies by distribution and shell configuration. Historically extglob was off by default, but many modern Linux distributions enable it in interactive shells. Scripts should not rely on extglob being enabled by default and should explicitly enable it with shopt -s extglob if needed.
The nocaseglob option is off by default. When enabled, bash performs filename matching in a case-insensitive manner during filename expansion.
The +(pattern-list) operator matches one or more occurrences of the given patterns. It requires at least one match. For example, +([0-9]) matches strings containing one or more digits.
The failglob option is off by default. When enabled, patterns that fail to match any filenames cause an expansion error to be issued instead of being left unexpanded or expanded to null.
There is no caseglob shell option in bash. The option for case-insensitive matching is called nocaseglob, which is off by default. The name caseglob does not exist in bash.
When globstar is not enabled, the ** pattern is treated the same as *. It will only match files and directories within the current directory level, not recursively.
The *(pattern-list) operator matches zero or more occurrences of the given patterns. It behaves like * in regex but works with the pattern-list syntax. For example, *([0-9]) matches strings with zero or more digits.
The @(pattern-list) operator matches exactly one of the given patterns. For example, @(*.txt|*.md) matches exactly one file ending in either .txt or .md, but not both.
When both nullglob and failglob are set, failglob takes precedence. The pattern expansion will result in an error instead of expanding to nothing (null).
The nullglob option is off by default. When disabled (the default), patterns that match no filenames are left unchanged and expanded to themselves. When enabled, such patterns expand to nothing (a null string).
The dotglob option is off by default. When enabled, it includes filenames beginning with . in the results of filename expansion, with the exceptions of . and .. which are always excluded.
When globstar is enabled, ** matches all files and zero or more directories. When ** is followed by / (i.e., **/), it only matches directories and their subdirectories, not regular files in the current directory context.
The extglob option is on by default in bash when enabled programmatically (in scripts), but the default varies by bash version. Starting from bash 4.1, extglob is enabled by default in interactive shells on Linux. Extended pattern matching includes patterns such as ?(pattern-list), *(pattern-list), +(pattern-list), @(pattern-list), and !(pattern-list).
The command shopt with no options displays the current status of all bash shell options controlled by shopt. Options that are enabled are listed, while disabled options are not shown unless using shopt -u or shopt -p.
The globasciiranges option is on by default. When enabled, range expressions in pattern matching (like [a-z]) use the traditional ASCII ordering. When disabled, ranges use the current locale's collating order.
The ?(pattern-list) operator matches zero or one occurrence of the given patterns. It makes the pattern optional. For example, ?(file) matches either an empty string or file.
Job Control > Execution States
28 questionsThe 'fg' command resumes a stopped job in the foreground, changing its state from Stopped to Running, and makes it the active job that receives terminal input. It sends a SIGCONT signal to the job.
The 'bg' command resumes a stopped job in the background, changing its state from Stopped to Running. It sends a SIGCONT signal but the job continues executing without terminal input access.
The 'wait' command pauses the shell until all background jobs have reached the Done state, or until specific jobs specified as arguments complete. It returns the exit status of the last job waited for.
SIGTERM can be caught, blocked, or ignored by processes, allowing them to perform cleanup before terminating. SIGKILL cannot be caught, blocked, or ignored and immediately kills the process with no chance for cleanup.
The 'jobs' command lists all active jobs with their current status: 'Running' for active jobs, 'Stopped' (or 'Suspended') for paused jobs, and 'Done' for completed jobs along with their exit codes.
SIGQUIT is signal number 3. It is generated when the user presses Ctrl+\ (the quit character) and causes the process to terminate and produce a core dump, which can be used for debugging.
The default signal is SIGTERM (signal number 15), which requests a process to terminate gracefully. The process can catch this signal and perform cleanup before exiting.
SIGSTOP is signal number 19. Unlike SIGTSTP, SIGSTOP cannot be caught or ignored by processes - it is an unstoppable stop signal that always suspends the target process immediately. It can only be sent via the kill command.
SIGKILL immediately terminates the process, changing its state to Done. SIGKILL cannot be caught, blocked, or ignored by the process - it is always fatal. The process has no chance to clean up.
SIGCONT is signal number 18. It resumes execution of a process that has been stopped by SIGSTOP or SIGTSTP. If a stopped process receives SIGCONT, it continues execution even if it was in the foreground or background.
SIGINT is signal number 2. It is generated when the user presses Ctrl+C (the interrupt character), sending an interrupt signal to the foreground process group, typically terminating the process.
A job started with '&' begins in the Running state in the background. The shell immediately returns control to the user without waiting for the job to complete.
When 'set -b' or 'set -o notify' is enabled, Bash reports the completion of background jobs immediately instead of waiting to print the status just before the next prompt.
When a background job attempts to read from the terminal, Bash automatically stops it with a SIGTTIN signal (signal 21), changing its state from Running to Stopped. The job will remain stopped until explicitly continued with fg or bg.
SIGTSTP is signal number 20 on most systems. It is the terminal stop signal sent when a user presses Ctrl+Z, which suspends (stops) the foreground process. This signal can be caught and ignored by processes.
'kill %1' sends a signal to job number 1 in Bash's job table, while 'kill 1234' sends a signal directly to process ID 1234. The percent sign (%) indicates a job specification rather than a PID.
SIGTTIN is signal number 21. It is sent by the kernel when a background process attempts to read from the terminal. The signal causes the process to stop, preventing background jobs from interfering with terminal input.
'wait -n' returns as soon as any of the specified jobs changes state (completes or stops), rather than waiting for all jobs. It returns the exit status of that job.
'stty tostop' enables SIGTTOU signal delivery, causing background jobs to stop when they write to the terminal. 'stty -tostop' disables this behavior (the default), allowing background jobs to write output without being stopped.
Ctrl+Z sends SIGTSTP to the current foreground process, causing it to stop and become a background job in the 'Stopped' state. The susp character can be changed with stty but defaults to Ctrl+Z.
Bash sends SIGHUP (signal 1) to all jobs when an interactive login shell exits. This causes jobs to terminate unless they were disowned or have their own SIGHUP handling. The 'shopt -s huponexit' controls this behavior.
Use 'kill -CONT PID' or 'kill -18 PID' to send the SIGCONT signal, which resumes execution of the stopped process. Alternatively, use 'fg %job' to bring it to foreground or 'bg %job' to continue it in background.
SIGTTOU is signal number 22. It is sent when a background process attempts to write to the terminal if 'stty tostop' is enabled. By default this signal is not sent, allowing background jobs to write output freely.
The three main execution states are: 1) Running - the process is executing or ready to execute; 2) Stopped (suspended) - the process has paused but still exists in memory; 3) Done - the process has completed or been terminated.
The 'suspend' command sends SIGTSTP to the Bash shell itself, suspending the shell and changing its state to Stopped. This pauses the entire shell session until a SIGCONT signal resumes it.
The '+' marks the current job (most recent job stopped or started in background), which is the default for fg and bg commands. The '-' marks the previous job (second most recent). If there is only one job, it is marked with '+'.
Use 'kill -STOP PID' or 'kill -19 PID' where PID is the process ID. This sends the SIGSTOP signal which cannot be caught or ignored, forcing the process to stop immediately.
The 'disown' command removes jobs from Bash's job table, causing Bash to stop tracking them. The jobs continue running but are no longer listed by 'jobs' and won't receive SIGHUP when the shell exits.
Quoting > Character Interpretation Control
28 questionsANSI-C quoting supports: \a (alert/bell), \b (backspace), \e or \E (escape character), \f (form feed), \n (newline), \r (carriage return), \t (horizontal tab), \v (vertical tab), and \cx (control-x character).
A double quote may be quoted within double quotes by preceding it with a backslash.
Explicit null arguments ("" or '') are retained and passed to commands as empty strings.
No, when the shell is in POSIX mode, the ! character has no special meaning within double quotes, even when history expansion is enabled.
If the current locale is C or POSIX, if there are no translations available, or if the string is not translated, the dollar sign is ignored and the string is treated as a normal double-quoted string.
Unquoted implicit null arguments, resulting from the expansion of parameters that have no values, are removed.
Yes, the shell scans the results of parameter expansion that occurred within double quotes, and word splitting is not performed on expansions within double quotes.
No, a single quote may not occur between single quotes, even when preceded by a backslash.
If history expansion is enabled, it will be performed unless an ! appearing in double quotes is escaped using a backslash. The backslash preceding the ! is not removed.
Use \xHH where HH is one or two hex digits, representing the eight-bit character whose value is the hexadecimal value HH.
The expanded result of ANSI-C quoting is single-quoted, as if the dollar sign had not been present.
If IFS is unset, or its value is exactly
The four quoting mechanisms in Bash are: the escape character (backslash), single quotes, double quotes, and ANSI-C quoting (dollar-single quotes). Locale-specific translation is a fifth related mechanism.
Quoting is used to remove the special meaning of certain characters or words to the shell, disable special treatment for special characters, prevent reserved words from being recognized as such, and prevent parameter expansion.
The gettext infrastructure performs the lookup and translation using the LC_MESSAGES, TEXTDOMAINDIR, and TEXTDOMAIN shell variables.
The special parameters * and @ have special meaning when in double quotes, particularly regarding how they expand positional parameters.
Use \uHHHH for Unicode (ISO/IEC 10646) characters with 4 hex digits, or \UHHHHHHHH for 8 hex digits.
Within double quotes, the backslash retains its special meaning only when followed by one of the following characters: $, `, ", , or newline.
Backslashes preceding characters without a special meaning are left unmodified (not removed) within double quotes.
Enclosing characters in single quotes preserves the literal value of each character within the quotes.
If a parameter with no value is expanded within double quotes, a null argument results and is retained and passed to a command as an empty string.
A non-quoted backslash preserves the literal value of the next character that follows, removing any special meaning it has, with the exception of newline.
Use \nnn where nnn is one to three octal digits, representing the eight-bit character whose value is the octal value nnn.
If a backslash-newline pair appears and the backslash itself is not quoted, the backslash-newline is treated as a line continuation (it is removed from the input stream and effectively ignored).
If the noexpand_translation option is enabled using shopt, translated strings are single-quoted instead of double-quoted.
Within double quotes, the characters $ (dollar sign), ` (backtick), \ (backslash), and ! (exclamation mark, when history expansion is enabled) retain their special meaning.
Shell Arithmetic > Comparison Operations
28 questionsNo, Bash arithmetic operations including comparisons only support integer arithmetic. Floating point numbers are truncated to integers. For example, (( 3.5 > 3 )) will result in an error or truncation.
The ** operator performs exponentiation within (( )). It has higher precedence than multiplication/division. For example: (( 28 == 256 )) is true. (( 32 > 5 )) is also true.
Within (( )), Bash supports shorthand assignment: +=, -=, *=, /=, %=, <<=, >>=, &=, |=, ^=. For example: (( a += 5 )) is shorthand for (( a = a + 5 )). These can be used before or after comparisons.
Bash arithmetic uses signed 64-bit integers on most modern systems, allowing values from -9,223,372,036,854,775,808 to 9,223,372,036,854,775,807. Overflow wraps around using modulo 2^64 arithmetic.
Yes, (( )) allows assignment combined with comparison. For example: (( x = 5, x > 3 )) assigns 5 to x and then compares. The result of assignment is the assigned value, so (( x = 5 )) sets x to 5 and evaluates to 5 (true).
The ! operator performs logical NOT within (( )). For example: (( ! (a > b) )) is true when a is not greater than b. This is equivalent to (( a <= b )).
Within (( )), ++ increments and -- decrements. Pre-increment (++a) increments before use, post-increment (a++) increments after. For example: (( ++a > 5 )) increments a first, then compares; (( a++ > 5 )) compares current value, then increments.
Within (( )) for arithmetic evaluation, Bash supports these C-style comparison operators: == (equal), != (not equal), < (less than), > (greater than), <= (less than or equal), and >= (greater than or equal). These operators operate on integer values only.
Within (( )), bitwise operators work on integer binary representations: & (bitwise AND), | (bitwise OR), ^ (bitwise XOR), ~ (bitwise NOT), << (left shift), >> (right shift). These are arithmetic, not comparison operators, but can be used in comparisons: (( (a & b) > 0 ))
When an unset or empty variable is used in (( )) arithmetic comparison, it evaluates to 0. For example, if x is unset, (( x > 0 )) is equivalent to (( 0 > 0 )), which evaluates to false.
Yes, negative numbers are supported in (( )) comparisons. For example: (( -5 < 0 )) evaluates to true. The minus sign must not have spaces between it and the number when used as a literal.
Division by zero in (( )) causes an error and the expression fails. For example: (( 5 / 0 > 1 )) will produce an error message and the script may continue or exit depending on settings.
Within (( )) arithmetic context, both == and = perform equality comparison of integer values. The operators are synonymous in this context, though == is the more common convention for C-style syntax.
The modulus operator % returns the remainder of integer division within (( )). It can be used in comparisons: (( a % b == 0 )) checks if a is divisible by b. For example: (( 10 % 3 == 1 )) is true.
Within (( )), comparison operators have lower precedence than arithmetic operators but higher precedence than logical AND/OR. Arithmetic operations (+, -, *, /, %) are evaluated first, then comparisons (<, >, ==, etc.), then logical AND (&&), then logical OR (||). Parentheses can override precedence.
Yes, the comma operator (,) can be used within (( )) to evaluate multiple expressions, returning the value of the last one. For example: (( i++, j > i )) increments i and then compares j to the new i value.
The (( )) compound command returns an exit status of 1 when the arithmetic expression evaluates to zero (false). For example, (( 5 > 10 )) returns exit status 1.
(( )) uses C-style syntax for integer comparisons and allows arithmetic directly (e.g., (( a > b ))). [ ] with -eq requires spaced arguments and variable expansion (e.g., [ $a -eq $b ]). Both compare integers, but (( )) is more concise and allows complex expressions.
Yes, within (( )) you can use && (logical AND) and || (logical OR) for compound arithmetic comparisons. For example: (( a > 5 && b < 10 )) or (( x == 0 || y == 0 ))
Within (( )), = is assignment (sets a variable), while == is comparison (tests equality). For example: (( x = 5 )) assigns 5 to x, while (( x == 5 )) checks if x equals 5. Using = alone for comparison like (( x = 5 )) assigns rather than compares.
You can use $(( )) within [ ] or [[ ]], or directly use (( )) for cleaner syntax. For example: [ $(( a + b )) -gt 10 ] or (( a + b > 10 )). The latter is preferred for arithmetic comparisons.
When (( )) evaluates a comparison with a variable containing non-numeric content, Bash treats it as 0. For example, if x='hello', then (( x > 5 )) is equivalent to (( 0 > 5 )), which is false. No error is raised.
Within (( )), you can use the C-style ternary operator: condition ? value_if_true : value_if_false. For example: (( max = a > b ? a : b )) assigns the greater of a or b to max.
In (( )), a comparison that is true evaluates to 1, and false evaluates to 0. For example: (( result = a > b )) sets result to 1 if a > b, or 0 otherwise.
The (( )) compound command returns an exit status of 0 when the arithmetic expression evaluates to a non-zero value (true). For example, (( 5 > 3 )) returns exit status 0.
Yes, inside (( )) the dollar sign prefix ($) can and should be omitted for variable names. For example, (( a > b )) is equivalent to (( $a > $b )) and is the preferred form.
The -eq, -ne, -lt, -le, -gt, and -ge operators are NOT valid inside (( )) arithmetic evaluation. These test operators are designed for [ ] and [[ ]] constructs. Inside (( )), you must use C-style operators: <, >, <=, >=, ==, !=
Yes, let supports the same arithmetic operators as (( )) but returns 1 (true) for non-zero results and 0 (false) for zero. For example: let 'a > b' or let result=$(( a > b )) . Note that let 's exit status is inverted compared to (( ))
Modifying Shell Behavior > Pathname Expansion and Globbing
28 questionsYes, when GLOBIGNORE is set and not empty, filenames beginning with '.' are no longer treated specially. This means dot files will be included in pathname expansion unless explicitly excluded by patterns in GLOBIGNORE.
The '@(pattern-list)' operator matches exactly one of the given patterns. This requires the 'extglob' option to be enabled. Example: '@(foo|bar)' matches 'foo' or 'bar' but nothing else.
Special glob characters can be escaped with a backslash ('') or quoted to treat them literally. For example, '*' or "*" matches a literal asterisk character in a filename, not as a wildcard.
By default, an unmatched pattern is left unchanged and treated as a literal string. For example, if you run 'ls .xyz' and no .xyz files exist, bash will attempt to list a file literally named '.xyz'.
'nocaseglob' affects pathname expansion (globbing patterns like *.txt), while 'nocasematch' affects pattern matching in [[ conditionals and case statements. They control case sensitivity in different contexts.
The 'casematch' option controls case sensitivity in pattern matching performed by the '[[ conditional command' and 'case' statements. When disabled via 'shopt -u casematch', pattern matching becomes case-insensitive.
The '?' wildcard matches exactly one character. It will not match zero characters or multiple characters - only a single character position.
The '?(pattern-list)' operator matches zero or one occurrence of the given patterns. This requires the 'extglob' option to be enabled. Example: 'file.?(txt|md)' matches 'file.', 'file.txt', and 'file.md' but not 'file.txt.md'.
When 'nocasematch' is enabled via 'shopt -s nocasematch', pattern matching in '[[ conditional commands and 'case' statements is performed case-insensitively. This affects string matching, not pathname expansion.
By default, 'nocaseglob' is disabled (off), meaning pathname expansion is case-sensitive. 'shopt -u nocaseglob' ensures case-sensitive matching.
Pathname expansion is performed after variable expansion, command substitution, and arithmetic expansion have been completed. This order allows expanded variables to contain glob patterns that will then be expanded.
The '(pattern-list)' operator matches zero or more occurrences of the given patterns. This requires the 'extglob' option to be enabled. It's similar to '' but for complex patterns.
When 'failglob' is enabled via 'shopt -s failglob', patterns that match no files cause an error message and the command is not executed. This is more strict than the default behavior or nullglob.
When 'dotglob' is enabled via 'shopt -s dotglob', pathname expansion patterns include filenames that begin with a dot ('.'). By default, glob patterns like '*' do not match hidden files/directories.
There is no fixed maximum length in the bash specification. The limit is determined by system resources (ARG_MAX) and available memory. Each expanded filename counts toward the argument limit for command execution.
The '[...]' syntax matches any one of the enclosed characters. A range of characters can be expressed with a dash, like '[a-z]' for lowercase letters or '[0-9]' for digits. The '[!...]' or '[^...]' syntax matches any character NOT in the enclosed set.
When 'nocaseglob' is enabled via 'shopt -s nocaseglob', bash performs case-insensitive matching during pathname expansion. For example, '*.txt' will match both 'file.txt' and 'file.TXT'.
Pathname expansion can be disabled with 'set -f' or 'set -o noglob'. Re-enable it with 'set +f' or 'set +o noglob'. This prevents '*' and other wildcards from being expanded.
No, even with 'dotglob' enabled, the patterns '.' and '..' must always be matched explicitly. The 'dotglob' option affects other patterns but never includes '.' or '..' in expansion results.
The '+(pattern-list)' operator matches one or more occurrences of the given patterns. This requires the 'extglob' option to be enabled. Unlike '*(pattern-list)', it requires at least one match.
When GLOBIGNORE is unset, default behavior applies. When set to an empty value ('GLOBIGNORE='), it enables the behavior where filename expansion ignores dot files, similar to how '.*' patterns work. This is an edge case documented in the bash manual.
The '*' wildcard matches any string, including the empty string. It's the most common glob pattern and matches zero or more characters in filenames.
When 'globstar' is enabled via 'shopt -s globstar', the pattern '**' matches all files and zero or more directories and subdirectories. If followed by a '/', only directories and subdirectories match.
While not directly related to globbing, 'expand_aliases' controls whether aliases are expanded during pathname expansion context. By default, aliases are not expanded in non-interactive shells unless this option is set.
The 'extglob' option (extended globbing) enables additional pattern matching operators: ?(pattern-list) for zero or one occurrence, *(pattern-list) for zero or more occurrences, +(pattern-list) for one or more occurrences, @(pattern-list) for exactly one occurrence, and !(pattern-list) for anything except the pattern.
No, failglob and nullglob cannot be enabled simultaneously. If you try to enable both, whichever was set last will take precedence, and they are mutually exclusive options.
GLOBIGNORE is a colon-separated list of patterns defining filenames to ignore during pathname expansion. Files matching these patterns are excluded from expansion results. If GLOBIGNORE is set and not empty, dot files are included unless the pattern explicitly excludes them.
The '!(pattern-list)' operator matches anything except one of the given patterns. This requires the 'extglob' option to be enabled. Example: '!(*.txt)' matches all files except those ending in '.txt'.
Conditional Constructs > Pattern Matching Conditionals
27 questionsThe word character class matches letters, digits, and the character _ (underscore).
If you quote any part of the pattern using any of the shell's quoting mechanisms, the quoted portion is matched literally (every character matches itself instead of having special pattern matching meaning).
The special pattern characters must be quoted if they are to be matched literally.
The exact syntax is: case word in [ [(] pattern [| pattern]...) command-list ;;]... esac
The array variable BASH_REMATCH records which parts of the string matched the pattern. Index 0 contains the portion matching the entire regular expression, and index n contains the portion matching the nth parenthesized subexpression.
The extglob shell option must be enabled using the shopt builtin to use extended pattern matching operators.
The word undergoes tilde expansion, parameter expansion, command substitution, process substitution, arithmetic expansion, and quote removal before pattern matching is attempted.
The == and != operators, when used with [[, treat the string to the right of the operator as a pattern and match according to pattern matching rules (as if extglob were enabled). The = operator is identical to ==.
The * pattern is commonly used as the final pattern to define the default case, since it will always match.
When ;; is used, the case command completes after executing the command-list for the first matching pattern, without attempting any further pattern matches.
The +(pattern-list) operator matches one or more occurrences of the given patterns.
The return value is 0 if the string matches the pattern, 1 if it does not match, and 2 if the regular expression is syntactically incorrect.
Each pattern undergoes tilde expansion, parameter expansion, command substitution, arithmetic expansion, process substitution, and quote removal.
Using ;;& causes the shell to test the patterns in the next clause and execute any associated command-list if the match succeeds, continuing case statement execution as if the pattern list had not matched.
The POSIX character classes are: alnum, alpha, ascii, blank, cntrl, digit, graph, lower, print, punct, space, upper, word, xdigit.
The match succeeds if the pattern matches any part of the string. To force the pattern to match the entire string, anchor the pattern using the ^ and $ regular expression operators.
The nocasematch shell option, when enabled via shopt, makes pattern matching in case statements disregard the case of alphabetic characters.
When a pattern matches, the return status is the exit status of the last command-list executed.
Using ;& causes execution to continue with the command-list associated with the next clause, if any, regardless of whether the next pattern matches.
The !(pattern-list) operator matches anything except one of the given patterns.
The =~ operator uses POSIX extended regular expressions (matched using the POSIX regcomp and regexec interfaces usually described in regex(3)).
When extglob is enabled, five extended pattern matching operators are recognized: ?(pattern-list) matches zero or one occurrence, *(pattern-list) matches zero or more occurrences, +(pattern-list) matches one or more occurrences, @(pattern-list) matches one of the patterns, and !(pattern-list) matches anything except one of the patterns.
Interactive Shells > Job Control
27 questionsThe SIGCONT signal is sent to resume a stopped process. When you use 'fg' or 'bg', the shell sends SIGCONT to the job to resume execution. The job then runs in the foreground (fg) or background (bg).
In Bash job control, each job is a process group with a unique process group ID (PGID). The foreground job has control of the terminal, and background jobs do not. The 'jobs -l' command displays both job numbers and process group IDs.
In interactive shells, Bash does not send SIGHUP to background jobs by default when the shell exits, unless the huponexit option is set. The jobs continue running (or are orphaned) after the shell exits. Using 'disown' removes jobs from the job table but they continue running.
The wait builtin waits for background processes to complete. If given job specifications or process IDs, wait waits for each specified process/job to exit and returns the exit status of the last command waited for. With no arguments, wait waits for all currently active child processes and returns 0.
The huponexit option controls whether Bash sends SIGHUP to all jobs when an interactive login shell exits. If set (shopt -s huponexit), Bash sends SIGHUP to all jobs; if unset (the default), jobs are not sent SIGHUP on exit.
Ctrl+Z sends the SIGTSTP signal to the foreground process group, which stops (suspends) the process.
The suspend builtin suspends the execution of the shell until it receives a SIGCONT signal. The -f option prevents the shell from complaining if it cannot suspend itself (e.g., if it's a login shell).
When a background job attempts to read from the terminal, it receives a SIGTTIN signal, which causes the job to stop. The shell will notify the user that the job is stopped.
By default, Bash sends SIGHUP to all jobs when an interactive login shell exits. This behavior can be prevented using the 'shopt -s huponexit' option (disabled by default) or by using 'disown -h' on specific jobs.
The job_control variable (set automatically by Bash, not settable by users) indicates whether job control is enabled. It is set when the shell has job control enabled, typically in interactive shells on systems that support job control.
The auto_resume option controls how the shell treats single word simple commands without redirections. If set, the shell searches the job table for a job whose command starts with the specified word and resumes it in the foreground or background depending on how the job was started.
Ctrl+Y sends the SIGSTOP signal to the foreground process group when the shell supports software flow control (IXON), causing the process to suspend but delaying the signal until the process attempts to read from the terminal.
Job control is enabled when the 'set -m' option is used (set -o monitor). In interactive shells on systems that support job control, job control is enabled by default.
The bg builtin resumes suspended jobs in the background, or moves a stopped job to the background. If no job specification is given, the current job is used.
Job control is typically disabled in non-interactive shells. The 'set -m' option can enable it, but job control is primarily designed for interactive use where the shell has a controlling terminal.
The fg builtin resumes a suspended job in the foreground, or moves a background job to the foreground. If no job specification is given, the current job (%% or %+) is used.
In job listings, the symbol + indicates the current job (the most recent job started or foregrounded), and - indicates the previous job (the second most recent job). These symbols are used with job specifications: %% or %+ refers to the current job, and %- refers to the previous job.
Ctrl+C sends the SIGINT signal to the foreground process group, which typically terminates the process.
Job control is a facility that allows users to stop and resume processes, and move processes between the foreground and background. It requires the operating system to support job control and is typically only available in interactive shells.
The monitor option (set -m or set -o monitor) enables job control. When set, Bash places all processes in each pipeline into separate process groups and allows interactive job control facilities.
The default format for job status includes: job number, status (Running, Done, Stopped, Exit), and the command. For example: '[1]+ Running sleep 100 &' where 1 is the job number, + indicates it's the current job, 'Running' is the status, and 'sleep 100 &' is the command.
Jobs are specified using '%' followed by the job number: %% or %+ for the current job, %- for the previous job, %n for job number n, %string for a job whose command starts with string, and %?string for a job whose command contains string.
You can refer to a job by its process group ID using %-PGID where PGID is the process group ID. For example, 'kill %-1234' sends a signal to the process group with PGID 1234.
When the tostop option has been set (stty tostop), a background process attempting to write to the terminal receives a SIGTTOU signal, which stops the job.
The disown builtin removes jobs from the shell's job table. Options include -a (remove all jobs), -h (mark each job so SIGHUP is not sent to the job if the shell receives a SIGHUP), and -r (remove only running jobs). Jobs that have been disowned are no longer managed by the shell.
When multiple jobs or process IDs are specified to the wait builtin, it waits for each one to exit and returns the exit status of the last command or job waited for.
The jobs builtin displays the status of jobs in the current shell. Options include -l (list process IDs in addition to job numbers), -n (list only jobs whose status has changed since the last notification), -p (list process group IDs only), and -r (restrict to running jobs) or -s (restrict to stopped jobs).
Filename Expansion > Character Classes and Bracket Expressions
27 questions[[:alnum:]] matches any alphanumeric character (letters and digits). This is equivalent to [A-Za-z0-9] but respects locale settings for international characters.
No, bracket expressions cannot match newlines in filename expansion because filenames cannot contain newline characters. However, bracket expressions can match newlines in other contexts like [[ string =~ regex ]] or parameter expansion patterns.
Yes, character classes can be used in case statement patterns. For example: case "$var" in [[:digit:]]) echo 'starts with digit';; [[:upper:]]) echo 'starts with uppercase';; esac
Use a hyphen between two characters: [a-z] matches all lowercase letters, [0-9] matches digits, [A-Za-z] matches all letters. The hyphen must be escaped or placed at the beginning or end of the bracket expression to be treated as a literal hyphen.
[[:print:]] matches all printable characters including the space character, while [[:graph:]] matches all printable characters except space. So [[:graph:]] is equivalent to [[:print:]] minus space.
[[:alpha:]] matches all alphabetic characters. This is equivalent to [A-Za-z] but respects locale settings for international characters.
[[:xdigit:]] matches hexadecimal digits: 0-9, a-f, and A-F. This is useful for matching files containing hexadecimal numbers.
Place the closing bracket as the first character in the expression. For example, []abc] matches a closing bracket or 'a' or 'b' or 'c'. The ] must be immediately after the opening [ to be treated literally.
[[:space:]] matches whitespace characters including space, tab, newline, carriage return, form feed, and vertical tab.
[[:lower:]] matches lowercase letters only (a-z in POSIX locale, but locale-dependent), while [[:upper:]] matches uppercase letters only (A-Z in POSIX locale, but locale-dependent). Both respect the current locale settings.
When globasciiranges is enabled (default in bash 4.3+), range expressions like [a-z] are interpreted based on ASCII/Unicode code point ordering regardless of locale. When disabled, ranges respect the current locale's collation order.
POSIX character classes require double brackets: [[:class:]]. For example, [[:alpha:]] matches any alphabetic character. The outer brackets are the bracket expression container, and the inner brackets with colons denote the character class.
[[:cntrl:]] matches control characters (ASCII codes 0-31 and 127). These are non-printing characters like bell, backspace, escape, etc.
Yes, POSIX character classes like [[:alpha:]], [[:upper:]], and [[:lower:]] respect the current locale settings. For example, [[:alpha:]] may match accented characters in non-POSIX locales.
Yes, you can combine multiple character classes and literal characters. For example, [[:alpha:]_[[:digit:]]] matches letters, underscores, and digits. The characters inside the outer brackets form the set of matching characters.
Escape the hyphen with a backslash: [a-z] matches 'a', '-', or 'z'. Alternatively, place it where it cannot form a range, such as at the beginning or end of the expression.
Equivalence classes use the syntax [[=c=]] where c is a character. They match all characters that are equivalent to c according to the current locale. For example, [[=e=]] might match 'e', 'è', 'é', 'ê', etc. depending on the locale.
When nullglob is enabled and a pattern produces no matches, the pattern expands to nothing (is removed) rather than being left as the literal pattern string. This affects all glob patterns including those using bracket expressions.
Use ! as the first character inside the brackets. For example, [![:digit:]] matches any character that is NOT a digit. The ^ character also works for negation: [^[:digit:]] is equivalent to [![:digit:]].
[[:digit:]] matches the characters 0 through 9. This is equivalent to [0-9] but is the locale-independent portable form.
Collating elements use the syntax [[.symbol.]] where symbol is a multi-character collating element or a symbolic name. For example, in some locales, [[.ch.]] treats 'ch' as a single collating element (used in Spanish collation order).
When dotglob is enabled, filename expansion matches filenames that begin with a dot (.). By default, files starting with dot are not matched by wildcard patterns like * or ?.
[[:punct:]] matches punctuation characters. In the C locale, this includes: ! " # $ % & ' ( ) * + , - . / : ; < = > ? @ [ \ ] ^ _ ` { | } ~
[[:blank:]] matches only space and tab characters, while [[:space:]] matches all whitespace characters including space, tab, newline, carriage return, form feed, and vertical tab.
No, the ? wildcard does not match filenames that begin with a dot by default, unless the dotglob option is enabled. This applies even if the ? appears in a pattern like [[:alpha:]]?.
When failglob is enabled and a pattern produces no matches, bash reports an error instead of leaving the pattern as literal text or expanding it to nothing. This applies to patterns with bracket expressions that have no matching files.
When nocaseglob is enabled, bash matches filenames in a case-insensitive manner during filename expansion. This means [[:upper:]] and [[:lower:]] would match both uppercase and lowercase letters.
Shell Parameters > Positional Parameters
27 questionsWhen a positional parameter consisting of more than a single digit is expanded, it must be enclosed in braces. Without braces, a digit following '$' can only refer to one of the first nine positional parameters ($1-$9). For example, if the first positional parameter has the value 'a', then ${11} expands to the value of the eleventh positional parameter, while $11 expands to 'a1'.
No, positional parameters and special parameters may not be assigned using ${parameter:=word}.
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.
No, positional parameters may not be assigned to with assignment statements. The set and shift builtins are used to set and unset them.
If parameter is '@' or '*', the @operator operation (U, u, L, Q, E, P, A, K, a, k) is applied to each positional parameter in turn, and the expansion is the resultant list.
If parameter is '@' or '*', the result is length positional parameters beginning at offset. Substring indexing is zero-based unless the positional parameters are used, in which case the indexing starts at 1 by default. If offset is 0, and the positional parameters are used, $0 is prefixed to the list.
When there are no positional parameters, "$@" and $@ expand to nothing (i.e., they are removed).
shift shifts the positional parameters to the left by n (default 1). The positional parameters from n+1 ... $# are renamed to $1 ... $#-n. Parameters represented by the numbers $# to $#-n+1 are unset.
If parameter is '@' or '*', the pattern removal operation (#, ##, %, %%) is applied to each positional parameter in turn, and the expansion is the resultant list.
No, 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.
If parameter is '@' or '*', the case modification operation (^, ^^, ,, ,,) is applied to each positional parameter in turn, and the expansion is the resultant list.
Within double quotes, "$*" expands to a single word with the value of each parameter separated by the first character of the IFS variable (equivalent to "$1c$2c…" where c is the first character of IFS). "$@" expands to each parameter as a separate word (equivalent to "$1" "$2" …).
In a subshell, $$ expands to the process ID of the invoking shell, not the subshell.
$# expands to the number of positional parameters in decimal, excluding $0.
If IFS is unset, the parameters in "$*" are separated by spaces. If IFS is null, the parameters are joined without intervening separators.
The first element of the FUNCNAME variable is set to the name of the function while the function is executing.
If parameter is '@' or '*', the substitution operation (/pattern/string/, //pattern/string/, etc.) is applied to each positional parameter in turn, and the expansion is the resultant list.
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.
$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, $0 is set to the name of that file. If Bash is started with the -c option, 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.
If n is zero or greater than $#, the positional parameters are not changed.
The return status is zero unless n is greater than $# or less than zero, in which case it is non-zero.
getopts is used by shell scripts to parse positional parameters. Each time it is invoked, getopts places the next option in the shell variable name, 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.
Positional parameter N may be referenced as ${N}, or as $N when N consists of a single digit.
getopts normally parses the positional parameters, but if more arguments are given in args, getopts parses those instead.
If parameter is '*' or '@', ${#parameter} substitutes the number of positional parameters.
The positional parameters are temporarily replaced when a shell function is executed. When a function is executed, the arguments to the function become the positional parameters during its execution. The special parameter '#' is updated to reflect the new set of positional parameters, but special parameter 0 is unchanged.
Readline Interaction > Text Manipulation
26 questionsM-d (Meta-d or Alt-d) is the default key binding for 'kill-word', which kills the text from the current cursor position to the end of the current word, using readline's word boundaries.
The yank-pop command (bound to M-y or Alt-y by default) rotates through the kill ring, replacing the previously yanked text with the next entry in the kill ring. It can only be used immediately after a yank (C-y) or another yank-pop.
The 'kill-whole-line' command kills all characters on the current line, no matter where the cursor is positioned. There is no default key binding for this command.
M-\ (Meta-backslash or Alt-backslash) is the default key binding for 'delete-horizontal-space', which deletes all spaces and tabs around the current cursor position.
Rubout (Backspace or C-h) is the default key binding for 'backward-delete-char', which deletes the character before the current cursor position.
M-u (Meta-u or Alt-u) is the default key binding for 'upcase-word', which converts the current (or following) word to uppercase and moves the cursor to the end of the word.
M-" (Meta-quote or Alt-") is the default key binding for 'quote-and-complete-word', which adds single quotes around the current or next word. If the word is already quoted, it unquotes it.
The default maximum number of entries in the readline kill ring is 15. This can be changed by setting the 'kill-ring-max' variable in the .inputrc file.
The 'tilde-shell-expand' variable is not related to this. For case conversion commands like capitalize-word, downcase-word, and upcase-word, a numeric argument of N causes the operation to affect the next N words. Without a numeric argument, they affect the current word.
The 'tab-insert' command inserts a tab character at the current cursor position. There is no default key binding; users typically bind it if they need to insert literal tabs.
C-y (Ctrl-y) is the default key binding for the 'yank' command, which inserts the most recently killed text at the current cursor position.
unix-word-rubout (C-w) kills text backward to the beginning of the word using whitespace as the word boundary, while backward-kill-word (M-DEL) kills text backward to the beginning of the word using readline's word boundaries (which consider alphanumeric characters and underscores as part of words).
The 'shell-expand-line' command (bound to M-C-e by default) expands the line as the shell would, performing alias expansion, history expansion, and all shell word expansions. It is useful for previewing how the shell will interpret the command before executing it.
C-s (Ctrl-s) is the default key binding for 'forward-search-history', which searches forward through the command history starting from the current line.
M-l (Meta-l or Alt-l) is the default key binding for 'downcase-word', which converts the current (or following) word to lowercase and moves the cursor to the end of the word.
C-k (Ctrl-k) is the default key binding for 'kill-line', which kills the text from the current cursor position to the end of the line.
M-. (Meta-. or Alt-.) or M-_ (Meta-_ or Alt-_) is the default key binding for 'yank-last-arg', which inserts the last argument from the previous command in the history. Repeated presses cycle through previous arguments.
M-& (Meta-& or Alt-&) is not correct. The 'history-expand-line' command performs history expansion on the current line. There is no standard default key binding; users typically bind it to a key.
M-c (Meta-c or Alt-c) is the default key binding for 'capitalize-word', which capitalizes the current (or following) word and moves the cursor to the end of the word.
The 'alias-expand-line' command performs alias expansion and history expansion on the current line. There is no default key binding for this command.
C-d (Ctrl-d) is the default key binding for 'delete-char', which deletes the character at the current cursor position. If the line is empty, it causes EOF.
M-o (Meta-o or Alt-o) is the default key binding for 'overwrite-mode', which toggles between insert mode and overwrite mode. In overwrite mode, typed characters replace existing characters instead of being inserted.
C-t (Ctrl-t) is the default key binding for 'transpose-chars', which swaps the character at the cursor position with the character before it, and moves the cursor forward one character.
M-t (Meta-t or Alt-t) is the default key binding for 'transpose-words', which swaps the word at the cursor position with the word before it, and moves the cursor forward one word.
C-r (Ctrl-r) is the default key binding for 'reverse-search-history', which searches backward through the command history starting from the current line.
C-u (Ctrl-u) is the default key binding for 'unix-line-discard', which kills the text from the current cursor position to the beginning of the line.
Shell Functions > Function Execution and Invocation
26 questionsIf return is supplied a numeric argument, that becomes the function's return status. The return value is its least significant 8 bits (effectively limiting it to 0-255).
FUNCNAME can be used with BASH_LINENO and BASH_SOURCE. Each element of FUNCNAME has corresponding elements in BASH_LINENO and BASH_SOURCE to describe the call stack.
The -f option to export is used to export shell functions. Using -p and -f together displays exported functions.
Bash uses dynamic scoping to control a variable's visibility within functions. With dynamic scoping, visible variables and their values are a result of the sequence of function calls that caused execution to reach the current function.
The unset builtin acts using dynamic scoping: if a variable is local to the current scope, unset unsets it; otherwise the unset will refer to the variable found in any calling scope.
Shell functions are executed just like a 'regular' simple command. They are executed in the current shell context; no new process is created to interpret them.
By default, Bash places no limit on the number of recursive calls. Functions may be recursive without any built-in restriction.
Any redirections associated with the shell function are performed when the function is executed.
The ERR trap is not inherited by functions unless the -o errtrace shell option has been enabled.
If a variable at the current local scope is unset, it remains so (appearing as unset) until it is reset in that scope or until the function returns. Once the function returns, any instance of the variable at a previous scope becomes visible.
The special parameter # that expands to the number of positional parameters is updated to reflect the new set of positional parameters when a function is executed.
The element with index 0 of FUNCNAME is the name of any currently-executing shell function.
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.
FUNCNEST defines a maximum function nesting level when set to a numeric value greater than 0. Function invocations that exceed this nesting level will cause the current command to abort.
If return is not supplied a numeric argument, the function's return status is the exit status of the last command executed before the return.
Yes. Functions may be exported so that child shell processes (those created when executing a separate shell invocation) automatically have them defined with the -f option to the export builtin.
Set the FUNCNEST variable to a numeric value greater than 0. This defines a maximum function nesting level. Function invocations that exceed the limit cause the entire command to abort.
Function definitions are deleted using the -f option to the unset builtin.
FUNCNAME is an array variable containing the names of all shell functions currently in the execution call stack. The element with index 0 is the name of any currently-executing shell function. This variable exists only when a shell function is executing. Assignments to FUNCNAME have no effect.
${FUNCNAME[$i]} was called from the file ${BASH_SOURCE[$i+1]} at line number ${BASH_LINENO[$i]}. The caller builtin displays the current call stack using this information.
If a variable is declared as local in one function, and that function calls another function, references to that variable from within the called function resolve to the local variable from the calling function, shadowing any global variable with the same name.
When executed, the exit status of a function is the exit status of the last command executed in the body.
The bottom-most element of FUNCNAME (the one with the highest index) is "main".
By default, the DEBUG and RETURN traps are not inherited by functions. They are only inherited if the function has been given the trace attribute using the declare builtin or if the -o functrace option has been enabled with the set builtin (in which case all functions inherit the DEBUG and RETURN traps).
If return is executed by a trap handler, the last command used to determine the status is the last command executed before the trap handler. If return is executed during a DEBUG trap, the last command used to determine the status is the last command executed by the trap handler before return was invoked.
No. Special parameter 0 is unchanged during function execution. The first element of the FUNCNAME variable is set to the name of the function while the function is executing.
Controlling the Prompt > Command Context
26 questions$ displays a # if the effective UID is 0 (root), otherwise displays a $.
\h produces the hostname up to the first dot (.), while \H produces the full hostname.
\W displays the basename of $PWD, with $HOME abbreviated with a tilde (~).
\t produces current time in 24-hour HH:MM:SS format, \T produces current time in 12-hour HH:MM:SS format, @ produces current time in 12-hour am/pm format, and \A produces current time in 24-hour HH:MM format.
The default value of PS2 is ``> '' (greater-than sign followed by a space).
PROMPT_DIRTRIM is used by the \w prompt escape to truncate the working directory path to a specified number of trailing path components when the path becomes too long.
\s displays the name of the shell, which is the basename of $0 (the portion following the final slash).
After the prompt 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.
The default value of PS1 is ``\s-\v$ '' which displays the shell name, version, and a $ or # prompt character.
PS0 is displayed by interactive shells after reading a command and before the command is executed. The value is expanded according to the PROMPTING rules.
\w displays the value of the PWD shell variable ($PWD) with $HOME abbreviated with a tilde (uses PROMPT_DIRTRIM variable). \W displays only the basename of $PWD, with $HOME abbreviated with a tilde.
\n produces a newline character and \r produces a carriage return character.
PS1 is displayed when bash is ready to read a command. PS2 is displayed when bash needs more input to complete a command. PS0 is displayed after reading a command but before executing it. PS4 is displayed before tracing each command when the -x option is enabled.
! displays the history number of this command (its position in the history list), while # displays the command number of this command (position in the sequence of commands executed during the current shell session).
The format string is passed to strftime(3) and the result is inserted into the prompt string. An empty format results in a locale-specific time representation. The braces are required.
The default value of PS4 is ``+ '' (plus sign followed by a space). The first character of the expanded PS4 value is replicated multiple times to indicate multiple levels of indirection.
[ begins a sequence of non-printing characters, and ] ends a sequence of non-printing characters. These are used to embed terminal control sequences into the prompt without affecting line wrapping calculations.
The promptvars shell option controls whether prompt strings undergo parameter expansion, command substitution, arithmetic expansion, and quote removal.
\d produces the date in "Weekday Month Date" format (e.g., "Tue May 26").
\v displays the version of bash (e.g., 2.00), while \V displays the release of bash including version + patch level (e.g., 2.00.0).
Bourne Shell Builtins > Script Lifecycle
26 questionsExecuting 'trap -' resets all signal handlers to their default dispositions for the current shell.
The 'wait -n' option waits for exactly one background job or process to complete and returns its exit status. If multiple jobs terminate while wait is waiting, the status of one of them is returned (not necessarily the one that terminated first).
The let builtin requires at least one argument. Each argument is evaluated as an arithmetic expression. The last expression's value becomes the exit status (0 if true/non-zero, 1 if false/zero). With no arguments, let prints an error message and returns status 1.
When exit is called without an argument, it returns the exit status of the last command executed.
ERR is a special condition that trap recognizes. When used (trap 'command' ERR), the command is executed whenever a pipeline or list of commands (which may be a single compound command) exits with a non-zero status, subject to these conditions: 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 with !.
Traps that are set while a subshell is executing remain in effect when the subshell exits. However, traps are not inherited by subshells when they are first created.
The exec builtin replaces the shell with a new command without creating a new process. After exec, the new command becomes the shell process, and the original shell's PID is retained. If no command is specified, any redirections take effect in the current shell.
If wait is invoked when all background jobs have already terminated or no jobs are running, it returns an exit status of 127.
RETURN is a special condition that trap recognizes. When used (trap 'command' RETURN), the command is executed after each shell function or script sourced with the . or source builtins finishes executing.
The command 'trap -p' displays the trap commands associated with each signal. If signal specifications are provided, only traps for those signals are displayed.
When exec is called with a command, the shell is replaced without running the EXIT trap. This is because the shell process itself is replaced, not terminated.
The exit builtin accepts an integer n in the range 0-255. If n is omitted, the exit status is that of the last command executed. Values outside this range are wrapped modulo 256.
The times builtin prints the accumulated user and system times for the shell and for all processes that have executed as children of the shell. The output format shows two lines: user and system time for the shell, and user and system time for child processes.
The exit builtin causes the shell to exit with a given status, while return causes a function to exit with a given status. If return is not executed within a function, it behaves identically to exit.
When trap is executed without arguments, it prints a list of commands associated with each signal, in a format that can be reused as shell input.
When the trap argument is an empty string (''), the specified signals are ignored by the shell and by the commands it invokes.
If return is used outside of a function or during execution of a script by the . (source) builtin, it causes the shell to exit with the specified status. Otherwise, it returns from a function with the specified status.
DEBUG is a special condition that trap recognizes. When used (trap 'command' DEBUG), the command is executed before every simple command, for command, case command, select command, every arithmetic for command, and before the first command executes in a shell function.
The eval builtin concatenates all its arguments with spaces and evaluates the resulting string as a command. The command is then read and executed by the shell, and its exit status is returned as the exit status of eval.
The return builtin accepts an integer n in the range 0-255. If n is omitted, the return status is that of the last command executed.
No, the logout builtin only exits a login shell. If executed in a non-login shell, it produces an error message and returns a non-zero exit status.
The trap builtin cannot trap SIGKILL (9), SIGSTOP (19), or SIGCONT (18). These signals cannot be caught or ignored by any process on POSIX systems.
The source builtin can be invoked as either 'source' or '.' (a single period). Both names are identical in function.
EXIT is not a real signal but a special condition that trap recognizes. When used (trap 'command' EXIT), the command is executed when the shell exits, regardless of whether the exit is from an exit command, reaching end-of-file, or from a signal.
The 'wait -f' option causes wait to wait until each job or process terminates before returning its exit status, rather than returning when the job status changes. This requires job control to be enabled.
The wait builtin waits for each specified job or process to complete and returns the exit status of the last awaited command. If no specifications are given, it waits for all currently active child processes.
Filename Expansion > Extended Pattern Matching
26 questionsWhen dotglob is enabled ('shopt -s dotglob'), filename expansion patterns that include * and ? will match filenames beginning with a dot (hidden files). Without dotglob, these patterns don't match hidden files unless the pattern explicitly starts with a dot.
Use the ?(pattern-list) operator: 'file?(.bak).txt'. This matches both 'file.txt' and 'file.bak.txt' but not 'file..bak.txt' or 'file.bak.bak.txt'.
The !(pattern-list) operator matches anything except one of the given patterns. For example, '!(*.txt)' matches any string that does not end with '.txt'. It's useful for excluding specific patterns.
When nullglob is enabled ('shopt -s nullglob'), patterns that match no filenames expand to nothing rather than being treated as literal strings. This applies to extended patterns too - if '!(*.txt)' matches nothing, it expands to null.
*(pattern) matches zero or more occurrences (including an empty match), while +(pattern) matches one or more occurrences (requires at least one match). For example, *(foo) matches '', 'foo', 'foofoo', but +(foo) only matches 'foo', 'foofoo', etc.
The extglob option is disabled by default in bash. You must explicitly enable it with 'shopt -s extglob' to use extended pattern matching operators.
The (pattern-list) operator matches zero or more occurrences of the given patterns. For example, 'file(.txt)' would match 'file', 'file.txt', 'file.txt.txt', etc.
Use the +(pattern-list) operator with a character class: 'file+([0-9]).txt'. This matches 'file1.txt', 'file123.txt', but not 'file.txt' (requires at least one digit).
GLOBIGNORE is a colon-separated list of patterns defining files to be ignored during pathname expansion. When set, files matching these patterns are not considered in expansion. This works with extended patterns if extglob is enabled, e.g., GLOBIGNORE='.o:.~'.
When extglob is disabled, the extended pattern matching characters (?, *, +, @, !) followed by a parenthesis are treated literally as regular filename characters and lose their special meaning in pattern matching contexts.
When nocasematch is enabled ('shopt -s nocasematch'), pattern matching becomes case-insensitive. '@(FILE|file).txt' would match both 'FILE.txt' and 'file.txt' as well as 'File.txt'.
Extended pattern matching is case-sensitive by default. To make it case-insensitive, you must set the nocasematch shell option with 'shopt -s nocasematch'.
Yes, extended pattern matching operators can be nested. For example, '@(file?(.txt|@(pdf|doc)))' is valid. The pattern-list can contain other extended pattern operators.
Yes, when extglob is enabled, extended pattern matching operators work in the [[ compound command's == and != operators. For example: '[[ $file == @(foo|bar) ]]' checks if $file matches 'foo' or 'bar'.
The +(pattern-list) operator matches one or more occurrences of the given patterns. Unlike *(pattern-list), it requires at least one match. For example, '+([0-9])' matches one or more digits but would not match an empty string.
nocaseglob enables case-insensitive matching specifically for filename expansion (globbing), while nocasematch affects all pattern matching including case statements and [[ ]] tests. Both can affect extended patterns in different contexts.
Use the !(pattern-list) operator: '!(*.sh)'. This matches any filename that does not end with .sh. This requires extglob to be enabled.
Patterns in a pattern-list are separated by the | (pipe) character. For example, '@(file1|file2|file3)' matches exactly one of 'file1', 'file2', or 'file3'.
The extglob shell option enables extended pattern matching. Enable it with 'shopt -s extglob' and disable it with 'shopt -u extglob'. When extglob is enabled, extended pattern matching operators are recognized in pathname expansion.
When extquote is enabled (the default), $'string' and $"string" quoting is performed within ${parameter} expansions enclosed in double quotes. This affects how patterns are interpreted when used in parameter expansions.
Yes, when extglob is enabled, extended pattern matching operators can be used in case statement patterns. For example: 'case $filename in @(foo|bar)) echo "matched";; esac'.
When globasciiranges is enabled (the default), range expressions in pattern matching like [a-z] are interpreted using the traditional ASCII ordering. When disabled with 'shopt -u globasciiranges', ranges use the current locale's collating order.
Use the @(pattern-list) operator with a pipe-separated list: '*.@(jpg|png|gif)'. This matches exactly one of the specified extensions, so 'file.jpg' matches but 'file.jpg.png' does not.
The @(pattern-list) operator matches exactly one of the given patterns. For example, '@(foo|bar)' matches either 'foo' or 'bar', but not 'foobar' or an empty string. It's useful for matching specific alternatives.
The ?(pattern-list) operator matches zero or one occurrence of the given patterns. For example, 'file?(.txt)' would match 'file.txt' or 'file', but not 'filea.txt' or 'fileab.txt'.
Shell Parameter Expansion > Substring Extraction
25 questionsSubstring Expansion. It expands to up to length characters of the value of parameter starting at the character specified by offset.
If offset is omitted, it defaults to 0, and if the colon is present without a length value, length defaults to 0, resulting in an empty string.
If offset is omitted, it is treated as 0. For example, ${string::3} is equivalent to ${string:0:3}.
If parameter is '@' or '*', the result is length positional parameters beginning at offset. This works on the positional parameter list, not a string.
If offset is 0 and the positional parameters are used, $0 is prefixed to the list. For example, ${@:0:2} expands to "$0 $1".
If length is omitted but the colon after offset is present, length is treated as 0. For example, ${string:7:} returns an empty string.
No, it is an expansion error if length evaluates to a number less than zero when using positional parameters. Bash will report 'substring expression < 0'.
Yes, both offset and length are arithmetic expressions and can contain variables, arithmetic operations, and nested expansions. For example, ${string:$((2+3)):$((1+1))} is valid.
A negative offset is taken relative to one greater than the maximum index of the specified array. For example, if array has indices 0-4, offset -1 refers to position 5.
${parameter:offset:length} - where 'parameter' is the variable name, 'offset' is the starting position, and 'length' is the number of characters to extract. The length parameter can be omitted to extract from offset to the end of the value.
Yes, substring expansion can be applied to individual indexed array elements. For example, ${array[0]:7:2} extracts a substring from the first element of the array.
Substring expansion applied to an associative array produces undefined results. This is a documented limitation in Bash.
The expansion returns all characters from offset to the end of the string. It does not error if length is greater than the remaining characters.
Both offset and length are arithmetic expressions. They can include variables, mathematical operations, and command substitutions that evaluate to integers.
If offset evaluates to a number less than zero, the value is used as an offset in characters from the end of the value of parameter. For example, ${string: -3} extracts the last 3 characters.
If length evaluates to a number less than zero, it is interpreted as an offset in characters from the end of the value of parameter rather than a number of characters. The expansion is the characters between offset and that result. For example, with string='01234567890abcdefgh', ${string:7:-2} returns '7890abcdef'.
No, it is an expansion error if length evaluates to a number less than zero when using indexed arrays. Bash will report 'substring expression < 0'.
${@:offset:length} or ${*:offset:length} - this expands to length positional parameters beginning at offset.
${array[@]:offset:length} or ${array[*]:offset:length} - this expands to length members of the array beginning with ${array[offset]}.
A negative offset must be separated from the colon by at least one space to avoid being confused with the ':-' default value expansion operator. For example, ${string: -5} instead of ${string:-5}.
${var:offset} expands to the substring from offset to the end of the value. ${var:offset:length} expands to up to length characters starting at offset.
You can use parentheses: ${string:(-5)} as an alternative to ${string: -5} to avoid ambiguity with the :- operator.
For positional parameters ($@, $*), the indexing starts at 1 by default. This is different from regular variables which use zero-based indexing.
A negative offset is taken relative to one greater than the greatest positional parameter. An offset of -1 evaluates to the last positional parameter (or 0 if there are no positional parameters).
If the offset is beyond the end of the string, the expansion returns an empty string.
Arrays > Element Access and Retrieval
25 questions${array[$index]} - use variable expansion without quotes inside the brackets. Example: idx=2; echo ${arr[$idx]}
${array[@]^} - first char uppercase, ${array[@]^} - all first chars uppercase, ${array[@],} - first char lowercase, ${array[@],} - all first chars lowercase, ${array[@]^^} - all uppercase, ${array[@,,} - all lowercase (Bash 4.0+)
Yes. ${array[@]:-n} takes the last n elements. The space before -n is required to distinguish from default value syntax. Example: ${array[@]:-2} gets the last 2 elements.
Only the indices that actually exist, not a continuous range. For array arr=([0]=a [3]=b [5]=c), ${!arr[@]} returns '0 3 5'.
${array[-1]} (Bash 4.3+) or ${array[@]: -1} (note the space before -1) works in earlier versions
${array[@]:offset:length} where offset is the starting index (0-based) and length is the number of elements. Length is optional - if omitted, returns all elements from offset to end.
${array[index]:offset:length} - extracts a substring from the element at index. Example: ${arr[0]:2:3} gets 3 characters starting at position 2 from the first element.
${#array[index]} - returns the character length of the element at that index
It returns an empty string. Bash does not throw an error for out-of-bounds array access.
Returns all available elements from offset to end. No error is produced.
${array[-1]} accesses the last element, ${array[-2]} the second-to-last, etc. Negative indexing was added in Bash 4.3+.
"${array[@]}" expands each element to a separate word, preserving boundaries. "${array[*]}" expands to a single word with all elements joined by the first character of IFS (default: space).
${array[index]} where index starts at 0. For example: ${arr[2]} accesses the third element.
Use parameter expansion with pattern removal: ${array[@]#pattern} removes prefix from each element, ${array[@]%pattern} removes suffix from each element, ${array[@]/pattern/replacement} replaces pattern in each element.
When quoted, "${array[@]:1:3}" preserves each element as a separate word, while "${array[*]:1:3}" joins them with IFS. The slicing behavior is otherwise identical.
Pipelines
25 questionsThe 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.
A pipeline is a sequence of simple commands separated by one of the control operators '|' or '|&'. The output of each command in the pipeline is connected via a pipe to the input of the next command.
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.
Changes made to the subshell environment (where pipeline commands run) cannot affect the shell's main execution environment. Variables set in pipeline subshells are lost when the command completes.
If pipefail is enabled, the pipeline's return status is the value of the last (rightmost) command to exit with a non-zero status, or zero if all commands exit successfully. This option is disabled by default.
Yes, 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.
With errexit enabled, the shell does not exit if a command fails that is part of any command in a pipeline but the last, subject to the state of the 'pipefail' shell option.
The TIMEFORMAT variable is a format string that specifies how the timing information for pipelines prefixed with the 'time' reserved word should be displayed.
Builtin commands that are invoked as part of a pipeline, except possibly in the last element depending on the value of the 'lastpipe' shell option, are also executed in a subshell environment.
If the reserved word '!' precedes the pipeline, the exit status is the logical negation of the exit status described above.
If TIMEFORMAT 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.
Each command in a pipeline is executed in its own subshell, except possibly the last element depending on the value of the 'lastpipe' shell option.
If the precision (p) is not specified in TIMEFORMAT escape sequences, the value 3 is used (3 decimal places). At most three places after the decimal point may be specified; values of p greater than 3 are changed to 3.
Yes, if the pipeline is not executed asynchronously, the shell waits for all commands in the pipeline to terminate before returning a value.
The connection of output from each command to the input of the next command is performed before any redirections specified by the command.
PIPESTATUS is an array variable containing a list of exit status values from the processes in the most-recently-executed foreground pipeline (which may contain only a single command).
If '|&' is used, the standard error of command1 is connected to command2's standard input through the pipe; it is shorthand for '2>&1 |'. This implicit redirection of the standard error is performed after any redirections specified by the command.
The exit status of a pipeline is the exit status of the last command in the pipeline.
If set, and job control is not active, the shell runs the last command of a pipeline not executed in the background in the current shell environment (not a subshell).
Shell Parameters > Special Parameters
25 questions$- expands to the current option flags (those specified by set or implicitly set by the shell).
$PIPESTATUS is an array variable containing the exit statuses of each command in the most recently executed foreground pipeline, not a special parameter like those listed in the Special Parameters section.
When not quoted, $* expands to all positional parameters starting from 1, separated by the first character of IFS (internal field separator, typically space).
Exit status values range from 0 to 255, with 0 indicating success and 1-255 indicating various failure conditions.
Positional parameters beyond $9 must be referenced using braces, such as ${10}, ${11}, etc.
When double-quoted as "$@", it expands to each positional parameter as a separate word, preserving arguments with spaces exactly as they were passed.
No, special parameters are read-only and cannot be assigned values. Attempting to assign to them causes an error.
When not quoted, $@ expands to all positional parameters starting from 1, identical to $*.
When double-quoted as "$*", it expands to a single word containing all positional parameters separated by the first character of IFS.
$? expands to the exit status of the most recently executed foreground pipeline.
Yes, $_ in an interactive shell expands to the last argument of the previous command, useful for quickly reusing the last argument.
When IFS is unset, "$" and "$@" behave identically to when IFS is set to a space - parameters are separated by spaces in "$" and remain separate in "$@".
When IFS is null, "$" and "$@" both suppress delimiter joining, but "$@" still separates parameters into individual words while "$" joins them without delimiters.
$_ expands to the last argument of the previous command. At shell startup, it expands to the absolute pathname used to invoke the shell or script being executed.
$- displays the current set of options as a string, such as 'himBH' or 'himBHe' when options are enabled. Each letter represents an active option flag (e.g., 'x' for debug, 'e' for exit-on-error).
$! expands to the process ID (PID) of the most recently executed background (asynchronous) command.
After a command expansion like $(command), $_ contains the output of that command.
At shell startup, $_ contains the absolute pathname used to invoke the shell or script being executed.
"$*" treats all arguments as a single string (one iteration), while "$@" treats each argument as a separate string, which is critical for preserving arguments containing spaces: for arg in "$@" iterates once per original argument.
Readline Interaction > History Search
25 questionsforward-search-history performs an incremental search (like Ctrl+s) where you search for a string anywhere in the command. history-search-forward is non-incremental and searches for commands starting with the current line contents.
The 'history-preserve-point' variable, when set to 'on', preserves the cursor position during history searches. The default is 'off'.
Use the format: 'keysequence': command. Example: '\C-xr': reverse-search-history binds Ctrl+x followed by 'r' to reverse search. Key sequences use C- for Ctrl, \M- for Meta/Alt, and \e for Escape.
Ctrl+r (C-r) is the default key binding for reverse incremental search (reverse-search-history). This allows searching backward through the command history interactively.
reverse-search-history performs an incremental search (like Ctrl+r) where you search for a string anywhere in the command. history-search-backward is non-incremental and searches for commands starting with the current line contents.
Add these lines to ~/.inputrc: "\e[A": history-search-backward and "\e[B": history-search-forward. This makes arrow keys search for commands starting with what you've typed, rather than stepping through history one line at a time.
Yes, incremental search works in vi mode. In vi command mode, '/' performs forward search and '?' performs reverse search through history. Ctrl+r and Ctrl+s still work in both emacs and vi modes.
The 'beginning-of-history' command moves to the first line in the history list. By default, this is not bound to any key.
Ctrl+s may be intercepted by the terminal for software flow control (XON/XOFF). To fix this, run 'stty -ixon' to disable flow control, allowing Ctrl+s to reach bash.
Press Ctrl-g (C-g) to cancel an incremental search and return to the command line as it was before the search began.
Ctrl+s (C-s) is the default key binding for forward incremental search (forward-search-history). This allows searching forward through the command history interactively.
The 'next-history' command retrieves the next line from history. By default, this is bound to Ctrl+n (C-n) and the Down arrow (\e[B).
The 'echo-control-characters' variable, when set to 'on' (default), echoes characters during incremental search. When 'off', it suppresses the echo.
The readline command name is 'reverse-search-history'. This can be bound to different keys in .inputrc.
The 'completion-ignore-case' variable, when set to 'on', makes history searches case-insensitive. The default is 'off' (case-sensitive).
Yes, press any cursor movement key (like Left/Right arrows, Ctrl+a, Ctrl+e) or backspace to accept the search result and enter edit mode, allowing you to modify the command before execution.
The 'previous-history' command retrieves the previous line from history. By default, this is bound to Ctrl+p (C-p) and the Up arrow (\e[A).
During reverse incremental search (Ctrl+r), press Ctrl+r again to find the previous matching command. During forward incremental search (Ctrl+s), press Ctrl+s again to find the next matching command.
Pressing Enter accepts the current search result and immediately executes the command, retrieving it from history.
Use !?string? syntax. For example, !?foo? retrieves and executes the most recent command containing 'foo'. Add :p to print without executing: !?foo?:p
The 'history-search-backward' command performs a non-incremental search backward through history for commands beginning with the current line contents.
Readline doesn't control this. The bash HISTSIZE variable controls how many commands are stored in the session history list. The readline history-size variable in .inputrc can set a limit from the readline side.
This is not a readline variable but a bash shell variable. HISTAPPEND (when set) causes the history file to be appended rather than overwritten. Readline itself doesn't control history file writing.
There is no readline variable for this. History search direction is determined by the specific command used (history-search-backward, history-search-forward, reverse-search-history, forward-search-history).
The 'history-size' variable sets the maximum number of history commands to save. If set to 0, no history is saved. A negative value means unlimited. The default is typically 500.
Readline Interaction > Command Modifiers
25 questionsThe exchange-point-and-mark command (Ctrl-x Ctrl-x) swaps the positions of the mark and point (cursor). This allows you to jump back to a previously marked location and then return to the original position by invoking it again. It's useful for working with marked regions of text.
The dump-macros command prints all currently defined Readline macros and their key bindings. Macros are sequences of characters or commands that are bound to a single key sequence and expanded when that key is pressed.
The do-lowercase-version command is used internally by Readline when a Meta-character is entered without a valid binding. It executes the lowercase version of the unbound character if it exists. This is an internal mechanism and not typically invoked directly by users.
You can abort the current editing session using Ctrl-g (abort). The abort command cancels the current command and returns you to the command prompt with an empty line. It also cancels incremental searches if one is active.
The character-search command (Ctrl-]) searches forward in the command line for the next character that matches the character typed immediately after Ctrl-]. The cursor moves to that character. For example, Ctrl-] followed by 'n' moves to the next 'n' in the line.
The skip-csi-sequence command is used internally by Readline to skip over CSI (Control Sequence Introducer) escape sequences that are produced by certain function keys. This ensures that these special escape sequences don't interfere with normal editing operations. It's part of Readline's terminal handling and not typically invoked directly.
The re-read-init-file command (Meta-Ctrl-x or Alt-Ctrl-x) re-reads the inputrc file (~/.inputrc or /etc/inputrc) and applies any changes immediately without restarting Bash. This allows you to test new key bindings or variable changes in your current session.
The numeric argument in Readline can be any integer value that fits in a C int type (typically -2,147,483,648 to 2,147,483,647 on 32-bit systems, or larger on 64-bit systems). In practice, you can enter very large numbers by typing multiple digits, but most commands will have practical limits based on the buffer size.
To specify a numeric argument in Emacs mode, type Meta-0 through Meta-9 (or Alt-0 through Alt-9) followed by the command. For example, Meta-4 Meta-f moves forward four words. You can also type the digit and then hold Meta while typing additional digits. A negative argument is specified with Meta-- (Alt+-).
You can execute the last Readline command again using Ctrl-o (operate-and-get-next). After the current command is executed, Ctrl-o fetches the next line from history and allows you to edit it. This is different from simply pressing Enter which just executes and shows the next prompt.
The digit-argument command (Meta-0 through Meta-9, or Alt-0 through Alt-9) adds the specified digit to the current numeric argument being accumulated. When you start typing digits with the Meta key, it begins building a numeric argument that will be applied to the next command.
The complete command (Tab) performs completion according to the settings of 'readline-completion-auto-skip', 'readline-completion-case-fold', and other variables. It either completes the word, lists possible completions, or does nothing depending on the situation. The possible-completions command (Meta-? or Alt-?) always lists all possible completions without attempting to complete.
The tilde-expand command (Meta-& or Alt-&) performs tilde expansion on the current word. It expands ~ to the value of HOME, ~user to user's home directory, and other tilde prefixes according to the rules in the Bash manual. This can be invoked on a word before pressing Enter to see the expansion.
The undo command (Ctrl-_ or Ctrl-x Ctrl-u) undoes the most recent change to the command line. To undo multiple changes, you can invoke it repeatedly. Each undo reverses one unit of editing (insertions, deletions, or other modifications). In some configurations, you can also use Meta-- (Alt+-) followed by commands to apply numeric arguments.
The prefix-meta command (Meta or Escape) makes the next character typed be interpreted as a Meta-character. This allows you to use the Escape key as a Meta prefix on keyboards that don't have a dedicated Meta or Alt key. For example, pressing Escape followed by 'f' is equivalent to Meta-f.
When a Readline command is executed without a numeric argument, it uses a default count of 1 for commands that repeat actions. For some commands like 'kill-line', the absence of a numeric argument may affect how much text is affected (e.g., killing from point to end of line versus a specific number of characters).
The universal-argument command is used to multiply the numeric argument by 4. It can be invoked with Ctrl-u followed by digits. When invoked multiple times before entering digits, each Ctrl-u multiplies the multiplier by 4 (e.g., Ctrl-u Ctrl-u = 16, Ctrl-u Ctrl-u Ctrl-u = 64).
The dump-variables command prints all Readline variables that can be set in the inputrc file along with their current values. This is useful for checking the current state of Readline configuration and understanding which options are enabled.
The character-search command (Ctrl-]) searches forward for the specified character, while character-search-backward (Meta-Ctrl-] or Alt-Ctrl-]) searches backward. Both commands wait for you to type the character to search for after invoking the command.
The quoted-insert command (Ctrl-v or Ctrl-q) allows you to insert the next character literally, even if it would normally be interpreted as a Readline command. For example, Ctrl-v followed by Ctrl-c would insert a literal Ctrl-C character rather than interrupting. This is useful for inserting special characters into the command line.
You can execute any Readline command by name using Meta-x (or Alt-x) which invokes the 'execute-extended-command' function. This prompts for a command name and then executes it. You can use Tab completion at the prompt to see and select from available Readline commands.
The insert-completions command (Meta-* or Alt-*) inserts all possible completions for the current word before point. If there are multiple completions, they are all inserted separated by spaces. This is useful when you want to see or operate on all possible matches at once.
The set-mark command (Ctrl-@ or Ctrl-Space) sets the mark at the current cursor position. The mark is used in conjunction with point (cursor) to define a region of text for operations like copy and kill-region. In some terminal configurations Ctrl-Space may not work due to terminal flow control, making Ctrl-@ the alternative.
The keyboard-quit command (Ctrl-g) aborts the current editing command or incremental search and returns to the top-level prompt. It clears the current input line if not in a search, and exits incremental search mode if one is active. It's essentially the same as the 'abort' command.
A negative numeric argument reverses the direction of movement commands. For example, if Meta-f normally moves forward one word, a negative argument (Meta-- Meta-f) will move backward one word instead. Similarly, a negative argument to 'forward-char' moves backward instead of forward.
Bash Conditional Expressions > File Permission Tests
24 questionsIn Bash, [ is a synonym for the test builtin. They are functionally equivalent. Both support file permission tests like -r file, -w file, and -x file. The modern [[ compound command is preferred for conditional expressions as it has fewer quirks and better handling of special characters.
For directories, the -x test checks if the directory can be searched (i.e., you can access files within it by name), not whether it can be 'executed' like a program.
The -r test respects the operating system's access() system call, which typically considers ACLs on systems that support them (Linux with POSIX ACLs, FreeBSD, etc.). If an ACL grants read permission, -r will return true even if traditional Unix permissions would deny it.
The -O file operator returns true if file exists and is owned by the effective user ID of the current process.
Variables in file permission tests should always be quoted to prevent word splitting and globbing. Use: [ -r "$file" ] or [[ -r $file ]] (quoting is optional but safe inside [[ ]]). Incorrect: [ -r $file ]
Yes, you can combine multiple file permission tests using && (AND) and || (OR) operators. For example: [ -r "$file" ] && [ -w "$file" ] or with [[ ]]: [[ -r "$file" && -w "$file" ]]
The -w operator works correctly on directories and tests whether the directory is writable (i.e., files can be created or deleted within it, subject to additional permissions on individual files).
The -r file operator returns true if file exists and read permission is granted to the current user (effective user ID). The test is performed based on the real user ID/real group ID.
Bash itself doesn't impose a filename length limit for file permission tests, but the underlying filesystem does. Most modern filesystems support filenames up to 255 bytes. PATH_MAX (usually 4096 bytes) limits the full path length.
The -g file operator returns true if file exists and its set-group-id bit is set. This allows a user to execute a file with the permissions of the file's group.
The -u file operator returns true if file exists and its set-user-id bit is set. This allows a user to execute a file with the permissions of the file's owner.
The -w file operator returns true if file exists and write permission is granted to the current user (effective user ID). Note that this test may not be accurate on read-only filesystems.
In POSIX mode (enabled with sh -c or set -o posix), Bash follows POSIX standards more strictly. The [[ ]] construct is not POSIX compliant and may not work. Use [ ] for portable scripts. However, the basic file test operators (-r, -w, -x, -O, -G, -u, -g, -k) remain available in POSIX mode.
The -a (AND) and -o (OR) binary operators used inside [ ] are deprecated in favor of the && and || shell control operators. However, single-letter file test operators like -r, -w, -x are not deprecated.
The -G file operator returns true if file exists and its group ID matches the effective group ID of the current process.
File permission tests return exit status 0 (true) if the condition is met, and 1 (false) if not met. Exit status >1 indicates an error (e.g., invalid syntax). The if and while commands interpret 0 as true and non-zero as false.
No, Bash cannot handle null bytes in filenames. Filenames with embedded null characters cannot be created or tested because Bash uses null-terminated strings internally.
The -k file operator returns true if file exists and its sticky bit is set. This is commonly used on directories to restrict file deletion to the file owner.
Yes, the -w (write permission) test may not be accurate on read-only file systems. The kernel may report that write permission is granted based on file mode bits, but the underlying filesystem may be mounted read-only.
The -x file operator returns true if file exists and execute (or search) permission is granted to the current user (effective user ID). For directories, this tests if the directory can be searched.
Bash file permission tests (-r, -w, -x) use the effective user ID (euid) and effective group ID (egid), not the real user ID. This means if you're running a program with setuid/setgid, the tests use the elevated permissions, not your original login credentials.
Yes, all file permission test operators (-r, -w, -x, -O, -G, -u, -g, -k) require the file to exist. If the file does not exist, all these tests return false.
The -O (ownership) and -G (group ownership) tests are based on effective user ID and effective group ID, matching the behavior of -r, -w, and -x permission tests.
File permission tests follow symbolic links. If a symbolic link is broken (points to a non-existent target), permission tests will fail because the target file does not exist. The -L or -h tests should be used to check for the existence of symbolic links themselves.
Bash Builtin Commands > Command History Builtins
24 questionsThe fc -r option reverses the order of the lines so the newest commands are listed first.
The fc -s option re-executes a command from history after optionally performing pat=rep substitution. This is commonly aliased as 'r' for quick re-execution.
The fc builtin has two synopsis formats: fc [-e ename] [-lnr] [first] [last] for listing/editing, and fc -s [pat=rep] [command] for re-execution with substitution.
In fc, FIRST and LAST can be numbers specifying a range of commands, or FIRST can be a string which means the most recent command beginning with that string.
The history -s option appends the ARGs to the history list as a single entry.
If the HISTTIMEFORMAT variable is set and not null, its value is used as a format string for strftime(3) to print the timestamp associated with each displayed history entry. No timestamps are printed otherwise.
A useful alias is r='fc -s', which allows typing 'r cc' to run the last command beginning with 'cc', or typing 'r' alone to re-execute the last command.
The history -r option reads the history file and appends the contents to the history list.
The history -p option performs history expansion on each ARG and displays the result without storing it in the history list.
The history -n option reads all history lines not already read from the history file and appends them to the history list.
When you pass a numeric argument n to the history command, it lists only the last n entries from the history.
The history builtin has three synopsis formats: history [-c] [-d offset] [n] for display/manipulation, history -anrw [filename] for file operations, and history -ps arg [arg...] for expansion and appending.
The history -a option appends history lines from the current session to the history file.
The history -d offset option deletes the history entry at position OFFSET. Negative offsets count back from the end of the history list.
When HISTFILE is not set, bash uses ~/.bash_history as the default history file.
The two builtin commands for command history in bash are history and fc. Both are shell builtins, not external commands.
The fc -e ENAME option selects which editor to use for editing commands from history.
By default, the history command displays the history list with line numbers, prefixing each modified entry with an asterisk (*).
The fc builtin uses the first editor found in this order: FCEDIT environment variable, then EDITOR environment variable, then vi as the final default.
The history command returns success (0) unless an invalid option is given or an error occurs.
The fc command returns success (0) or the status of the executed command; it returns non-zero if an error occurs.
The history -c option clears the history list by deleting all of the entries.
Shell Commands > Simple Commands
24 questionsIf there were no command substitutions in the assignment-only command, the command exits with a zero status. If one of the expansions contained a command substitution, the exit status is the exit status of the last command substitution performed.
If a command fails because of an error during expansion or redirection, the exit status is greater than zero.
If 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 (a file containing shell commands), and the shell executes it.
If the command was not begun asynchronously (without &), the shell waits for the command to complete and collects its exit status.
The exit status of an executed command is the value returned by the waitpid system call or equivalent function.
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.
A word is a sequence of characters treated as a unit by the shell. Words may not include unquoted metacharacters.
Exit statuses in Bash are restricted to eight bits, with a maximum value of 255. The valid range is 0-255.
A simple command is a sequence of words separated by blanks (spaces or tabs), terminated by one of the shell's control operators. The first word generally specifies the command to be executed, with the rest of the words being that command's arguments.
If the search is unsuccessful, the shell searches for a defined shell function named command_not_found_handle. If that function exists, it is invoked in a separate execution environment and its exit status becomes the exit status. If not defined, the shell prints an error message and returns exit status 127.
All builtins return an exit status of 2 to indicate incorrect usage, generally invalid options or missing arguments.
Variable assignments preceding a command name are added to the environment of the executed command and do not affect the current shell environment. If no command name results, the variable assignments affect the current shell environment.
Bash searches for commands in this order: 1) Shell functions, 2) Shell builtins, 3) Each element of $PATH for an executable file.
Bash 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.
For the shell's purposes, a command which exits with a zero exit status has succeeded. A non-zero exit status indicates failure.
If the command name contains one or more slashes, the shell does not search PATH. Instead, it attempts to execute the named program directly at that path.
Exit status 127 indicates command not found, while exit status 126 indicates command found but not executable.
Control operators in Bash are: newline, '||', '&&', '&', ';', ';;', ';&', ';;&', '|', '|&', '(', or ')'.
When a command terminates on a fatal signal whose number is N, Bash uses the value 128+N as the exit status.
When the shell executes a program, argument 0 is set to the name given, and the remaining arguments to the command are set to the arguments supplied, if any.
When executing a simple command, Bash performs expansions from left to right in this order: 1) Variable assignments and redirections are saved, 2) Words (not assignments/redirections) are expanded, 3) Redirections are performed, 4) Variable assignments undergo expansion.
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.
Installing Bash > Basic Installation Process
24 questions--disable-printf. This removes the printf builtin from the compiled shell.
DESTDIR allows installing into a staging directory without hardcoding paths. Example: 'make install DESTDIR=/tmp/staging' installs all files under /tmp/staging, useful for package building.
gcc (GNU C Compiler) or any ISO C99-compliant compiler. Bash requires a C compiler that supports the C99 standard.
--enable-multibyte. This is enabled by default on systems with appropriate wide character support.
--enable-casemod-attrs or --enable-casemod-expansion. Programmable completion is enabled by default and cannot be fully disabled.
make clean. This removes the built bash executable and all .o object files but preserves the configuration.
autoconf version 2.60 or higher. When building from the development repository, you must run autoreconf before configure.
CC. Example: 'CC=clang ./configure' uses clang instead of gcc. CFLAGS can additionally set compilation flags.
INSTALL file in the top-level source directory. It contains platform-specific notes for various Unix-like systems.
-O2. The configure script adds -O2 optimization flag to CFLAGS by default.
INSTALL file in the source distribution contains platform-specific notes and compilation hints for different operating systems.
System-wide profiles go to /etc/profile and /etc/bash.bashrc, user files are ~/.bash_profile and ~/.bashrc in each user's home directory.
make (with no target) or 'make all'. This builds the bash executable in the current directory.
./configure && make && make install. The configure script checks system capabilities and creates Makefiles, make compiles the source code, and make install installs the compiled binaries.
--disable-history. This removes command history features from the compiled shell.
/usr/local. This can be changed with './configure --prefix=/custom/path' or 'make install prefix=/custom/path'.
--enable-debug. This adds -g to CFLAGS and disables optimization, useful for development and debugging.
There is no configure option for this. Default PATH is set at runtime and can be changed in the compilation by modifying config-top.h before building.
/usr/local. Binaries are installed to /usr/local/bin, man pages to /usr/local/share/man, and libraries to /usr/local/lib.
GNU make version 3.79 or higher. The build system uses GNU make-specific features.
./configure or autoreconf. When building from the repository, the configure script may not exist and must be generated using autoreconf -f -i.
GNU Readline library. Bash includes readline by default, but you can use --with-installed-readline to use a system-installed version instead.
Bash Startup Files > File Selection Order
24 questionsNo. Bash looks for ~/.bash_profile, ~/.bash_login, and ~/.profile in that specific order, and reads and executes commands from the first one that exists and is readable. Only the first file found is executed; the others are ignored.
When Bash is invoked as an interactive login shell (or as a non-interactive shell with the --login option), it reads and executes commands from: (1) /etc/profile (if it exists), then (2) the first existing and readable file from ~/.bash_profile, ~/.bash_login, and ~/.profile, in that specific order. Only the first one found is executed.
When invoked as an interactive shell with the name 'sh', Bash looks for the variable ENV (not BASH_ENV), expands its value if it is defined, and uses the expanded value as the name of a file to read and execute. A shell invoked as 'sh' does not attempt to read and execute commands from any other startup files.
After reading /etc/profile, Bash looks for and checks files in this exact order: (1) ~/.bash_profile, (2) ~/.bash_login, (3) ~/.profile. It reads and executes commands from the first one that exists and is readable, then stops checking.
When Bash is started non-interactively (for example, to run a shell script), 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 command 'if [ -n "$BASH_ENV" ]; then . "$BASH_ENV"; fi' were executed, but the value of the PATH variable is not used to search for the filename.
When Bash is invoked as 'sh', it enters POSIX mode after the startup files are read. This happens automatically when the shell is invoked with the name 'sh'.
If any of the startup files exist but cannot be read (due to permissions or other issues), Bash reports an error. Tildes are expanded in filenames as described under Tilde Expansion in the EXPANSION section of the manual.
A login shell is one whose first character of argument zero is -, or one started with the --login option. This is the official definition from the Bash manual.
When Bash is invoked with the name 'sh' 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. It does not look for ~/.bash_profile or ~/.bash_login.
When Bash determines it is being run non-interactively with its standard input connected to a network connection (like through sshd), it reads and executes commands from /etc/bash.bashrc and ~/.bashrc if these files exist and are readable. The --norc option can inhibit this behavior, and --rcfile can force another file to be read.
The --rcfile file option forces Bash to read and execute commands from the specified file instead of /etc/bash.bashrc and ~/.bashrc when an interactive shell that is not a login shell is started.
No. Since a shell invoked as 'sh' does not attempt to read and execute commands from any other startup files besides those specified by the ENV variable, the --rcfile option has no effect when Bash is invoked as 'sh'.
No. When Bash expands the BASH_ENV variable to get the filename to read and execute, the value of the PATH variable is not used to search for the filename. The filename is used exactly as specified in the expanded BASH_ENV value.
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.
An interactive shell is one started without non-option arguments (unless -s is specified) and without the -c option, whose standard input and error are both connected to terminals (as determined by isatty(3)), or one started with the -i option. PS1 is set and $- includes i if Bash is interactive, allowing a shell script or a startup file to test this state.
No. When Bash determines it is being run non-interactively with standard input connected to a network connection, it will not read /etc/bash.bashrc or ~/.bashrc if it is invoked as 'sh'. The automatic reading of these files for network-connected shells only applies when Bash is not invoked as 'sh'.
No. A non-interactive shell invoked with the name 'sh' does not attempt to read any startup files. This is different from a non-interactive Bash shell (not invoked as sh), which reads the file specified by BASH_ENV.
If the -p option is supplied at invocation when the effective user (group) ID is not equal to the real user (group) ID, the startup behavior is the same (startup files are read according to normal rules), but the effective user ID is not reset to the real user ID. Without the -p option, no startup files are read in this scenario.
If Bash determines it is being run non-interactively with its standard input connected to a network connection (as when executed by rshd or sshd), it reads and executes commands from /etc/bash.bashrc and ~/.bashrc, if these files exist and are readable. It will not do this if invoked as 'sh'. The --norc option may be used to inhibit this behavior, and --rcfile may force another file to be read.
The --norc option inhibits the reading of /etc/bash.bashrc and ~/.bashrc when an interactive shell that is not a login shell is started. This option has no effect unless the shell is interactive.
When an interactive login shell exits, or when a non-interactive login shell executes the exit builtin command, Bash reads and executes commands from the file ~/.bash_logout, if it exists.
The --noprofile option inhibits the reading of /etc/profile and any of the personal initialization files (~/.bash_profile, ~/.bash_login, or ~/.profile) when the shell is started as a login shell.
When an interactive shell that is not a login shell is started, Bash reads and executes commands from /etc/bash.bashrc and ~/.bashrc, if these files exist. This can be inhibited using the --norc option, or the --rcfile file option can force Bash to read and execute commands from a specified file instead of /etc/bash.bashrc and ~/.bashrc.
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, no startup files are read. Additionally, shell functions are not inherited from the environment, and the SHELLOPTS, BASHOPTS, CDPATH, and GLOBIGNORE variables are ignored if they appear in the environment.
Grouping Commands
24 questionsUse parentheses () to create a subshell when you want to avoid affecting the parent shell's variables and directory. Changes made inside the parentheses remain isolated to the subshell.
Yes. Command substitution uses a dollar prefix $(command) and captures output, while subshell grouping uses (command) without the dollar prefix for execution in a child process.
Yes. Parentheses () create subshells and increment the BASH_SUBSHELL variable, while curly braces {} do not create subshells and do not increment BASH_SUBSHELL.
Yes. 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.
Parentheses are operators, and are recognized as separate tokens by the shell even if they are not separated from the list by whitespace.
No. Directory changes made inside parentheses () execute in a subshell and do not affect the parent shell's current directory.
(command) creates a subshell for command grouping, while $(command) is command substitution that executes the command and replaces the expression with its output. The dollar prefix is what distinguishes command substitution from subshell grouping.
Placing a list of commands between parentheses forces the shell to create a subshell, and each of the commands in the list is executed in that subshell environment.
Bash provides exactly two ways to group a list of commands to be executed as a unit: (1) using parentheses () which creates a subshell, and (2) using curly braces {} which executes in the current shell environment.
Use curly braces {} when you want variable changes to persist after the command group completes, since they execute in the current shell environment.
The proper syntax is { command1; command2; } - note the space after {, the semicolon after the last command, and the space before }.
The proper syntax is (command1; command2) - semicolons are optional before the closing parenthesis since parentheses are operators.
No. Placing a list of commands between parentheses causes a subshell to be created 'without removing non-exported variables.' A subshell is a child process that inherits variables from the parent without requiring export.
Placing a list of commands between curly braces causes the list to be executed in the current shell environment. No subshell is created.
This is a historical design choice. Reserved words like braces must be separated from adjacent tokens by blanks or metacharacters, while operators like parentheses are recognized as separate tokens regardless of whitespace.
For both parentheses () and curly braces {}, the exit status is the exit status of the last command executed in the list.
Curly braces are reserved words, which means they must be separated from the command list by blanks or other shell metacharacters.
Yes. The semicolon (or newline) following the list is required when using curly braces for command grouping.
No. Since the list is executed in a subshell when using parentheses, variable assignments do not remain in effect after the subshell completes.
Yes. Since curly braces {} execute commands in the current shell environment, directory changes made with cd affect the parent shell's current directory.
Yes. Since braces are reserved words, they must be separated from the list by blanks or other shell metacharacters.
The exit status of both parentheses () and curly braces {} constructs is the exit status of the list (the last command executed in the group).
No. Since parentheses are operators, they are recognized as separate tokens by the shell even if they are not separated from the list by whitespace.
The character following the open brace must be a space, tab, newline, or pipe |. Blanks (whitespace) are required to separate the reserved word { from the command list.
Shell Syntax > Advanced Command Forms
24 questionsThe process ID of the shell spawned to execute the coprocess is available as the value of the variable NAME_PID (or COPROC_PID for the default coprocess). The wait builtin can be used to wait for the coprocess to terminate.
Bit shift operators (<<, >>) have lower precedence than addition and subtraction. The order is: * / % (highest), then + -, then << >>. For example, $(( 10 + 2 << 1 )) evaluates as $(( 12 << 1 )) = 24.
If the expression is invalid, Bash prints a message indicating failure to the standard error and no substitution occurs.
Arithmetic expansion uses the format $(( expression )). The expression is evaluated and the result is substituted. All tokens undergo parameter expansion, command substitution, and quote removal.
The alternate form ${ command } executes in the current execution environment (not a subshell), so any side effects persist after the command completes. The character following the open brace must be a space, tab, newline, or |.
When available, process substitution is performed simultaneously with parameter and variable expansion, command substitution, and arithmetic expansion.
The exponentiation operator ** is right-associative, meaning it evaluates from right to left. For example, $(( 2 ** 2 ** 3 )) evaluates as $(( 2 ** 8 )) = 256, not $(( 4 ** 3 )) = 64.
Yes, arithmetic expansions may be nested. The expression undergoes the same expansions as if it were within double quotes, but double quote characters in the expression are not treated specially and are removed.
Bash supports two forms of process substitution: <(list) for input (reading from the process) and >(list) for output (writing to the process). The process list runs asynchronously and its input/output appears as a filename.
The return status of a coprocess is the exit status of the command executed by the coprocess.
The command substitution $(cat file) can be replaced by the equivalent but faster $(< file). This avoids forking a new process for the cat command and uses Bash's built-in file reading directly.
Yes, command substitutions may be nested. When using the backquoted form, you must escape the inner backquotes with backslashes. When using the $(command) form, no escaping is needed.
Multiplication, division, and modulo (*, /, %) have higher precedence than addition and subtraction (+, -). For example, $(( 10 + 2 * 3 )) evaluates to $(( 10 + 6 )) = 16, not 36.
Yes, Bash supports the ternary operator (?:) inside arithmetic expressions like $((...)) or ((...)). The syntax is condition ? value_if_true : value_if_false. It only works with integer arithmetic.
The two-way pipe between the executing shell and the coprocess is established before any redirections specified by the command. The file descriptors can be utilized using standard word expansions in arguments and redirections.
Command substitution removes any trailing newlines from the standard output of the command. Embedded newlines are not deleted, but they may be removed during word splitting.
In the backquote form, backslash retains its literal meaning except when followed by $, backtick (`), or \. For these three characters, the backslash acts as an escape character.
If the first character following the open brace is |, the construct expands to the value of the REPLY shell variable after command executes. No trailing newlines are removed. Bash creates REPLY as an initially-unset local variable and restores it to its previous value after completion.
$(< file) is faster because it uses Bash's built-in file reading mechanism directly, avoiding the fork/exec overhead of creating a new process for the cat command. It also avoids searching for the cat executable in PATH.
The syntax is coproc [NAME] command [redirections]. A coprocess is a shell command preceded by the coproc reserved word, executed asynchronously in a subshell.
If NAME is not supplied when creating a coprocess, the default name is COPROC. NAME must not be supplied if command is a simple command, otherwise it is interpreted as the first word of the command.
No space may appear between the < or > and the left parenthesis. If space appears, the construct would be interpreted as a redirection instead of process substitution.
Bash supports two forms of command substitution: the modern form $(command) and the legacy backtick form `command`. The modern form is preferred for better readability and easier nesting.
Process substitution is supported on systems that support named pipes (FIFOs) or the /dev/fd method of naming open files. The system must have at least one of these mechanisms.
Programmable Completion > Completion Specification Management
24 questionsUsing '+o' instead of '-o' with compopt turns off the specified option. For example, 'compopt +o filenames' would turn off the filenames option.
The 'complete' builtin command specifies how arguments to a command are to be completed by Readline. For each NAME supplied, it defines how arguments should be completed. If no options are supplied, existing completion specifications are printed in a reusable format.
The 'complete -A action' option specifies the type of completion to perform. Actions include: alias, arrayvar, binding, builtin, command, directory, disabled, enabled, export, file, function, group, helptopic, hostname, job, keyword, running, service, setopt, shopt, signal, stopped, user, variable.
The 'complete -G globpat' option uses globpat as a glob pattern to expand and generate possible completions.
The 'complete -C command' option specifies an external command to generate completions. The command is invoked when completion is attempted for the specified command.
Each NAME passed to compopt must refer to a command that has a completion specification previously defined using the 'complete' builtin. If NAME does not have a completion specification defined, compopt returns failure.
The 'compgen' builtin returns failure (non-zero exit status) if an invalid option is supplied or an error occurs. It returns success otherwise.
The 'complete -r' option removes a completion specification for each NAME supplied. If no NAMEs are supplied, it removes all completion specifications.
The 'complete -W wordlist' option splits wordlist (using IFS) and uses the resulting words as possible completions.
The 'complete -P prefix' option adds prefix to each completion after all other options have been applied.
Yes, compopt can modify completion options for named commands (NAME arguments) outside of a completion function. However, if no NAMEs are supplied, compopt must be called from within a function currently generating completions.
The 'complete -X filterpat' option uses filterpat as a pattern to filter out completions. Any completion matching the pattern is removed from the list of possible completions.
The 'compgen' builtin displays possible completions depending on the options. It is intended to be used from within a shell function generating possible completions. If the optional WORD argument is supplied, matches against WORD are generated.
The 'complete -D' option applies the completions and actions as the default for commands without any specific completion defined. This allows defining a fallback completion behavior.
The 'compopt' builtin modifies or displays completion options. It can modify completion options for each NAME, or if no NAMEs are supplied, the completion currently being executed.
The 'complete -o option' syntax sets completion options for the command. Common options include: default, dirnames, filenames, nospace, plusdirs, etc.
The 'compopt' builtin returns failure (non-zero exit status) if an invalid option is supplied or NAME does not have a completion specification defined. It returns success otherwise.
The 'complete' builtin returns failure (non-zero exit status) if an invalid option is supplied or an error occurs. It returns success otherwise.
The 'complete -I' option applies the completions and actions to the initial (usually the command) word. This allows defining custom completion for the command word itself.
When multiple options are supplied, the -D option takes precedence over -E, and both -E and -D take precedence over -I.
The 'complete -p' option prints existing completion specifications in a reusable format that can be reused as input. This is useful for viewing currently defined completion specifications.
The 'complete -S suffix' option adds suffix to each completion after all other options have been applied.
The 'complete -F function' option specifies a shell function to generate completions. The function is invoked when completion is attempted for the specified command.
The 'complete -E' option applies the completions and actions to 'empty' commands -- completion attempted on a blank line.
Shell Commands > Reserved Words
24 questionsThe 'function' reserved word is used to define shell functions. When the 'function' reserved word is supplied, the parentheses are optional. For example, both 'function foo() {}' and 'function foo {}' are valid syntax.
There are 22 reserved words in Bash: !, [[, ]], {, }, case, coproc, do, done, elif, else, esac, fi, for, function, if, in, select, then, time, until, while.
When the reserved word '!' precedes a pipeline, the exit status of that pipeline is the logical negation of the exit status of the last command in the pipeline.
'in' is recognized as a reserved word if it is the third word of a 'case' or 'select' command, or if it is the third word in a 'for' command.
Curly braces '{ list; }' group commands in the current shell environment (no subshell is created), while parentheses '(list)' create a subshell. A trailing semicolon or newline is required before the close brace.
The conditional constructs use the reserved words: 'if' (starts the conditional), 'then' (required after the condition), 'elif' (else if), 'else' (optional alternative), 'fi' (closes the entire conditional structure), and '[[', ']]' (conditional expression constructs).
Reserved words are words that have special meaning to the shell. They are used to begin and end the shell's compound commands.
The reserved word 'do' marks the beginning of the loop body, and 'done' marks the end of the loop body in all Bash loop constructs (for, while, until).
The case statement uses the reserved words 'case', 'in', and 'esac'. The statement ends with 'esac' (which is 'case' spelled backward). Each pattern clause is terminated with ';;' (double semicolon).
Yes, quoting can prevent reserved words from being recognized as such. Quoting is used to remove the special meaning of certain characters or words to the shell.
Yes, technically reserved words can be used as variable names when quoted, as quoting prevents reserved words from being recognized as such. However, this is strongly discouraged as it leads to confusing and hard-to-maintain code.
No, the 'function' keyword is a Bash-specific extension and is not part of the POSIX standard. It is a pre-POSIX ksh-ism supported for backwards compatibility. The POSIX-compatible syntax is 'funcname() {}' without the 'function' keyword.
Each pattern in a case statement is terminated with ';;' (double semicolon). Alternative terminators include ';&' for fall-through to the next clause, and ';;&' for fall-through with continued testing.
No, reserved words cannot be aliased in Bash. The POSIX standard states that reserved words cannot be subject to alias expansion. Operators and reserved words are hard-coded with no syntax to override them.
'[[' and ']]' are reserved words that form a conditional construct for testing expressions. They support pattern matching with the '==' operator and regular expression matching with the '=~' operator, unlike the single '[' test command.
'while' runs the loop while the condition is true, whereas 'until' runs the loop until the condition is true (i.e., while the condition is false).
The complete list of Bash reserved words is: !, case, coproc, do, done, elif, else, esac, fi, for, function, if, in, select, then, until, while, {, }, [[, ]], time
'do' is recognized as a reserved word if it is the third word in a 'for' command.
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 because it would only time one component of the pipeline.
Reserved words are recognized when they are unquoted and the first word of a command, with specific exceptions for 'in', 'do', and other positional contexts.
The 'select' reserved word is used to create interactive menu systems. It displays a numbered list of items to the user and prompts for selection using the PS3 prompt variable.
The 'coproc' reserved word was introduced in Bash version 4.0-alpha, released on February 20, 2009.
When the shell is in POSIX mode, Bash does not recognize 'time' as a reserved word if the next token begins with a '-'.
The looping constructs use the reserved words: 'for' (iterates over a list), 'while' (repeats while condition is true), 'until' (repeats until condition is true), 'do' (marks beginning of loop body), and 'done' (marks end of loop body).
Shell Variables > History Management
23 questionsThe quick substitution character is used as shorthand for re-running the previous command, substituting one string for another in the command.
If set and not null, its value is used as a format string for strftime(3) to print the timestamp associated with each history entry displayed by the history builtin.
Non-numeric values and numeric values less than zero inhibit truncation.
HISTCMD contains the history number, or index in the history list, of the current command.
Each pattern is tested against the line after the checks specified by HISTCONTROL are applied.
No. Assignments to HISTCMD are ignored. If HISTCMD is unset, it loses its special properties even if subsequently reset.
Yes. When HISTTIMEFORMAT is set, timestamps are written to the history file so they may be preserved across shell sessions.
The '&' character matches the previous history line. It can be escaped using a backslash.
The second and subsequent lines of a multi-line compound command are not tested and are added to the history regardless of HISTIGNORE value.
The second and subsequent lines of a multi-line compound command are not tested and are added to the history regardless of HISTCONTROL value.
No. Each pattern is anchored at the beginning of the line and must match the complete line with no implicit '*' appended.
Bash uses the history comment character to distinguish timestamps from other history lines.
The shell sets the default value to the value of HISTSIZE after reading any startup files.
The histchars variable contains two or three characters controlling history expansion and tokenization.
The default editor for the fc builtin command. If FCEDIT is not set, bash uses EDITOR; if EDITOR is not set, bash uses vi.
HISTCONTROL accepts: ignorespace (lines beginning with space are not saved), ignoredups (lines matching previous entry are not saved), ignoreboth (shorthand for ignorespace and ignoredups), and erasedups (all previous lines matching current line are removed before saving).
The history comment character indicates that the remainder of the line is a comment when found as the first character of a word. It causes history substitution to be skipped for the remaining words on the line but does not necessarily cause the shell parser to treat the rest of the line as a comment.
Bash Conditional Expressions > Arithmetic Comparison Tests
23 questionsThe -eq operator tests if two integers are equal. Syntax: [ $a -eq $b ] or [[ $a -eq $b ]]. Example: if [ $count -eq 10 ]; then echo 'Count is 10'; fi
No, arithmetic comparison operators in [ ] and [[ ]] treat numbers with leading zeros as decimal, not octal. For true octal/hex handling, use arithmetic expansion $(( )) first. Example: octal=$((010)); [ $octal -eq 8 ] correctly compares octal 010 (decimal 8) to 8.
No, the operators <, >, <=, >= are NOT valid within single brackets [ ] or double brackets [[ ]] for arithmetic comparison. You must use -lt, -gt, -le, -ge instead. The <, >, <=, >= operators only work within (( )) arithmetic context.
Within single brackets [ ], parentheses for grouping must be escaped as \( and \). Example: [ \( $a -gt 0 \) -a \( $a -lt 10 \) ]. Within double brackets [[ ]], parentheses can be used directly but are rarely needed since && and || have lower precedence.
The -gt operator tests if the left integer is greater than the right integer. Syntax: [ $a -gt $b ] or [[ $a -gt $b ]]. Example: if [ $count -gt 0 ]; then echo 'Positive'; fi
Use the ! operator before the entire expression. Within [ ]: [ ! $a -gt 5 ]. Within [[ ]]: [[ ! $a -gt 5 ]]. This negates the result of the comparison. Alternatively, you can swap the operator: [ $a -le 5 ] is equivalent to [ ! $a -gt 5 ].
If a variable is unset or empty when used in arithmetic comparison, it's treated as 0. This can lead to unexpected results. Example: unset x; [ $x -eq 0 ] returns true (exit status 0) because unset x evaluates to 0. Always validate variables before arithmetic comparison to avoid this behavior.
The = operator (or == in [[ ]]) performs string/lexical comparison, while -eq performs integer/numeric comparison. Example: [ 10 -eq 010 ] is false (different numeric values), but [ 10 = 010 ] or [[ 10 == 010 ]] may have different behavior depending on context. Always use -eq for numbers to ensure numeric comparison.
Bash's built-in arithmetic comparison operators (-eq, -ne, -lt, -le, -gt, -ge) only work with integers. For floating-point comparison, use external tools like bc or awk. Example: if (( $(echo "$a > $b" | bc -l) )); then echo 'a is greater'; fi
The -le operator tests if the left integer is less than or equal to the right integer. Syntax: [ $a -le $b ] or [[ $a -le $b ]]. Example: if [ $count -le 100 ]; then echo 'Within limit'; fi
No, arithmetic comparison operators are for integers only. For string comparison use = (or == in [[ ]]) for equality and != for inequality. Using -eq on strings treats them as variable names and evaluates their integer values, not lexical comparison.
Within [ ] or [[ ]], use -eq, -ne, -lt, -le, -gt, -ge operators. Within (( )), you can use C-style operators ==, !=, <, >, <=, >=. Example: [ $a -gt 5 ] vs (( a > 5 )). Both achieve the same result but use different syntax.
Yes, spaces are strictly required around all arithmetic comparison operators. [ $a-eq $b ] will cause a syntax error, while [ $a -eq $b ] is correct. The operators must be separated by spaces on both sides.
All arithmetic comparison operators have the same precedence and are evaluated left-to-right. To control evaluation order, use escaped parentheses within [ ] or use [[ ]] with &&/|| for logical operations which have lower precedence than comparison operators.
The -ne operator tests if two integers are not equal. Syntax: [ $a -ne $b ] or [[ $a -ne $b ]]. Example: if [ $count -ne 0 ]; then echo 'Count is not zero'; fi
When an arithmetic comparison evaluates to true, the test command returns exit status 0 (success). When false, it returns exit status 1 (failure). Example: [ 5 -gt 3 ]; echo $? outputs '0', while [ 3 -gt 5 ]; echo $? outputs '1'.
Within single brackets [ ], you can use -a (AND) and -o (OR) to chain arithmetic comparisons. Example: [ $a -gt 0 -a $a -lt 10 ]. However, within [[ ]], use && and || instead. Example: [[ $a -gt 0 && $a -lt 10 ]].
Bash will generate an error: 'integer expression expected' when variables contain non-numeric characters. Example: x='abc'; [ $x -eq 5 ] produces error. Always validate or sanitize variables before arithmetic comparisons.
The -ge operator tests if the left integer is greater than or equal to the right integer. Syntax: [ $a -ge $b ] or [[ $a -ge $b ]]. Example: if [ $score -ge 60 ]; then echo 'Passing'; fi
Arithmetic comparison operators (-eq, -ne, -lt, -le, -gt, -ge) require being used within [ ], [[ ]], or as arguments to the test command. They cannot be used standalone. Example of valid usage: test $a -gt $b is equivalent to [ $a -gt $b ].
These operators strictly require integer arguments. If used with non-integer values (strings or floating-point numbers), Bash will generate an error: 'integer expression expected'. For floating-point comparison, you must use external tools like bc or awk.
The -lt operator tests if the left integer is less than the right integer. Syntax: [ $a -lt $b ] or [[ $a -lt $b ]]. Example: if [ $age -lt 18 ]; then echo 'Minor'; fi
Arithmetic comparison operators handle negative numbers correctly. Example: [ -5 -lt 0 ] is true, [ -10 -gt -20 ] is true. The negative sign must be immediately before the number or the variable containing it: [ $negative_num -lt 0 ].
Bash Conditional Expressions > File Type Tests
23 questionsThe -k file operator returns true if file exists and its sticky bit is set.
The -c file operator returns true if file exists and is a character special file.
The file1 -ef file2 operator returns true if file1 and file2 refer to the same device and inode numbers.
The -N file operator returns true if file exists and has been modified since it was last read.
The file1 -nt file2 operator returns true if file1 is newer (according to modification date) than file2, or if file1 exists and file2 does not.
The -h file operator returns true if file exists and is a symbolic link.
The -p file operator returns true if file exists and is a named pipe (FIFO).
The -b file operator returns true if file exists and is a block special file.
The -L file operator returns true if file exists and is a symbolic link (synonym for -h).
Yes, unless otherwise specified, primaries that operate on files follow symbolic links and operate on the target of the link, rather than the link itself. Exceptions are -h, -L which test the link itself.
The -s file operator returns true if file exists and has a size greater than zero.
Conditional expressions are used by the [[ compound command and the test and [ builtin commands.
The -a file operator returns true if the file exists. Note: This operator is deprecated in favor of -e.
Yes, when used with [[, the < and > operators sort lexicographically using the current locale. The test command sorts using ASCII ordering.
The file1 -ot file2 operator returns true if file1 is older than file2, or if file2 exists and file1 does not.
If any file argument to one of the primaries is of the form /dev/fd/n, then file descriptor n is checked.
The -t fd operator returns true if file descriptor fd is open and refers to a terminal.
The -f file operator returns true if file exists and is a regular file.
The -u file operator returns true if file exists and its set-user-id bit is set.
Invoking Bash > Startup File Processing
23 questionsThe --rcfile option forces Bash to read and execute commands from the specified file instead of ~/.bashrc when starting as an interactive shell. For example: bash --rcfile /custom/custom_bashrc
No, non-interactive shells do not read any startup files by default. However, if the environment variable BASH_ENV is set and the shell is not in POSIX mode, Bash expands BASH_ENV and reads the file it names before executing the script.
Bash reads /etc/profile first, then looks for ~/.bash_profile, ~/.bash_login, or ~/.profile (in that order), and executes commands from the first one that exists and is readable.
The recommended practice is to add this code at the end of ~/.bash_profile: 'if [ -f ~/.bashrc ]; then . ~/.bashrc; fi'. This sources ~/.bashrc from the login shell startup file, ensuring consistent configuration across both shell types.
In POSIX mode, Bash follows POSIX standard behavior and uses the ENV variable instead of BASH_ENV. If ENV is set in POSIX mode, Bash expands and executes the file it names when starting an interactive shell. BASH_ENV is only used in non-POSIX mode for non-interactive shells.
Bash checks for these files in this exact order: 1) ~/.bash_profile, 2) ~/.bash_login, 3) ~/.profile. It executes the first one found and readable, then stops. It does not continue checking the remaining files.
No. Bash looks for these files in order: ~/.bash_profile, ~/.bash_login, ~/.profile. It reads and executes commands from only the first one that exists and is readable, then stops checking.
Yes. If a startup file returns a non-zero exit status (e.g., due to 'exit 1' or a command that fails with 'set -e'), the shell startup may be affected. However, for interactive shells, the shell typically continues despite errors in startup files, though error messages are displayed.
Bash determines if a shell is interactive by checking: 1) if standard input is a terminal, 2) if the -i option is used, 3) if the 'i' option is set in $-. A shell started with bash -i is always interactive. A shell started with 'ssh host' (no command) is typically an interactive login shell.
When Bash is invoked as sh (name starts with 'sh' or with --posix), it tries to mimic the startup behavior of POSIX sh. In POSIX mode, Bash reads /etc/profile and ~/.profile, but does NOT look for ~/.bash_profile or ~/.bash_login.
Startup files are executed by sourcing (running in the current shell context), not by spawning a subshell. This means variables, functions, and aliases defined in startup files affect the current shell session.
Login shells read /etc/profile and the first available of ~/.bash_profile, ~/.bash_login, or ~/.profile. Non-login interactive shells read ~/.bashrc. Non-interactive shells read no startup files unless BASH_ENV is set.
An interactive non-login shell reads and executes commands from ~/.bashrc, if it exists. On some systems, it may also read /etc/bash.bashrc (this is a system-specific addition, not part of standard Bash).
If ~/.bashrc doesn't exist, Bash simply continues without reading any user-specific initialization file for interactive non-login shells. Some distributions may have /etc/bash.bashrc as a fallback, but this is not part of standard Bash behavior.
When Bash is invoked as a non-interactive shell (e.g., running a script), it checks if BASH_ENV is set. If set (and not in POSIX mode), Bash expands the value of BASH_ENV and executes commands from that file before running the script. This is similar to how ENV works for POSIX shells.
The --login (or -l) option forces Bash to be treated as a login shell, regardless of how it was invoked. This causes Bash to read /etc/profile and the first available of ~/.bash_profile, ~/.bash_login, or ~/.profile, even if started from a GUI terminal or with bash -c.
The --norc option prevents Bash from reading ~/.bashrc when starting as an interactive shell. This option only works for interactive shells. To disable reading /etc/bash.bashrc as well, use --norc and also set the environment variable or use distribution-specific methods.
Most GUI terminal emulators (gnome-terminal, xterm, konsole, etc.) start shells as non-login interactive shells by default. This means they read ~/.bashrc but not ~/.bash_profile or /etc/profile. This can be configured in terminal emulator settings.
When an interactive login shell exits, Bash reads and executes commands from ~/.bash_logout, if it exists.
When SSH executes a remote command (e.g., 'ssh host command'), Bash typically starts as a non-login, non-interactive shell. This means startup files like ~/.bash_profile are NOT read. However, if BASH_ENV is set, that file will be sourced before the command executes.
Bash looks for ~/.profile when invoked as an interactive login shell AND neither ~/.bash_profile nor ~/.bash_login exist. Additionally, when Bash is invoked as 'sh' or in POSIX mode, it looks for ~/.profile instead of ~/.bash_profile.
The --noprofile option prevents Bash from reading /etc/profile and any of the personal initialization files (~/.bash_profile, ~/.bash_login, or ~/.profile) when starting as an interactive login shell, or when invoked as bash --login.
SSH sessions typically start login shells, which means they read /etc/profile and then the first available of ~/.bash_profile, ~/.bash_login, or ~/.profile. This is why environment variables set in ~/.bashrc may not be available in SSH sessions unless ~/.bash_profile sources ~/.bashrc.
Shell Parameter Expansion > Pattern Removal
22 questionsUse ${filename%.} to remove the shortest match of . from the end. For example, if filename='document.txt', then ${filename%.*} returns 'document'.
Use ${filename##.} to get everything after the last dot. For example, if filename='document.txt', then ${filename##.} returns 'txt'. This works because ##*. removes the longest match ending with a dot from the beginning.
Pattern removal operators use glob-style pathname expansion patterns, not regular expressions. They support * (matches any string), ? (matches any single character), and [...] (matches any character in brackets). They do not support regex syntax like +, {n,m}, or | unless extended globbing (extglob) is enabled.
${parameter##word} removes the longest matching prefix pattern from the expanded value of parameter. The word is expanded to produce a pattern that is matched against the beginning of the parameter's value. If the pattern matches the beginning, the result is the expanded value with the longest matching pattern deleted.
When 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.
When the extglob shell option is enabled, extended pattern matching operators like ?(pattern-list), *(pattern-list), +(pattern-list), @(pattern-list), and !(pattern-list) can be used in patterns for pattern removal. These allow more complex matching patterns such as removing a suffix that matches one or more alternatives.
The result is 'archive' because %% removes the longest matching suffix pattern. The pattern .* matches '.tar.gz' (the longest suffix starting with a dot), leaving only 'archive'.
Single characters (# and %) remove the shortest matching pattern, while double characters (## and %%) remove the longest matching pattern. For prefix removal: # removes shortest match, ## removes longest match. For suffix removal: % removes shortest match, %% removes longest match.
${parameter#word} removes the shortest matching prefix pattern from the expanded value of parameter. The word is expanded to produce a pattern that is matched against the beginning of the parameter's value using pattern matching rules. If the pattern matches the beginning, the result is the expanded value with the shortest matching pattern deleted.
Use ${path##*/} to remove the longest match of / from the beginning. For example, if path='/usr/local/bin/bash', then ${path##/} returns 'bash'.
When you use pattern removal on an unset or null variable, the result is an empty string. The pattern removal operates on the expanded value, and if the variable is unset or null, its expanded value is empty.
If the pattern does not match (either the beginning for #/## or the trailing portion for %/%%), the parameter's value is not modified and is returned unchanged.
When pattern removal is applied to an associative array subscripted with @ or *, the operation is applied to each member of the array in turn, and the expansion is the resultant list. The pattern removal works on the values, not the keys of the associative array.
${parameter%%word} removes the longest matching suffix pattern from the expanded value of parameter. The word is expanded to produce a pattern that is matched against a trailing portion of the parameter's value. If the pattern matches the end, the result is the value with the longest matching pattern deleted.
When parameter is '@' or '*', the pattern removal operation is applied to each positional parameter in turn, and the expansion is the resultant list.
Use ${path#*/} to remove the shortest match of / from the beginning. For example, if path='/usr/local/bin/bash', then ${path#/} returns 'usr/local/bin/bash'.
When the pattern contains no wildcards and matches exactly at the end of the parameter value, ${parameter%%pattern} removes the entire matching suffix. For example, if x='hello' and pattern='lo', then ${x%%lo} returns 'hel'.
The word is expanded to produce a pattern just as in pathname expansion, and matched against the expanded value of parameter using the rules described under Pattern Matching in the Bash manual. The pattern uses glob-style wildcards: * matches any string, ? matches any single character, and [...] matches any character in brackets.
Pattern removal operations can be chained by using multiple parameter expansions. For example: ${path##/} removes the directory path to get the filename, then ${filename%.} removes the extension. You can nest them like: ${${path##/}%.} to get the filename without extension from a full path.
The pattern supports glob-style wildcards: * matches any string (including empty string), ? matches any single character, [abc...] matches any one of the enclosed characters, [!abc...] or [^abc...] matches any character not enclosed. The pattern can also include character classes like [:class:] where class can be alnum, alpha, digit, etc.
${parameter%word} removes the shortest matching suffix pattern from the expanded value of parameter. The word is expanded to produce a pattern that is matched against a trailing portion of the parameter's value. If the pattern matches the end, the result is the value with the shortest matching pattern deleted.
The result is 'archive.tar' because % removes the shortest matching suffix pattern. The pattern .* matches '.gz' (the shortest suffix starting with a dot), leaving 'archive.tar'.
Shell Commands > Pipelines
22 questionsIf lastpipe is set, and job control is not active, the shell runs the last command of a pipeline not executed in the background in the current shell environment instead of a subshell.
A pipeline is a sequence of simple commands separated by one of the control operators '|' or '|&'. The output of each command in the pipeline is connected via a pipe to the input of the next command, so each command reads the previous command's output.
If the reserved word ! precedes the pipeline, the exit status is the logical negation of the exit status described above. The shell waits for all commands in the pipeline to terminate before returning a value.
Implementing time as a reserved word permits the timing of shell builtins, shell functions, and pipelines. An external time command cannot time these easily.
BASH_SUBSHELL is a variable that is incremented by one each time a subshell or subshell environment is spawned. The initial value is 0.
If TIMEFORMAT 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.
Yes, if the pipeline is not executed asynchronously (using &), the shell waits for all commands in the pipeline to complete before returning.
The pipe connection between commands is performed BEFORE any redirections specified by the command. However, when using |&, the implicit redirection of standard error is performed AFTER any redirections specified by the command.
%[p][l]U displays the number of CPU seconds spent in user mode. %[p][l]S displays the number of CPU seconds spent in system mode. The optional p specifies precision (0-3, default 3). The optional l specifies longer format with minutes (MMmSS.FFs).
When pipefail is enabled, the pipeline's return status is the value of the last (rightmost) command to exit with a non-zero status, or zero if all commands exit successfully.
The TIMEFORMAT variable may be set to a format string that specifies how the timing information should be displayed.
%[p][l]R displays the elapsed time in seconds. The optional p is a digit specifying precision (0-3 decimal places, default 3). The optional l specifies a longer format including minutes, of the form MMmSS.FFs.
lastpipe only works when job control is not active. The shopt documentation states: 'If set, and job control is not active, the shell runs the last command of a pipeline not executed in the background in the current shell environment.'
At most three places after the decimal point may be specified; values of p greater than 3 are changed to 3.
By default, the exit status of a pipeline is the exit status of the last command in the pipeline. Each command in a pipeline is executed in its own subshell.
If |& is used, the standard error of command1 is connected to command2's standard input through the pipe; it is shorthand for 2>&1 |. This implicit redirection of the standard error is performed after any redirections specified by the command.
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.
Yes, each command in a pipeline is executed in its own subshell. This means variables set in pipeline commands do not persist after the pipeline completes.
PIPESTATUS is an array variable containing a list of exit status values from the processes in the most-recently-executed foreground pipeline (which may contain only a single command).
Lists of Commands
22 questionsThe TIMEFORMAT variable's default value is '$'\nreal\t%3lR\nuser\t%3lU\nsys\t%3lS'. This displays the real, user, and system times consumed by the pipeline or command list.
By default, the return status of a pipeline is the exit status of the last command in the pipeline. The exit status of earlier commands in the pipeline is ignored unless the pipefail option is enabled.
Placing commands in parentheses ( ) causes them to be executed in a subshell. Variables, function definitions, and directory changes (cd) inside the subshell do not affect the parent shell environment.
There is no fixed maximum number of commands in a Bash pipeline defined by the shell itself. The limit is determined by system resources such as the maximum number of open file descriptors and the POSIX_PIPE_LIMIT system constant.
The pipe operator '|' connects the standard output of the command on its left to the standard input of the command on its right. Each command in a pipeline executes as a separate process, and all commands in the pipeline can run concurrently.
The '|&' operator is shorthand for '2>&1 |', which redirects both standard output and standard error of the preceding command to the standard input of the following command through a pipe.
For both AND (&&) and OR (||) operators, the return status of the command list is the exit status of the last command executed. If no commands are executed in the list, the return status is zero.
The semicolon (;) operator separates sequential commands, causing each command to be executed in turn. The shell waits for each command to complete before executing the next command. The return status is the exit status of the last command executed.
The AND operator (&&) has higher precedence than the OR operator (||). This means that in a mixed expression like 'cmd1 && cmd2 || cmd3', the AND operation is evaluated first.
The 'set -o pipestatus' option is not a valid Bash option. Instead, Bash provides the PIPESTATUS array variable which contains the exit status of each command in the most recently executed pipeline. Access it with ${PIPESTATUS[0]}, ${PIPESTATUS[1]}, etc.
When a command is terminated by an ampersand (&), the shell executes the command asynchronously in a subshell. The shell does not wait for the command to finish before executing the next command.
The AND operator (&&) executes the second command only if the first command returns an exit status of zero (success). The return status of the AND list is the exit status of the last command executed, or zero if no commands were executed.
The OR operator (||) executes the second command only if the first command returns a non-zero exit status (failure). The return status of the OR list is the exit status of the last command executed, or zero if none were executed.
Command lists cannot be executed within arithmetic expansion $(( )). Arithmetic expansion only evaluates arithmetic expressions. To execute commands conditionally based on arithmetic results, use (( )) as a separate command or within if statements.
The 'wait' command waits for all background jobs started with '&' to complete. When given specific process IDs or job specifications as arguments, it waits only for those processes. The return status is the exit status of the last job waited for.
The '!' operator negates the exit status of a command or pipeline. If the command returns zero, the negated result is non-zero. If the command returns non-zero, the negated result is zero. The operator must appear immediately before the command.
Bash supports two types of command groups: (1) Group commands enclosed in curly braces { } execute in the current shell environment, and (2) Group commands enclosed in parentheses ( ) execute in a subshell. The subshell version isolates changes to variables and the working directory.
When the pipefail option is set (set -o pipefail), the pipeline's return status is the value of the last (rightmost) command to exit with a non-zero status, or zero if all commands exit successfully. Without pipefail, the pipeline's status is the exit status of the last command.
When 'set -e' (errexit) is enabled, the shell exits immediately if any command in a command list exits with a non-zero status, unless the command is part of a compound list (using && or ||), or the failing command is followed by a while or until loop, or part of a test in an if statement.
Commands inside curly brace groups { } must be followed by a semicolon or newline, and the closing brace must be separated by a semicolon or newline. For example: '{ command1; command2; }' or '{ command1\n command2\n}'.
The three operators that can separate commands in a command list are: semicolon (;), ampersand (&), and newline. These operators control the execution flow and can optionally be followed by ampersand (&) for asynchronous execution.
The 'time' reserved word, when placed before a pipeline or command list, causes timing statistics to be printed for the pipeline when it completes. The statistics include user time, system time, and elapsed real time. The format can be controlled with the TIMEFORMAT variable.
Arrays > Array Types and Declaration
22 questionsUse 'local -a array_name' for indexed arrays or 'local -A array_name' for associative arrays.
No, array names must follow variable naming rules and cannot start with a digit.
array_name=(value1 value2 value3) - space-separated values in parentheses.
Use 'declare -ar array_name' for indexed or 'declare -Ar array_name' for associative to make arrays read-only.
Yes, negative indices count from the end of the array (-1 refers to the last element).
Arrays cannot be exported. The 'export' attribute does not work with arrays in Bash.
Yes, associative arrays MUST be declared explicitly using 'declare -A' before they can be used.
No, indexed arrays can be declared implicitly by assignment without using 'declare -a'.
Bash creates an indexed array instead, causing unexpected behavior. Associative arrays must be declared with 'declare -A' before use.
Array names must begin with a letter or underscore, and may contain letters, digits, and underscores.
Bash supports two types of arrays: indexed arrays and associative arrays.
'declare -a' lists indexed arrays and 'declare -A' lists associative arrays.
Process Substitution
21 questionsNo, process substitution requires either /dev/fd support or the ability to create named pipes (FIFOs). On systems lacking both features, process substitution is not available.
Use the form >(list) to create an output process substitution. For example: command > >(grep pattern) redirects command's stdout to grep's stdin through a temporary file descriptor.
The exit status of the parent command is determined by the parent command itself. The exit status of the command within the process substitution is not directly accessible through the parent command's exit status. Use PIPESTATUS or wait for background jobs to check subprocess status.
Yes, process substitution can be used with mapfile or readarray to populate arrays. For example: mapfile -t array < <(seq 1 10) reads lines from process substitution into an array.
The limit is determined by the system's maximum number of open file descriptors (ulimit -n) and available inodes. Each process substitution consumes at least one file descriptor. On typical Linux systems, the default soft limit is 1024 open file descriptors.
Process substitution was introduced in Bash version 2.0. It was not available in Bash 1.x versions.
Bash automatically handles creation and cleanup of the temporary file descriptors or named pipes used for process substitution. Users do not need to manually remove them; they are cleaned up when the process substitution completes.
Process substitution uses named pipes (FIFOs) or the /dev/fd method for naming files. The system presents the output of one process as a filename that another process can read from or write to.
Bash supports two forms of process substitution: 1) Input process substitution with syntax <(list) which provides the output of list as a file, and 2) Output process substitution with syntax >(list) which passes input written to the file as input to list.
No, the correct syntax for output process substitution is >(list) not >>(list). The >>(command) syntax is used for append redirection to files, not process substitution.
No, process substitution cannot be used as the source for a here-document (<<). Here-documents require either a literal word or a quoted expansion, not process substitution syntax.
A pipe (|) connects stdout of one command directly to stdin of another, while process substitution creates a temporary file-like object (typically in /dev/fd) that can be passed to commands expecting file arguments. Process substitution allows a command to accept multiple file inputs where pipes would only allow one input stream.
Yes, process substitution can be nested. For example, wc -l < <(cat <(echo hello)) is valid syntax where process substitutions appear within other substitutions.
On systems with /dev/fd support, Bash typically creates file descriptors in the /dev/fd directory, such as /dev/fd/63 or /dev/fd/62, which serve as the proxy for the process substitution.
Stderr from a command inside process substitution is not redirected by the substitution itself. It will still be displayed on the terminal unless explicitly redirected within the subprocess using 2> or similar redirection.
No, process substitution cannot be combined with redirection operators. The syntax < <(command) uses process substitution with a separate redirection operator (the first <), but <(command) itself cannot be preceded by another < or > operator directly.
If the command within a process substitution terminates, the shell attempts to keep the substitution file open until any processes using it have completed. However, reading from the substitution after the command terminates will return an end-of-file condition.
The script will fail with a syntax error because process substitution is a Bash-specific feature not supported by POSIX sh. The shebang must specify bash or the script must be run explicitly with bash interpreter.
Yes, this is a primary use case. For example, diff <(sort file1) <(sort file2) works because each process substitution creates a separate file descriptor that diff can open and read as if they were regular files.
No, process substitutions typically do not create files in /tmp. On systems with /dev/fd support, they create file descriptors in the /dev/fd filesystem. On systems without /dev/fd, they may create named pipes using mkfifo, but these are not necessarily in /tmp.
No, process substitution is not available when Bash is running in POSIX mode (invoked with --posix or set -o posix). It is a Bash-specific feature not defined by the POSIX standard.
Executing Commands > Execution Environment Management
21 questionsShell variables that are not exported are not available in the execution environment of external commands. Only variables and functions marked for export are passed to child processes.
Yes, when 'exec' is used, the new command replaces the current shell process and retains the same PID. No new process is created.
When 'exec' is used with arguments, those arguments replace the current shell's positional parameters ($0, $1, $2, etc.) and the command replaces the shell process. If no command is specified and only redirections are given, positional parameters are unchanged.
When 'exec' successfully replaces the shell with another command, the shell's exit status becomes the exit status of that command. If 'exec' fails to execute the command, the shell exits with a non-zero status.
Yes, 'exec' can be used without a command to perform redirections that affect the current shell. For example: 'exec >file.txt' redirects all future stdout from the current shell to file.txt.
Command substitution executes commands in a subshell environment. Both the $(command) and command syntaxes create a subshell to run the command, with the output replacing the substitution.
Each command in a pipeline runs in its own subshell. This is a key difference in Bash compared to some other shells, and it means variable assignments in pipeline components do not affect the parent shell.
When a command is invoked, it inherits: (1) the shell's open files, (2) file descriptors modified by any redirections applied to the command, (3) the current working directory, (4) the file creation mask, (5) all exported variables and functions, (6) signal traps are reset to default except for those ignored by the shell.
Asynchronous commands run in a subshell. The shell executes the command in a separate process group and returns control to the user immediately.
The execution environment includes: (1) open files inherited by the command at invocation, plus any modifications and additions specified by redirections, (2) the current working directory, (3) the file creation mode mask, (4) shell variables and functions marked for export, and (5) traps caught by the shell are reset to the values inherited from the shell's parent.
Yes, shell functions marked for export (using 'export -f') are available to subshells and executed commands in Bash.
When a command is executed without 'exec', Bash forks and creates a subprocess. The child process has a copy of the parent's environment but operates independently. When the command completes, control returns to the parent shell.
Traps caught by the shell are reset to the values inherited from the shell's parent, and traps that are not ignored are set to the default action when executing an external command.
When 'exec' is used, the current shell process is replaced by the new command without creating a new process. The command inherits the file descriptors and environment of the shell, and when the command terminates, the shell exits as well because no shell process remains.
Yes, 'exec' can replace the current shell with another shell or command. For example, 'exec zsh' replaces the current Bash shell with Zsh, preserving the current PID and environment.
Environment variables set within a pipeline command are lost after the pipeline completes because each pipeline command runs in a subshell. The variable changes do not affect the parent shell.
Signals that are being ignored when a command is executed remain ignored in the execution environment of the command. This is inherited from the shell's parent process.
File descriptors 0 (stdin), 1 (stdout), and 2 (stderr) are always open when a command is executed, unless explicitly closed or redirected.
The umask (file creation mode mask) is inherited from the shell when a command is executed. The command receives the current umask setting.
When 'exec' is used with redirections but no command (e.g., 'exec 3>file'), the redirections are applied to the current shell process and remain in effect for the lifetime of the shell or until explicitly changed.
The 'lastpipe' option, when enabled with 'shopt -s lastpipe' and job control is not active, causes the last command in a pipeline to execute in the current shell rather than a subshell.
The Restricted Shell
21 questionsThe restrictions in restricted shell mode are enforced after any startup files are read.
No. Adding or deleting builtin commands with the -f and -d options to the enable builtin command is disallowed in restricted shell mode.
No. When a command that is found to be a shell script is executed, rbash turns off any restrictions in the shell spawned to execute the script.
No. Specifying command names containing / (such as /bin/ls) is disallowed in restricted shell mode.
No. Specifying a filename containing a slash as an argument to the -p option to the hash builtin command is disallowed in restricted shell mode.
Yes. The restricted shell documentation only disallows output redirection operators (>, >|, <>, >&, &>, >>). Input redirection using < is not listed as a restriction.
There are two ways to start Bash in restricted shell mode: (1) Invoke bash with the name 'rbash', or (2) Supply the -r or --restricted option at invocation.
The following redirection operators are disallowed in restricted shell mode: >, >|, <>, >&, &>, and >>.
No. Specifying the -p option to the command builtin command is disallowed in restricted shell mode.
No. Importing function definitions from the shell environment at startup is disallowed in restricted shell mode.
No. Using the enable builtin command to enable disabled shell builtins is disallowed in restricted shell mode.
No. Specifying a filename containing a slash as an argument to the history builtin command is disallowed in restricted shell mode.
No. Turning off restricted mode with 'set +r' or 'shopt -u restricted_shell' is disallowed in restricted shell mode.
The following environment variables cannot be set or unset in restricted shell mode: SHELL, PATH, HISTFILE, ENV, and BASH_ENV.
No. Changing directories with the cd command is explicitly disallowed in restricted shell mode.
You can use either -r or --restricted as a command-line option when invoking bash to enable restricted mode.
The restricted shell is not designed to provide complete security. It is intended to create a more controlled environment, but the documentation explicitly states that when a shell script is executed, rbash turns off restrictions in the spawned shell, which can be used to escape the restrictions.
No. Specifying a filename containing a / as an argument to the . (source) builtin command is disallowed in restricted shell mode.
No. Parsing the value of SHELLOPTS from the shell environment at startup is disallowed in restricted shell mode.
A restricted shell is used to set up an environment more controlled than the standard shell. It behaves identically to bash with the exception that certain operations are disallowed.
No. Using the exec builtin command to replace the shell with another command is disallowed in restricted shell mode.
Modifying Shell Behavior > Error Handling and Exit Behavior
21 questionsIf a script finishes without an explicit 'exit' command, it returns the exit status of the last command executed in the script.
The 'set -u' option causes Bash to 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. This does NOT apply to special parameters like '*', '@', '#', '?', '$', '!', '0', or '_' that are expanded when the shell is invoked.
It depends on context. When 'set -e' is active, a 'command not found' error (exit status 127) will cause the shell to exit UNLESS it's part of a condition (if, while, etc.) or the command is part of a pipeline where 'pipefail' is not set. The error is treated like any other non-zero exit status.
When 'exit' is called with no argument, it returns the exit status of the last command executed. If no commands have been executed, it returns 0.
The 'set -o pipefail' option changes the exit status of a pipeline. Without pipefail, the pipeline's exit status is the last command's exit status. With pipefail, the exit status is the exit status of the rightmost command that exited with a non-zero status, or zero if all commands exited successfully. This option is disabled by default.
By default, NO. 'set -e' alone does NOT cause the shell to exit when a command in a pipeline fails, because the pipeline's exit status is determined by the last command. You must also set 'set -o pipefail' to detect failures anywhere in the pipeline and cause the shell to exit when any command in the pipeline fails.
Using 'command || true' prevents 'set -e' from exiting the script even if 'command' fails. The '||' operator means the shell only executes 'true' if the first command fails, and 'true' always returns exit status 0. This pattern is commonly used to intentionally ignore specific command failures.
The '?' special parameter expands to the exit status of the most recently executed foreground pipeline. It is read-only and cannot be assigned to. It's commonly used to check if a command succeeded ('if [ $? -eq 0 ]') or to return the last command's exit status.
The 'set -e' option causes the shell to exit immediately if a command exits with a non-zero status. However, it will NOT exit if: (1) the command that fails is part of a compound command (like if, while, until, ||, &&), (2) the command's exit status is being tested with !, (3) the command follows while/until, or (4) the pipeline in which the command appears has its exit status checked with '!'
The 'set -o ignoreeof' option prevents an interactive shell from exiting when it encounters EOF (end-of-file, typically Ctrl+D). Instead, the shell displays 'Use "exit" to leave the shell.' This helps prevent accidental shell termination.
Without 'set -o pipefail', the exit status of a pipeline is the exit status of the last command in the pipeline. For example, in 'false | true | true', the exit status would be 0 (success) because the last command succeeded.
Bash exit status values range from 0 to 255. Exit status 0 indicates success, while 1-255 indicate various failure conditions. Exit status 126 indicates command was found but could not be executed, 127 indicates command was not found, and 128 and above typically indicate termination by a signal (128 + signal number).
When 'set -e' is active, commands that fail within an 'if' statement condition do NOT cause the shell to exit. The 'if' statement explicitly tests the exit status, so this is one of the exceptions to errexit behavior.
Inside command substitutions, 'set -e' behavior is suppressed. Commands that fail within a command substitution do NOT cause the shell to exit, even with 'set -e' active. The command substitution returns the command's exit status, but does not trigger errexit.
'return' exits a function and returns a status code to the calling context, while 'exit' terminates the entire shell or script. Using 'exit' inside a function will terminate the script unless the function is called in a subshell.
The 'set -T' option causes the DEBUG and RETURN traps to be inherited by shell functions. This allows debugging and return tracking to work within function calls. Without this option, these traps only apply to the main script execution.
Unlike 'set -e' which immediately exits on error, 'trap command ERR' allows you to execute custom error handling code (cleanup, logging, etc.) when a command fails. The ERR trap runs before the shell would exit (if errexit is also set), giving you a chance to perform cleanup operations. The trap command can receive the exit status in '$?' and line number in '$LINENO'.
The ERR trap is triggered when a command exits with a non-zero status. However, it is NOT triggered if: (1) the failed command is part of a compound command (if, while, until, etc.), (2) the command follows 'while' or 'until', (3) the command is in a pipeline except the last one (without pipefail), or (4) the command's exit status is being inverted with '!'. The ERR trap is also not inherited by functions, command substitutions, or subshells unless 'set -E' (set -o errtrace) is enabled.
The 'set -o posix' option changes Bash behavior to be more POSIX-compliant. One key effect is that it causes the shell to exit if a special builtin (like 'source', '.', 'return', 'break', 'continue', 'exec') fails. Without this option, failures in special builtins don't necessarily exit the shell.
With both 'set -e' and 'set -o pipefail' enabled, the shell will exit immediately if ANY command in the pipeline fails (returns non-zero). The pipefail option ensures the pipeline's exit status reflects the first failing command, and errexit causes the shell to exit upon that non-zero status.
When a command is terminated by a signal, Bash returns an exit status of 128 plus the signal number. For example, SIGKILL (signal 9) results in exit status 137, SIGTERM (signal 15) results in exit status 143.
Bash Startup Files > Shell Invocation Types
21 questionsIf the -p option is supplied at invocation when effective user ID differs from real user ID, the startup behavior is the same (no startup files are read), but the effective user id is not reset to the real user id.
The --noprofile option prevents bash from reading the system-wide startup file /etc/profile or any of the personal initialization files ~/.bash_profile, ~/.bash_login, or ~/.profile when invoked as a login shell.
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.
When invoked as an interactive login shell, or a non-interactive shell with the --login option with the name sh, bash first attempts to read and execute commands from /etc/profile and ~/.profile, in that order. It does NOT read ~/.bash_profile or ~/.bash_login.
Yes. Tildes are expanded in filenames as described under Tilde Expansion in the EXPANSION section of the Bash manual.
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 /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.
No. Bash behaves as if the command 'if [ -n "$BASH_ENV" ]; then . "$BASH_ENV"; fi' were executed, but the value of the PATH variable is not used to search for the filename.
Bash 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. Only the first existing file is read; the others are ignored.
The --noprofile option may be used when the shell is started to inhibit reading profile files.
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, no startup files are read, shell functions are not inherited from the environment, the SHELLOPTS, BASHOPTS, CDPATH, and GLOBIGNORE variables, if they appear in the environment, are ignored, and the effective user id is set to the real user id.
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.
A login shell is one whose first character of argument zero is a -, or one started with the --login option.
PS1 is set and $- includes i if bash is interactive, allowing a shell script or a startup file to test this state.
When an interactive shell that is not a login shell is started, bash reads and executes commands from /etc/bash.bashrc and ~/.bashrc, if these files exist.
When invoked as sh, bash enters posix mode after the startup files are read.
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.
The --rcfile file option will force bash to read and execute commands from file instead of /etc/bash.bashrc and ~/.bashrc. This can also be specified as --init-file file.
An interactive shell is one started without non-option arguments (unless -s is specified) and without the -c option, whose standard input and error are both connected to terminals (as determined by isatty(3)), or one started with the -i option.
The --norc option prevents reading the system-wide initialization file /etc/bash.bashrc and the personal initialization file ~/.bashrc if the shell is interactive.
No. Since a shell invoked as sh does not attempt to read and execute commands from any other startup files besides those specified by ENV for interactive shells, the --rcfile option has no effect.
Bindable Readline Commands > Miscellaneous Commands
21 questionsWhen given a numeric argument, insert-comment acts as a toggle: if the characters at the beginning of the line do not match the value of comment-begin, the value is inserted; otherwise, the characters in comment-begin are deleted from the beginning of the line. In either case, the line is accepted as if a newline had been typed.
The set-mark command has two default key bindings: C-@ (Control-@) and M-
The default key binding for abort is C-g (Control-g). This command aborts the current editing command and rings the terminal's bell (subject to the setting of bell-style).
The dump-variables command prints 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.
The default key binding for character-search-backward is M-C-] (Meta-Control-close bracket). A character is read and point is moved to the previous occurrence of that character. A negative argument searches for subsequent occurrences.
The Miscellaneous Commands section shows two formats: single-key combinations like C-g, ESC, M-r, M-&, C-@, M-
A Control Sequence Indicator (CSI) is the beginning of a multi-key sequence, usually ESC-[, used by keys like Home and End. The skip-csi-sequence command is designed to read and consume these sequences to prevent stray characters from being inserted into the editing buffer.
The default key binding for character-search is-C-] (Control-close bracket). A character is read and point is moved to the next occurrence of that character. A negative argument searches for previous occurrences.
The default key binding for emacs-editing-mode is C-e (Control-e). When in vi command mode, this causes a switch to emacs editing mode.
The default key binding for exchange-point-and-mark is C-x C-x (Control-x followed by Control-x). This command swaps 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.
The undo command has two default key bindings: C-_ (Control-underscore) and C-x C-u (Control-x followed by Control-u). This performs incremental undo, separately remembered for each line.
The skip-csi-sequence command reads enough characters to consume a multi-key sequence such as those defined for keys like Home and End. Such sequences begin with a Control Sequence Indicator (CSI), usually ESC-[. If this sequence is bound to '\e[', keys producing such sequences will have no effect unless explicitly bound to a readline command, instead of inserting stray characters into the editing buffer. This is unbound by default, but usually bound to ESC-[.
The do-lowercase-version command is bound to metafied uppercase characters (M-A, M-B, M-x, etc.). If the metafied character x is uppercase, it runs the command that is bound to the corresponding metafied lowercase character. The behavior is undefined if x is already lowercase.
The dump-functions command prints 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.
The default key binding for prefix-meta is ESC (Escape key). This command metafies the next character typed. For example, ESC f is equivalent to Meta-f.
The default key binding for re-read-init-file is C-x C-r (Control-x followed by Control-r). This command reads in the contents of the inputrc file and incorporates any bindings or variable assignments found there.
The default key binding for insert-comment is M-# (Meta-#). Without a numeric argument, the value of the readline comment-begin variable is inserted at the beginning of the current line. If a numeric argument is supplied, this command acts as a toggle.
The dump-macros command prints 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.
The default key binding for vi-editing-mode is M-C-j (Meta-Control-j). When in emacs editing mode, this causes a switch to vi editing mode.
The default key binding for revert-line is M-r (Meta-r). This command undoes all changes made to the current line, equivalent to executing the undo command enough times to return the line to its initial state.
The default key binding for tilde-expand is M-& (Meta-ampersand). This command performs tilde expansion on the current word (e.g., expanding ~username to the user's home directory).
Arrays > Assignment and Modification
21 questionsYes, but you must use parentheses with key-value pairs: assoc_array+=([key]=value [key2]=value2). For example: colors+=([green]='#00FF00' [yellow]='#FFFF00'). This adds new keys or updates existing ones. The parentheses are required even for a single key-value pair.
Index 0. Bash arrays are 0-indexed by default. When using compound assignment like array=(a b c), elements are assigned to indices 0, 1, 2 respectively.
Use mapfile or readarray with process substitution: mapfile -t array_name < <(command). Or use IFS=$'\n' read -d '' -ra array_name < <(command). For example: mapfile -t lines < <(cat file.txt). The -t option removes trailing newlines from each line.
Use command substitution with $() inside the assignment: array[index]=$(command). For example: files[0]=$(ls *.txt | head -1). The command's stdout becomes the element's value. Newlines are preserved but trailing newlines are stripped.
Bash creates a sparse array with gaps. For example, if array has elements 0 and 1, and you assign array[5]=value, bash creates element at index 5 without creating elements 2, 3, and 4. The array length becomes 6 (highest index + 1) for counting purposes, but iterating with ${array[@]} skips empty indices.
Negative indices count from the end of the array. For an array with elements, array[-1] refers to the last element, array[-2] to the second-to-last, etc. Assignment like array[-1]=newvalue modifies the last element. This requires bash 4.3 or later.
The entire array is replaced. The declare -a attribute persists but all previous elements are discarded. For example: declare -a arr=(a b c); arr=(x y z) results in arr containing only 'x', 'y', 'z' at indices 0, 1, 2. The original elements are completely lost.
Use parentheses: array_name=(value1 value2 value3 ...). For example: my_array=(apple banana cherry). The parentheses are mandatory for compound assignment. Spaces between elements become the delimiter, not commas.
The element is created with an empty string value. For example: arr[3]='' creates element at index 3 with an empty string. This element is counted by ${#arr[@]} and will appear when expanding ${arr[@]} as an empty string. It is not the same as an unset element.
Use the += operator: array_name+=(element1 element2). For example: my_array+=(new_item) appends a single element, and my_array+=(item1 item2) appends multiple elements. The parentheses are required when appending multiple elements.
array+=(value) is the append operator that adds to the end, while array[${#array[@]}]=value manually calculates the last index and assigns. However, for sparse arrays, ${#array[@]} returns the count of elements (not the highest index), so array[${#array[@]}]=value may overwrite existing elements. Use array+=(value) for safe appending.
This can cause unexpected behavior. ${#array[@]} returns the count of assigned elements, not the highest index. For a sparse array like arr=([0]=a [5]=b), ${#arr[@]} is 2, so arr[${#arr[@]}]=arr[2]= would overwrite or create element at index 2, not append after index 5. Use arr+=(value) to always append correctly.
Use compound assignment without declare: array_name=(new_values). For example: my_array=(new1 new2 new3). This completely replaces all previous contents. You don't need to unset the array first; compound assignment to an existing array replaces it entirely.
Use the syntax array=([index]=value [index]=value). For example: sparse_array=([0]=first [3]=fourth [10]=tenth). This creates an array with elements only at the specified indices, leaving gaps elsewhere.
Use declare -A or readonly -A before assignment: declare -A my_array. Associative arrays require Bash 4.0 or later. Assignment uses the syntax array_name([key]=value [key2]=value2). For example: declare -A colors; colors=([red]='#FF0000' [blue]='#0000FF').
Use the syntax array_name[index]=value. For example: colors[3]=blue. Bash supports sparse arrays, so you can assign to any index without filling intermediate positions.
The previous value is completely replaced with the new value. For example, if assoc_array[key]=old, then assoc_array[key]=new replaces 'old' with 'new'. There is no warning when overwriting existing associative array elements.
Use unset array[index]. For example: unset my_array[2] removes the element at index 2. This creates a gap in the array (sparse array). The indices of other elements do not shift automatically.
Use readonly -a array_name or declare -ra array_name. For example: arr=(a b c); readonly -a arr. After this, any attempt to modify the array (arr[0]=x or arr+=(y)) will result in an error: 'arr: readonly variable'. You must set readonly after initial assignment.
This creates or sets a regular scalar variable, not an array. The variable name is treated literally, including the brackets if present. To create or assign to an array, you must use either array[index]=value for single element assignment or array=(values) for compound assignment.
Use array=([index]=value [index2]=value2). For example: nums=([0]=zero [5]=five [10]=ten). This allows creating sparse arrays with gaps. Elements at unspecified indices are not created.
Redirections > Here Documents and Here Strings
20 questionsNo. Here documents cannot contain null bytes (ASCII 0) as the shell interprets text as null-terminated strings. Binary data with null bytes cannot be reliably passed via here documents.
The syntax is: <<[-]word
then newline-separated content until a line containing only word (with no trailing spaces).
The format is: [n]<<[-]word
here-document
delimiter
Yes, a here string automatically appends a trailing newline to the word being passed as input.
The word undergoes: tilde expansion (~), parameter expansion ($var), command substitution ($(cmd)), and arithmetic expansion ($((expr))).
File descriptor 0 (standard input, stdin) is the default. You can specify a different file descriptor using the [n] prefix before the << or <<< operator.
<<EOF: The body undergoes parameter expansion, command substitution, and arithmetic expansion.\n<<'EOF': The body is treated literally with NO expansion - all text appears exactly as written.
No. The delimiter must be a single word with no spaces. The closing delimiter must appear on a line by itself with no other characters, including no trailing spaces.
Only TAB characters (ASCII 9, \t) are stripped from the beginning of each line. Space characters are NOT stripped - only tabs.
<<EOF provides inline multi-line input directly within the script, with optional parameter/command expansion. < file reads input from an external file. Here-documents are embedded in the script itself rather than stored separately.
Newlines in the here-document body are preserved in the output. Each line including its newline character is passed to the command.
With an unquoted delimiter: backslash is NOT special in the body of a here-document, except that $`, $', and $" retain their special meaning for parameter expansion.\nWith a quoted delimiter: backslash is treated literally like any other character.
The hyphen causes bash to strip leading tab characters from each line of the here-document body and from the line containing the delimiter. Only tab characters are removed, not spaces.
If the delimiter is quoted with any form of quoting (single quotes, double quotes, or backslash), the here-document body is treated literally. No parameter expansion, command substitution, or arithmetic expansion is performed on the body.
Yes, here documents can be combined with other redirections. The optional [n] before << specifies the file descriptor number (default is 0 for stdin).
With a quoted delimiter, $- (and all other special parameters) are treated literally and NOT expanded. No expansions occur when the delimiter is quoted.
The syntax is: [n]<<< word
This redirects word to the input of the command with a trailing newline appended. The word undergoes tilde expansion, parameter expansion, command substitution, and arithmetic expansion.
Yes, by using command substitution: command <<< $(other_command). However, this is less efficient than using a pipe (othercommand | command) because it creates a temporary string.
With an unquoted delimiter, the here-document body undergoes: parameter expansion ($var or ${var}), command substitution ($(cmd) or cmd), and arithmetic expansion ($((expr))). No tilde expansion, pathname expansion, or quote removal occurs.
The closing delimiter must: (1) be on a line by itself, (2) contain ONLY the delimiter word, (3) have NO leading or trailing whitespace (except tabs when using <<-), and (4) be exactly the same word used after <<.
Conditional Constructs > Loop-Based Conditionals
20 questionsThe syntax of the until command is: until test-commands; do consequent-commands; done. The semicolons may be replaced with newlines.
In a C-style for loop, expr2 is repeatedly evaluated until it evaluates to zero. Each time expr2 evaluates to a non-zero value, commands are executed and expr3 is evaluated.
The return status of continue is non-zero if n is not greater than or equal to 1.
When break n is used, the nth enclosing loop is exited. n must be greater than or equal to 1.
If there are no items in the expansion of words in a for loop, no commands are executed, and the return status is zero.
The return status of an until loop is zero if no consequent-commands were executed.
The continue command resumes the next iteration of an enclosing for, while, until, or select loop.
The syntax of the while command is: while test-commands; do consequent-commands; done. The semicolons may be replaced with newlines.
The return status of break is non-zero if n is not greater than or equal to 1.
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.
The syntax of the C-style for command is: for (( expr1 ; expr2 ; expr3 )) [;] do commands ; done
The return status of a while loop is the exit status of the last command executed in consequent-commands, or zero if none was executed.
If any expression is omitted in a C-style for loop, it behaves as if it evaluates to 1.
An until loop executes consequent-commands as long as test-commands has an exit status which is NOT zero (non-zero means false in shell conditionals).
The syntax of the for command is: for name [ [in words ...] ; ] do commands; done. The semicolons may be replaced with newlines.
The argument n must be greater than or equal to 1. There is no upper limit specified other than the number of actual enclosing loops.
When continue n is used, the execution of the nth enclosing loop is resumed. n must be greater than or equal to 1.
Bash Startup Files > Configuration Purpose
20 questionsBash first reads and executes commands from /etc/profile (if it exists), then 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 inhibits reading of 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.
The --rcfile file option forces bash to read and execute commands from the specified file instead of /etc/bash.bashrc and ~/.bashrc for interactive shells. The --init-file option is a synonym.
When bash is started non-interactively (e.g., to run a shell script), 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.
When an interactive shell that is not a login shell is started, bash reads and executes commands from /etc/bash.bashrc and ~/.bashrc, if these files exist.
/etc/bash.bashrc contains system-wide initialization for interactive shells, while ~/.bashrc contains personal initialization for interactive non-login shells. Both are read for interactive non-login shells.
When bash determines it is being run with its standard input connected to a network connection (as when executed by rshd or sshd), it reads and executes commands from /etc/bash.bashrc and ~/.bashrc, if these files exist and are readable. It will not do this if invoked as sh.
If any of the startup files exist but cannot be read, bash reports an error.
You can test if bash is interactive by checking if PS1 is set or if $- includes the letter 'i'.
Bash 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. Only the first existing file is used.
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, no startup files are read, shell functions are not inherited from the environment, and the SHELLOPTS, BASHOPTS, CDPATH, and GLOBIGNORE variables are ignored if they appear in the environment.
No. When bash executes the file specified by BASH_ENV, the value of the PATH variable is not used to search for the filename.
A login shell is one whose first character of argument zero is a -, or one started with the --login option.
When an interactive login shell exits, or a non-interactive login shell executes the exit builtin command, bash reads and executes commands from ~/.bash_logout if it exists.
When invoked as 'sh', bash reads /etc/profile and ~/.profile for login shells (not ~/.bash_profile or ~/.bash_login), uses ENV instead of BASH_ENV for interactive shells, and a shell invoked as sh does not attempt to read any other startup files in non-interactive mode.
When bash is started in POSIX mode (with the --posix command line option), 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.
The --norc option inhibits reading and execution of the system-wide initialization file /etc/bash.bashrc and the personal initialization file ~/.bashrc if the shell is interactive. This option is on by default if the shell is invoked as sh.
When bash is invoked as sh, it enters POSIX mode after the startup files are read. When started with --posix, it follows POSIX startup file behavior (interactive shells read ENV file, no other startup files).
When invoked as an interactive login shell with the name sh, bash first attempts to read and execute commands from /etc/profile and ~/.profile, in that order. It does not read .bash_profile or .bash_login.
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.
Shell Parameter Expansion > Case Modification
20 questions${parameter,,pattern} - This operator converts all characters that match pattern to lowercase. For example, ${var,,A} would convert all 'A' characters to lowercase.
If var is empty or unset, ${var^} expands to an empty string. The operator requires at least one character to modify.
Yes, case modification can be combined with other parameter expansions. For example, ${var:${#var}-3^^} would get the last 3 characters and convert them to uppercase.
${parameter^^} - This operator converts all characters in the parameter value to uppercase.
No, case modification parameter expansion (${var^^}, ${var,,}, ${var^}, ${var,}) is not POSIX-compliant. This is a bash-specific feature introduced in version 4.0.
For arrays, you can use ${array[@]^^} to convert all elements to uppercase, or ${array[@],,} for lowercase. You can also access individual elements: ${array[0]^^}.
${parameter^} - This operator converts the first character of the parameter value to uppercase.
When the pattern is empty or omitted, the operation applies to all characters. For ${parameter^^} and ${parameter,,}, this means all alphabetic characters are converted.
If the first character is non-alphabetic (digit, space, punctuation), it remains unchanged. The operator only affects the first character if it is a letter.
${parameter,,} - This operator converts all characters in the parameter value to lowercase.
Yes, case modification can be used with special parameters. For example, ${$#^^} is valid syntax, though typically less useful since special parameters often contain numeric values.
Yes, case modification can be applied to positional parameters. For example, ${@^^} would convert all positional parameters to uppercase.
${parameter,} - This operator converts the first character of the parameter value to lowercase.
No, case modification parameter expansion does not modify the original variable. It returns a modified string but the variable itself remains unchanged unless you reassign it (e.g., var=${var^^}).
The pattern matching in case modification is case-sensitive. ${var^^a} will only convert lowercase 'a' characters to uppercase, not 'A' characters which are already uppercase.
Non-alphabetic characters (digits, punctuation, spaces, etc.) remain unchanged. Only alphabetic characters are converted to lowercase.
Non-alphabetic characters (digits, punctuation, spaces, etc.) remain unchanged. Only alphabetic characters are converted to uppercase.
${parameter^^pattern} - This operator converts all characters that match pattern to uppercase. For example, ${var^^a} would convert all 'a' characters to uppercase.
Bash case modification handles multibyte characters based on the current locale. When using appropriate UTF-8 locales, it can correctly case-convert Unicode letters.
Bash 4.0 - Case modification parameter expansion was introduced in bash version 4.0.
Bash Conditional Expressions > String Comparison Tests
20 questionsYes, the < and > string comparison operators use the current locale's collation order for lexicographic comparison. The ordering depends on LC_ALL or LC_COLLATE environment variables.
When a string variable is used alone without any operator (such as [[ $var ]]), it tests if the string is non-empty, equivalent to [[ -n $var ]].
The -z test returns true for both unset variables and variables set to an empty string. There is no distinction between the two cases with -z.
Bash does NOT strip trailing newlines when comparing strings with ==, =, or !=. However, command substitution $(...) strips trailing newlines, which can cause unexpected comparison results.
When doing literal string comparison (not pattern matching), the right-hand side of == should be quoted to prevent glob interpretation. For example: [[ $var == 'literal*' ]] compares to literal 'literal*' while [[ $var == literal* ]] treats * as a wildcard.
The =~ operator performs Extended Regular Expression (ERE) matching. The string on the left is matched against the ERE on the right. If the match succeeds, the return status is 0. The regex should NOT be quoted. Captured groups are stored in BASH_REMATCH array.
The shell interprets < and > as redirection operators, causing syntax errors or unexpected behavior. To use them for string comparison, they must be escaped as < and > within [ ], or better yet, use [[ ]] instead.
No, -n is optional. When using a string variable without any operator in a conditional expression (like [[ $var ]]), Bash implicitly tests if the string is non-empty.
The -n operator tests if a string has non-zero length (is not empty). It returns true if the string has any characters.
Yes, all Bash string comparison operators (=, ==, !=, <, >) are case-sensitive by default. 'A' and 'a' are considered different characters.
Both = and == perform string equality comparison, but = is POSIX standard (works with [ and test), while == is a Bash extension (only works with [[). The == operator has additional pattern matching capabilities when used inside [[ ]].
The -z operator tests if a string has zero length (is empty). It returns true if the string is empty.
After a successful =~ match, BASH_REMATCH[0] contains the entire matched string, and BASH_REMATCH[1] through BASH_REMATCH[n] contain the captured groups (parenthesized subexpressions) from the regex.
No, the < and > string comparison operators are NOT allowed inside single brackets [ ]. They must be used inside double brackets [[ ]] and the operators must be escaped to prevent redirection interpretation.
No quoting or escaping is required for < and > operators inside [[ ]]. The double-bracket construct correctly interprets them as string comparison operators rather than redirection.
Yes, like ==, the != operator inside [[ ]] supports pattern matching with glob characters on the right-hand side. It returns true if the string does NOT match the pattern.
No, you should NOT quote the right-hand side of =~. Quoting causes the regex to be treated as a literal string rather than a regular expression.
Yes, when used inside [[ ]], the == operator performs pattern matching where the right-hand side can contain glob patterns like *, ?, and [character ranges].
String comparison with < and > in Bash follows the lexicographic order based on byte values or locale-dependent collation rules. The comparison is NOT numeric. For example, '10' < '2' is true because '1' has a lower byte value than '2'.
No, -a (AND) and -o (OR) are NOT supported inside [[ ]]. You must use && and || instead. The -a and -o operators only work inside single brackets [ ].
Invoking Bash > Security and Privilege Settings
20 questionsIn privileged mode (-p option), the following environment variables are ignored if they appear in the environment: SHELLOPTS, BASHOPTS, CDPATH, and GLOBIGNORE. Additionally, $ENV and $BASH_ENV files are not processed.
The restrictions of a restricted shell are enforced AFTER any startup files are read.
In restricted shell mode, the following are disallowed: changing directories with cd; setting or unsetting SHELL, PATH, HISTFILE, ENV, or BASH_ENV; specifying command names containing /; specifying filenames containing / as arguments to the ., history, or hash -p builtins; importing function definitions from the environment at startup; parsing SHELLOPTS from the environment; redirecting output using >, >|, <>, >&, &>, and >>; using exec to replace the shell; adding or deleting builtins with enable -f/-d; enabling disabled builtins with enable; using command -p; and turning off restricted mode.
When Bash is started non-interactively to run a shell script, 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. The value of PATH is not used to search for the filename.
When bash is started in POSIX mode 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.
In restricted shell mode, setting or unsetting the values of SHELL, PATH, HISTFILE, ENV, or BASH_ENV is not allowed.
Bash attempts to determine when it is being run with its standard input connected to a network connection, as when executed by rshd or sshd. If bash determines it is being run non-interactively in this fashion, it reads and executes commands from /etc/bash.bashrc and ~/.bashrc if these files exist and are readable, unless invoked as sh.
The --rcfile file option forces Bash to read and execute commands from the specified file instead of /etc/bash.bashrc and ~/.bashrc if the shell is interactive. This option takes precedence over the default startup file behavior.
When Bash is started with effective user (group) ID not equal to 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, BASHOPTS, CDPATH, and GLOBIGNORE variables are ignored if they appear in the environment, and the effective user ID is set to the real user ID.
When invoked as sh in interactive login mode or with --login option, bash 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 name sh, bash looks for the ENV variable instead of other startup files.
No. The restricted shell mode cannot be unset once it has been set. The -r option creates a restriction that cannot be turned off with set +r or shopt -u restricted_shell.
When an interactive shell is invoked in POSIX mode (or when bash is invoked with the name sh), the ENV variable is expanded and commands are read and executed from the file whose name is the expanded value.
When a command found to be a shell script is executed, rbash turns off any restrictions in the shell spawned to execute the script.
The following redirection operators are prohibited in restricted shell mode: >, >|, <>, >&, &>, and >>.
When the -p option is supplied at invocation and the effective user ID is not equal to the real user ID, the startup behavior is the same (no startup files, functions not inherited, certain variables ignored), but the effective user ID is NOT reset to the real user ID. In privileged mode, $ENV and $BASH_ENV files are not processed, shell functions are not inherited from the environment, and SHELLOPTS, BASHOPTS, CDPATH, and GLOBIGNORE variables are ignored if they appear in the environment.
Turning off privileged mode with set +p causes the effective user and group IDs to be set to the real user and group IDs.
A restricted shell is started by invoking bash with the name rbash, or by supplying the -r or --restricted option at invocation.
The --norc option prevents Bash from reading and executing the system-wide initialization file /etc/bash.bashrc and the personal initialization file ~/.bashrc if the shell is interactive. This option is on by default if the shell is invoked as sh.
The --noprofile option prevents Bash from reading the system-wide startup file /etc/profile or any of the personal initialization files ~/.bash_profile, ~/.bash_login, or ~/.profile when invoked as a login shell.
If BASH_ENV is set when bash is executing a shell script, its value is interpreted as a filename containing commands to initialize the shell. The value is subjected to parameter expansion, command substitution, and arithmetic expansion before being interpreted as a filename. PATH is not used to search for the resultant filename.
Tilde Expansion
20 questionsIf the tilde-prefix is '~+', the value of the shell variable PWD (current working directory) replaces the tilde-prefix.
If the tilde-prefix is a null string (just '~'), the tilde is replaced with the value of the HOME shell variable. If HOME is unset, the tilde expands to the home directory of the user executing the shell.
No. Tilde expansion does not occur when the tilde is within either single quotes ('') or double quotes (""). The tilde must be unquoted for expansion to occur.
Yes. Bash performs tilde expansion on words satisfying the conditions of variable assignments when they appear as arguments to simple commands.
The tilde-prefix '~username' is replaced with the home directory associated with the specified login name 'username'.
If the tilde-prefix is '~-', the shell substitutes the value of the shell variable OLDPWD (previous working directory), if it is set.
~+N expands to the directory that would be displayed by 'dirs +N' (counting from the top of the stack starting at 0), while ~-N expands to the directory that would be displayed by 'dirs -N' (counting from the bottom of the stack).
In POSIX mode, Bash does not perform tilde expansion on assignment words when they appear as arguments to simple commands (except for declaration commands like 'declare'). In default Bash mode, this expansion does occur.
Bash checks each variable assignment for unquoted tilde-prefixes immediately following a ':' or the first '=', and performs tilde expansion in these cases.
Bash performs tilde expansion on unquoted tilde-prefixes immediately following a ':' in variable assignments. This allows constructs like PATH=~:/other/path to work correctly.
If the login name is invalid or the tilde expansion fails, the tilde-prefix is left unchanged.
This parameter expansion means: use the value of OLDPWD if it is set, otherwise use the literal string '-'. When shown in tilde expansion documentation, it demonstrates that '-/foo' expands to OLDPWD/foo if OLDPWD is set, or the literal '~/foo' if OLDPWD is not set.
No. Tilde expansion only occurs on literal tilde characters in the original word, not on tildes that appear as a result of variable expansion or other expansion mechanisms.
No. Tilde expansion only occurs on unquoted tilde-prefixes. If the tilde or any characters in the tilde-prefix are quoted, tilde expansion does not occur.
PATH, MAILPATH, and CDPATH support tilde expansion in assignment statements. The shell assigns the expanded value when tildes are used in assignments to these variables.
A tilde-prefix consists of all characters from the beginning of a word that starts with an unquoted tilde character ('~') up to the first unquoted slash ('/'). If there is no unquoted slash in the word, all characters up to the end of the word constitute the tilde-prefix.
Tilde expansion processing begins when a word begins with an unquoted tilde character ('~'). If the word does not begin with an unquoted tilde, no tilde expansion is performed on that word.
Tilde expansion is the second type of expansion performed by Bash, occurring immediately after brace expansion and before parameter and variable expansion, command substitution, arithmetic expansion, word splitting, and filename expansion.
No. The results of tilde expansion are treated as if they were quoted, so the replacement is not subject to word splitting and filename expansion.
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. If the number has no leading '+' or '-', tilde expansion assumes '+'.
Conditional Constructs > Interactive Selection Constructs
20 questionsThe 'name' variable (specified after 'select') is set to the selected word from the list. 'REPLY' contains the actual line read from the user's input (typically the number they typed).
The words following 'in' are expanded according to standard shell expansion rules including tilde expansion, parameter expansion, command substitution, and arithmetic expansion
A break command must be executed. The commands are executed after each selection until a break command is executed.
The select command uses the positional parameters as the word list, equivalent to 'in "$@"'
The exit status of select is the exit status of the last command executed in the command list, or zero if no commands were executed.
The select construct has almost the same syntax as the for command: 'select name [in words ...]; do commands; done' - the difference being select creates an interactive menu from the word list
The select construct automatically generates a numbered list menu, displaying each word with a number starting from 1
Yes, select displays the list and PS3 prompt, reads a line from standard input, and executes the commands. The loop continues until a break command is executed, meaning the menu redisplays with each iteration.
PS3 should be set before the select statement begins, as the value of PS3 is used when select displays the prompt
name is set to null (empty), but the commands in the loop body are still executed. The select loop continues unless explicitly broken.
Select is a looping construct. The select construct has almost the same syntax as the for command: select name [in words ...]; do commands; done
REPLY stores the actual line/number entered by the user from stdin. The variable named after 'select' stores the text of the selected item from the word list.
Yes, the break and continue builtins (see Bourne Shell Builtins) can be used to control select loop execution, similar to other looping constructs
Command Substitution
20 questionsNo, command substitution cannot be used directly inside $(( )). The command substitution must be done outside, with the result used in the arithmetic context.
The $() syntax allows nesting without escaping: $(outer $(inner)). With backticks, you must escape inner backticks: outer \inner``. The $() syntax is much more readable for nested substitutions.
Inside $(), backslashes preserve their literal meaning except when followed by $, `, or . Inside backticks, backslash behavior is more complex and requires escaping for literal backslashes.
Command substitution inside double quotes preserves word splitting and prevents pathname expansion. The output is treated as a single word even if it contains spaces or special characters.
Command substitution runs in a subshell environment. Variables set during command substitution do not affect the parent shell's variables.
Yes, command substitution output can be assigned to variables: var=$(command). The trailing newline stripping applies to variable assignments as well.
Unquoted command substitution results undergo pathname expansion (globbing). Quoted command substitution does NOT perform globbing. Wildcards in the output are treated literally when quoted.
Unquoted command substitution undergoes word splitting using IFS (Internal Field Separator). The output is split into separate words based on spaces, tabs, and newlines by default.
In $() syntax, a backslash followed by a newline is not continued. In backticks, a backslash at the end of a line continues the command substitution to the next line.
Command substitution can be used within here-documents. The substitution is performed when the here-document is processed, not when it is defined.
When the command produces no output, command substitution results in an empty string. This is not an error condition and is valid behavior.
Yes, but inner backticks must be escaped with backslashes: command1 \command2``. Each level requires additional escaping, making it impractical for deep nesting.
The exit status of command substitution is the exit status of the substituted command. If the command is terminated by a signal, the exit status is 128 plus the signal number.
Command substitution cannot contain NUL characters in the output. NUL bytes are stripped from the command output because Bash variables cannot contain NUL characters.
To preserve trailing newlines, append and then remove a character: output=$(cat file; echo x); output=${output%x}. This ensures the trailing newline before the 'x' is preserved.
Bash supports two forms: $(command) - the modern preferred syntax, and command - the legacy backtick syntax. Both POSIX-compliant, but $() is recommended for better readability and nesting support.
Yes, command substitution removes trailing newline characters from the output. Embedded newlines are preserved, but only trailing newlines at the very end are stripped.
Quoted command substitution does NOT undergo word splitting. The entire output is treated as a single word, preserving all whitespace.
POSIX specifies both $(command) and command syntaxes. The $(command) syntax is specified by POSIX as the preferred form in the Shell Command Language standard.
The maximum size is limited by available memory. Bash does not impose a fixed limit on command substitution output size beyond system memory constraints.
Executing Commands > Environment Variable Handling
20 questionsdeclare -x VAR=value declares and exports a variable as an environment variable. The -x option means the variable will be exported to child processes. Using declare +x VAR removes the export attribute but keeps the variable as a shell variable.
When a command is executed, Bash passes all exported environment variables to that command. Non-exported shell variables are not passed. The command receives a copy of the environment, so modifications made by the command to its own environment do not affect the parent shell's variables.
No. When using the VAR=value command syntax, the variable assignment only affects the environment of that specific command. The variable is not set in the current shell after the command completes. This is true for both simple commands and pipelines.
Variables declared with readonly VAR or declare -r VAR cannot be modified or unset after being marked readonly. If a variable is both exported and readonly (declare -xr VAR), it is passed to child processes but cannot be changed in the current shell or by child processes.
The export command (with no arguments) lists all exported environment variables in the current shell. Alternatively, printenv or env commands can also display all environment variables, while declare -x shows exported variables with their declarations.
Commands in parentheses (list) execute in a subshell. Exported environment variables are inherited by this subshell, but any changes (including new exports) are local to the subshell and do not affect the parent shell when the subshell completes.
Command substitution runs the command in a subshell. Any environment variables set or modified within the command substitution using export are local to that subshell and do not affect the parent shell. Only the output (stdout) captured by $() is returned to the parent.
Each command in a pipeline (cmd1 | cmd2 | cmd3) runs in a subshell and receives a copy of the exported environment variables. Environment variable changes made in one pipeline command do not affect other commands in the pipeline or the parent shell. Using VAR=value before a pipeline affects all commands in the pipeline.
env -i command starts the command with an empty environment (no inherited environment variables). The -i or --ignore-environment option clears all environment variables before executing the command. You can then add specific variables: env -i VAR=value command.
Multiple variable assignments can be chained before a command: VAR1=value1 VAR2=value2 VAR3=value3 command. Each assignment is evaluated and all specified variables are set in the command's environment simultaneously. The order of assignments does not matter for independent variables.
export -n VAR removes the export attribute from variable VAR, turning it from an environment variable into a regular shell variable. The variable remains defined in the current shell but will no longer be passed to child processes.
$VAR and ${VAR} are typically equivalent, but ${VAR} is required in cases where the variable name is adjacent to other text that would be interpreted as part of the name (e.g., ${VAR}_file). The brace syntax also enables parameter expansion operations like ${VAR:-default}, ${VAR:=default}, and ${VAR#pattern}.
Bash itself does not impose a fixed limit on environment variable name or value length. However, the operating system limits apply: Linux typically has a limit of 32 pages for environment variables (typically 128KB on 4KB page systems). Individual variable names and values can be very long (up to the total environment size limit). getconf ARG_MAX shows the maximum size of command and environment arguments.
VAR=value creates a shell variable that is local to the current shell and is not inherited by child processes. export VAR=value (or export VAR after setting) makes the variable an environment variable that will be inherited by child processes (commands and subshells). Only exported variables are passed to commands executed by the shell.
The unset VAR command removes both shell variables and environment variables. After unsetting, the variable is no longer defined in the current shell. If a variable was exported, it will no longer be passed to subsequently executed child processes. The -f option (unset -f) unsets a shell function instead.
Prefix the command with VAR=value before the command name. For example: PATH=/custom/path:$PATH command. This syntax sets the variable only for that command execution. The variable is set in the environment of the command but does not persist in the current shell after the command completes.
Use the syntax VAR=value command where VAR is the variable name, value is the new value, and command is the command to run. For example: TZ=UTC date runs the date command with timezone set to UTC without changing the TZ variable in the current shell.
Use quotes: export VAR='value with spaces' or export VAR="value with $other". Single quotes preserve literal characters (no variable expansion), while double quotes allow variable expansion and command substitution within the value.
Environment variables are expanded when the command line is parsed, before the command executes. For example, echo $HOME expands $HOME to its value at the time the command line is interpreted. Variable expansion happens before word splitting and pathname expansion.
${VAR:-default} uses 'default' as the value if VAR is unset or null (empty). This does not modify VAR. For contrast, ${VAR:=default} assigns 'default' to VAR if VAR is unset or null, and also uses that value. These are parameter expansion features for handling unset or empty variables.
Command Line Editing > Keyboard Macros and Arguments
20 questionsCtrl-Ctrl+y followed by a number inserts the nth argument from the previous command. For example, Ctrl-Ctrl+y 2 inserts the second argument.
Ctrl-X followed by 'e' (C-x e). This executes the last recorded keyboard macro.
Use the syntax: "\C-xkey": "macro_text". For example: "\C-xa": "sudo apt update && sudo apt upgrade". This binds Ctrl-X followed by 'a' to insert that text.
There is no hardcoded limit in readline on the number of keyboard macros. You can define as many macros as you have unique key bindings available.
Ctrl-U (or Alt+0) reads a numeric argument and multiplies it by 4. This allows specifying larger numeric arguments to other readline commands.
bind -P in bash displays all readline functions, their current bindings, and whether they are bound to a key sequence.
yank-last-arg inserts the last argument from the previous command history line. Its default binding is Alt+. (Meta-period).
There is no direct command to print only macros, but 'bind -p' shows all bindings including macros, and 'bind -S' shows all macros that have been defined via inputrc or dynamically.
Alt+Number (or ESC followed by a number) starts a numeric argument that can be used to prefix other commands. For example, Alt+4 followed by Ctrl-k kills the next 4 characters instead of just 1.
Macros can contain both literal text and special character sequences that represent readline commands. Use the syntax '\C-x' for Ctrl-X, '\e' or '\M-x' for Meta/Esc sequences within macro definitions.
Ctrl-X followed by '(' (C-x (). This begins recording a keyboard macro.
When set to 'on', readline displays characters with the eighth bit set directly rather than as a meta-prefixed character. The default varies by terminal but is typically 'off'.
yank-nth-arg inserts the first argument of the previous command by default, but accepts a numeric argument to specify which argument. The default binding is Ctrl-Ctrl+Meta+y (or similar depending on terminal).
Ctrl-X followed by ')' (C-x )). This ends recording a keyboard macro.
Alt+- (Meta-minus) makes the next command take a negative argument. For example, Alt+- followed by Ctrl-d would delete characters backward instead of forward.
The 'meta-flag' variable controls whether readline interprets the eighth bit of input characters as the meta flag. When 'on', characters with the eighth bit set are treated as meta characters (Alt+key).
By setting the readline variable 'history-preserve-point' to a non-zero value, or using the numeric argument behavior: Alt+1 Alt+. to start from the first argument of the previous command, Alt+2 Alt+. for the second, etc.
When 'convert-meta' is 'on' (the default), readline converts characters with the eighth bit set to ASCII meta prefix characters. Setting it to 'off' passes the eighth-bit characters through directly.
Alt+. (Meta-period or ESC period) retrieves the last argument from the previous command. This can be repeated to cycle through earlier commands' last arguments.
When you provide a numeric argument before executing a macro (e.g., Alt+1 Alt+0 C-x e), the macro executes that many times. For example, a numeric argument of 10 would execute the macro 10 times.
Bindable Readline Commands > Commands For Moving
20 questionsforward-word (M-f) moves forward to the end of the next word where words are composed of alphanumeric characters (letters and digits). shell-forward-word moves forward to the end of the next word where words are delimited by non-quoted shell metacharacters.
M-C-l (Meta-Control-L). The clear-display command clears the screen and, if possible, the terminal's scrollback buffer, then redraws the current line, leaving the current line at the top of the screen.
M-b (Meta-B). The backward-word command moves back to the start of the current or previous word. Words are composed of alphanumeric characters (letters and digits).
With an argument, clear-screen (C-l) refreshes the current line without clearing the screen.
The previous-screen-line command attempts to move point to the same physical screen column on the previous physical screen line. This will not have the desired effect if the current readline line does not take up more than one physical line or if point is not greater than the length of the prompt plus the screen width.
The next-screen-line command attempts to move point to the same physical screen column on the next physical screen line. This will not have the desired effect if the current readline line does not take up more than one physical line or if the length of the current readline line is not greater than the length of the prompt plus the screen width.
No. shell-forward-word has no default key binding (unlike forward-word which is bound to M-f).
M-f (Meta-F). The forward-word command moves forward to the end of the next word. Words are composed of alphanumeric characters (letters and digits).
next-screen-line will not have the desired effect if the current readline line does not take up more than one physical line or if the length of the current readline line is not greater than the length of the prompt plus the screen width.
C-a (Control-A). The beginning-of-line command moves to the start of the current line.
previous-screen-line will not have the desired effect if the current readline line does not take up more than one physical line or if point is not greater than the length of the prompt plus the screen width.
clear-display (M-C-l) clears the screen and, if possible, the terminal's scrollback buffer, then redraws the current line. clear-screen (C-l) clears the screen and redraws the current line but does not clear the scrollback buffer.
No. shell-backward-word has no default key binding (unlike backward-word which is bound to M-b).
C-l (Control-L). The clear-screen command clears the screen, then redraws the current line, leaving the current line at the top of the screen. With an argument, it refreshes the current line without clearing the screen.
The redraw-current-line command refreshes the current line. It has no default key binding.
Bash Startup Files > Execution Lifecycle
20 questionsIn POSIX mode (started with --posix or set -o posix), an interactive Bash shell reads only $ENV and does not read ~/.bashrc.
When Bash is invoked with the --noprofile option, it does not read /etc/profile or any of the personal initialization files (~/.bash_profile, ~/.bash_login, ~/.profile).
There is no difference. --init-file is a synonym for --rcfile. Both options specify an alternative initialization file instead of ~/.bashrc for interactive shells.
No, an interactive non-login shell does not read /etc/profile. It only reads ~/.bashrc (or the file specified by --rcfile).
Only /.bash_profile is executed. Bash stops searching after finding the first file in the sequence (/.bash_profile, ~/.bash_login, ~/.profile).
When an interactive login shell exits, Bash reads and executes commands from ~/.bash_logout if it exists.
Yes, when Bash is in POSIX mode, it follows POSIX standard startup behavior: it reads $ENV instead of ~/.bashrc for interactive shells, and does not read ~/.bash_profile.
When invoked as 'sh -l', Bash reads /etc/profile and ~/.profile, ignoring ~/.bash_profile and ~/.bash_login because it's mimicking the Bourne shell.
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, and uses the expanded value as the name of a file to read and execute.
When Bash is invoked with the name 'sh', it mimics the startup behavior of historical Bourne shells, reading /etc/profile and ~/.profile only, and ignoring ~/.bash_profile and ~/.bashrc.
The --norc option prevents Bash from reading ~/.bashrc for an interactive shell. For a login shell, use --noprofile to prevent reading profile files.
The --rcfile option forces Bash to read and execute commands from the specified file instead of ~/.bashrc for an interactive shell.
No, Bash does not read any startup files by default when invoked non-interactively. However, it uses the value of the BASH_ENV environment variable if set.
When ssh runs a command, Bash starts as a non-interactive login shell. It reads /etc/profile and the first of ~/.bash_profile, ~/.bash_login, or ~/.profile that exists, and uses BASH_ENV if set.
When an interactive shell that is not a login shell is started, Bash reads and executes commands from ~/.bashrc if that file exists.
Bash searches for ~/.bash_profile first, then ~/.bash_login, then ~/.profile. It executes only the first one found and ignores the others.
BASH_ENV is expanded and used for all non-interactive shells, regardless of whether they are login shells or not.
No, ~/.bash_logout is only executed when an interactive login shell exits, not when a non-login shell exits.
Bash first reads and executes commands from the file /etc/profile if that file exists.
Bash 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.
Shell Parameter Expansion > Pattern Substitution
19 questionsPattern substitution always performs the longest match of the pattern in the expanded value. The documentation states: 'The longest match of pattern in the expanded value is replaced with string.'
The four forms are: ${parameter/pattern/string} for first match, ${parameter//pattern/string} for all matches, ${parameter/#pattern/string} for match at beginning only, and ${parameter/%pattern/string} for match at end only.
Double quotes surrounding the replacement string quote the expanded characters, while double quotes enclosing the entire parameter substitution do not, since the expansion is performed in a context that doesn't take any enclosing double quotes into account.
When the expansion of string is null, matches of pattern are deleted and the '/' following pattern may be omitted. For example, ${var/pattern} deletes the first match of pattern without needing the trailing '/'.
Backslash escapes '&' in string; the backslash is removed to permit a literal '&' in the replacement string. For example, ${var/abc/& } produces '& def' from var='abcdef'.
Pattern substitution performs the check for unquoted '&' after expanding string, so users should ensure to properly quote any occurrences of '&' they want taken literally and ensure any instances of '&' they want replaced are unquoted.
The string undergoes tilde expansion, parameter and variable expansion, arithmetic expansion, command and process substitution, and quote removal.
${parameter/%pattern/string} - The % character preceding the pattern requires the pattern to match at the end of the expanded value. For example, ${var/%foo/bar} will only replace 'foo' if it appears at the end of var.
The double slash (//) indicates all matches should be replaced, while a single slash (/) indicates only the first match should be replaced.
Users should take care if string is double-quoted to avoid unwanted interactions between the backslash and double-quoting, since backslash has special meaning within double quotes.
Yes, if the nocasematch shell option is enabled, the match is performed without regard to the case of alphabetic characters in pattern substitution.
Yes, quoting any part of string inhibits replacement in the expansion of the quoted portion, including replacement strings stored in shell variables. For example, if rep='& ', then ${var/abc/$rep} produces 'abc def' while ${var/abc/& } produces '& def'.
Use '\' to insert a literal backslash into the replacement. The backslash can escape '&' and can also escape a backslash in the replacement string. For example, ${var/abc/\&xyz} with var='abcdef' outputs '\abcxyzdef'.
When 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.
${parameter/pattern/string} - This form replaces only the first match of the pattern with the string. For example, if var='foo bar foo', then ${var/foo/baz} produces 'baz bar foo'.
${parameter/#pattern/string} - The # character preceding the pattern requires the pattern to match at the beginning of the expanded value. For example, ${var/#foo/bar} will only replace 'foo' if it appears at the start of var.
${parameter//pattern/string} - The double slash (//) indicates that all matches of the pattern should be replaced with the string. For example, if var='foo bar foo', then ${var//foo/baz} produces 'baz bar baz'.
When patsub_replacement is enabled using shopt, any unquoted instances of '&' in the replacement string are replaced with the matching portion of the pattern. This is intended to duplicate a common sed idiom.
When parameter is '@' or '*', the substitution operation is applied to each positional parameter in turn, and the expansion is the resultant list.
Shell Functions > Variable Scope and Locality
19 questionsFUNCNEST is a variable that, if set to a numeric value greater than 0, defines a maximum function nesting level for recursion. Function invocations that exceed the limit cause the entire command to abort. By default, Bash places no limit on the number of recursive calls (FUNCNEST is unset or set to 0).
The '-g' option forces variables to be created or modified at the global scope, even when 'declare' is executed in a shell function. Without '-g', 'declare' makes variables local when used in a function. The '-g' option is ignored when 'declare' is not executed in a shell function.
The 'typeset' command is a synonym for the 'declare' builtin command in Bash. It is supplied for compatibility with the Korn shell. Both commands can be used to declare variables and give them attributes. When used in a function, both make variables local unless the '-g' option is supplied.
Use 'local -a arrayname' to declare a local indexed array. You can initialize it with 'local -a arrayname=(element1 element2 element2)'. The '-a' flag specifically declares the variable as an indexed array type, restricting its scope to the function.
No, a local variable cannot be unset in the function it was declared in. However, it can be unset in a function called from that function. This is intentional Bash behavior - local variables maintain their scope throughout the function's execution.
Local variables 'shadow' variables with the same name declared at previous scopes. The local variable hides the global variable within that function - references and assignments refer to the local variable, leaving the global variable unmodified. When the function returns, the global variable is once again visible.
Use 'local -A arrayname' to declare a local associative array (key-value pairs). You can then assign values with 'arrayname[key]=value'. Associative arrays require Bash 4.0+. The '-A' flag declares the variable specifically as an associative array type.
Yes, functions may be recursive in Bash. The FUNCNEST variable may be used to limit the depth of the function call stack and restrict the number of function invocations. However, recursion in shell scripts is slow and resource-intensive compared to compiled languages.
When declaring and setting a local variable in a single command like 'local t1=$(exit 1)', the variable assignment takes place BEFORE the local declaration. This means the return value is for the local declaration (success, returns 0) rather than the assignment. When declared separately, the return value reflects the assignment command's actual exit status.
Yes, you can declare a local variable as readonly using 'local -r varname' or 'declare -r varname'. Readonly variables cannot be assigned subsequent values or be unset. However, attempting to create a local variable with the same name as a global readonly variable will fail.
FUNCNAME is an array variable that contains the names of all shell functions currently in the execution call stack. The first element (index 0) is set to the name of the currently executing function. When a function completes, this variable is updated to reflect the caller's function name or becomes unset if not in a function.
The '-n' option gives each variable the 'nameref' attribute, making it a name reference to another variable. The referenced variable is defined by the value of the nameref variable. All references and assignments to the nameref are performed on the variable it references, except for changes to the '-n' attribute itself. The nameref attribute cannot be applied to array variables.
By default, variables declared inside a Bash function are global. They are accessible anywhere in the script, including outside the function. A variable is local ONLY if explicitly declared with the 'local' keyword.
When a function is executed, the arguments to the function become the positional parameters during its execution. The special parameter '#' that expands to the number of positional parameters is updated to reflect the new set. Special parameter '0' (the script name) remains unchanged. When the function completes, the values of positional parameters and '#' are restored to their prior values.
No, 'local' can only be used within a function. It causes the variable name to have a visible scope restricted to that function and its children. It is an error to use 'local' when not within a function.
Bash uses dynamic scoping, not lexical scoping. With dynamic scoping, visible variables and their values depend on the sequence of function calls that caused execution to reach the current function. The value of a variable that a function sees depends on its value within its caller.
The '-I' option causes local variables to inherit the attributes (except the 'nameref' attribute) and value of any existing variable with the same name at a surrounding scope. If there is no existing variable, the local variable is initially unset.
If the name argument to 'local' is '-', it makes the set of shell options local to the function. Any shell options changed using the 'set' builtin inside the function after 'local -' are restored to their original values when the function returns.
The 'unset' builtin in Bash acts using dynamic scope. If a variable is local to the current scope, 'unset' unsets it and it remains so (appearing as unset) until reset in that scope or until the function returns. Once the function returns, any instance of the variable at a previous scope becomes visible.
Bash Startup Files > Scope of Configuration
19 questionsThe --rcfile option forces Bash to read and execute commands from the specified file instead of ~/.bashrc. This option only applies to interactive shells.
~/.bash_logout is executed when a login shell exits. This file is not read by non-login shells.
An interactive login shell reads: 1) /etc/profile, then 2) the first existing file among ~/.bash_profile, ~/.bash_login, and ~/.profile (in that order). Only the first found file is executed, not all three.
When --norc is used, Bash does not read and execute commands from ~/.bashrc. This option only applies to interactive shells.
Bash will read ~/.bash_profile and ignore ~/.bash_login (and ~/.profile). Bash stops at the first file found in the precedence order.
An interactive non-login shell reads ~/.bashrc (if it exists). On some systems, it may also read /etc/bash.bashrc before ~/.bashrc.
Bash reads and executes commands from the file named by BASH_ENV only when running as a non-interactive shell. This variable is not used by interactive shells.
No. Non-interactive shells do not read ~/.bashrc. They only read the file specified by the BASH_ENV variable if it is set.
The recommended pattern is: 'if [ -f ~/.bashrc ]; then . ~/.bashrc; fi'. This sources ~/.bashrc if it exists, ensuring login shells also get the configuration from .bashrc.
No. Interactive non-login shells only read ~/.bashrc, not ~/.bash_profile, ~/.bash_login, or ~/.profile.
/etc/profile applies system-wide configuration to all users' login shells, while ~/.bash_profile applies user-specific configuration to that user's login shells only. User-specific files are read after system-wide files.
When invoked as 'sh', Bash looks for the variable ENV and reads commands from the file it names. It mimics the behavior of historical Bourne shells, reading /etc/profile and ~/.profile for login shells, but never reading ~/.bashrc.
No. The startup file behavior is based on shell type (login vs non-login, interactive vs non-interactive), not on whether the login is remote (SSH) or local. SSH logins typically start login shells.
Shell scripts (non-interactive shells) do not read ~/.bashrc, ~/.bash_profile, or /etc/profile by default. They only read the file specified by BASH_ENV if that variable is set.
When --noprofile is used, Bash does not read /etc/profile or any of the personal initialization files (~/.bash_profile, ~/.bash_login, ~/.profile).
The order is: ~/.bash_profile first, then ~/.bash_login second, then ~/.profile third. Bash stops after finding the first existing file and does not read the others.
No. The order is fixed: Bash always checks for ~/.bash_profile first, then ~/.bash_login, then ~/.profile. This is built into Bash's source code.
No. /etc/profile is only read by login shells, not by interactive non-login shells or non-interactive shells.
In POSIX mode (invoked as 'sh' or with --posix), Bash does not read ~/.bashrc. It follows POSIX standard startup behavior, reading /etc/profile and ~/.profile for login shells.
Looping Constructs > Loop Flow Control
19 questionsbash produces the error: 'break: only meaningful in a loop'
Yes, break and continue are Bourne Shell builtins implemented as specified by the POSIX standard.
When called without n, break exits only the innermost (currently executing) enclosing loop.
continue [n] - where n is an optional parameter specifying the nth enclosing loop to resume.
The return status is non-zero (failure) when n is not greater than or equal to 1.
continue 2 resumes execution at the next iteration of the second enclosing loop, skipping to the outer loop's next iteration.
break 0 is invalid because n must be >= 1, and will return a non-zero exit status.
continue 0 is invalid because n must be >= 1, and will return a non-zero exit status.
When called without n, continue resumes the next iteration of the innermost (currently executing) enclosing loop.
break 2 exits the second enclosing loop, meaning it breaks out of two levels of nested loops at once.
Break or continue inside a subshell will only affect the subshell, not the parent loop, because subshells are not considered 'enclosed' by the loop according to POSIX.
The return status is zero when the break command executes successfully.
The return status is zero when the continue command executes successfully.
The return status is non-zero (failure) when n is not greater than or equal to 1.
Programmable Completion > Completion Variables
19 questionsCOMP_DEBUG is a boolean variable. When set to a non-empty value, bash will print debugging information about completion functions to stderr.
When using -F (shell function), the function receives three arguments: the command name being completed, the current word being completed, and the previous word.
COMPREPLY is an array variable that completion functions use to store the possible completions. Bash displays these values to the user as completion suggestions.
COMP_GENREPLY is used internally by bash during completion generation to store intermediate completion results before applying filtering.
COMPREPLY is initialized as an empty array when a completion function is invoked. The completion function is responsible for populating it with completion candidates.
The default value of COMP_WORDBREAKS is ' \t\n"'><=;|&(:'. This includes space, tab, newline, quotes, and various shell metacharacters.
COMP_WORDS uses standard bash array indexing starting at 0, where COMP_WORDS[0] contains the command name and subsequent indices contain the command arguments.
COMP_IGNORE_CASE is a boolean variable that, when set to a non-empty value, causes completion to be performed case-insensitively.
COMP_KNOWN_HOSTS_WITH_HOSTFILE is a boolean variable. When set, bash completion will read the hostnames from the file specified by the HOSTFILE variable when completing hostnames.
A completion function must populate the COMPREPLY array variable with completion suggestions. Bash reads from COMPREPLY to display the completions to the user.
COMP_WORDBREAKS contains the characters that the readline library treats as word separators when performing completion. These characters are used to split the command line into words.
COMP_TYPE contains a value indicating the type of completion attempted. Possible values include: '!' for normal completion, '@' for menu completion, '%' for menu completion with listing, and '^' for listing completions.
COMP_KEY contains the key (or final key of a key sequence) that triggered the current completion function. It identifies which key invoked the completion.
COMP_CWORD contains an index into the COMP_WORDS array that points to the word containing the current cursor position. This indicates which word the user is currently completing.
COMP_LINE contains the current command line as a single string. It holds the complete command line exactly as typed by the user.
When a completion in COMPREPLY ends with a slash, bash recognizes it as a directory and will not add an additional space after the completion.
When COMPREPLY is set to an empty array or null, no completions are displayed and the completion function indicates no matches were found.
COMP_WORDS is an array variable containing the individual words in the current command line. The array is indexed starting from 0, where COMP_WORDS[0] is the command name being completed.
COMP_POINT contains the index of the current cursor position in COMP_LINE. It is a zero-based index indicating the character position where the cursor is located.
Shell Variables > Shell Ancestry and Compatibility
19 questionsWhen a subshell is created, it inherits all exported variables from its parent shell. Variables that are not exported are not visible to the subshell. The export command marks variables for inheritance by child processes.
HOME contains the path to the current user's home directory. If HOME is not set when Bash starts, it attempts to determine the home directory from the user database (/etc/passwd). It does not have a fixed hardcoded default value.
When POSIXLY_CORRECT is set, Bash changes its behavior to conform more strictly to POSIX.1 standard. This affects variable handling, command names, built-in commands, and other shell behaviors. Bash enters POSIX mode when this variable is set or when invoked with --posix option.
If BASH_COMPAT is not set, Bash uses its native version behavior. The variable has no default value - it must be explicitly set to enable compatibility mode.
HOSTTYPE is a read-only variable that contains a string describing the machine type (CPU architecture) on which Bash is executing. For example: 'x86_64', 'aarch64', 'i686', 'arm64', etc.
BASH_VERSION is a read-only variable that expands to the version number of the current Bash instance. It contains the major, minor, and patch levels in the format 'major.minor.patchlevel'. For example, Bash 5.1.16 would be stored as '5.1.16(1)-release' or similar format including the release status.
SHELLOPTS is a read-only variable containing the currently enabled shell options. It is a colon-separated list of options such as 'braceexpand:emacs:hashall:histexpand:history:interactive-comments:monitor'. The variable cannot be modified directly.
OSTYPE is a read-only variable that describes the operating system Bash is running on. It automatically expands to indicate the OS type. Common values include 'linux-gnu', 'darwin', 'msys', 'cygwin', etc.
MACHTYPE is a read-only variable that contains a string describing the system type on which Bash is executing, in the standard GNU cpu-company-system format. For example: 'x86_64-pc-linux-gnu' or 'aarch64-apple-darwin21.1'.
UID (User ID) is a read-only variable that expands to the real user ID of the current user, initialized at shell startup. This numeric value represents the actual user who started the shell.
The BASH_COMPAT variable controls the compatibility level of Bash. When set, it forces Bash to behave as if it were the specified version. For example, setting BASH_COMPAT=4.2 will make Bash 5.x behave like Bash 4.2 in terms of certain features and behaviors. This is useful for testing scripts for backward compatibility.
BASH_ENV is used by Bash for non-interactive shells (scripts) to determine the startup file path, while ENV is used in POSIX mode for interactive shells. BASH_ENV is executed before the script runs, whereas ENV is executed when starting an interactive POSIX shell.
A shell variable is local to the current shell instance unless exported. An environment variable is a shell variable that has been exported and is therefore available to child processes and subshells. Environment variables are passed to child processes through the execve system call.
If PATH is not set when Bash starts, it defaults to a system-dependent value, typically '/usr/gnu/bin:/usr/local/bin:/bin:/usr/bin:.' on many systems. The exact default depends on the compilation configuration and the system.
BASH_VERSION, MACHTYPE, and HOSTTYPE are read-only variables. They cannot be assigned new values or unset by the user. They are automatically set by Bash at startup.
HOSTNAME is automatically set to the name of the current host at shell startup. Bash sets this variable based on the system's hostname information. It is not set in POSIX mode.
EUID (Effective User ID) is a read-only variable that expands to the effective user ID of the current user, initialized at shell startup. This numeric value represents the user ID under which the shell is executing, which may differ from the real user ID if the setuid bit is set.
When Bash is invoked as 'sh' (via symlink or rename), it behaves more like POSIX sh. It attempts to mimic the startup behavior of historical Bourne shell, doesn't read ~/.bashrc in non-interactive mode, and enables POSIX compatibility mode.
ENV is a variable that, when set, contains the path to a file that is executed for startup when the shell is invoked in POSIX mode (as sh or with --posix). This file is sourced only for interactive shells, not for non-interactive scripts. Unlike BASH_ENV which is used for all non-interactive shells, ENV is specific to POSIX mode.
Filename Expansion > Special Matching Rules
19 questionsThe backslash () character is used to escape or quote any character that would otherwise be treated specially during pathname expansion, including *, ?, [, and ].
No, filenames that start with a dot (.) are not matched by wildcard characters (*, ?, or [...]) in pathname expansion. This is a special rule - dot files must be explicitly matched by including the dot at the beginning of the pattern.
When globasciiranges is enabled (default in bash 4.3+), range expressions like [a-z] are interpreted using the traditional ASCII ordering. When disabled, ranges use the current locale's collation order, which can cause unexpected behavior with non-ASCII characters.
extglob enables extended pattern matching operators: ?(pattern-list) for zero or one, *(pattern-list) for zero or more, +(pattern-list) for one or more, @(pattern-list) for exactly one, and !(pattern-list) for anything except the pattern. These use ksh-style extended globbing.
The expand_aliases option does not affect filename expansion directly. Aliases are expanded before pathname expansion occurs, so alias expansion happens in an earlier pass of command processing.
When a pattern contains no special characters (no *, ?, or []), bash does not perform pathname expansion. The word is simply removed from quotes and passed directly to the command as-is.
Character ranges in bracket expressions are determined by the current locale's collating sequence unless globasciiranges is enabled. The range includes all characters between the endpoints based on collation order, not just ASCII values.
The pattern [!...] matches any single character NOT enclosed in the brackets. It's equivalent to [^...] and is used for negation in bracket expressions. For example, [!0-9] matches any non-digit character.
When failglob is enabled (shopt -s failglob), patterns that do not match any files cause an error message to be printed and the command is not executed. This prevents commands from running with unexpected literal pattern arguments.
No, even when dotglob is enabled, the special directory entries '.' and '..' are never matched by wildcard patterns. They must always be specified explicitly.
When nocaseglob is enabled (shopt -s nocaseglob), bash matches filenames in a case-insensitive manner during pathname expansion. For example, '*.txt' would match both 'file.TXT' and 'file.txt'.
No, nullglob and failglob cannot both be enabled at the same time. If you attempt to enable both, the last one set will take precedence.
caseglob controls whether filename expansion is case-sensitive. When disabled (shopt -u caseglob), pattern matching becomes case-insensitive. It is enabled by default, making globbing case-sensitive. The nocaseglob option provides an alternative way to control this behavior.
By default, when a wildcard pattern does not match any files, the pattern is left unchanged and passed literally to the command. For example, if no .txt files exist, 'echo .txt' will literally print '.txt'.
When dotglob is enabled (shopt -s dotglob), filenames that start with a dot (.) will be matched by wildcard characters (*, ?, and [...]). By default, dot files are not matched by wildcards.
No, extended pattern matching operators (?(...), *(...), +(...), @(...), !(...)) only work when the extglob option is enabled via 'shopt -s extglob'. Otherwise, these characters are treated literally and will not be recognized as pattern operators.
When nullglob is enabled (shopt -s nullglob), patterns that do not match any files are removed entirely instead of being left as literal strings. For example, 'ls *.txt' with no matching .txt files would become 'ls' with no arguments.
GLOBIGNORE is a colon-separated list of patterns that define files to be ignored during pathname expansion. When set, filenames matching these patterns are removed from the list of matches. Additionally, setting GLOBIGNORE has the side effect of enabling dotglob.
When * appears directly before a slash (as in */), it matches zero or more directory names but does not match filenames in the current directory. This is commonly used to list only subdirectories. For example, 'echo */' lists only directories with a trailing slash.
Shell Arithmetic > Logical Operations
18 questionsNo comparison operators have lower precedence than logical operations. Comparison operators (<= >= < >) and equality operators (== !=) both have higher precedence than logical AND (&&) and logical OR (||). The order is: comparisons/equalities first, then bitwise operations (&, ^, |), then logical operations (&&, ||).
In bash arithmetic, logical operations return 1 for true and 0 for false. For logical AND (&&): returns 1 if both operands are non-zero, 0 if either is zero. For logical OR (||): returns 1 if either operand is non-zero, 0 if both are zero. For logical NOT (!): returns 1 if the operand is zero, 0 if the operand is non-zero.
Bitwise OR (|) has higher precedence than logical AND (&&). The precedence order from highest to lowest is: & (bitwise AND), ^ (bitwise XOR), | (bitwise OR), && (logical AND), || (logical OR). So bitwise OR is evaluated before logical AND.
The comma operator (expr1, expr2) has the lowest precedence of all operators, lower than assignment operators and much lower than logical operators (&&, ||). It is evaluated last in the precedence hierarchy.
Yes, sub-expressions in parentheses are evaluated first and may override the precedence rules. Parentheses can be used to force a different evaluation order than the default operator precedence.
A shell variable that is null or unset evaluates to 0 when referenced by name within an arithmetic expression without using the parameter expansion syntax (i.e., $var is not required, just var works). The value 0 is used for any variable that is null or unset.
No, a shell variable need not have its integer attribute turned on to be used in an expression. Variables can be used in arithmetic expressions regardless of whether they were declared with the integer attribute (declare -i).
The conditional operator (expr?expr:expr) has lower precedence than both logical AND (&&) and logical OR (||). In the precedence hierarchy from highest to lowest: ... && (logical AND), || (logical OR), expr?expr:expr (conditional operator). So logical operators are evaluated before the ternary conditional.
Yes, bash uses short-circuit evaluation for logical operators. For && (logical AND), if the left operand evaluates to 0 (false), the right operand is not evaluated. For || (logical OR), if the left operand evaluates to non-zero (true), the right operand is not evaluated. This behavior is inherited from C language semantics.
Logical negation (!) is at the second highest precedence level, grouped with bitwise negation (~). It comes after post-increment/decrement (id++, id--) and before unary minus/plus (- +) and pre-increment/decrement (++id, --id). The full order from highest to lowest is: id++ id--, - +, ++id --id, ! ~, **.
The logical NOT (!) operator treats any non-zero value as true, including negative numbers. So ! applied to any non-zero value (positive or negative) returns 0 (false), and ! applied to 0 returns 1 (true). For example, !-1 returns 0, and !5 returns 0.
Logical AND (&&) has higher precedence than logical OR (||). In the operator precedence list from highest to lowest: comparison operators (<= >= < >), equality (== !=), bitwise AND (&), bitwise XOR (^), bitwise OR (|), logical AND (&&), logical OR (||). The && operator is evaluated before || when both appear in an expression.
The bash manual states that operators and their precedence, associativity, and values are the same as in the C language. In C, logical AND (&&) and logical OR (||) are left-to-right associative with sequence points and short-circuit evaluation.
Bash arithmetic evaluation is done in fixed-width integers with no check for overflow. The manual explicitly states 'Evaluation is done in fixed-width integers with no check for overflow'. However, division by 0 is trapped and flagged as an error.
When using the let builtin command, if the last ARG evaluates to 0, let returns 1; otherwise let returns 0. This is the opposite of typical shell exit status conventions where 0 means success, reflecting that 0 is 'false' in arithmetic context.
The logical negation operator (!) is grouped with bitwise negation (~) at the same precedence level. Both operators have identical precedence and are evaluated with equal priority.
Assignment operators (=, *=, /=, %=, +=, -=, <<=, >>=, &=, ^=, |=) have lower precedence than logical operators. They are evaluated after logical AND (&&), logical OR (||), and the conditional operator (expr?expr:expr).
Yes, shell variables may be referenced by name without using the parameter expansion syntax (the $ prefix) within arithmetic expressions. For example, both $((a + b)) and $(( $a + $b )) work, and the variable name alone can be used.
Installing Bash > Multi-Platform Support
18 questionsBash requires GNU Readline version 6.0 or later. The Readline library is typically bundled with the Bash source distribution, but Bash can also link against an already-installed Readline library.
The --enable-minimal-config option disables many of Bash's extended features to create a smaller binary. This disables features like array variables, history, job control, process substitution, and programmable completion.
The --disable-net-redirections option disables support for network redirections using /dev/tcp and /dev/udp special files, which allow Bash to open TCP and UDP connections for network communication.
Bash requires an ISO C99-compliant C library. On most Unix-like systems, this is glibc (GNU C Library) version 2.7 or later, though it can also compile with other ISO C99-compliant libraries like musl.
No, GNU Bash does not officially support native Windows compilation. To run Bash on Windows, you must use a POSIX compatibility layer such as Cygwin, MSYS2 (which Git Bash uses), or Windows Subsystem for Linux (WSL).
The --disable-echo-builtins configure option will disable the built-in echo command, causing Bash to use an external echo command (typically /bin/echo) instead.
The standard optimization flag -O2 is commonly used. For GCC specifically, you can use CFLAGS="-O2 -Wall" when running configure to enable optimization and compiler warnings.
Bash officially supports POSIX-compliant Unix systems including GNU/Linux (all distributions), Solaris, AIX, HP-UX, Tru64 UNIX, and BSD variants (FreeBSD, OpenBSD, NetBSD). Support is provided for systems with an ISO C99 compiler and POSIX-compliant system libraries.
The --enable-strict-posix-compliance option configures Bash to be strictly POSIX-compliant by default, disabling many Bash-specific extensions and behaviors that are not part of the POSIX standard.
GCC version 2.95 or later is recommended for compiling Bash, though GCC 3.x or 4.x is preferred for better optimization and standards compliance.
The --with-installed-readline option tells Bash to use an already-installed Readline library on the system rather than the version bundled with the Bash source. You can optionally specify the path with --with-installed-readline=/path/to/readline.
The default installation prefix is /usr/local. When running ./configure without specifying a prefix, Bash will be installed to /usr/local/bin, with libraries in /usr/local/lib, and documentation in /usr/local/share.
Yes, Bash supports macOS (formerly Mac OS X). On macOS, you can compile Bash using the standard configure and make process. However, you must have Xcode Command Line Tools installed to provide the necessary compiler (clang) and development tools.
The --enable-malloc-debug option enables debugging support for memory allocation, while --enable-malloc-warnings enables warnings about memory usage. The --without-bash-malloc option forces Bash to use the system's malloc instead of Bash's custom memory allocator.
Autoconf version 2.69 or later is required to regenerate the configure script from configure.in if you modify the build configuration.
Bash requires ncurses version 5.3 or later for terminal handling capabilities. Alternatively, the termcap library can be used if ncurses is not available, though ncurses is preferred for better terminal feature support.
The --enable-nls option enables Native Language Support (NLS) for internationalization. When enabled, Bash can display messages in different languages if the appropriate translation files are installed.
No, the GNU Project does not provide pre-compiled Bash binaries. Users must compile Bash from source or use binaries provided by their operating system distribution or package manager.
Bash Builtin Commands > Job Control Builtins
18 questionsWhen fg is invoked without a job_spec, the shell uses the current job (the shell's notion of the current job)
The bg builtin returns failure (non-zero exit status) when job control is not enabled or an error occurs
The -n option lists only processes that have changed status since the last notification
The fg builtin places the job identified by job_spec in the foreground, making it the current job
When bg is invoked without a job_spec, the shell uses the current job (the shell's notion of the current job)
The jobs builtin syntax is: jobs [-lnprs] [jobspec ...] or jobs -x command [args]
The bg builtin places jobs identified by each job_spec in the background, as if they had been started with &
No, the disown builtin does not require job control to be enabled - unlike bg and fg which require job control
The fg builtin returns the exit status of the command placed in the foreground, or failure if an error occurs
No, bg and fg cannot be used when job control is not enabled - they return failure in that case
The -x option runs a command after all job specifications that appear in args have been replaced with the process ID of that job's process group leader
The main job control builtins in bash are: jobs, bg, fg, disown, wait, and suspend
The -l option lists process IDs in addition to the normal job information
The Directory Stack
18 questionsdirs returns success unless an invalid option is supplied or an error occurs.
The -N argument 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 and becomes the current working directory.
The -n option suppresses the normal change of directory when removing directories from the stack, so only the stack is manipulated without changing the current working directory.
The -c option clears the directory stack by deleting all of the elements.
pushd returns success unless an invalid argument is supplied or the directory change fails.
When called without arguments, pushd exchanges the top two directories in the stack, making the second directory the current working directory.
When called without arguments, popd removes the top directory from the stack and changes to the new top directory.
When called without arguments, 'dirs' displays the list of currently remembered directories in the directory stack. Directories are added to the stack with the pushd command.
The +N argument displays the Nth entry counting from the left of the list shown by dirs when invoked without options, starting with zero. For example, dirs +1 displays the second entry from the left.
The -N argument displays the Nth entry counting from the right of the list shown by dirs when invoked without options, starting with zero. For example, dirs -0 displays the last entry in the list.
The -N argument 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 removes the next to last.
The -l option prevents printing tilde-prefixed versions of directories relative to your home directory; it displays the full path instead.
The three built-in commands for managing the directory stack are: dirs (display the stack), pushd (add directories to the stack), and popd (remove directories from the stack).
The +N argument 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 and becomes the current working directory.
The -n option suppresses the normal change of directory when adding directories to the stack, so only the stack is manipulated without changing the current working directory.
When called with a directory argument (pushd dir), pushd adds that directory to the directory stack at the top, making it the new current working directory.
Both -p and -v print the directory stack with one entry per line. The -v option additionally prefixes each entry with its position in the stack.
The +N argument 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 removes the second.
Brace Expansion
18 questionsTo avoid conflicts with parameter expansion, the string '${' is not considered eligible for brace expansion, and inhibits brace expansion until the closing '}'.
You can disable brace expansion using the set +B command. To re-enable it, use set -B.
When integers are supplied, they may be prefixed with '0' to force each term to have the same width. When either x or y begins with a zero, the shell attempts to force all generated terms to contain the same number of digits, zero-padding where necessary.
No, both x and y must be of the same type (either both integers or both letters).
A { or ',' may be quoted with a backslash to prevent its being considered part of a brace expression.
Both zero padding and step size (increment) features were added in bash 4.
A correctly-formed brace expansion must contain unquoted opening and closing braces, and at least one unquoted comma or a valid sequence expression.
Patterns to be brace expanded take the form of an optional preamble, followed by either a series of comma-separated strings or a sequence expression between a pair of braces, followed by an optional postscript.
Yes, any characters special to other expansions are preserved in the result. Brace expansion is strictly textual and Bash does not apply any syntactic interpretation to the context of the expansion or the text between the braces.
A sequence expression takes the form {x..y[..incr]}, where x and y are either integers or letters, and incr, an optional increment, is an integer.
The default increment is 1 or -1 as appropriate, depending on whether x is less than or greater than y.
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.
Any incorrectly formed brace expansion is left unchanged (no expansion occurs).
No, the results of each expanded string are not sorted; left to right order is preserved. For example, echo a{d,c,b}e produces ade ace abe (not alphabetically sorted).
When letters are supplied in a sequence expression, the expression expands to each character lexicographically between x and y, inclusive, using the default C locale.
Bourne Shell Builtins > System Information and Permissions
18 questionsThe hash builtin remembers the full pathnames of commands executed, to avoid searching PATH on subsequent invocations. 'hash' displays the remembered command locations. 'hash -r' clears the hash table.
The cd builtin returns a non-zero exit status if it fails to change directory (e.g., directory doesn't exist, permission denied, or not a directory). It returns 0 on success.
The readonly builtin marks variables or functions as read-only, preventing them from being modified or unset. Once marked, the variable cannot have its value changed and cannot be unset. The -a option works on array variables, -f on functions.
Yes, if the 'cd -e' option is used and cd fails to change the directory, the shell will exit with a non-zero status. This is useful in scripts where you want to ensure you're in the correct directory before proceeding.
The pwd builtin displays the current working directory. In Bash, it accepts -L (logical, follows symlinks, this is the default) and -P (physical, avoids symlinks) options to control whether it displays the logical or physical path.
Use 'ulimit -n' to display or set the maximum number of open file descriptors. For example, 'ulimit -n 4096' sets the limit to 4096. The -a flag shows all current resource limits.
If you use 'cd' with no arguments or an empty string, it changes to the value of the HOME directory. 'cd ~' also changes to the HOME directory.
The 'cd -' command changes to the previous working directory (the value of $OLDPWD). This is equivalent to 'cd $OLDPWD' but also prints the new directory name.
The umask builtin sets the shell's file mode creation mask. This mask is used to determine the permissions bits for newly created files. It can be specified as an octal number (e.g., 022) or in symbolic mode (e.g., u=rwx,g=rx,o=rx). If no argument is provided, it displays the current mask value.
The type builtin displays information about command type. It indicates whether a command is a shell builtin, alias, function, or external file (keyword). It's similar to the external 'which' command but is shell-aware.
The default umask is typically 022 (or in symbolic notation: u=rwx,g=rx,o=rx), which results in new files being created with permissions 644 (rw-r--r--) and new directories with permissions 755 (rwxr-xr-x).
The cd builtin sets the PWD environment variable to the new working directory and OLDPWD to the previous working directory. These variables are automatically maintained by the shell.
Yes, the -S option causes umask to display the current mask in symbolic form rather than octal. For example, 'umask -S' might output 'u=rwx,g=rx,o=rx' instead of '022'.
pwd -L displays the logical current working directory (may include symlinks, uses $PWD if valid), while pwd -P displays the physical current working directory (resolves all symlinks to show the actual filesystem path).
The type builtin accepts -t (outputs a single word: 'alias', 'keyword', 'function', 'builtin', or 'file'), -p (returns the name of the disk file if command is an external command), or -P (forces a PATH search, even if command is a builtin or alias).
The -H flag sets or displays the hard limit (maximum possible, can only be increased by root), while -S sets or displays the soft limit (currently enforced, can be lowered/raised by user up to the hard limit). If neither is specified, ulimit sets both soft and hard limits.
Yes, cd accepts -L to force symbolic link handling (default) and -P to use physical directory structure. These options affect how the shell treats the current directory when navigating through symlinks.
The ulimit builtin controls system resource limits available to the shell and processes started from it. It can control limits such as maximum file size, core dump size, number of open file descriptors, maximum memory size, CPU time, maximum user processes, and more.
Shell Commands > Coprocesses
18 questionsWhen the command is a simple command, you cannot specify a NAME. If NAME is given, the command that follows must be a compound command. If no NAME is given, the command can be either simple or compound.
Coproc uses two pipes for bidirectional communication: one pipe to send input to the coprocess (connected to its stdin) and one pipe to receive output from the coprocess (connected to its stdout).
Use the wait builtin with the coprocess's process ID (available in $NAME_PID or $COPROC_PID). Save the PID immediately after starting the coprocess as the _PID variable gets unset when the coprocess exits.
Use echo or printf with output redirection to the file descriptor: echo "data" >&"${COPROC[1]}" or echo "data" >&"${NAME[1]}" for named coprocesses.
Creating a new unnamed coprocess while one already exists will replace the existing COPROC array variable and COPROC_PID with values for the new coprocess.
Compound commands include commands delimited with braces {}, parentheses (), or control keywords like if, while, for, case, and select. These have clear delimiter markers that distinguish the NAME from the command.
The coproc keyword was introduced in Bash 4.0, released on February 20, 2009.
The syntax is: coproc NAME compound-command [redirections]. When using a named coprocess, NAME must be followed by a compound command, not a simple command.
Yes, you can have multiple coprocesses running simultaneously by using named coprocesses. Each named coprocess gets its own array variable and _PID variable.
COPROC[0] is the file descriptor connected to the standard output of the coprocess, used for reading from the coprocess.
Bash unsets the _PID variable before you can wait on the coprocess. You must save the value of $COPROC_PID (or named variant) in a separate variable immediately after starting the coprocess.
Use read with input redirection from the file descriptor: read variable <&"${COPROC[0]}" or read variable <&"${NAME[0]}" for named coprocesses.
coproc [NAME] compound-command [redirections] or coproc simple-command. NAME is optional and only valid with compound commands.
When a coprocess terminates, the file descriptor to write to it becomes invalid. Bash automatically closes file descriptors associated with terminated coprocs.
The coproc command always returns success (exit status 0) because it creates an asynchronous command. The return status of the actual command run in the coprocess must be obtained using wait with the process ID.
No, Bash closes coproc file descriptors in child processes and subshells. To use them in subshells, you must duplicate the descriptors first using exec (e.g., exec 10>&"${COPROC[1]}").
COPROC[1] is the file descriptor connected to the standard input of the coprocess, used for writing to the coprocess.
For a named coprocess called NAME, the process ID is stored in the variable NAME_PID. For an unnamed coprocess, it's stored in COPROC_PID.
Bindable Readline Commands > Killing And Yanking
18 questionsThe default key binding for yank is C-y (Control-y). It yanks (pastes) the top of the kill-ring back to the buffer at the current cursor position.
The default key binding for backward-kill-word is M-DEL (Meta-Delete or Alt-Backspace). It kills the word behind the cursor position, using word boundaries composed of alphanumeric characters.
The shell-kill-word command (default binding M-C-k or Meta-Control-k) kills from the cursor position to the end of the current word, or if between words, to the end of the next word. It differs from kill-word by using shell word boundaries (quoting and metacharacters) rather than readline word boundaries.
Consecutive kills of the same type (e.g., multiple consecutive kill-word or kill-line commands) are appended together as a single entry in the kill-ring, rather than stored as separate entries.
The default key binding for unix-word-rubout is C-w (Control-w). It kills backwards from the cursor to the beginning of the previous word, using whitespace as a word boundary (unlike backward-kill-word which uses alphanumeric characters).
The shell-backward-kill-word command has no default key binding. It kills the word behind the cursor position, using shell word boundaries rather than readline word boundaries.
The readline key bindings are customized in the ~/.inputrc file (or /etc/inputrc for system-wide settings). Bindings are set using the syntax: '\C-x': command-name
The yank-nth-arg command accepts a numeric argument n and yanks the nth argument from the previous command. It has no default key binding. With a negative argument, it yanks the nth argument from the end of the previous command.
The default key binding for yank-pop is M-y (Meta-y or Alt-y). It can only be used immediately after a yank (C-y) command. It rotates the kill-ring and yanks the new top, replacing the previously yanked text.
The backward-kill-line command has no default key binding. It kills the text from the cursor position back to the beginning of the line.
The default key binding for kill-word is M-d (Meta-d or Alt-d). It kills from the cursor position to the end of the current word, or if between words, to the end of the next word.
The unix-line-discard command kills the text from the current cursor position to the beginning of the line. Its default key binding is C-u (Control-u).
The kill-whole-line command kills all characters on the current line, no matter where the cursor position is. It has no default key binding.
The default key binding for kill-line is C-k (Control-k). It kills the text from the current cursor position to the end of the line.
C-w (unix-word-rubout) kills backward using only whitespace as word boundaries, while M-DEL (backward-kill-word) kills backward considering both whitespace and alphanumeric characters as word boundaries. For 'test.txt', C-w kills 'test.txt' as one unit, while M-DEL may kill only '.txt' or 'test' depending on cursor position.
The delete-horizontal-space command has no default key binding. It deletes all spaces and tabs around the current cursor position.
The default key bindings for yank-last-arg are M-. (Meta-period or Alt-period) and M-_ (Meta-underscore or Alt-underscore). It yanks the last argument from the previous history command.
After pressing M-. to yank the last argument, pressing M-. again (or M-_) will yank the second-to-last argument from the previous history command, and subsequent presses continue cycling backward through arguments.
Programmable Completion > Completion Action Types
17 questionsReturns failure (non-zero) unless an invalid option is supplied or an error occurs
compgen [-abcdefgjksuv] [-o option] [-A action] [-G globpat] [-W wordlist] [-F function] [-C command] [-X filterpat] [-P prefix] [-S suffix] [word]
compopt modifies or displays completion options for each NAME, or if no NAMEs are supplied, the completion currently being executed. If no OPTIONs are given, it prints the completion options for each NAME or the current completion specification.
If no NAMEs are supplied to compopt, it must be called by a function currently generating completions, and the options for that currently-executing completion generator are modified.
Use +o option instead of -o to turn off the specified option
The -E option applies the completions and actions to 'empty' commands -- completion attempted on a blank line
Use -o option to set completion option OPTION for each NAME
When completion is attempted, if multiple options are supplied, the -D option takes precedence over -E, and both take precedence over -I
The valid single-letter action flags are: -a, -b, -c, -d, -e, -f, -g, -j, -k, -s, -u, -v
The -p option prints existing completion specifications in a reusable format
compopt [-o|+o option] [-DEI] [name ...]
compgen displays possible completions depending on the options. It is intended to be used from within a shell function generating possible completions. If the optional WORD argument is supplied, matches against WORD are generated.
The -D option applies the completions and actions as the default for commands without any specific completion defined
The -I option applies the completions and actions to the initial (usually the command) word
complete [-abcdefgjksuv] [-pr] [-DEI] [-o option] [-A action] [-G globpat] [-W wordlist] [-F function] [-C command] [-X filterpat] [-P prefix] [-S suffix] [name ...]
The -r option removes a completion specification for each NAME, or if no NAMEs are supplied, all completion specifications
Returns failure (non-zero) if an invalid option is supplied or NAME does not have a completion specification defined
Using History Interactively > History Filtering and Control
17 questionsHISTFILESIZE sets the maximum number of lines contained in the history file when the shell exits. When this limit is reached, the oldest entries are truncated.
The 'history -d offset' command deletes the history entry at position 'offset'. For example, 'history -d 5' removes the 5th entry in the history list.
HISTSIZE determines the maximum number of commands to remember in the history list. The default value is typically 500, but this can vary by distribution.
By default, when histappend is not set, the history file is overwritten (truncated) when the shell exits, losing any history from other concurrent sessions.
When 'histappend' is enabled (set via 'shopt -s histappend'), the history list is appended to the history file when the shell exits, rather than overwriting the file. This preserves history from multiple concurrent shell sessions.
The default value of HISTCONTROL is empty/unset, meaning all commands are saved to history without any filtering.
When 'erasedups' is set in HISTCONTROL, all previous lines matching the current line are removed from the history list before the line is saved. This removes all duplicates, not just consecutive ones.
The 'history -c' command clears the history list by deleting all entries from the current session's history.
When HISTSIZE is set to 0, the history list is truncated to 0 entries and no new entries are saved. When HISTFILESIZE is 0, the history file is truncated to 0 size on shell exit.
HISTIGNORE is a colon-separated list of patterns determining which commands should not be saved in the history list. Patterns can include shell wildcards. For example: 'HISTIGNORE="ls:cd:pwd:exit"' would prevent those commands from being saved.
Commands are first checked against HISTIGNORE patterns. If they match, they are not saved regardless of HISTCONTROL settings. HISTCONTROL rules only apply to commands that pass HISTIGNORE filtering.
HISTCONTROL can contain these colon-separated values: 'ignorespace' (don't save commands starting with space), 'ignoredups' (don't save commands matching the last history entry), 'ignoreboth' (both ignorespace and ignoredups), and 'erasedups' (remove all previous matching lines before saving). If not set, all commands are saved.
The default history file is ~/.bash_history. The file name is stored in the HISTFILE variable, which defaults to ~/.bash_history if not set.
HISTTIMEFORMAT specifies a format string for strftime(3) to display timestamps in history output. If set, each history entry is preceded by its timestamp. For example, 'HISTTIMEFORMAT="%F %T "' displays timestamps as 'YYYY-MM-DD HH:MM:SS'.
When 'lithist' is enabled, multi-line commands are saved to history with embedded newlines rather than using semicolons as separators.
The 'cmdhist' option causes Bash to attempt to save multi-line commands as a single history entry. This is enabled by default.
HISTIGNORE patterns are checked against the entire command line, not just the command name. For example, 'HISTIGNORE="ls *"' would ignore any 'ls' command with arguments.
Shell Variables > Locale and Internationalization
16 questionsTEXTDOMAINDIR specifies the base directory where message catalogs for the TEXTDOMAIN are stored. The actual path is constructed as TEXTDOMAINDIR/locale/LC_MESSAGES/TEXTDOMAIN.mo.
The priority order from highest to lowest is: 1) LC_ALL, 2) Specific LC_* variables (e.g., LC_CTYPE, LC_MESSAGES), 3) LANG. LC_ALL overrides all other locale variables.
The default value for LANG is 'C' or 'POSIX', which specifies the minimal locale environment, using traditional Unix/POSIX behavior with no localization.
TEXTDOMAIN specifies the name of the message domain used for translating messages in shell scripts. It is used by the gettext translation system to locate the appropriate message catalog (.mo files).
No, locale variables are not automatically exported when assigned in Bash. They must be explicitly exported using the 'export' command to be inherited by child processes.
In practice, the 'C' and 'POSIX' locales are equivalent in Bash. Both specify the minimal, standard POSIX locale environment with ASCII character set, traditional Unix sorting, and no language-specific translations.
The 'gettext' shell builtin (when enabled) or the external 'gettext' command is used for internationalization. The syntax is: eval_gettext "format-string" or gettext "format-string".
LC_CTYPE controls character classification and case conversion. It affects how characters are interpreted (which are letters, digits, whitespace) and the behavior of case modification in parameter expansion.
Locale variable values follow standard environment variable constraints. There is no Bash-specific maximum, but system limits on environment variables apply (typically the length of the value plus the variable name cannot exceed the platform's ARG_MAX limit, usually 128KB or more on modern systems).
LC_TIME controls the format of date and time strings, affecting the output of the date command and time-related parameter expansions.
LC_MESSAGES controls the language and cultural conventions used for system messages and the formatting of affirmative and negative responses (yes/no expressions).
LC_NUMERIC affects the formatting of numeric values, particularly the decimal separator character (period vs comma) and thousands separator.
The default value of TEXTDOMAIN is 'messages'. This domain is used when translating messages if TEXTDOMAIN is not explicitly set.
LC_ALL overrides all other LC_* variables and LANG. Setting LC_ALL forces the entire locale to a specific setting, ignoring any individual category variables.
LC_COLLATE affects the collation order used by the shell when sorting filename expansion results and determines the behavior of range expressions in pattern matching.
Setting LC_ALL to an empty string forces the locale to be based solely on the remaining environment variables (specific LC_* variables and LANG), removing the override effect of LC_ALL.
Interactive Shells > Shell Initialization
16 questionsThe --rcfile option forces Bash to read and execute commands from the specified file instead of ~/.bashrc. This option only applies to interactive shells.
When Bash is invoked with the --norc option, it prevents reading and execution of ~/.bashrc for an interactive shell. This option only affects interactive shells.
Bash reads ~/.bashrc for interactive non-login shells. This file is not read automatically for login shells unless explicitly sourced from the profile file.
Bash looks for ~/.bash_profile first, then ~/.bash_login, then ~/.profile. It reads and executes commands from the first file that exists and is readable, then stops.
No. Bash does not execute any startup files for non-interactive shells unless BASH_ENV is set. Non-interactive shells (shell scripts) execute without reading initialization files.
If ~/.bash_profile, ~/.bash_login, and ~/.profile do not exist, Bash reads only /etc/profile for login shell initialization and then starts the shell with no user-specific startup commands.
When Bash is invoked with the --noprofile option, it prevents reading of both /etc/profile and any of the personal initialization files (~/.bash_profile, ~/.bash_login, ~/.profile).
Bash reads only the first file found in the search order: ~/.bash_profile, ~/.bash_login, then ~/.profile. If ~/.bash_profile exists, Bash will NOT read ~/.profile even if both files exist.
No. An interactive non-login shell does not read /etc/profile. It only reads ~/.bashrc (and /etc/bash.bashrc on some systems if configured).
Use 'shopt -q login_shell' which returns true (exit status 0) if the shell is a login shell. Alternatively, check if the option '-l' is in $-.
When a login shell exits, Bash reads and executes commands from ~/.bash_logout if it exists.
When Bash is started non-interactively (e.g., to run a shell script), it checks the BASH_ENV environment variable and expands its value to the name of a file to read and execute.
Many systems use /etc/bash.bashrc for system-wide configuration of interactive non-login shells, though this is not default Bash behavior and must be enabled at compile time or through distribution patches.
No. On systems where Bash is invoked as sh (e.g., via symlink), Bash attempts to read only /etc/profile and ~/.profile, specifically ignoring ~/.bash_profile and ~/.bashrc.
No. Bash does NOT read ~/.bashrc automatically for login shells. Users must explicitly source ~/.bashrc from their ~/.bash_profile (or ~/.profile) file if they want it read during login.
When invoked as 'sh', Bash looks for the variable ENV, expands its value, and uses that file for startup commands (similar to BASH_ENV). It does not read any other startup files and tries to mimic POSIX sh behavior more closely.
Word Splitting
16 questionsSetting IFS='' (empty string) before parameter/command/arithmetic expansion causes NO word splitting to occur on the expansion results. This is because there are no delimiter characters defined.
No, word splitting does NOT occur within double quotes. The text $var and $(cmd) inside double quotes preserves all whitespace exactly, with no word splitting performed.
The order is: 1) Brace expansion, 2) Tilde expansion, 3) Parameter and variable expansion, 4) Arithmetic expansion, 5) Command substitution, 6) Word splitting, 7) Pathname expansion. Word splitting occurs at step 6.
Sequences of IFS whitespace characters (space, tab, newline) are treated as a single delimiter. Additionally, any leading or trailing IFS whitespace is ignored.
When quoted, "$@" expands to each positional parameter as a separate word, preserving each parameter exactly (no word splitting within each parameter). When quoted, "$*" expands to a single word with all parameters joined by the first character of IFS.
Word splitting occurs after parameter expansion ($var), command substitution ($(cmd) or cmd), and arithmetic expansion (($((expr)))). It does NOT occur after tilde expansion, brace expansion, or pathname expansion.
When using the 'read' builtin, if IFS is unset, the default value of
Tab characters are part of the default IFS whitespace characters. They are treated exactly like spaces and newlines: sequences of multiple tabs (or mixed tabs/spaces/newlines) are treated as a single delimiter, and leading/trailing tabs are ignored.
Non-whitespace IFS characters (when IFS contains characters like comma, colon, etc.) are NOT treated as delimiters when they appear alone. They are treated as delimiters, but each non-whitespace IFS character serves as a separate delimiter, and sequences of them are NOT collapsed into a single delimiter.
Leading and trailing IFS whitespace characters (space, tab, newline) are ignored during word splitting. However, leading and trailing non-whitespace IFS characters are NOT ignored - they create empty fields (though those empty fields are subsequently removed).
Yes. ${array[@]} expands to each element as a separate word (with or without quotes, quotes preserve whitespace within elements). ${array[*]} expands to all elements joined by the first character of IFS as a single word if quoted, or splits into multiple words based on IFS if unquoted.
No, word splitting does NOT occur on pathname expansion results. The filenames generated by globbing patterns (*.txt) are not split according to IFS.
The default value of IFS is
If IFS is unset, word splitting behaves as if the default IFS (
Zero-length strings (empty words) resulting from word splitting are removed from the result entirely. For example, if IFS=: and value is 'a::b', the result is 'a' and 'b' - the empty word between the colons is discarded.
The 'set -f' option disables pathname expansion (globbing) but does NOT affect word splitting. Word splitting still occurs normally with 'set -f' enabled.
Shell Parameter Expansion > Name and Key Operations
16 questionsIf no shell variables begin with the specified prefix, ${!name*} expands to nothing (an empty string).
When name is an indexed array, ${!name[@]} expands to all the keys (indices) of the array. For example, if arr=(a b c), ${!arr[@]} expands to '0 1 2'.
Yes, ${!name[@]} can be used with nameref variables. If name is a nameref pointing to an array, ${!name[@]} expands to the keys of the referenced array.
When name expands to special characters like '@' or '*', they are treated specially. For example, if arr=(a b c) and x='arr[@]', then ${!x} expands to all elements of the array, not the keys.
${!name} performs indirect expansion. The value of 'name' is treated as a variable name, and the expansion returns the value of that variable. For example, if var='myvar' and myvar='hello', then ${!var} expands to 'hello'.
${!prefix*} expands to the names of all shell variables whose names begin with 'prefix'. The names are separated by the first character of the IFS variable.
No, the order of keys returned by ${!name[@]} for associative arrays is not guaranteed or sorted. The keys appear in the order they were stored internally by bash.
When name is an indexed array, ${!name[*]} expands to all the keys (indices) of the array as a single word with keys separated by the first character of IFS.
When name is an associative array, ${!name[@]} expands to all the keys of the associative array. For example, if declare -A arr=([foo]=bar [baz]=qux), ${!arr[@]} expands to the keys 'foo baz'.
Yes, ${!prefix*} lists all shell variables (including environment variables) whose names begin with the prefix. It doesn't distinguish between environment variables and regular shell variables.
When using @, the resulting variable names each appear in a separate word. When using *, the names are separated by the first character of the IFS variable.
${#name[@]} returns the number of elements in the array, while ${!name[@]} returns the actual keys/indices themselves. For arr=(a b c), ${#arr[@]} is '3' while ${!arr[@]} is '0 1 2'.
Associative arrays and ${!name[@]} key expansion for associative arrays require bash 4.0 or later, as associative arrays were introduced in bash 4.0.
When name is not an array, ${!name[@]} expands to '0' if the variable is set and null otherwise.
If name='arr[@]', then ${name} would literally expand to the string 'arr[@]', but ${!name} performs indirect expansion and expands to all elements of the array arr. The ${!} syntax interprets the value as a variable reference.
${!prefix@} expands to the names of all shell variables whose names begin with 'prefix'. Unlike ${!prefix*}, each name appears in a separate word when using ${!prefix@}.
Simple Commands
16 questionsExit statuses fall between 0 and 255, though the shell may use values above 125 specially.
The control operators are: newline, ||, &&, &, ;, ;;, ;&, ;;&, |, |&, (, and )
The return 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.
The exit status of the last command is available in the special parameter $?.
The exit status value is restricted to eight bits, so the maximum value is 255.
All builtins return an exit status of 2 to indicate incorrect usage, generally invalid options or missing arguments.
A simple command is a sequence of words separated by blanks, terminated by one of the shell's control operators. The first word generally specifies a command to be executed, with the rest of the words being that command's arguments.
No, a command invoked in a separate execution environment cannot affect the shell's execution environment.
If a command is not found, the child process created to execute it returns a status of 127.
When a command terminates on a fatal signal whose number is N, Bash uses the value 128+N as the exit status.
A zero exit status indicates success. A non-zero exit status indicates failure.
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.
A metacharacter is a character that, when unquoted, separates words. A metacharacter is a space, tab, newline, or one of the following characters: |, &, ;, (, ), <, or >
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 shell's open files plus any modifications and additions specified by redirections; the current working directory; the file creation mode mask; shell variables and functions marked for export along with variables exported for the command passed in the environment; and traps caught by the shell are reset to the values inherited from the shell's parent, while traps ignored by the shell are ignored.
Shell Parameter Expansion > Default and Alternative Values
16 questions${parameter:=word} assigns 'word' to parameter if parameter is unset OR null (empty string), while ${parameter=word} (without the colon) only assigns 'word' if parameter is unset (but NOT if it's null/empty). Both forms then substitute the value of parameter.
${parameter:?word} (with colon) triggers the error message if parameter is unset OR null. ${parameter?word} (without colon) only triggers the error if parameter is unset, but NOT if it's null (empty string). Both write the error message to stderr and cause non-interactive shells to exit.
Yes. Use ${parameter+word} (without colon). This substitutes 'word' if parameter is set (even if empty/null), and substitutes nothing if parameter is unset. Commonly used as: ${var+isset} which expands to 'isset' if var is set, or nothing if unset.
The value of parameter is substituted. When parameter is unset or null, 'word' is first assigned to parameter, and then the final value of parameter (which is now 'word') is substituted.
${1:-default_value} - This provides 'default_value' if the first positional parameter ($1) is unset or null, otherwise uses $1's value. Note that this does NOT assign the value to $1 (since positional parameters cannot be assigned this way).
${parameter:+word} (with colon) substitutes 'word' only if parameter is set AND non-null. ${parameter+word} (without colon) substitutes 'word' if parameter is set (even if it's null/empty). Both substitute nothing if the parameter is unset.
${parameter:-word} substitutes 'word' if parameter is unset OR null (empty string), while ${parameter-word} (without the colon) only substitutes 'word' if parameter is unset (but NOT if it's null/empty). When the colon is included, the operator tests for both parameter existence AND that its value is not null. When the colon is omitted, it tests only for existence.
The 'word' value is subject to tilde expansion, parameter expansion, command substitution, and arithmetic expansion. These expansions happen recursively when evaluating the default/alternate value.
If parameter is set and non-null, ${parameter:+word} substitutes the expansion of 'word'. The value of parameter itself is NOT used or substituted.
In an interactive shell, when ${parameter:?word} encounters an unset or null parameter, the shell writes the error message to standard error and does NOT execute the command associated with the expansion. The exit status ($?) is set to a non-zero value, but the shell does not exit.
If parameter is null or unset, the shell writes the expansion of word (or a message to that effect if word is not present) to standard error. If the shell is not interactive, it exits with a non-zero status. An interactive shell does not exit, but does not execute the command associated with the expansion.
No. Positional parameters and special parameters may NOT be assigned using the ${parameter:=word} syntax. The assignment form of parameter expansion cannot be used with positional parameters like $1, $2, etc., or special parameters like $?, $$, etc.
It's commonly used to conditionally add text or warnings when a variable is set. For example: echo "Application installed${JAVAPATH:+ NOTE: JAVAPATH is set}" - This appends the warning only if JAVAPATH is set and non-null. The parameter's value is not used, only whether it's set and non-null matters.
If parameter is null or unset, ${parameter:+word} substitutes nothing (empty string).
No. ${parameter:-word} only substitutes the default value but does NOT assign it to the parameter. The parameter remains unchanged after the expansion. To assign the default value, use ${parameter:=word} instead.
When word is not present in ${parameter:?word}, the shell writes a message to that effect (indicating the parameter is null or unset) to standard error. The default message format is 'parameter: parameter is null or unset' (where 'parameter' is the actual parameter name).
Readline Init File > Conditional Constructs
16 questionsThe application name is determined from the first argument passed to the readline initialization function by the calling program. For Bash, this is 'Bash'. For other programs using readline (Python, Ruby, MySQL, etc.), it's the program name.
The readline $if construct supports four test structures:
- mode - tests the editing mode (e.g., mode=emacs, mode=vi)
- term - tests the terminal type (e.g., term=xterm)
- application - tests the application using readline (e.g., application=Bash)
- variable=value - tests if a readline variable has a specific value
Use the mode test structure. For example:
$if mode=emacs
Control-x: "emacs-mode\n"
$endif
$if mode=vi
Control-x: "vi-mode\n"
$endif
No, readline conditional constructs cannot be nested. The documentation does not support nested $if statements.
The application test structure allows you to apply settings only when readline is being used by a specific application. The application name is determined from the first argument to readline (the application's name). For example:
$if application=Bash
"\C-x\C-r": re-read-init-file
$endif
$if application=python
# Python-specific readline settings
$endif
Use the term test structure with the value of the TERM environment variable. For example:
$if term=xterm
# xterm-specific bindings
$endif
$if term=screen
# GNU Screen-specific bindings
$endif
The $endif directive marks the end of a conditional construct started by $if. Every $if must have a corresponding $endif. Directives after $endif are processed unconditionally.
The conditional construct uses the $if directive. The full syntax is:
$if
# directives
$else
# alternate directives
$endif
The $else clause is optional.
For the application test, the application name 'Bash' is case-sensitive and must be capitalized. For other tests (mode, term), the comparison is typically case-sensitive and should match the actual value of the variable being tested.
Use the variable=value test structure. For example:
$if show-all-if-ambiguous=on
# settings when show-all-if-ambiguous is enabled
$endif
$if completion-query-items=100
# settings when completion-query-items is 100
$endif
The valid mode values are 'emacs' and 'vi', corresponding to readline's two editing modes. These are set by the 'editing-mode' variable in the init file or by the application.
Use the term test structure with the TERM environment variable value. For example:
$if term=xterm
"\eOH": beginning-of-line
"\eOF": end-of-line
$endif
$if term=rxvt
"\e[C": forward-word
"\e[D": backward-word
$endif
No, readline conditional tests do not support wildcards or pattern matching. The mode, term, and application tests require exact string matches. The term test matches against the exact value of the TERM environment variable.
Use the application test with 'Bash':
$if application=Bash
"\C-x\C-e": edit-and-execute-command
"\C-x\C-r": re-read-init-file
"\C-x\C-v": display-shell-version
$endif
No, the $else clause is optional in readline conditional constructs. You can use a simple $if/$endif structure without an $else clause.
If the $if test fails, all directives between the $if and the corresponding $else (if present) or $endif are ignored. If an $else clause exists and the test fails, the directives between $else and $endif are processed instead.
Arrays > Array Manipulation
15 questionsReturns the last N elements of the array. The space before -N is required to distinguish it from the default value syntax ${parameter:-word}. For example, ${array[@]: -3} returns the last 3 elements.
Bash does NOT support negative indices directly in array access like array[-1]. However, in parameter expansion slicing ${array[@]: -N}, the negative offset counts from the end. Note the space before -N is mandatory.
Within double quotes, "${array[*]}" expands to a single word with all elements joined by the first character of IFS (typically space), while "${array[@]}" expands to separate words with each element as an individual argument. For array manipulation, @ is typically preferred to preserve element boundaries.
${array[@]:N} - This returns all elements starting from index N to the end of the array. The @ symbol expands all elements and the colon N specifies the starting offset.
array=("${array[@]:1}") - This creates a new array containing all elements from index 1 onwards, effectively removing the first element (index 0).
No. Assigning to array[N] where N is beyond the current maximum index does NOT automatically grow the array or create intermediate elements. This creates a sparse array. The maximum index is updated, but intermediate indices remain unset.
Use the += operator: array+=("new_element"). The parentheses are required when appending a single element to ensure it's added as one element, not split on IFS.
When you use 'unset array[index]' to delete an element, the array becomes sparse - the indices are NOT renumbered. The gap remains and other elements keep their original indices. To reindex the array and remove gaps, you must recreate it: array=("${array[@]}")
array+=new_element (without parentheses) will append new_element as a string to element 0, not add it as a new array element. The word splitting and IFS behavior applies. Always use array+=("new_element") to append as a new element.
array=("${array[@]:0:${#array[@]}-1}") - This creates a new array containing all elements except the last one. ${#array[@]} gives the length, so ${#array[@]}-1 is the new length.
${array[@]:N:LENGTH} - This returns LENGTH elements starting from index N. If LENGTH is omitted, it returns all elements from N to the end.
${!array[@]} - The ! prefix returns the list of indices (keys) rather than values. This is useful for iterating over sparse arrays where indices may not be consecutive.
Use 'unset array' without any brackets or index. This completely removes the array variable. Using 'unset array[@]' will also unset the entire array.
array1+=("${array2[@]}") - This appends all elements of array2 to the end of array1. The quotes and @ expansion ensure each element is preserved correctly.
${#array[@]} returns the number of set (non-null) elements, NOT the highest index. For a sparse array with gaps, this counts only the existing elements, not the missing indices.
Looping Constructs > Condition-Based Iteration
15 questionsWhile loops continue while test-commands have exit status zero (success). Until loops continue while test-commands have exit status non-zero (failure). They are logical opposites.
Both break and continue can be used with for, while, until, or select loops.
The syntax is: continue [n]. It resumes 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.
The condition part is called 'test-commands' and the body is called 'consequent-commands'.
The syntax is: break [n]. It exits from a for, while, until, or select loop. If n is supplied, the nth enclosing loop is exited.
The break and continue builtins are documented in the Bourne Shell Builtins section.
A while loop executes consequent-commands as long as test-commands has an exit status of zero.
Bash provides the break and continue builtins to control loop execution.
The syntax of a while command is: while test-commands; do consequent-commands; done
An until loop executes consequent-commands as long as test-commands has an exit status which is not zero.
If no commands are executed in the loop body, the return status is zero.
The return status is the exit status of the last command executed in consequent-commands, or zero if no commands were executed.
Yes. In the description of a command's syntax, wherever a ';' appears, it may be replaced with one or more newlines.
Bindable Readline Commands > Specifying Numeric Arguments
15 questionsPress M-0 through M-9 in sequence to build multi-digit numbers. Each digit-argument invocation adds that digit to the argument already accumulating. For example, M-1 followed by M-0 creates an argument of 10.
The digit-argument command is bound to M-0, M-1, through M-9 (Meta + digits 0-9), and M-- (Meta + minus). M-0 through M-9 add a digit to the accumulating argument or start a new argument. M-- starts a negative argument.
By default, C-u is bound to universal-argument for numeric argument specification. The unix-line-discard command (which kills backward from point to the beginning of the line) is conceptually separate. In some readline configurations or applications, the binding may differ, but the readline default for C-u is universal-argument.
Each execution of universal-argument multiplies the argument count by four. Starting from 1, one execution makes it 4, two executions make it 16, three executions make it 64, and so on.
Yes, universal-argument can be followed by a minus sign and then digits to specify a negative argument (e.g., C-u - 5 creates an argument of -5).
Readline commands may be given numeric arguments, which normally act as a repeat count.
Press C-u twice (to get 16), then M-- to make it negative, resulting in -16. Alternatively, press C-u, then -, then 1, then 6.
Passing a negative argument to a command that acts in the forward direction (e.g., kill-line) causes that command to act in a backward direction instead. Commands whose behavior with arguments deviates from this are noted in the documentation.
M-- starts a negative argument. When followed by digit-argument commands (M-0 through M-9), it creates a negative numeric argument for the next command.
The universal-argument command is bound to C-u (Control-u) by default.
The digit-argument command (M-0 through M-9) starts a new argument if one is not already accumulating, or adds to the argument already accumulating.
The two primary ways are: (1) Using digit-argument (M-0 through M-9 and M--) to build multi-digit positive or negative arguments, and (2) Using universal-argument (C-u) which either multiplies the count by four or accepts digits to define a specific argument value.
When universal-argument is followed by one or more digits (optionally with a leading minus sign), those digits define the argument. If followed by digits and then universal-argument is executed again, it ends the numeric argument but is otherwise ignored.
The argument count is initially one before universal-argument begins multiplying it by four.
As a special case, if universal-argument is immediately followed by a character that is neither a digit nor 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 it sixteen, and so on.
Looping Constructs > Iteration by Collection
15 questionsIf there are no items in the expansion of words, no commands are executed, and the return status is zero.
The for command expands words (see Shell Expansions), and then executes commands once for each word in the resultant list, with name bound to the current word.
Yes, the for command expands words first (according to Shell Expansions), and then executes commands once for each word in the resultant list.
First, the arithmetic expression expr1 is evaluated according to the rules described in Shell Arithmetic. Then, repeatedly evaluate the arithmetic expression expr2 until it evaluates to zero. Each time expr2 evaluates to a non-zero value, execute commands and evaluate the arithmetic expression expr3.
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.
If any expression is omitted in a C-style for loop, it behaves as if it evaluates to 1.
During each iteration, the variable name is bound to the current word from the expanded list of words.
The return status is the exit status of the last command that executes.
When 'in words' is omitted, the for loop behaves as if 'in "$@"' had been specified, which means it iterates over all positional parameters.
The syntax of the for command is: for name [ [in words ...] ; ] do commands; done
Yes, wherever a ';' appears in the description of a command's syntax, it may be replaced with one or more newlines.
The return value is the exit status of the last command in commands that is executed, or non-zero if any of the expressions is invalid.
No, the 'in words' portion is optional. The brackets in 'for name [ [in words ...] ; ] do commands; done' indicate that the entire 'in words ...' section can be omitted.
Bindable Readline Commands > Keyboard Macros
15 questionsThe default key binding for end-kbd-macro is C-x ) (Ctrl-x followed by close parenthesis). This command stops saving the characters typed into the current keyboard macro and saves the macro definition.
The print-last-kbd-macro command has no default key binding. It must be explicitly bound to a key. This command prints the last keyboard macro defined in a format suitable for the ~/.inputrc file.
Use the print-last-kbd-macro command (which has no default binding and must be bound explicitly) to display the last keyboard macro in a format suitable for ~/.inputrc. Alternatively, use 'bind -p' to view all current readline bindings.
The 'echo-control-characters' variable controls whether characters are echoed. However, there is no specific readline variable to control macro definition display - macros are recorded silently when using start-kbd-macro/end-kbd-macro.
No, readline keyboard macros cannot be nested. Attempting to start a new keyboard macro with start-kbd-macro while already recording a macro will result in an error or undefined behavior.
In ~/.inputrc, you define a keyboard macro using: "\C-xkey": "macro-sequence". For example: "\C-xp": "ls -la\n" binds Ctrl-x followed by 'p' to execute 'ls -la' followed by a newline.
Interactive recording with start-kbd-macro (C-x () and end-kbd-macro (C-x )) creates a temporary macro that lasts only for the current session. Defining macros in ~/.inputrc creates permanent key bindings available in all bash sessions.
Readline stores only one keyboard macro at a time - the 'last' keyboard macro. Recording a new macro with start-kbd-macro/end-kbd-macro replaces any previously recorded macro.
After executing C-x e to call the last keyboard macro, pressing just 'e' (without the Ctrl-x prefix) will re-execute the same macro again. This allows rapid repetition of the last macro.
The default key binding for call-last-kbd-macro is C-x e (Ctrl-x followed by 'e'). This command re-executes the last keyboard macro defined.
The print-last-kbd-macro command prints the last keyboard macro defined in a format suitable for ~/.inputrc. This command has no default key binding and must be explicitly bound.
In ~/.inputrc macro definitions, the newline (Enter key) is represented as '\n'. For example: "\C-xp": "ls -la\n" defines a macro that types 'ls -la' and then presses Enter.
The default key binding for start-kbd-macro is C-x ( (Ctrl-x followed by open parenthesis). This command begins saving the characters typed into the current keyboard macro.
Interactive keyboard macros recorded with start-kbd-macro/end-kbd-macro are NOT shared across sessions - they exist only in the current shell session. Only macros defined in ~/.inputrc or /etc/inputrc are persistent across sessions.
No, readline keyboard macros are simple text/keystroke sequences only. They do not support conditional logic, variables, loops, or any programming constructs. They merely replay a sequence of characters or readline commands.
Shell Parameter Expansion > String Length and Counting
15 questionsNo, this is invalid syntax. You must assign to a variable first: result=$(command); echo ${#result}
${#array[index]} - For example, ${#myarray[2]} returns the length of the element at index 2.
Bash variables cannot contain NUL characters. If a command substitution outputs a NUL, it terminates the string at that point.
A decimal integer (as a string), usable in arithmetic contexts without additional conversion.
Yes. For example, if the exit status is 0, ${#?} returns 1 (the length of the string '0').
${#array[@]} - This works for both indexed and associative arrays to return the count of elements/key-value pairs.
${#N} where N is the positional parameter number. For example, if $1 is 'hello', ${#1} returns 5.
${#parameter} - For example, if mystring="hello", then ${#mystring} returns 5.
No. ${#parameter:offset:length} is not valid. You must first perform substring extraction or assign it, then get length.
${#array[@]} returns the number of elements in the array, while ${#array[0]} returns the length of the string stored at index 0.
Characters. The ${#parameter} expansion returns the length in characters, not bytes. This is important for multi-byte UTF-8 characters.
Shell Variables > Bash-Specific Extensions
15 questionsHISTFILESIZE defaults to 500 lines. This variable sets the maximum number of lines contained in the history file.
HISTSIZE defaults to 500 commands. This variable controls the maximum number of commands to remember on the history list.
HISTCONTROL has no default value (empty). When unset or set to an empty value, all commands are saved to the history list. It can be set to 'ignorespace', 'ignoredups', 'ignoreboth', or 'erasedups'.
COMP_WORDBREAKS defaults to '
"'><=;|&(:'. It contains characters that readline treats as word breaks when performing word completion.
BASH_CMDS is an array variable containing the commands in the internal hash table maintained by the hash builtin. It's indexed by command name.
BASH_REMATCH[0] contains the entire string matching the entire regular expression. BASH_REMATCH[1] through BASH_REMATCH[n] contain the substrings matched by corresponding parenthesized subexpressions.
HISTTIMEFORMAT has no default value (unset). When set, it causes bash to save timestamps with each history entry, using strftime format specifications.
This appears to be a request about BASH_XORIG_LOC which is not a documented Bash variable in the official manual. There may be a typo in this question.
BASH_ARGV is only available when the extdebug option is enabled using 'shopt -s extdebug'. It contains all parameters in the current bash execution call stack.
BASH_ARGC is an array variable whose values are the number of parameters in each frame of the current bash execution call stack. It requires extdebug to be enabled.
BASH_ENV contains the filename of a startup script that is executed when a non-interactive shell is started, similar to how .bashrc is used for interactive shells.
RANDOM returns a pseudo-random integer in the range 0 to 32767. Assigning a value to RANDOM seeds the random number generator.
BASH_SOURCE is an array whose members are the source filenames where corresponding shell function names in FUNCNAME are defined. BASH_SOURCE[$i] contains the file that defines function ${FUNCNAME[$i]}.
BASHPID expands to the process ID of the current Bash process, unlike $$ which may vary in subshells. BASHPID reflects the actual process ID even in subshells.
FIGNORE has no default value (empty). When set, it contains suffixes that cause matches to be ignored during filename completion.
Filename Expansion > Basic Wildcard Patterns
15 questionsThe / character (slash) must be matched explicitly by wildcards in pathname expansion. The * and ? wildcards do NOT match / in pathname expansion. This means that patterns like *.txt will only match .txt files in the current directory, not recursively in subdirectories.
In filename expansion, a dot (.) at the beginning of a filename must be matched explicitly. It is NOT matched by wildcard patterns like , ?, or [..]. For example, * matches all files except hidden files (those starting with .). To match hidden files, you must use . explicitly.
Bash processes filename expansion after brace expansion, tilde expansion, parameter and variable expansion, and arithmetic expansion, but before command substitution. This ordering ensures that expanded values can then be used as patterns for filename matching.
When wildcard characters (, ?, [, ]) are quoted (with single quotes, double quotes, or backslash), they lose their special meaning and are treated as literal characters. For example, '.txt' matches only a file literally named '*.txt', not all .txt files.
The * (asterisk) matches any string, including the empty string. It is a pattern that expands to all filenames that match the pattern. For example, *.txt matches all files ending in .txt, including .txt itself (if it exists as a filename).
There is no option to disable this behavior - it's a fundamental rule of bash filename expansion. Wildcards never match filenames that begin with a dot unless the wildcard pattern itself starts with a dot. This is a built-in security feature to prevent accidental manipulation of hidden configuration files.
When a wildcard pattern fails to match any files, the pattern itself is left unchanged and passed literally to the command. This is different from the behavior when nullglob is enabled. For example, if no .txt files exist, 'echo .txt' will literally print '.txt'.
The ? (question mark) matches any single character. It will match exactly one character and no more. For example, file?.txt matches file1.txt, filea.txt, but not file10.txt or file.txt.
Use either [!...] or [^...] at the beginning of the bracket expression. For example, [!0-9] matches any character that is NOT a digit. Both ! and ^ are supported for negation.
No, bash pattern matching is case-sensitive by default. [a-z] matches only lowercase letters, not uppercase. However, you can use nocasematch shell option with some constructs, but this does not apply to filename expansion, only to case statements and [[ commands.
To include a literal ] in a bracket expression, it must be the first character after the opening [. For example, []abc] matches ], a, b, or c. If ] is not first, it closes the bracket expression.
If a bracket expression contains invalid syntax (such as [a- where a range is not properly closed), bash treats it as a literal string rather than a pattern. The pattern will not expand and will be passed literally to the command.
Use [start-end] syntax. For example, [a-z] matches any lowercase letter, [A-Z] matches any uppercase letter, and [0-9] matches any digit. The range is inclusive of both endpoints.
To include a literal hyphen - in a bracket expression, it must be placed as the first or last character within the brackets. For example, [-abc] or [abc-] includes - as a literal character to match. If placed in the middle, it creates a range.
Multiple bracket expressions in a pattern are evaluated independently and sequentially. For example, [a-z][0-9] matches any two-character string where the first character is a lowercase letter and the second is a digit. Each bracket expression matches exactly one character.
Shell Arithmetic > Assignment Operations
15 questionsThe decrement operator is -- and can be used as either a pre-decrement (( --var )) or post-decrement (( var-- )). The pre-decrement decrements the variable before using its value, while post-decrement returns the original value before decrementing.
Yes, bash allows chained assignments in shell arithmetic. For example: (( a = b = c = 5 )) assigns 5 to all three variables. The assignment operator associates right-to-left, so this is evaluated as (( a = (b = (c = 5)) )).
The modulo assignment operator %= computes the remainder and assigns it back: (( x %= y )) is equivalent to (( x = x % y )). The sign of the result follows the sign of the dividend. Using zero as the divisor causes a division by zero error.
The bitwise AND assignment &= performs: (( x &= mask )) equivalent to (( x = x & mask )). The bitwise OR assignment |= performs: (( x |= mask )) equivalent to (( x = x | mask )). The bitwise XOR assignment ^= performs: (( x ^= mask )) equivalent to (( x = x ^ mask )).
Yes, assignment operators work with the let command. For example: let x+=5 or let "x += 5" performs addition assignment. The let command evaluates arithmetic expressions and supports all assignment operators that (( )) supports.
When using division assignment /= with a zero divisor, bash will generate a division by zero error. For example, (( x /= 0 )) will produce an error message like 'division by 0' and the assignment will not be performed.
Both operators increment var by 1, but (( var++ )) returns the original value before the increment, while (( var += 1 )) returns the new value after the increment. When used as a standalone statement without using the return value, they are functionally equivalent.
Both assign a value to var, but (( var = value )) is a compound command that performs the assignment and returns an exit status based on whether the result is non-zero, while var=$(( value )) is an assignment that uses arithmetic expansion to compute the value. The (( )) form is preferred for arithmetic assignment operations.
Bash supports the following assignment operators in shell arithmetic: = (assignment), += (addition assignment), -= (subtraction assignment), *= (multiplication assignment), /= (division assignment), %= (modulo assignment), <<= (left shift assignment), >>= (right shift assignment), &= (bitwise AND assignment), |= (bitwise OR assignment), and ^= (bitwise XOR assignment).
The (( )) compound command returns an exit status of 0 if the value of the expression is non-zero, and 1 if the value is zero. For example, (( x = 5 )) returns exit status 0 (since 5 is non-zero), while (( x = 0 )) returns exit status 1.
The comma operator , evaluates multiple expressions from left to right and returns the value of the rightmost expression. For example: (( a = 1, b = 2, c = 3 )) assigns all values and the overall expression evaluates to 3 (the last value).
The increment operator is ++ and can be used as either a pre-increment (( ++var )) or post-increment (( var++ )). The pre-increment increments the variable before using its value, while post-increment returns the original value before incrementing.
The addition assignment operator is +=. It can be used as (( var += value )) which is equivalent to (( var = var + value )). For example: (( x += 5 )) adds 5 to x and stores the result back in x.
The left shift assignment operator <<= shifts the bits of the variable left by the specified number of positions: (( x <<= 2 )) is equivalent to (( x = x << 2 )). The right shift assignment operator >>= shifts bits right: (( x >>= 2 )) is equivalent to (( x = x >> 2 )).
Yes, the assignment operator = can be used in arithmetic expansion. For example: $(( x = 5 )) assigns 5 to x and returns 5. However, note that variables assigned inside $(( )) do not retain their value outside the expansion unless they were already declared. Use (( )) without the $ prefix for assignment side effects.
Bash Conditional Expressions > Logical and Negation Operators
13 questionsThe result is false. Because ! has higher precedence than &&, this is evaluated as (! true) && true, which is false && true, resulting in false.
Yes, ! can be used as a command prefix to negate any command's exit status. For example: ! grep pattern file returns 0 if grep fails (doesn't find the pattern) and 1 if grep succeeds.
Parentheses can be used to override the default precedence and group expressions. For example: cmd1 && (cmd2 || cmd3) forces cmd2 || cmd3 to be evaluated as a unit before the &&. Note: parentheses create a subshell.
The ! operator requires a space after it when used within [ ] or [[ ]] constructs. For example: [ ! -f file ] or [[ ! -d dir ]]. Without the space, it may cause syntax errors.
The && operator only evaluates the right side if the left side exits with status 0 (true). The || operator only evaluates the right side if the left side exits with non-zero status (false). This is called short-circuit evaluation.
Yes, ! [[ -f file && -r file ]] negates the entire compound expression, returning true if the file does not exist OR is not readable. The ! applies to the result of the entire expression.
Both [ ! -f file ] and [[ ! -f file ]] work for negation, but [[ ]] is a bash-specific keyword that provides safer parsing and prevents word splitting and globbing. The ! operator works the same way in both constructs.
Multiple && operators are evaluated left-to-right with short-circuit evaluation. If any expression returns false (non-zero), evaluation stops and subsequent expressions are not evaluated.
-a (AND) and -o (OR) are test command operators used inside [ ], while && and || are shell logical operators used to combine commands or expressions. Inside [[ ]], only && and || should be used. The -a and -o operators are deprecated in POSIX.
The precedence from highest to lowest is: ! (negation), && (AND), then || (OR). The ! operator has the highest precedence and binds most tightly.
The exit status is non-zero (false). The ! operator inverts the exit status: if a command returns 0, ! makes it return 1; if a command returns non-zero, ! makes it return 0.
The exclamation point ! operator negates the result of a conditional expression. For example, ! -f file returns true if the file does NOT exist.
Multiple || operators are evaluated left-to-right with short-circuit evaluation. If any expression returns true (exit status 0), evaluation stops and subsequent expressions are not evaluated.
Bindable Readline Commands > Commands For Completion
12 questionsThe 'complete-username' command attempts completion on the text before point, treating it as a username. It is bound to M-~ (Meta-) or ESC- by default.
The 'dabbrev-expand' command attempts completion on the text before point from the list of words in the other lines currently in the history. It expands to the longest matching prefix and is not bound to any key by default.
When 'menu-complete-display-prefix' is set to 'on', 'menu-complete' displays the common prefix of the possible completions before cycling through them. The default is 'off'.
The 'possible-completions' command lists the possible completions of the text before point. It is typically bound to M-? (Meta-?) or ESC-? by default.
The 'show-all-if-ambiguous' readline variable, when set to 'on', alters completion behavior. If set to 'off' (default), the word is completed to the longest common prefix and a bell sounds. The 'completion-ignore-case' variable affects case sensitivity during completion.
The 'complete-into-braces' command performs filename completion and inserts the list of possible completions enclosed in braces, converting 'file' to '{file1,file2,file3}'. It is not bound to any key by default.
The 'dynamic-complete-history' command attempts completion on the text before point, comparing the text against lines from the history list. It is not bound to any key by default.
The 'complete-variable' command attempts completion on the text before point, treating it as a shell variable. It is bound to M-$ (Meta-$) or ESC-$ by default.
The 'complete' command is bound to Tab by default. It attempts to perform completion on the text before point, treating it as a filename, command name, or variable depending on the context.
The 'insert-completions' command is bound to M-* (Meta-) or ESC- by default. It inserts all possible completions of the text before point, listing them if there are more than one.
The 'complete-filename' command is bound to M-/ (Meta-/) or ESC-/ by default. It attempts completion on the text before point, treating it as a filename.
The 'menu-complete-backward' command cycles through the possible completions in the opposite direction from 'menu-complete', moving backward through the completion list instead of forward.
Controlling the Prompt > Temporal Information
12 questionsThe \A escape sequence displays the current time in 24-hour HH:MM format (without seconds). Example: '14:30'
All temporal escape sequences (\t, \T, @, \A, \d, \D) use the local timezone as configured on the system
The \D{format} escape sequence allows custom formatting using strftime(3) format specifiers. The format string is enclosed in braces immediately after \D
@ displays time in 12-hour format with am/pm indicator (e.g., '02:30 PM'), while \A displays time in 24-hour format without seconds (e.g., '14:30')
The \d escape sequence displays the date in 'Weekday Month Day' format. Example: 'Tue May 26'
No, the \d escape sequence displays the date in 'Weekday Month Day' format (e.g., 'Tue May 26') and does not include the year. To include the year, use \D{format} with strftime specifiers like \D{%Y-%m-%d}
Temporal escape sequences are evaluated dynamically each time the prompt is displayed, showing the current time/date at that moment
The \T escape sequence displays the current time in 12-hour HH:MM:SS format. Example: '02:30:45'
The @ escape sequence displays the current time in 12-hour am/pm format. Example: '02:30 PM'
The \t escape sequence displays the current time in 24-hour HH:MM:SS format. Example: '14:30:45'
\t displays time in 24-hour format (HH:MM:SS, range 00:00:00 to 23:59:59), while \T displays time in 12-hour format (HH:MM:SS, range 01:00:00 to 12:59:59)
Use the \D{format} escape sequence, where format uses strftime(3) format specifiers. Example: \D{%Y-%m-%d %H:%M:%S} displays '2025-01-15 14:30:45'
Shell Parameter Expansion > Basic Value Access
11 questionsThe basic form of parameter expansion is ${parameter}, which substitutes the value of parameter. The parameter is a shell parameter or an array reference.
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.
Braces 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.
If parameter is a nameref, it expands to the name of the variable referenced by parameter instead of performing the complete indirect expansion.
Without braces, a digit following $ can only refer to one of the first nine positional parameters ($1-$9) or the special parameter $0.
$11 expands to 'a1' (interpreted as $1 followed by the character '1'), while ${11} expands to the value of the eleventh positional parameter.
Indirect expansion occurs when the first character of parameter is an exclamation point (!) and parameter is not a nameref. Bash uses the value formed by expanding the rest of parameter as the new parameter, then expands that value and uses it in the rest of the expansion.
The exceptions to nameref behavior are the expansions of ${!prefix*} and ${!name[@]}.
Braces are required when parameter is a positional parameter with more than one digit. For example, if $1 has value 'a', then ${11} expands to the eleventh positional parameter, while $11 expands to 'a1'.
The exclamation point must immediately follow the left brace in order to introduce indirection.
The $ character introduces parameter expansion, command substitution, or arithmetic expansion.
Redirections > Process Substitution
8 questionsYes, the filename generated by process substitution is passed as an argument to the current command as the result of the expansion.
Process substitution allows a process's input or output to be referred to using a filename.
The process list is run asynchronously, meaning it runs in the background as a separate process.
When the <(list) form is used, the file passed as an argument should be read to obtain the output of the list.
Process substitution is performed simultaneously with parameter and variable expansion, command substitution, and arithmetic expansion.
Process substitution takes two forms: <(list) for input process substitution and >(list) for output process substitution.
When the >(list) form is used, writing to the file will provide input for the list.
Process substitution is supported on systems that support named pipes (FIFOs) or the /dev/fd method of naming open files.
Bash Conditional Expressions > File Ownership Tests
8 questionsConditional expressions are used by the [[ compound command and the test and [ builtin commands.
The -k file operator returns true if the file exists and its 'sticky' bit is set.
The -g file operator returns true if the file exists and is set-group-id.
Yes, unless otherwise specified, primaries that operate on files follow symbolic links and operate on the target of the link, rather than the link itself.
The -u file operator returns true if the file exists and its set-user-id bit is set.
File test operators require the file to exist. For example, -O returns true if file exists AND is owned by the effective user ID.
The -O file operator returns true if the file exists and is owned by the effective user ID of the current process.
The -G file operator returns true if the file exists and is owned by the effective group ID of the current process.
Programmable Completion > Completion Behavior Options
2 questionsThe 'nospace' option prevents a trailing space from being added to the completed word. This is useful when you want to immediately continue typing more characters after the completion without an intervening space.
The 'filenames' option tells Readline that the completed values are filenames, so it performs filename-specific processing like adding a slash to directory names. The 'dirnames' option specifically completes only directory names.