set
Set or unset shell options and variables
TLDR
Display the names and values of shell variables
Export newly initialized variables to child processes
Write formatted messages to stderr when jobs finish
Write and edit text in the command-line with vi-like keybindings (e.g. yy)
Return to default mode
List all modes
Exit the shell when (some) command fails
Reset all shell parameters and assign new ones
SYNOPSIS
set [options] [--] [arg ...]
set -o [option_name]
set +o [option_name]
PARAMETERS
-a, -o allexport
Automatically marks variables and functions that are modified or created for export to the environment of subsequent commands.
-b, -o notify
Reports the status of terminated background jobs immediately, rather than waiting for the next primary prompt.
-e, -o errexit
Exits immediately if a command exits with a non-zero status. Useful for scripting to prevent unexpected behavior after an error.
-f, -o noglob
Disables filename expansion (globbing). Shell metacharacters like *, ?, [ will be treated as literal characters.
-h, -o hashall
Locates commands by hashing their path during command lookup. This is usually enabled by default in Bash.
-k, -o keyword
All arguments in a command line that appear to be assignment statements are placed in the environment of that command, not just those that precede the command name.
-m, -o monitor
Enables job control (e.g., stopping processes with Ctrl+Z, putting them in the background with &).
-n, -o noexec
Reads commands but does not execute them. Useful for checking script syntax without running it.
-o option_name
Enables the specified option. If used without an option name (set -o), it lists all current shell options and their status.
+o option_name
Disables the specified option.
-p, -o privileged
Turns on privileged mode, which disables processing of ~/.bashrc and /etc/profile files when running as root, for security.
-t, -o onecmd
Exits after reading and executing one command. Useful for single-command execution in interactive shells.
-u, -o nounset
Treats unset variables and parameters as an error when performing parameter expansion. Useful for catching typos in variable names.
-v, -o verbose
Prints shell input lines as they are read. Useful for debugging scripts by showing the raw input.
-x, -o xtrace
Prints commands and their expanded arguments to standard error as they are executed. Indispensable for debugging script execution flow.
-B, -o braceexpand
Enables brace expansion (e.g., {a,b}c expands to ac bc). This is usually enabled by default.
-C, -o noclobber
Prevents output redirection (>, >&) from overwriting existing files. Use >| to force overwrite.
-E, -o errtrace
If errexit is set, traps on ERR are inherited by shell functions, command substitutions, and subshells. (Bash 4.0+)
-H, -o histexpand
Enables !-style history expansion. This is usually enabled by default for interactive shells.
-P, -o physical
If set, do not follow symbolic links when performing commands that change the current directory (e.g., cd). The current working directory will be the physical directory.
-T, -o extdebug
Enables extended debugging mode. When a function is called, the BASH_COMMAND and BASH_SUBSHELL variables are set and ERR trap is inherited.
--
Signals the end of options. Subsequent arguments are treated as positional parameters, even if they begin with a hyphen.
arg ...
When -- is used, these arguments become the new positional parameters ($1, $2, ...). If no arguments are provided after --, positional parameters are unset.
DESCRIPTION
The set command is a fundamental shell built-in used to modify the behavior of the current shell session or script. It allows users to enable or disable various shell options that control how the shell interprets and executes commands, handles errors, manages jobs, and performs filename expansion. Additionally, set can be used to explicitly define or redefine the shell's positional parameters ($1, $2, ...), which are crucial for script argument processing. Unlike external commands, set directly interacts with and alters the shell's internal state. This command is indispensable for writing robust shell scripts by enforcing specific execution rules, such as exiting on error, tracing command execution for debugging, or preventing accidental file overwrites.
CAVEATS
The set command is a shell built-in; its exact behavior and available options can vary slightly between different shells (e.g., Bash, Zsh, Dash). Changes made with set are generally local to the current shell process or script and do not affect parent shells or other concurrently running shells. When using -e (errexit), be aware of its interaction with command pipelines (cmd1 | cmd2), logical operators (&&, ||), and command substitutions, as these can sometimes mask or alter the expected error propagation.
LISTING SHELL VARIABLES
When invoked without any arguments or options (i.e., just set), the command typically outputs a list of all currently defined shell variables and their values in a format suitable for re-input to the shell. This can be very useful for inspecting the shell's current state.
POSITIONAL PARAMETERS
Beyond setting options, set is also used to explicitly assign values to the shell's positional parameters ($1, $2, ...). Using set -- arg1 arg2 ... allows you to define these parameters, overriding any passed to the script or function. If no arguments are given after --, all positional parameters are unset.
SHELL BUILT-IN
It's important to remember that set is a shell built-in command, meaning it's an integral part of the shell itself, not an external executable program. This allows it to directly modify the shell's internal state and context, which external commands cannot do.
DEBUGGING SCRIPTS
The -n (noexec), -v (verbose), and especially -x (xtrace) options are invaluable tools for debugging shell scripts. They allow you to examine script syntax, see input lines as they are read, and trace the execution path with expanded commands, respectively.
HISTORY
The set command has been a core component of Unix shells since the original Bourne Shell (sh) in the late 1970s, providing essential control over shell behavior and script execution. Its fundamental purpose of manipulating shell options and positional parameters has remained consistent across shell implementations. The -o option_name syntax for more descriptive option names was introduced with KornShell (ksh) and later adopted by Bash, enhancing readability and usability compared to the original single-letter flags. Its evolution reflects the growing complexity and scripting needs of Unix-like systems.